From 3ac4252c0fe859d95417293e00d02774b69ad25f Mon Sep 17 00:00:00 2001 From: gsk <171930433@qq.com> Date: Sat, 23 Mar 2024 20:34:57 +0800 Subject: [PATCH] remove useless code --- CMakeLists.txt | 34 +- include/ylt/coro_http/coro_http_client.hpp | 29 - include/ylt/coro_http/coro_http_server.hpp | 30 - include/ylt/coro_io/channel.hpp | 235 - include/ylt/coro_io/client_pool.hpp | 603 -- include/ylt/coro_io/coro_file.hpp | 541 -- include/ylt/coro_io/coro_io.hpp | 419 - include/ylt/coro_io/detail/client_queue.hpp | 88 - include/ylt/coro_io/io_context_pool.hpp | 301 - include/ylt/coro_io/rate_limiter.hpp | 181 - include/ylt/coro_rpc/coro_rpc_client.hpp | 17 - include/ylt/coro_rpc/coro_rpc_context.hpp | 18 - include/ylt/coro_rpc/coro_rpc_server.hpp | 18 - include/ylt/coro_rpc/impl/common_service.hpp | 117 - include/ylt/coro_rpc/impl/context.hpp | 243 - include/ylt/coro_rpc/impl/coro_connection.hpp | 556 -- include/ylt/coro_rpc/impl/coro_rpc_client.hpp | 849 -- include/ylt/coro_rpc/impl/coro_rpc_server.hpp | 407 - .../impl/default_config/coro_rpc_config.hpp | 43 - include/ylt/coro_rpc/impl/errno.h | 92 - include/ylt/coro_rpc/impl/expected.hpp | 50 - .../impl/protocol/coro_rpc_protocol.hpp | 212 - .../impl/protocol/struct_pack_protocol.hpp | 38 - include/ylt/coro_rpc/impl/router.hpp | 405 - include/ylt/coro_rpc/impl/rpc_execute.hpp | 253 - include/ylt/easylog.hpp | 329 - include/ylt/easylog/appender.hpp | 409 - include/ylt/easylog/record.hpp | 283 - include/ylt/struct_json/json_reader.h | 19 - include/ylt/struct_json/json_writer.h | 20 - include/ylt/struct_pack.hpp | 714 -- include/ylt/struct_pack/alignment.hpp | 212 - include/ylt/struct_pack/calculate_size.hpp | 475 -- include/ylt/struct_pack/compatible.hpp | 151 - include/ylt/struct_pack/derived_helper.hpp | 230 - include/ylt/struct_pack/derived_marco.hpp | 35 - include/ylt/struct_pack/endian_wrapper.hpp | 273 - include/ylt/struct_pack/error_code.hpp | 84 - include/ylt/struct_pack/foreach_macro.h | 181 - include/ylt/struct_pack/marco.h | 70 - include/ylt/struct_pack/md5_constexpr.hpp | 335 - include/ylt/struct_pack/packer.hpp | 591 -- include/ylt/struct_pack/reflection.hpp | 2320 ------ include/ylt/struct_pack/size_info.hpp | 34 - include/ylt/struct_pack/trivial_view.hpp | 103 - include/ylt/struct_pack/tuple.hpp | 629 -- include/ylt/struct_pack/type_calculate.hpp | 915 --- include/ylt/struct_pack/type_id.hpp | 367 - include/ylt/struct_pack/type_trait.hpp | 54 - include/ylt/struct_pack/unpacker.hpp | 1474 ---- include/ylt/struct_pack/user_helper.hpp | 85 - include/ylt/struct_pack/util.h | 286 - include/ylt/struct_pack/varint.hpp | 356 - include/ylt/struct_pb.hpp | 102 - include/ylt/struct_pb/struct_pb_impl.hpp | 184 - include/ylt/struct_xml/xml_reader.h | 20 - include/ylt/struct_xml/xml_writer.h | 19 - include/ylt/struct_yaml/yaml_reader.h | 19 - include/ylt/struct_yaml/yaml_writer.h | 19 - include/ylt/thirdparty/asio.hpp | 208 - .../ylt/thirdparty/asio/any_io_executor.hpp | 303 - include/ylt/thirdparty/asio/append.hpp | 78 - include/ylt/thirdparty/asio/as_tuple.hpp | 139 - .../thirdparty/asio/associated_allocator.hpp | 177 - .../asio/associated_cancellation_slot.hpp | 178 - .../thirdparty/asio/associated_executor.hpp | 222 - include/ylt/thirdparty/asio/associator.hpp | 35 - include/ylt/thirdparty/asio/async_result.hpp | 1627 ---- include/ylt/thirdparty/asio/awaitable.hpp | 142 - .../thirdparty/asio/basic_datagram_socket.hpp | 1396 ---- .../thirdparty/asio/basic_deadline_timer.hpp | 715 -- include/ylt/thirdparty/asio/basic_file.hpp | 829 -- .../ylt/thirdparty/asio/basic_io_object.hpp | 290 - .../asio/basic_random_access_file.hpp | 701 -- .../ylt/thirdparty/asio/basic_raw_socket.hpp | 1387 ---- .../thirdparty/asio/basic_readable_pipe.hpp | 635 -- .../asio/basic_seq_packet_socket.hpp | 835 -- .../ylt/thirdparty/asio/basic_serial_port.hpp | 1000 --- .../ylt/thirdparty/asio/basic_signal_set.hpp | 598 -- include/ylt/thirdparty/asio/basic_socket.hpp | 1947 ----- .../thirdparty/asio/basic_socket_acceptor.hpp | 2751 ------- .../thirdparty/asio/basic_socket_iostream.hpp | 407 - .../asio/basic_socket_streambuf.hpp | 687 -- .../ylt/thirdparty/asio/basic_stream_file.hpp | 754 -- .../thirdparty/asio/basic_stream_socket.hpp | 1189 --- .../ylt/thirdparty/asio/basic_streambuf.hpp | 452 -- .../thirdparty/asio/basic_streambuf_fwd.hpp | 36 - .../thirdparty/asio/basic_waitable_timer.hpp | 833 -- .../thirdparty/asio/basic_writable_pipe.hpp | 631 -- .../ylt/thirdparty/asio/bind_allocator.hpp | 722 -- .../asio/bind_cancellation_slot.hpp | 724 -- include/ylt/thirdparty/asio/bind_executor.hpp | 770 -- include/ylt/thirdparty/asio/buffer.hpp | 2676 ------- .../thirdparty/asio/buffer_registration.hpp | 328 - .../thirdparty/asio/buffered_read_stream.hpp | 285 - .../asio/buffered_read_stream_fwd.hpp | 25 - .../ylt/thirdparty/asio/buffered_stream.hpp | 308 - .../thirdparty/asio/buffered_stream_fwd.hpp | 25 - .../thirdparty/asio/buffered_write_stream.hpp | 277 - .../asio/buffered_write_stream_fwd.hpp | 25 - .../ylt/thirdparty/asio/buffers_iterator.hpp | 521 -- .../thirdparty/asio/cancellation_signal.hpp | 305 - .../thirdparty/asio/cancellation_state.hpp | 235 - .../ylt/thirdparty/asio/cancellation_type.hpp | 174 - include/ylt/thirdparty/asio/co_spawn.hpp | 523 -- .../thirdparty/asio/completion_condition.hpp | 218 - include/ylt/thirdparty/asio/compose.hpp | 806 -- include/ylt/thirdparty/asio/connect.hpp | 1207 --- include/ylt/thirdparty/asio/connect_pipe.hpp | 83 - include/ylt/thirdparty/asio/coroutine.hpp | 328 - .../ylt/thirdparty/asio/deadline_timer.hpp | 38 - include/ylt/thirdparty/asio/defer.hpp | 216 - include/ylt/thirdparty/asio/deferred.hpp | 675 -- include/ylt/thirdparty/asio/detached.hpp | 113 - include/ylt/thirdparty/asio/detail/array.hpp | 38 - .../ylt/thirdparty/asio/detail/array_fwd.hpp | 34 - include/ylt/thirdparty/asio/detail/assert.hpp | 32 - .../thirdparty/asio/detail/atomic_count.hpp | 67 - .../detail/base_from_cancellation_state.hpp | 163 - .../asio/detail/base_from_completion_cond.hpp | 69 - .../thirdparty/asio/detail/bind_handler.hpp | 1071 --- .../asio/detail/blocking_executor_op.hpp | 107 - .../asio/detail/buffer_resize_guard.hpp | 66 - .../asio/detail/buffer_sequence_adapter.hpp | 841 -- .../asio/detail/buffered_stream_storage.hpp | 126 - .../asio/detail/bulk_executor_op.hpp | 88 - .../ylt/thirdparty/asio/detail/call_stack.hpp | 125 - include/ylt/thirdparty/asio/detail/chrono.hpp | 66 - .../asio/detail/chrono_time_traits.hpp | 190 - .../asio/detail/completion_handler.hpp | 88 - .../asio/detail/concurrency_hint.hpp | 94 - .../detail/conditionally_enabled_event.hpp | 120 - .../detail/conditionally_enabled_mutex.hpp | 149 - include/ylt/thirdparty/asio/detail/config.hpp | 2188 ------ .../asio/detail/consuming_buffers.hpp | 451 -- .../ylt/thirdparty/asio/detail/cstddef.hpp | 31 - .../ylt/thirdparty/asio/detail/cstdint.hpp | 62 - .../thirdparty/asio/detail/date_time_fwd.hpp | 34 - .../asio/detail/deadline_timer_service.hpp | 335 - .../thirdparty/asio/detail/dependent_type.hpp | 36 - .../thirdparty/asio/detail/descriptor_ops.hpp | 179 - .../asio/detail/descriptor_read_op.hpp | 150 - .../asio/detail/descriptor_write_op.hpp | 150 - .../asio/detail/dev_poll_reactor.hpp | 230 - .../thirdparty/asio/detail/epoll_reactor.hpp | 278 - include/ylt/thirdparty/asio/detail/event.hpp | 48 - .../detail/eventfd_select_interrupter.hpp | 83 - .../ylt/thirdparty/asio/detail/exception.hpp | 40 - .../asio/detail/executor_function.hpp | 204 - .../thirdparty/asio/detail/executor_op.hpp | 84 - .../thirdparty/asio/detail/fd_set_adapter.hpp | 39 - .../thirdparty/asio/detail/fenced_block.hpp | 80 - .../ylt/thirdparty/asio/detail/functional.hpp | 44 - include/ylt/thirdparty/asio/detail/future.hpp | 33 - .../asio/detail/gcc_arm_fenced_block.hpp | 91 - .../asio/detail/gcc_hppa_fenced_block.hpp | 68 - .../asio/detail/gcc_sync_fenced_block.hpp | 65 - .../asio/detail/gcc_x86_fenced_block.hpp | 99 - include/ylt/thirdparty/asio/detail/global.hpp | 52 - .../asio/detail/handler_alloc_helpers.hpp | 288 - .../asio/detail/handler_cont_helpers.hpp | 45 - .../asio/detail/handler_invoke_helpers.hpp | 80 - .../asio/detail/handler_tracking.hpp | 264 - .../asio/detail/handler_type_requirements.hpp | 559 -- .../thirdparty/asio/detail/handler_work.hpp | 525 -- .../ylt/thirdparty/asio/detail/hash_map.hpp | 331 - .../detail/impl/buffer_sequence_adapter.ipp | 118 - .../asio/detail/impl/descriptor_ops.ipp | 933 --- .../asio/detail/impl/dev_poll_reactor.hpp | 111 - .../asio/detail/impl/dev_poll_reactor.ipp | 460 -- .../asio/detail/impl/epoll_reactor.hpp | 109 - .../asio/detail/impl/epoll_reactor.ipp | 817 -- .../impl/eventfd_select_interrupter.ipp | 171 - .../asio/detail/impl/handler_tracking.ipp | 396 - .../impl/io_uring_descriptor_service.ipp | 205 - .../detail/impl/io_uring_file_service.ipp | 140 - .../asio/detail/impl/io_uring_service.hpp | 112 - .../asio/detail/impl/io_uring_service.ipp | 880 --- .../impl/io_uring_socket_service_base.ipp | 249 - .../asio/detail/impl/kqueue_reactor.hpp | 113 - .../asio/detail/impl/kqueue_reactor.ipp | 599 -- .../asio/detail/impl/null_event.ipp | 74 - .../detail/impl/pipe_select_interrupter.ipp | 129 - .../asio/detail/impl/posix_event.ipp | 63 - .../asio/detail/impl/posix_mutex.ipp | 46 - .../detail/impl/posix_serial_port_service.ipp | 168 - .../asio/detail/impl/posix_thread.ipp | 84 - .../asio/detail/impl/posix_tss_ptr.ipp | 46 - .../impl/reactive_descriptor_service.ipp | 230 - .../impl/reactive_socket_service_base.ipp | 302 - .../detail/impl/resolver_service_base.ipp | 158 - .../thirdparty/asio/detail/impl/scheduler.ipp | 674 -- .../asio/detail/impl/select_reactor.hpp | 124 - .../asio/detail/impl/select_reactor.ipp | 392 - .../asio/detail/impl/service_registry.hpp | 94 - .../asio/detail/impl/service_registry.ipp | 197 - .../asio/detail/impl/signal_set_service.ipp | 773 -- .../asio/detail/impl/socket_ops.ipp | 3969 ---------- .../detail/impl/socket_select_interrupter.ipp | 185 - .../detail/impl/strand_executor_service.hpp | 354 - .../detail/impl/strand_executor_service.ipp | 158 - .../asio/detail/impl/strand_service.hpp | 87 - .../asio/detail/impl/strand_service.ipp | 202 - .../asio/detail/impl/thread_context.ipp | 35 - .../asio/detail/impl/throw_error.ipp | 70 - .../asio/detail/impl/timer_queue_ptime.ipp | 97 - .../asio/detail/impl/timer_queue_set.ipp | 101 - .../thirdparty/asio/detail/impl/win_event.ipp | 76 - .../detail/impl/win_iocp_file_service.ipp | 264 - .../detail/impl/win_iocp_handle_service.ipp | 618 -- .../asio/detail/impl/win_iocp_io_context.hpp | 120 - .../asio/detail/impl/win_iocp_io_context.ipp | 608 -- .../impl/win_iocp_serial_port_service.ipp | 200 - .../impl/win_iocp_socket_service_base.ipp | 821 -- .../thirdparty/asio/detail/impl/win_mutex.ipp | 84 - .../detail/impl/win_object_handle_service.ipp | 452 -- .../asio/detail/impl/win_static_mutex.ipp | 136 - .../asio/detail/impl/win_thread.ipp | 150 - .../asio/detail/impl/win_tss_ptr.ipp | 57 - .../impl/winrt_ssocket_service_base.ipp | 626 -- .../detail/impl/winrt_timer_scheduler.hpp | 92 - .../detail/impl/winrt_timer_scheduler.ipp | 121 - .../asio/detail/impl/winsock_init.ipp | 82 - .../ylt/thirdparty/asio/detail/io_control.hpp | 84 - .../thirdparty/asio/detail/io_object_impl.hpp | 181 - .../detail/io_uring_descriptor_read_at_op.hpp | 192 - .../detail/io_uring_descriptor_read_op.hpp | 187 - .../detail/io_uring_descriptor_service.hpp | 679 -- .../io_uring_descriptor_write_at_op.hpp | 186 - .../detail/io_uring_descriptor_write_op.hpp | 182 - .../asio/detail/io_uring_file_service.hpp | 262 - .../asio/detail/io_uring_null_buffers_op.hpp | 113 - .../asio/detail/io_uring_operation.hpp | 84 - .../asio/detail/io_uring_service.hpp | 318 - .../asio/detail/io_uring_socket_accept_op.hpp | 281 - .../detail/io_uring_socket_connect_op.hpp | 139 - .../asio/detail/io_uring_socket_recv_op.hpp | 202 - .../detail/io_uring_socket_recvfrom_op.hpp | 203 - .../detail/io_uring_socket_recvmsg_op.hpp | 189 - .../asio/detail/io_uring_socket_send_op.hpp | 188 - .../asio/detail/io_uring_socket_sendto_op.hpp | 191 - .../asio/detail/io_uring_socket_service.hpp | 631 -- .../detail/io_uring_socket_service_base.hpp | 663 -- .../asio/detail/io_uring_wait_op.hpp | 111 - .../asio/detail/is_buffer_sequence.hpp | 338 - .../thirdparty/asio/detail/is_executor.hpp | 126 - .../asio/detail/keyword_tss_ptr.hpp | 70 - .../thirdparty/asio/detail/kqueue_reactor.hpp | 254 - include/ylt/thirdparty/asio/detail/limits.hpp | 26 - .../asio/detail/local_free_on_block_exit.hpp | 59 - .../asio/detail/macos_fenced_block.hpp | 62 - include/ylt/thirdparty/asio/detail/memory.hpp | 149 - include/ylt/thirdparty/asio/detail/mutex.hpp | 48 - .../asio/detail/non_const_lvalue.hpp | 54 - .../thirdparty/asio/detail/noncopyable.hpp | 43 - .../ylt/thirdparty/asio/detail/null_event.hpp | 106 - .../asio/detail/null_fenced_block.hpp | 47 - .../thirdparty/asio/detail/null_global.hpp | 59 - .../ylt/thirdparty/asio/detail/null_mutex.hpp | 60 - .../thirdparty/asio/detail/null_reactor.hpp | 83 - .../asio/detail/null_signal_blocker.hpp | 69 - .../asio/detail/null_socket_service.hpp | 519 -- .../asio/detail/null_static_mutex.hpp | 60 - .../thirdparty/asio/detail/null_thread.hpp | 67 - .../thirdparty/asio/detail/null_tss_ptr.hpp | 68 - .../thirdparty/asio/detail/object_pool.hpp | 171 - .../asio/detail/old_win_sdk_compat.hpp | 214 - .../ylt/thirdparty/asio/detail/op_queue.hpp | 162 - .../ylt/thirdparty/asio/detail/operation.hpp | 38 - .../asio/detail/pipe_select_interrupter.hpp | 89 - .../thirdparty/asio/detail/pop_options.hpp | 157 - .../thirdparty/asio/detail/posix_event.hpp | 175 - .../asio/detail/posix_fd_set_adapter.hpp | 118 - .../thirdparty/asio/detail/posix_global.hpp | 80 - .../thirdparty/asio/detail/posix_mutex.hpp | 76 - .../asio/detail/posix_serial_port_service.hpp | 249 - .../asio/detail/posix_signal_blocker.hpp | 85 - .../asio/detail/posix_static_mutex.hpp | 64 - .../thirdparty/asio/detail/posix_thread.hpp | 109 - .../thirdparty/asio/detail/posix_tss_ptr.hpp | 79 - .../thirdparty/asio/detail/push_options.hpp | 228 - .../detail/reactive_descriptor_service.hpp | 530 -- .../asio/detail/reactive_null_buffers_op.hpp | 98 - .../asio/detail/reactive_socket_accept_op.hpp | 246 - .../detail/reactive_socket_connect_op.hpp | 125 - .../asio/detail/reactive_socket_recv_op.hpp | 161 - .../detail/reactive_socket_recvfrom_op.hpp | 166 - .../detail/reactive_socket_recvmsg_op.hpp | 147 - .../asio/detail/reactive_socket_send_op.hpp | 164 - .../asio/detail/reactive_socket_sendto_op.hpp | 158 - .../asio/detail/reactive_socket_service.hpp | 633 -- .../detail/reactive_socket_service_base.hpp | 653 -- .../asio/detail/reactive_wait_op.hpp | 98 - .../ylt/thirdparty/asio/detail/reactor.hpp | 54 - .../ylt/thirdparty/asio/detail/reactor_op.hpp | 71 - .../asio/detail/reactor_op_queue.hpp | 212 - .../asio/detail/recycling_allocator.hpp | 105 - .../ylt/thirdparty/asio/detail/regex_fwd.hpp | 44 - .../asio/detail/resolve_endpoint_op.hpp | 140 - .../ylt/thirdparty/asio/detail/resolve_op.hpp | 45 - .../asio/detail/resolve_query_op.hpp | 150 - .../asio/detail/resolver_service.hpp | 147 - .../asio/detail/resolver_service_base.hpp | 158 - .../ylt/thirdparty/asio/detail/scheduler.hpp | 241 - .../asio/detail/scheduler_operation.hpp | 78 - .../thirdparty/asio/detail/scheduler_task.hpp | 49 - .../asio/detail/scheduler_thread_info.hpp | 40 - .../thirdparty/asio/detail/scoped_lock.hpp | 101 - .../ylt/thirdparty/asio/detail/scoped_ptr.hpp | 87 - .../asio/detail/select_interrupter.hpp | 46 - .../thirdparty/asio/detail/select_reactor.hpp | 274 - .../asio/detail/service_registry.hpp | 164 - .../thirdparty/asio/detail/signal_blocker.hpp | 44 - .../thirdparty/asio/detail/signal_handler.hpp | 90 - .../thirdparty/asio/detail/signal_init.hpp | 47 - .../ylt/thirdparty/asio/detail/signal_op.hpp | 53 - .../asio/detail/signal_set_service.hpp | 283 - .../thirdparty/asio/detail/socket_holder.hpp | 98 - .../ylt/thirdparty/asio/detail/socket_ops.hpp | 375 - .../thirdparty/asio/detail/socket_option.hpp | 316 - .../asio/detail/socket_select_interrupter.hpp | 91 - .../thirdparty/asio/detail/socket_types.hpp | 417 - .../asio/detail/solaris_fenced_block.hpp | 62 - .../asio/detail/source_location.hpp | 45 - .../thirdparty/asio/detail/static_mutex.hpp | 52 - .../ylt/thirdparty/asio/detail/std_event.hpp | 188 - .../asio/detail/std_fenced_block.hpp | 62 - .../ylt/thirdparty/asio/detail/std_global.hpp | 70 - .../ylt/thirdparty/asio/detail/std_mutex.hpp | 73 - .../asio/detail/std_static_mutex.hpp | 81 - .../ylt/thirdparty/asio/detail/std_thread.hpp | 71 - .../asio/detail/strand_executor_service.hpp | 173 - .../thirdparty/asio/detail/strand_service.hpp | 144 - .../thirdparty/asio/detail/string_view.hpp | 47 - include/ylt/thirdparty/asio/detail/thread.hpp | 60 - .../thirdparty/asio/detail/thread_context.hpp | 51 - .../thirdparty/asio/detail/thread_group.hpp | 99 - .../asio/detail/thread_info_base.hpp | 260 - .../thirdparty/asio/detail/throw_error.hpp | 62 - .../asio/detail/throw_exception.hpp | 55 - .../thirdparty/asio/detail/timer_queue.hpp | 389 - .../asio/detail/timer_queue_base.hpp | 68 - .../asio/detail/timer_queue_ptime.hpp | 103 - .../asio/detail/timer_queue_set.hpp | 66 - .../asio/detail/timer_scheduler.hpp | 37 - .../asio/detail/timer_scheduler_fwd.hpp | 42 - .../ylt/thirdparty/asio/detail/tss_ptr.hpp | 69 - .../thirdparty/asio/detail/type_traits.hpp | 164 - .../ylt/thirdparty/asio/detail/utility.hpp | 84 - .../asio/detail/variadic_templates.hpp | 294 - .../thirdparty/asio/detail/wait_handler.hpp | 90 - .../ylt/thirdparty/asio/detail/wait_op.hpp | 49 - .../ylt/thirdparty/asio/detail/win_event.hpp | 164 - .../asio/detail/win_fd_set_adapter.hpp | 149 - .../asio/detail/win_fenced_block.hpp | 90 - .../ylt/thirdparty/asio/detail/win_global.hpp | 71 - .../asio/detail/win_iocp_file_service.hpp | 287 - .../asio/detail/win_iocp_handle_read_op.hpp | 119 - .../asio/detail/win_iocp_handle_service.hpp | 431 -- .../asio/detail/win_iocp_handle_write_op.hpp | 114 - .../asio/detail/win_iocp_io_context.hpp | 345 - .../asio/detail/win_iocp_null_buffers_op.hpp | 129 - .../asio/detail/win_iocp_operation.hpp | 96 - .../asio/detail/win_iocp_overlapped_op.hpp | 100 - .../asio/detail/win_iocp_overlapped_ptr.hpp | 171 - .../detail/win_iocp_serial_port_service.hpp | 233 - .../asio/detail/win_iocp_socket_accept_op.hpp | 342 - .../detail/win_iocp_socket_connect_op.hpp | 137 - .../asio/detail/win_iocp_socket_recv_op.hpp | 126 - .../detail/win_iocp_socket_recvfrom_op.hpp | 135 - .../detail/win_iocp_socket_recvmsg_op.hpp | 127 - .../asio/detail/win_iocp_socket_send_op.hpp | 120 - .../asio/detail/win_iocp_socket_service.hpp | 683 -- .../detail/win_iocp_socket_service_base.hpp | 830 -- .../asio/detail/win_iocp_thread_info.hpp | 34 - .../asio/detail/win_iocp_wait_op.hpp | 130 - .../ylt/thirdparty/asio/detail/win_mutex.hpp | 78 - .../asio/detail/win_object_handle_service.hpp | 195 - .../asio/detail/win_static_mutex.hpp | 74 - .../ylt/thirdparty/asio/detail/win_thread.hpp | 147 - .../thirdparty/asio/detail/win_tss_ptr.hpp | 79 - .../thirdparty/asio/detail/winapp_thread.hpp | 124 - .../thirdparty/asio/detail/wince_thread.hpp | 124 - .../asio/detail/winrt_async_manager.hpp | 305 - .../thirdparty/asio/detail/winrt_async_op.hpp | 65 - .../asio/detail/winrt_resolve_op.hpp | 125 - .../asio/detail/winrt_resolver_service.hpp | 212 - .../asio/detail/winrt_socket_connect_op.hpp | 98 - .../asio/detail/winrt_socket_recv_op.hpp | 119 - .../asio/detail/winrt_socket_send_op.hpp | 110 - .../asio/detail/winrt_ssocket_service.hpp | 250 - .../detail/winrt_ssocket_service_base.hpp | 362 - .../asio/detail/winrt_timer_scheduler.hpp | 147 - .../thirdparty/asio/detail/winrt_utils.hpp | 106 - .../thirdparty/asio/detail/winsock_init.hpp | 128 - .../asio/detail/work_dispatcher.hpp | 153 - .../asio/detail/wrapped_handler.hpp | 327 - include/ylt/thirdparty/asio/dispatch.hpp | 205 - include/ylt/thirdparty/asio/error.hpp | 391 - include/ylt/thirdparty/asio/error_code.hpp | 202 - include/ylt/thirdparty/asio/execution.hpp | 48 - .../thirdparty/asio/execution/allocator.hpp | 337 - .../asio/execution/any_executor.hpp | 2351 ------ .../asio/execution/bad_executor.hpp | 47 - .../thirdparty/asio/execution/blocking.hpp | 1551 ---- .../asio/execution/blocking_adaptation.hpp | 1212 --- .../asio/execution/bulk_execute.hpp | 397 - .../asio/execution/bulk_guarantee.hpp | 1215 --- .../ylt/thirdparty/asio/execution/connect.hpp | 489 -- .../ylt/thirdparty/asio/execution/context.hpp | 233 - .../thirdparty/asio/execution/context_as.hpp | 221 - .../asio/execution/detail/as_invocable.hpp | 152 - .../asio/execution/detail/as_operation.hpp | 105 - .../asio/execution/detail/as_receiver.hpp | 128 - .../asio/execution/detail/bulk_sender.hpp | 261 - .../asio/execution/detail/submit_receiver.hpp | 233 - .../asio/execution/detail/void_receiver.hpp | 90 - .../ylt/thirdparty/asio/execution/execute.hpp | 283 - .../thirdparty/asio/execution/executor.hpp | 252 - .../asio/execution/impl/bad_executor.ipp | 40 - .../impl/receiver_invocation_error.ipp | 36 - .../asio/execution/invocable_archetype.hpp | 71 - .../ylt/thirdparty/asio/execution/mapping.hpp | 1116 --- .../thirdparty/asio/execution/occupancy.hpp | 226 - .../asio/execution/operation_state.hpp | 94 - .../asio/execution/outstanding_work.hpp | 867 --- .../thirdparty/asio/execution/prefer_only.hpp | 331 - .../thirdparty/asio/execution/receiver.hpp | 280 - .../execution/receiver_invocation_error.hpp | 48 - .../asio/execution/relationship.hpp | 865 --- .../thirdparty/asio/execution/schedule.hpp | 287 - .../thirdparty/asio/execution/scheduler.hpp | 86 - .../ylt/thirdparty/asio/execution/sender.hpp | 311 - .../thirdparty/asio/execution/set_done.hpp | 250 - .../thirdparty/asio/execution/set_error.hpp | 250 - .../thirdparty/asio/execution/set_value.hpp | 483 -- .../ylt/thirdparty/asio/execution/start.hpp | 247 - .../ylt/thirdparty/asio/execution/submit.hpp | 450 -- .../ylt/thirdparty/asio/execution_context.hpp | 412 - include/ylt/thirdparty/asio/executor.hpp | 347 - .../thirdparty/asio/executor_work_guard.hpp | 370 - .../thirdparty/asio/experimental/append.hpp | 36 - .../asio/experimental/as_single.hpp | 136 - .../thirdparty/asio/experimental/as_tuple.hpp | 36 - .../asio/experimental/awaitable_operators.hpp | 536 -- .../asio/experimental/basic_channel.hpp | 491 -- .../experimental/basic_concurrent_channel.hpp | 491 -- .../experimental/cancellation_condition.hpp | 155 - .../thirdparty/asio/experimental/channel.hpp | 70 - .../asio/experimental/channel_error.hpp | 84 - .../asio/experimental/channel_traits.hpp | 231 - .../thirdparty/asio/experimental/co_spawn.hpp | 187 - .../asio/experimental/concurrent_channel.hpp | 70 - .../ylt/thirdparty/asio/experimental/coro.hpp | 263 - .../asio/experimental/coro_traits.hpp | 228 - .../thirdparty/asio/experimental/deferred.hpp | 36 - .../experimental/detail/channel_handler.hpp | 70 - .../experimental/detail/channel_message.hpp | 122 - .../experimental/detail/channel_operation.hpp | 199 - .../experimental/detail/channel_payload.hpp | 93 - .../detail/channel_receive_op.hpp | 112 - .../detail/channel_send_functions.hpp | 132 - .../experimental/detail/channel_send_op.hpp | 140 - .../experimental/detail/channel_service.hpp | 497 -- .../detail/completion_handler_erasure.hpp | 194 - .../detail/coro_promise_allocator.hpp | 118 - .../experimental/detail/has_signature.hpp | 54 - .../detail/impl/channel_service.hpp | 609 -- .../experimental/detail/partial_promise.hpp | 176 - .../asio/experimental/impl/as_single.hpp | 229 - .../asio/experimental/impl/channel_error.ipp | 61 - .../asio/experimental/impl/coro.hpp | 1195 --- .../asio/experimental/impl/parallel_group.hpp | 418 - .../asio/experimental/impl/promise.hpp | 102 - .../asio/experimental/impl/use_coro.hpp | 268 - .../asio/experimental/parallel_group.hpp | 205 - .../thirdparty/asio/experimental/prepend.hpp | 36 - .../thirdparty/asio/experimental/promise.hpp | 228 - .../thirdparty/asio/experimental/use_coro.hpp | 169 - include/ylt/thirdparty/asio/file_base.hpp | 166 - .../asio/generic/basic_endpoint.hpp | 193 - .../asio/generic/datagram_protocol.hpp | 123 - .../asio/generic/detail/endpoint.hpp | 133 - .../asio/generic/detail/impl/endpoint.ipp | 110 - .../thirdparty/asio/generic/raw_protocol.hpp | 121 - .../asio/generic/seq_packet_protocol.hpp | 122 - .../asio/generic/stream_protocol.hpp | 127 - .../thirdparty/asio/handler_alloc_hook.hpp | 104 - .../asio/handler_continuation_hook.hpp | 54 - .../thirdparty/asio/handler_invoke_hook.hpp | 111 - .../thirdparty/asio/high_resolution_timer.hpp | 44 - .../thirdparty/asio/impl/any_io_executor.ipp | 129 - include/ylt/thirdparty/asio/impl/append.hpp | 216 - include/ylt/thirdparty/asio/impl/as_tuple.hpp | 244 - .../ylt/thirdparty/asio/impl/awaitable.hpp | 1155 --- .../asio/impl/buffered_read_stream.hpp | 508 -- .../asio/impl/buffered_write_stream.hpp | 488 -- .../asio/impl/cancellation_signal.ipp | 96 - include/ylt/thirdparty/asio/impl/co_spawn.hpp | 410 - include/ylt/thirdparty/asio/impl/connect.hpp | 937 --- .../ylt/thirdparty/asio/impl/connect_pipe.hpp | 73 - .../ylt/thirdparty/asio/impl/connect_pipe.ipp | 149 - include/ylt/thirdparty/asio/impl/defer.hpp | 266 - include/ylt/thirdparty/asio/impl/deferred.hpp | 95 - include/ylt/thirdparty/asio/impl/detached.hpp | 130 - include/ylt/thirdparty/asio/impl/dispatch.hpp | 261 - include/ylt/thirdparty/asio/impl/error.ipp | 128 - .../ylt/thirdparty/asio/impl/error_code.ipp | 206 - .../asio/impl/execution_context.hpp | 109 - .../asio/impl/execution_context.ipp | 82 - include/ylt/thirdparty/asio/impl/executor.hpp | 300 - include/ylt/thirdparty/asio/impl/executor.ipp | 43 - .../asio/impl/handler_alloc_hook.ipp | 62 - .../ylt/thirdparty/asio/impl/io_context.hpp | 450 -- .../ylt/thirdparty/asio/impl/io_context.ipp | 175 - .../asio/impl/multiple_exceptions.ipp | 49 - include/ylt/thirdparty/asio/impl/post.hpp | 266 - include/ylt/thirdparty/asio/impl/prepend.hpp | 216 - include/ylt/thirdparty/asio/impl/read.hpp | 1245 --- include/ylt/thirdparty/asio/impl/read_at.hpp | 753 -- .../ylt/thirdparty/asio/impl/read_until.hpp | 3375 -------- .../thirdparty/asio/impl/redirect_error.hpp | 609 -- .../thirdparty/asio/impl/serial_port_base.hpp | 59 - .../thirdparty/asio/impl/serial_port_base.ipp | 554 -- include/ylt/thirdparty/asio/impl/spawn.hpp | 1561 ---- include/ylt/thirdparty/asio/impl/src.hpp | 95 - .../thirdparty/asio/impl/system_context.hpp | 34 - .../thirdparty/asio/impl/system_context.ipp | 92 - .../thirdparty/asio/impl/system_executor.hpp | 185 - .../ylt/thirdparty/asio/impl/thread_pool.hpp | 354 - .../ylt/thirdparty/asio/impl/thread_pool.ipp | 141 - .../thirdparty/asio/impl/use_awaitable.hpp | 301 - .../ylt/thirdparty/asio/impl/use_future.hpp | 1028 --- include/ylt/thirdparty/asio/impl/write.hpp | 1145 --- include/ylt/thirdparty/asio/impl/write_at.hpp | 666 -- include/ylt/thirdparty/asio/io_context.hpp | 1547 ---- .../ylt/thirdparty/asio/io_context_strand.hpp | 388 - include/ylt/thirdparty/asio/io_service.hpp | 33 - .../ylt/thirdparty/asio/io_service_strand.hpp | 20 - include/ylt/thirdparty/asio/ip/address.hpp | 290 - include/ylt/thirdparty/asio/ip/address_v4.hpp | 429 -- .../asio/ip/address_v4_iterator.hpp | 162 - .../thirdparty/asio/ip/address_v4_range.hpp | 134 - include/ylt/thirdparty/asio/ip/address_v6.hpp | 416 - .../asio/ip/address_v6_iterator.hpp | 183 - .../thirdparty/asio/ip/address_v6_range.hpp | 129 - .../thirdparty/asio/ip/bad_address_cast.hpp | 53 - .../ylt/thirdparty/asio/ip/basic_endpoint.hpp | 291 - .../ylt/thirdparty/asio/ip/basic_resolver.hpp | 1142 --- .../asio/ip/basic_resolver_entry.hpp | 113 - .../asio/ip/basic_resolver_iterator.hpp | 192 - .../asio/ip/basic_resolver_query.hpp | 244 - .../asio/ip/basic_resolver_results.hpp | 311 - .../thirdparty/asio/ip/detail/endpoint.hpp | 141 - .../asio/ip/detail/impl/endpoint.ipp | 199 - .../asio/ip/detail/socket_option.hpp | 566 -- include/ylt/thirdparty/asio/ip/host_name.hpp | 42 - include/ylt/thirdparty/asio/ip/icmp.hpp | 115 - .../ylt/thirdparty/asio/ip/impl/address.hpp | 67 - .../ylt/thirdparty/asio/ip/impl/address.ipp | 239 - .../thirdparty/asio/ip/impl/address_v4.hpp | 67 - .../thirdparty/asio/ip/impl/address_v4.ipp | 210 - .../thirdparty/asio/ip/impl/address_v6.hpp | 67 - .../thirdparty/asio/ip/impl/address_v6.ipp | 350 - .../asio/ip/impl/basic_endpoint.hpp | 43 - .../ylt/thirdparty/asio/ip/impl/host_name.ipp | 54 - .../thirdparty/asio/ip/impl/network_v4.hpp | 54 - .../thirdparty/asio/ip/impl/network_v4.ipp | 216 - .../thirdparty/asio/ip/impl/network_v6.hpp | 53 - .../thirdparty/asio/ip/impl/network_v6.ipp | 185 - include/ylt/thirdparty/asio/ip/multicast.hpp | 191 - include/ylt/thirdparty/asio/ip/network_v4.hpp | 261 - include/ylt/thirdparty/asio/ip/network_v6.hpp | 235 - .../ylt/thirdparty/asio/ip/resolver_base.hpp | 129 - .../asio/ip/resolver_query_base.hpp | 43 - include/ylt/thirdparty/asio/ip/tcp.hpp | 155 - include/ylt/thirdparty/asio/ip/udp.hpp | 111 - include/ylt/thirdparty/asio/ip/unicast.hpp | 70 - include/ylt/thirdparty/asio/ip/v6_only.hpp | 69 - .../asio/is_applicable_property.hpp | 61 - .../asio/is_contiguous_iterator.hpp | 45 - include/ylt/thirdparty/asio/is_executor.hpp | 46 - .../ylt/thirdparty/asio/is_read_buffered.hpp | 59 - .../ylt/thirdparty/asio/is_write_buffered.hpp | 59 - .../thirdparty/asio/local/basic_endpoint.hpp | 247 - .../thirdparty/asio/local/connect_pair.hpp | 101 - .../asio/local/datagram_protocol.hpp | 80 - .../thirdparty/asio/local/detail/endpoint.hpp | 139 - .../asio/local/detail/impl/endpoint.ipp | 131 - .../thirdparty/asio/local/stream_protocol.hpp | 90 - .../thirdparty/asio/multiple_exceptions.hpp | 58 - include/ylt/thirdparty/asio/packaged_task.hpp | 126 - include/ylt/thirdparty/asio/placeholders.hpp | 151 - .../asio/posix/basic_descriptor.hpp | 781 -- .../asio/posix/basic_stream_descriptor.hpp | 569 -- .../ylt/thirdparty/asio/posix/descriptor.hpp | 37 - .../thirdparty/asio/posix/descriptor_base.hpp | 90 - .../asio/posix/stream_descriptor.hpp | 37 - include/ylt/thirdparty/asio/post.hpp | 212 - include/ylt/thirdparty/asio/prefer.hpp | 734 -- include/ylt/thirdparty/asio/prepend.hpp | 78 - include/ylt/thirdparty/asio/query.hpp | 324 - .../thirdparty/asio/random_access_file.hpp | 35 - include/ylt/thirdparty/asio/read.hpp | 1480 ---- include/ylt/thirdparty/asio/read_at.hpp | 795 -- include/ylt/thirdparty/asio/read_until.hpp | 3166 -------- include/ylt/thirdparty/asio/readable_pipe.hpp | 35 - .../thirdparty/asio/recycling_allocator.hpp | 138 - .../ylt/thirdparty/asio/redirect_error.hpp | 66 - .../ylt/thirdparty/asio/registered_buffer.hpp | 356 - include/ylt/thirdparty/asio/require.hpp | 571 -- .../ylt/thirdparty/asio/require_concept.hpp | 352 - include/ylt/thirdparty/asio/serial_port.hpp | 36 - .../ylt/thirdparty/asio/serial_port_base.hpp | 167 - include/ylt/thirdparty/asio/signal_set.hpp | 28 - include/ylt/thirdparty/asio/socket_base.hpp | 559 -- include/ylt/thirdparty/asio/spawn.hpp | 904 --- include/ylt/thirdparty/asio/ssl.hpp | 28 - include/ylt/thirdparty/asio/ssl/context.hpp | 764 -- .../ylt/thirdparty/asio/ssl/context_base.hpp | 209 - .../asio/ssl/detail/buffered_handshake_op.hpp | 119 - .../ylt/thirdparty/asio/ssl/detail/engine.hpp | 173 - .../asio/ssl/detail/handshake_op.hpp | 67 - .../asio/ssl/detail/impl/engine.ipp | 381 - .../asio/ssl/detail/impl/openssl_init.ipp | 169 - include/ylt/thirdparty/asio/ssl/detail/io.hpp | 425 - .../asio/ssl/detail/openssl_init.hpp | 101 - .../asio/ssl/detail/openssl_types.hpp | 34 - .../asio/ssl/detail/password_callback.hpp | 66 - .../thirdparty/asio/ssl/detail/read_op.hpp | 72 - .../asio/ssl/detail/shutdown_op.hpp | 69 - .../asio/ssl/detail/stream_core.hpp | 221 - .../asio/ssl/detail/verify_callback.hpp | 62 - .../thirdparty/asio/ssl/detail/write_op.hpp | 76 - include/ylt/thirdparty/asio/ssl/error.hpp | 125 - .../asio/ssl/host_name_verification.hpp | 90 - .../ylt/thirdparty/asio/ssl/impl/context.hpp | 67 - .../ylt/thirdparty/asio/ssl/impl/context.ipp | 1321 ---- .../ylt/thirdparty/asio/ssl/impl/error.ipp | 124 - .../asio/ssl/impl/host_name_verification.ipp | 73 - .../asio/ssl/impl/rfc2818_verification.ipp | 164 - include/ylt/thirdparty/asio/ssl/impl/src.hpp | 29 - .../asio/ssl/rfc2818_verification.hpp | 98 - include/ylt/thirdparty/asio/ssl/stream.hpp | 1073 --- .../ylt/thirdparty/asio/ssl/stream_base.hpp | 52 - .../thirdparty/asio/ssl/verify_context.hpp | 67 - .../ylt/thirdparty/asio/ssl/verify_mode.hpp | 63 - .../thirdparty/asio/static_thread_pool.hpp | 31 - include/ylt/thirdparty/asio/steady_timer.hpp | 42 - include/ylt/thirdparty/asio/strand.hpp | 580 -- include/ylt/thirdparty/asio/stream_file.hpp | 35 - include/ylt/thirdparty/asio/streambuf.hpp | 33 - .../ylt/thirdparty/asio/system_context.hpp | 90 - include/ylt/thirdparty/asio/system_error.hpp | 131 - .../ylt/thirdparty/asio/system_executor.hpp | 684 -- include/ylt/thirdparty/asio/system_timer.hpp | 42 - include/ylt/thirdparty/asio/this_coro.hpp | 280 - include/ylt/thirdparty/asio/thread.hpp | 92 - include/ylt/thirdparty/asio/thread_pool.hpp | 1140 --- include/ylt/thirdparty/asio/time_traits.hpp | 86 - .../asio/traits/bulk_execute_free.hpp | 114 - .../asio/traits/bulk_execute_member.hpp | 114 - .../thirdparty/asio/traits/connect_free.hpp | 112 - .../thirdparty/asio/traits/connect_member.hpp | 112 - .../asio/traits/equality_comparable.hpp | 104 - .../thirdparty/asio/traits/execute_free.hpp | 108 - .../thirdparty/asio/traits/execute_member.hpp | 108 - .../thirdparty/asio/traits/prefer_free.hpp | 108 - .../thirdparty/asio/traits/prefer_member.hpp | 108 - .../ylt/thirdparty/asio/traits/query_free.hpp | 108 - .../thirdparty/asio/traits/query_member.hpp | 108 - .../traits/query_static_constexpr_member.hpp | 108 - .../asio/traits/require_concept_free.hpp | 108 - .../asio/traits/require_concept_member.hpp | 108 - .../thirdparty/asio/traits/require_free.hpp | 108 - .../thirdparty/asio/traits/require_member.hpp | 108 - .../thirdparty/asio/traits/schedule_free.hpp | 108 - .../asio/traits/schedule_member.hpp | 108 - .../thirdparty/asio/traits/set_done_free.hpp | 108 - .../asio/traits/set_done_member.hpp | 108 - .../thirdparty/asio/traits/set_error_free.hpp | 112 - .../asio/traits/set_error_member.hpp | 112 - .../thirdparty/asio/traits/set_value_free.hpp | 234 - .../asio/traits/set_value_member.hpp | 234 - .../ylt/thirdparty/asio/traits/start_free.hpp | 108 - .../thirdparty/asio/traits/start_member.hpp | 108 - .../thirdparty/asio/traits/static_query.hpp | 108 - .../thirdparty/asio/traits/static_require.hpp | 123 - .../asio/traits/static_require_concept.hpp | 124 - .../thirdparty/asio/traits/submit_free.hpp | 112 - .../thirdparty/asio/traits/submit_member.hpp | 112 - include/ylt/thirdparty/asio/ts/buffer.hpp | 24 - include/ylt/thirdparty/asio/ts/executor.hpp | 35 - include/ylt/thirdparty/asio/ts/internet.hpp | 40 - include/ylt/thirdparty/asio/ts/io_context.hpp | 20 - include/ylt/thirdparty/asio/ts/net.hpp | 26 - include/ylt/thirdparty/asio/ts/netfwd.hpp | 254 - include/ylt/thirdparty/asio/ts/socket.hpp | 27 - include/ylt/thirdparty/asio/ts/timer.hpp | 26 - include/ylt/thirdparty/asio/unyield.hpp | 21 - include/ylt/thirdparty/asio/use_awaitable.hpp | 167 - include/ylt/thirdparty/asio/use_future.hpp | 163 - include/ylt/thirdparty/asio/uses_executor.hpp | 71 - include/ylt/thirdparty/asio/version.hpp | 23 - include/ylt/thirdparty/asio/wait_traits.hpp | 56 - .../asio/windows/basic_object_handle.hpp | 493 -- .../asio/windows/basic_overlapped_handle.hpp | 460 -- .../windows/basic_random_access_handle.hpp | 579 -- .../asio/windows/basic_stream_handle.hpp | 561 -- .../thirdparty/asio/windows/object_handle.hpp | 38 - .../asio/windows/overlapped_handle.hpp | 39 - .../asio/windows/overlapped_ptr.hpp | 145 - .../asio/windows/random_access_handle.hpp | 37 - .../thirdparty/asio/windows/stream_handle.hpp | 37 - include/ylt/thirdparty/asio/writable_pipe.hpp | 35 - include/ylt/thirdparty/asio/write.hpp | 1438 ---- include/ylt/thirdparty/asio/write_at.hpp | 805 -- include/ylt/thirdparty/asio/yield.hpp | 23 - .../thirdparty/async_simple/CMakeLists.txt | 73 - include/ylt/thirdparty/async_simple/Collect.h | 99 - include/ylt/thirdparty/async_simple/Common.h | 62 - .../ylt/thirdparty/async_simple/Executor.h | 177 - include/ylt/thirdparty/async_simple/Future.h | 366 - .../ylt/thirdparty/async_simple/FutureState.h | 331 - .../ylt/thirdparty/async_simple/IOExecutor.h | 76 - .../ylt/thirdparty/async_simple/LocalState.h | 96 - .../ylt/thirdparty/async_simple/MoveWrapper.h | 50 - include/ylt/thirdparty/async_simple/Promise.h | 122 - include/ylt/thirdparty/async_simple/Traits.h | 73 - include/ylt/thirdparty/async_simple/Try.h | 215 - include/ylt/thirdparty/async_simple/Unit.h | 37 - .../thirdparty/async_simple/coro/Collect.h | 589 -- .../async_simple/coro/ConditionVariable.h | 216 - .../thirdparty/async_simple/coro/CountEvent.h | 76 - .../async_simple/coro/DetachedCoroutine.h | 83 - .../async_simple/coro/FutureAwaiter.h | 49 - .../thirdparty/async_simple/coro/Generator.h | 621 -- .../ylt/thirdparty/async_simple/coro/Latch.h | 85 - .../ylt/thirdparty/async_simple/coro/Lazy.h | 520 -- .../ylt/thirdparty/async_simple/coro/Mutex.h | 235 - .../async_simple/coro/PromiseAllocator.h | 250 - .../thirdparty/async_simple/coro/Semaphore.h | 114 - .../async_simple/coro/SharedMutex.h | 155 - .../ylt/thirdparty/async_simple/coro/Sleep.h | 50 - .../thirdparty/async_simple/coro/SpinLock.h | 86 - .../thirdparty/async_simple/coro/SyncAwait.h | 62 - .../ylt/thirdparty/async_simple/coro/Traits.h | 75 - .../async_simple/coro/ViaCoroutine.h | 200 - .../async_simple/executors/SimpleExecutor.cpp | 49 - .../async_simple/executors/SimpleExecutor.h | 73 - .../async_simple/executors/SimpleIOExecutor.h | 167 - .../async_simple/experimental/coroutine.h | 413 - .../thirdparty/async_simple/uthread/Async.h | 129 - .../thirdparty/async_simple/uthread/Await.h | 127 - .../thirdparty/async_simple/uthread/Collect.h | 120 - .../thirdparty/async_simple/uthread/Latch.h | 79 - .../thirdparty/async_simple/uthread/Uthread.h | 98 - .../Darwin/arm64/jump_arm64_aapcs_macho_gas.S | 109 - .../Darwin/arm64/make_arm64_aapcs_macho_gas.S | 83 - .../arm64/ontop_arm64_aapcs_macho_gas.S | 108 - .../x86_64/jump_x86_64_sysv_macho_gas.S | 75 - .../x86_64/make_x86_64_sysv_macho_gas.S | 76 - .../x86_64/ontop_x86_64_sysv_macho_gas.S | 78 - .../Linux/aarch64/jump_arm64_aapcs_elf_gas.S | 114 - .../Linux/aarch64/make_arm64_aapcs_elf_gas.S | 85 - .../Linux/aarch64/ontop_arm64_aapcs_elf_gas.S | 113 - .../Linux/ppc64le/jump_ppc64_sysv_elf_gas.S | 221 - .../Linux/ppc64le/make_ppc64_sysv_elf_gas.S | 177 - .../Linux/ppc64le/ontop_ppc64_sysv_elf_gas.S | 244 - .../Linux/x86_64/jump_x86_64_sysv_elf_gas.S | 80 - .../Linux/x86_64/make_x86_64_sysv_elf_gas.S | 81 - .../Linux/x86_64/ontop_x86_64_sysv_elf_gas.S | 83 - .../async_simple/uthread/internal/thread.cc | 199 - .../async_simple/uthread/internal/thread.h | 73 - .../uthread/internal/thread_impl.h | 78 - .../thirdparty/async_simple/util/Condition.h | 68 - .../ylt/thirdparty/async_simple/util/Queue.h | 120 - .../thirdparty/async_simple/util/ThreadPool.h | 221 - .../cinatra/cinatra_log_wrapper.hpp | 75 - include/ylt/thirdparty/cinatra/cookie.hpp | 128 - .../thirdparty/cinatra/coro_http_client.hpp | 2044 ----- .../cinatra/coro_http_connection.hpp | 838 -- .../thirdparty/cinatra/coro_http_request.hpp | 275 - .../thirdparty/cinatra/coro_http_response.hpp | 330 - .../thirdparty/cinatra/coro_http_router.hpp | 275 - .../thirdparty/cinatra/coro_http_server.hpp | 793 -- .../thirdparty/cinatra/coro_radix_tree.hpp | 401 - include/ylt/thirdparty/cinatra/define.h | 417 - include/ylt/thirdparty/cinatra/gzip.hpp | 143 - .../ylt/thirdparty/cinatra/http_parser.hpp | 275 - .../thirdparty/cinatra/io_service_pool.hpp | 109 - include/ylt/thirdparty/cinatra/mime_types.hpp | 512 -- include/ylt/thirdparty/cinatra/multipart.hpp | 118 - .../ylt/thirdparty/cinatra/picohttpparser.h | 1246 --- .../ylt/thirdparty/cinatra/response_cv.hpp | 244 - include/ylt/thirdparty/cinatra/session.hpp | 104 - .../thirdparty/cinatra/session_manager.hpp | 106 - include/ylt/thirdparty/cinatra/sha1.hpp | 247 - .../ylt/thirdparty/cinatra/smtp_client.hpp | 212 - .../ylt/thirdparty/cinatra/string_resize.hpp | 130 - include/ylt/thirdparty/cinatra/time_util.hpp | 412 - include/ylt/thirdparty/cinatra/uri.hpp | 314 - .../thirdparty/cinatra/url_encode_decode.hpp | 123 - include/ylt/thirdparty/cinatra/use_asio.hpp | 17 - include/ylt/thirdparty/cinatra/utils.hpp | 295 - include/ylt/thirdparty/cinatra/websocket.hpp | 270 - include/ylt/thirdparty/cinatra/ws_define.h | 216 - include/ylt/thirdparty/frozen/CMakeLists.txt | 12 - include/ylt/thirdparty/frozen/algorithm.h | 203 - .../ylt/thirdparty/frozen/bits/algorithms.h | 240 - .../ylt/thirdparty/frozen/bits/basic_types.h | 224 - .../thirdparty/frozen/bits/constexpr_assert.h | 38 - include/ylt/thirdparty/frozen/bits/defines.h | 69 - include/ylt/thirdparty/frozen/bits/elsa.h | 60 - include/ylt/thirdparty/frozen/bits/elsa_std.h | 44 - .../ylt/thirdparty/frozen/bits/exceptions.h | 40 - .../ylt/thirdparty/frozen/bits/hash_string.h | 27 - include/ylt/thirdparty/frozen/bits/pmh.h | 259 - include/ylt/thirdparty/frozen/bits/version.h | 30 - include/ylt/thirdparty/frozen/map.h | 378 - include/ylt/thirdparty/frozen/random.h | 97 - include/ylt/thirdparty/frozen/set.h | 283 - include/ylt/thirdparty/frozen/string.h | 149 - include/ylt/thirdparty/frozen/unordered_map.h | 275 - include/ylt/thirdparty/frozen/unordered_set.h | 198 - include/ylt/thirdparty/iguana/define.h | 116 - .../ylt/thirdparty/iguana/detail/charconv.h | 53 - .../ylt/thirdparty/iguana/detail/dragonbox.h | 3044 -------- .../iguana/detail/dragonbox_to_chars.h | 629 -- .../ylt/thirdparty/iguana/detail/fast_float.h | 3196 -------- include/ylt/thirdparty/iguana/detail/itoa.hpp | 321 - .../iguana/detail/string_stream.hpp | 17 - .../ylt/thirdparty/iguana/detail/traits.hpp | 74 - include/ylt/thirdparty/iguana/detail/utf.hpp | 150 - .../ylt/thirdparty/iguana/enum_reflection.hpp | 186 - include/ylt/thirdparty/iguana/error_code.h | 100 - include/ylt/thirdparty/iguana/json_reader.hpp | 841 -- include/ylt/thirdparty/iguana/json_util.hpp | 217 - include/ylt/thirdparty/iguana/json_writer.hpp | 284 - include/ylt/thirdparty/iguana/prettify.hpp | 144 - include/ylt/thirdparty/iguana/reflection.hpp | 1015 --- include/ylt/thirdparty/iguana/util.hpp | 284 - include/ylt/thirdparty/iguana/value.hpp | 203 - include/ylt/thirdparty/iguana/xml_reader.hpp | 460 -- include/ylt/thirdparty/iguana/xml_util.hpp | 189 - include/ylt/thirdparty/iguana/xml_writer.hpp | 216 - include/ylt/thirdparty/iguana/yaml_reader.hpp | 573 -- include/ylt/thirdparty/iguana/yaml_util.hpp | 125 - include/ylt/thirdparty/iguana/yaml_writer.hpp | 194 - include/ylt/util/concurrentqueue.h | 4399 ----------- include/ylt/util/dragonbox.h | 3059 -------- include/ylt/util/dragonbox_to_chars.h | 644 -- include/ylt/util/expected.hpp | 2464 ------ include/ylt/util/function_name.h | 48 - include/ylt/util/magic_names.hpp | 227 - include/ylt/util/meta_string.hpp | 322 - include/ylt/util/string_finder.hpp | 120 - include/ylt/util/time_util.h | 562 -- include/ylt/util/type_traits.h | 216 - include/ylt/util/utils.hpp | 30 - src/coro_http/examples/CMakeLists.txt | 38 - src/coro_http/examples/channel.cpp | 78 - src/coro_http/examples/chat_room.cpp | 133 - src/coro_http/examples/client.html | 156 - src/coro_http/examples/example.cpp | 580 -- src/coro_io/examples/CMakeLists.txt | 35 - src/coro_io/examples/main.cpp | 211 - src/coro_io/tests/CMakeLists.txt | 15 - src/coro_io/tests/main.cpp | 24 - src/coro_io/tests/test_channel.cpp | 187 - src/coro_io/tests/test_client_pool.cpp | 241 - src/coro_io/tests/test_corofile.cpp | 950 --- src/coro_io/tests/test_rate_limiter.cpp | 89 - src/coro_rpc/benchmark/CMakeLists.txt | 24 - src/coro_rpc/benchmark/api/Monster.h | 59 - src/coro_rpc/benchmark/api/Rect.h | 22 - src/coro_rpc/benchmark/api/ValidateRequest.h | 42 - src/coro_rpc/benchmark/api/rpc_functions.hpp | 126 - src/coro_rpc/benchmark/client.cpp | 421 - src/coro_rpc/benchmark/data_gen.cpp | 122 - src/coro_rpc/benchmark/server.cpp | 22 - src/coro_rpc/benchmark/server.hpp | 49 - src/coro_rpc/examples/CMakeLists.txt | 7 - .../examples/base_examples/CMakeLists.txt | 54 - .../examples/base_examples/channel.cpp | 103 - .../examples/base_examples/client.cpp | 86 - .../examples/base_examples/client_pool.cpp | 91 - .../examples/base_examples/client_pools.cpp | 92 - .../base_examples/concurrent_clients.cpp | 92 - .../examples/base_examples/rpc_service.cpp | 116 - .../examples/base_examples/rpc_service.h | 40 - .../examples/base_examples/server.cpp | 50 - .../examples/file_transfer/BUILD.bazel | 28 - .../examples/file_transfer/CMakeLists.txt | 49 - .../examples/file_transfer/file_client.cpp | 111 - .../examples/file_transfer/file_server.cpp | 17 - .../examples/file_transfer/rpc_service.cpp | 71 - .../examples/file_transfer/rpc_service.h | 31 - .../rest_rpc/CMakeLists.txt | 60 - .../rest_rpc/config/msgpack_protocol.hpp | 51 - .../rest_rpc/config/rest_rpc_protocol.hpp | 111 - .../rest_rpc/rpc_service.h | 36 - .../rest_rpc/server/main.cpp | 70 - .../rest_rpc/server/rpc_service.cpp | 55 - src/coro_rpc/tests/BUILD.bazel | 31 - src/coro_rpc/tests/CMakeLists.txt | 46 - src/coro_rpc/tests/ServerTester.hpp | 437 -- src/coro_rpc/tests/inject_action.hpp | 43 - src/coro_rpc/tests/main.cpp | 25 - src/coro_rpc/tests/openssl_files/dh512.pem | 8 - src/coro_rpc/tests/openssl_files/dhparam.pem | 8 - .../tests/openssl_files/fake_server.crt | 14 - .../tests/openssl_files/fake_server.key | 18 - src/coro_rpc/tests/openssl_files/generate.txt | 7 - src/coro_rpc/tests/openssl_files/server.crt | 19 - src/coro_rpc/tests/openssl_files/server.csr | 11 - src/coro_rpc/tests/openssl_files/server.key | 30 - src/coro_rpc/tests/rpc_api.cpp | 120 - src/coro_rpc/tests/rpc_api.hpp | 90 - src/coro_rpc/tests/test_connection.cpp | 47 - src/coro_rpc/tests/test_coro_rpc_client.cpp | 612 -- src/coro_rpc/tests/test_coro_rpc_server.cpp | 354 - src/coro_rpc/tests/test_function_name.cpp | 107 - .../tests/test_register_duplication_1.cpp | 26 - .../tests/test_register_duplication_2.cpp | 25 - .../tests/test_register_duplication_3.cpp | 27 - src/coro_rpc/tests/test_register_handler.cpp | 72 - src/coro_rpc/tests/test_router.cpp | 390 - src/coro_rpc/tests/test_variadic.cpp | 60 - src/easylog/benchmark/CMakeLists.txt | 18 - src/easylog/benchmark/main.cpp | 149 - src/easylog/tests/CMakeLists.txt | 11 - src/easylog/tests/main.cpp | 24 - src/easylog/tests/test_easylog.cpp | 243 - src/include/doctest.h | 6817 ----------------- src/struct_json/examples/BUILD.bazel | 8 - src/struct_json/examples/CMakeLists.txt | 21 - src/struct_json/examples/main.cpp | 98 - .../examples/user_defined_struct.cpp | 59 - src/struct_pack/benchmark/.gitignore | 1 - src/struct_pack/benchmark/BUILD.bazel | 35 - src/struct_pack/benchmark/CMakeLists.txt | 43 - src/struct_pack/benchmark/ScopedTimer.hpp | 35 - src/struct_pack/benchmark/benchmark.cpp | 151 - src/struct_pack/benchmark/config.hpp | 84 - src/struct_pack/benchmark/data_def.fbs | 65 - src/struct_pack/benchmark/data_def.hpp | 178 - src/struct_pack/benchmark/data_def.proto | 60 - .../benchmark/flatbuffer_sample.hpp | 235 - src/struct_pack/benchmark/msgpack_sample.hpp | 101 - src/struct_pack/benchmark/no_op.cpp | 5 - src/struct_pack/benchmark/no_op.h | 5 - src/struct_pack/benchmark/protobuf_sample.hpp | 235 - src/struct_pack/benchmark/sample.hpp | 39 - .../benchmark/struct_pack_sample.hpp | 173 - .../benchmark/struct_pb_sample.hpp | 185 - src/struct_pack/examples/BUILD.bazel | 18 - src/struct_pack/examples/CMakeLists.txt | 21 - src/struct_pack/examples/basic_usage.cpp | 152 - src/struct_pack/examples/derived_class.cpp | 146 - src/struct_pack/examples/main.cpp | 29 - .../examples/non_aggregated_type.cpp | 151 - src/struct_pack/examples/serialize_config.cpp | 71 - .../examples/user_defined_serialization.cpp | 109 - src/struct_pack/tests/BUILD.bazel | 16 - src/struct_pack/tests/CMakeLists.txt | 25 - src/struct_pack/tests/binary_data/BUILD.bazel | 1 - .../tests/binary_data/test_cross_platform.dat | Bin 362 -> 0 bytes ...test_cross_platform_without_debug_info.dat | Bin 281 -> 0 bytes src/struct_pack/tests/main.cpp | 24 - src/struct_pack/tests/test_alignas.cpp | 216 - src/struct_pack/tests/test_compatible.cpp | 1310 ---- .../tests/test_compile_time_calculate.cpp | 539 -- src/struct_pack/tests/test_cross_platform.cpp | 52 - src/struct_pack/tests/test_data_struct.cpp | 651 -- src/struct_pack/tests/test_data_struct2.cpp | 616 -- src/struct_pack/tests/test_derived.cpp | 170 - src/struct_pack/tests/test_derived.hpp | 98 - .../tests/test_disable_meta_info.cpp | 148 - src/struct_pack/tests/test_fast_varint.cpp | 1190 --- .../tests/test_non_aggregated_type.cpp | 271 - src/struct_pack/tests/test_pragma_pack.cpp | 240 - .../test_pragma_pack_and_alignas_mix.cpp | 341 - src/struct_pack/tests/test_serialize.cpp | 1393 ---- src/struct_pack/tests/test_stream.cpp | 262 - src/struct_pack/tests/test_struct.hpp | 160 - src/struct_pack/tests/test_tuplet.cpp | 311 - .../tests/test_user_defined_type.cpp | 257 - src/struct_pack/tests/test_varint.cpp | 868 --- src/struct_pb/CMakeLists.txt | 2 - src/struct_pb/conformance/CMakeLists.txt | 68 - .../conformance/absl/status/status.h | 208 - .../conformance/absl/status/statusor.h | 20 - .../conformance/absl/strings/str_cat.h | 29 - .../conformance/absl/strings/str_format.h | 92 - .../binary_json_conformance_suite.cc | 1606 ---- .../binary_json_conformance_suite.h | 123 - .../conformance/conformance/conformance.proto | 180 - src/struct_pb/conformance/conformance_cpp.cc | 304 - .../conformance/conformance_struct_pb.cc | 242 - src/struct_pb/conformance/conformance_test.cc | 526 -- src/struct_pb/conformance/conformance_test.h | 331 - .../conformance/conformance_test_main.cc | 38 - .../conformance/conformance_test_runner.cc | 407 - .../conformance/failure_list_cpp.txt | 9 - .../conformance/google/protobuf/any.proto | 161 - .../google/protobuf/descriptor.proto | 921 --- .../google/protobuf/duration.proto | 115 - .../google/protobuf/field_mask.proto | 245 - .../google/protobuf/source_context.proto | 48 - .../conformance/google/protobuf/struct.proto | 95 - .../protobuf/test_messages_proto2.proto | 303 - .../protobuf/test_messages_proto3.proto | 288 - .../google/protobuf/timestamp.proto | 144 - .../conformance/google/protobuf/type.proto | 187 - .../google/protobuf/wrappers.proto | 123 - src/struct_pb/examples/CMakeLists.txt | 42 - src/struct_pb/examples/addressbook.proto | 53 - src/struct_pb/examples/demo.proto | 50 - src/struct_pb/examples/proto_to_struct.proto | 14 - src/struct_pb/examples/tutorial.cpp | 206 - src/struct_pb/tests/CMakeLists.txt | 55 - src/struct_pb/tests/data_def.proto | 60 - src/struct_pb/tests/helper.hpp | 78 - src/struct_pb/tests/hex_printer.hpp | 64 - src/struct_pb/tests/main.cpp | 24 - .../tests/test_bad_identifiers.proto | 191 - .../tests/test_large_enum_value.proto | 43 - src/struct_pb/tests/test_pb.cpp | 851 -- src/struct_pb/tests/test_pb.proto | 127 - .../tests/test_pb_bad_identifiers.cpp | 46 - .../tests/test_pb_benchmark_struct.cpp | 335 - src/struct_pb/tests/test_pb_oneof.cpp | 108 - src/struct_xml/examples/CMakeLists.txt | 24 - src/struct_xml/examples/main.cpp | 329 - src/struct_yaml/examples/CMakeLists.txt | 25 - src/struct_yaml/examples/main.cpp | 95 - src/util/tests/CMakeLists.txt | 8 - src/util/tests/test_meta_string.cpp | 225 - src/util/tests/test_time_util.cpp | 37 - website/.gitignore | 4 - website/.vitepress/config/en_data.ts | 34 - website/.vitepress/config/en_locale.ts | 30 - website/.vitepress/config/index.ts | 35 - website/.vitepress/config/zh_data.ts | 46 - website/.vitepress/config/zh_locale.ts | 31 - website/Doxyfile | 29 - website/Doxyfile_cn | 29 - website/README.md | 71 - .../docs/en/coro_rpc/coro_rpc_introduction.md | 378 - .../docs/en/coro_rpc/images/easy_to_use.png | Bin 122134 -> 0 bytes .../docs/en/coro_rpc/images/long_tail_qps.png | Bin 127574 -> 0 bytes .../en/coro_rpc/images/long_tail_time.png | Bin 112685 -> 0 bytes website/docs/en/coro_rpc/images/max_qps.png | Bin 122996 -> 0 bytes .../docs/en/coro_rpc/images/pingpong_qps.png | Bin 126174 -> 0 bytes .../docs/en/coro_rpc/images/pingpong_time.png | Bin 129205 -> 0 bytes .../en/guide/how_to_use_as_git_submodule.md | 62 - .../guide/how_to_use_by_cmake_find_package.md | 60 - .../docs/en/guide/what_is_yalantinglibs.md | 501 -- website/docs/en/index.md | 29 - .../docs/en/struct_pack/images/1byte_size.png | Bin 93406 -> 0 bytes .../docs/en/struct_pack/images/1byte_vec.png | Bin 102722 -> 0 bytes .../docs/en/struct_pack/images/2byte_size.png | Bin 93355 -> 0 bytes .../docs/en/struct_pack/images/2byte_vec.png | Bin 101157 -> 0 bytes .../docs/en/struct_pack/images/4byte_size.png | Bin 95229 -> 0 bytes .../docs/en/struct_pack/images/4byte_vec.png | Bin 104472 -> 0 bytes .../struct_pack/images/layout/LEN_SIZE.drawio | 13 - .../images/layout/array_layout.drawio | 28 - .../images/layout/array_layout.svg | 1 - .../images/layout/debug_person.drawio | 88 - .../images/layout/debug_person.svg | 1 - .../struct_pack/images/layout/expected.drawio | 28 - .../images/layout/hash_info.drawio | 34 - .../struct_pack/images/layout/hash_info.svg | 1 - .../images/layout/map_layout.drawio | 58 - .../struct_pack/images/layout/map_layout.svg | 1 - .../images/layout/memory_layout1.drawio | 22 - .../images/layout/memory_layout1.svg | 1 - .../images/layout/memory_layout2.drawio | 46 - .../images/layout/memory_layout2.svg | 4 - .../images/layout/meta_info.drawio | 46 - .../struct_pack/images/layout/meta_info.svg | 1 - .../images/layout/optional_has_value.drawio | 28 - .../images/layout/optional_has_value.svg | 1 - .../images/layout/optional_null.drawio | 19 - .../images/layout/optional_null.svg | 1 - .../images/layout/person_type_info.drawio | 34 - .../images/layout/person_type_info.svg | 1 - .../images/layout/release_person.drawio | 55 - .../images/layout/release_person.svg | 1 - .../layout/release_person_long_name.drawio | 58 - .../layout/release_person_long_name.svg | 1 - .../release_person_with_compatible.drawio | 73 - .../layout/release_person_with_compatible.svg | 1 - .../images/layout/set_layout.drawio | 34 - .../struct_pack/images/layout/set_layout.svg | 1 - .../images/layout/string_layout.drawio | 28 - .../images/layout/string_layout.svg | 1 - .../struct_pack/images/layout/variant.drawio | 28 - .../en/struct_pack/images/layout/variant.svg | 1 - .../images/layout/variant_with_error.drawio | 28 - .../images/layout/variant_with_error.svg | 1 - .../images/mem_layout_of_person.png | Bin 53035 -> 0 bytes .../images/mem_layout_of_vec_int.png | Bin 39489 -> 0 bytes .../images/mem_layout_of_vec_rect.png | Bin 39647 -> 0 bytes .../images/struct_pack_bench_binary_size.png | Bin 429253 -> 0 bytes .../images/struct_pack_bench_deserialize.png | Bin 444088 -> 0 bytes .../images/struct_pack_bench_serialize.png | Bin 434198 -> 0 bytes .../images/type_system/md5_generate.png | Bin 201350 -> 0 bytes .../docs/en/struct_pack/struct_pack_intro.md | 671 -- .../docs/en/struct_pack/struct_pack_layout.md | 372 - .../docs/en/struct_pack/struct_pack_tips.md | 97 - .../en/struct_pack/struct_pack_type_system.md | 366 - .../docs/en/struct_pb/images/pb_format.jpeg | Bin 19773 -> 0 bytes .../struct_pb/images/struct_pb_overview.jpeg | Bin 68961 -> 0 bytes website/docs/en/struct_pb/struct_pb_api.md | 65 - .../struct_pb_generating_your_struct.md | 34 - .../en/struct_pb/struct_pb_guide_proto3.md | 194 - website/docs/en/struct_pb/struct_pb_intro.md | 170 - .../en/struct_pb/struct_pb_quick_start.md | 237 - .../struct_pb/struct_pb_supported_features.md | 67 - website/docs/public/icon/logo.svg | 8 - .../img/yalantinglibs_ding_talk_group.png | Bin 137289 -> 0 bytes website/docs/public/index.html | 13 - website/docs/public/index.js | 19 - ... on Compile-time Reflection and C++ 20.pdf | Bin 3053299 -> 0 bytes .../public/resource/CppSummit_struct_pack.pdf | Bin 840350 -> 0 bytes .../coro_rpc_introduction_purecpp_talk.pdf | Bin 1289924 -> 0 bytes .../zh/coro_http/coro_http_introduction.md | 851 -- website/docs/zh/coro_rpc/coro_rpc_doc.hpp | 255 - .../docs/zh/coro_rpc/coro_rpc_introduction.md | 394 - .../docs/zh/easylog/easylog_introduction.md | 115 - .../zh/guide/how_to_use_as_git_submodule.md | 62 - .../guide/how_to_use_by_cmake_find_package.md | 60 - .../docs/zh/guide/what_is_yalantinglibs.md | 486 -- website/docs/zh/index.md | 31 - .../docs/zh/struct_pack/struct_pack_doc.hpp | 1401 ---- .../docs/zh/struct_pack/struct_pack_intro.md | 695 -- .../docs/zh/struct_pack/struct_pack_layout.md | 404 - .../docs/zh/struct_pack/struct_pack_tips.md | 100 - .../zh/struct_pack/struct_pack_type_system.md | 372 - website/docs/zh/struct_pb/struct_pb_api.md | 65 - .../struct_pb_generating_your_struct.md | 34 - .../zh/struct_pb/struct_pb_guide_proto3.md | 194 - website/docs/zh/struct_pb/struct_pb_intro.md | 170 - .../zh/struct_pb/struct_pb_quick_start.md | 237 - .../struct_pb/struct_pb_supported_features.md | 67 - .../zh/struct_xxx/struct_xxx_introduction.md | 347 - website/doxy/header.html | 127 - website/generate.sh | 28 - website/package.json | 18 - website/yarn.lock | 623 -- 1152 files changed, 5 insertions(+), 292168 deletions(-) delete mode 100644 include/ylt/coro_http/coro_http_client.hpp delete mode 100644 include/ylt/coro_http/coro_http_server.hpp delete mode 100644 include/ylt/coro_io/channel.hpp delete mode 100644 include/ylt/coro_io/client_pool.hpp delete mode 100644 include/ylt/coro_io/coro_file.hpp delete mode 100644 include/ylt/coro_io/coro_io.hpp delete mode 100644 include/ylt/coro_io/detail/client_queue.hpp delete mode 100644 include/ylt/coro_io/io_context_pool.hpp delete mode 100644 include/ylt/coro_io/rate_limiter.hpp delete mode 100644 include/ylt/coro_rpc/coro_rpc_client.hpp delete mode 100644 include/ylt/coro_rpc/coro_rpc_context.hpp delete mode 100644 include/ylt/coro_rpc/coro_rpc_server.hpp delete mode 100644 include/ylt/coro_rpc/impl/common_service.hpp delete mode 100644 include/ylt/coro_rpc/impl/context.hpp delete mode 100644 include/ylt/coro_rpc/impl/coro_connection.hpp delete mode 100644 include/ylt/coro_rpc/impl/coro_rpc_client.hpp delete mode 100644 include/ylt/coro_rpc/impl/coro_rpc_server.hpp delete mode 100644 include/ylt/coro_rpc/impl/default_config/coro_rpc_config.hpp delete mode 100644 include/ylt/coro_rpc/impl/errno.h delete mode 100644 include/ylt/coro_rpc/impl/expected.hpp delete mode 100644 include/ylt/coro_rpc/impl/protocol/coro_rpc_protocol.hpp delete mode 100644 include/ylt/coro_rpc/impl/protocol/struct_pack_protocol.hpp delete mode 100644 include/ylt/coro_rpc/impl/router.hpp delete mode 100644 include/ylt/coro_rpc/impl/rpc_execute.hpp delete mode 100644 include/ylt/easylog.hpp delete mode 100644 include/ylt/easylog/appender.hpp delete mode 100644 include/ylt/easylog/record.hpp delete mode 100644 include/ylt/struct_json/json_reader.h delete mode 100644 include/ylt/struct_json/json_writer.h delete mode 100644 include/ylt/struct_pack.hpp delete mode 100644 include/ylt/struct_pack/alignment.hpp delete mode 100644 include/ylt/struct_pack/calculate_size.hpp delete mode 100644 include/ylt/struct_pack/compatible.hpp delete mode 100644 include/ylt/struct_pack/derived_helper.hpp delete mode 100644 include/ylt/struct_pack/derived_marco.hpp delete mode 100644 include/ylt/struct_pack/endian_wrapper.hpp delete mode 100644 include/ylt/struct_pack/error_code.hpp delete mode 100644 include/ylt/struct_pack/foreach_macro.h delete mode 100644 include/ylt/struct_pack/marco.h delete mode 100644 include/ylt/struct_pack/md5_constexpr.hpp delete mode 100644 include/ylt/struct_pack/packer.hpp delete mode 100644 include/ylt/struct_pack/reflection.hpp delete mode 100644 include/ylt/struct_pack/size_info.hpp delete mode 100644 include/ylt/struct_pack/trivial_view.hpp delete mode 100644 include/ylt/struct_pack/tuple.hpp delete mode 100644 include/ylt/struct_pack/type_calculate.hpp delete mode 100644 include/ylt/struct_pack/type_id.hpp delete mode 100644 include/ylt/struct_pack/type_trait.hpp delete mode 100644 include/ylt/struct_pack/unpacker.hpp delete mode 100644 include/ylt/struct_pack/user_helper.hpp delete mode 100644 include/ylt/struct_pack/util.h delete mode 100644 include/ylt/struct_pack/varint.hpp delete mode 100644 include/ylt/struct_pb.hpp delete mode 100644 include/ylt/struct_pb/struct_pb_impl.hpp delete mode 100644 include/ylt/struct_xml/xml_reader.h delete mode 100644 include/ylt/struct_xml/xml_writer.h delete mode 100644 include/ylt/struct_yaml/yaml_reader.h delete mode 100644 include/ylt/struct_yaml/yaml_writer.h delete mode 100644 include/ylt/thirdparty/asio.hpp delete mode 100644 include/ylt/thirdparty/asio/any_io_executor.hpp delete mode 100644 include/ylt/thirdparty/asio/append.hpp delete mode 100644 include/ylt/thirdparty/asio/as_tuple.hpp delete mode 100644 include/ylt/thirdparty/asio/associated_allocator.hpp delete mode 100644 include/ylt/thirdparty/asio/associated_cancellation_slot.hpp delete mode 100644 include/ylt/thirdparty/asio/associated_executor.hpp delete mode 100644 include/ylt/thirdparty/asio/associator.hpp delete mode 100644 include/ylt/thirdparty/asio/async_result.hpp delete mode 100644 include/ylt/thirdparty/asio/awaitable.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_datagram_socket.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_deadline_timer.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_file.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_io_object.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_random_access_file.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_raw_socket.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_readable_pipe.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_seq_packet_socket.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_serial_port.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_signal_set.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_socket.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_socket_acceptor.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_socket_iostream.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_socket_streambuf.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_stream_file.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_stream_socket.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_streambuf.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_streambuf_fwd.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_waitable_timer.hpp delete mode 100644 include/ylt/thirdparty/asio/basic_writable_pipe.hpp delete mode 100644 include/ylt/thirdparty/asio/bind_allocator.hpp delete mode 100644 include/ylt/thirdparty/asio/bind_cancellation_slot.hpp delete mode 100644 include/ylt/thirdparty/asio/bind_executor.hpp delete mode 100644 include/ylt/thirdparty/asio/buffer.hpp delete mode 100644 include/ylt/thirdparty/asio/buffer_registration.hpp delete mode 100644 include/ylt/thirdparty/asio/buffered_read_stream.hpp delete mode 100644 include/ylt/thirdparty/asio/buffered_read_stream_fwd.hpp delete mode 100644 include/ylt/thirdparty/asio/buffered_stream.hpp delete mode 100644 include/ylt/thirdparty/asio/buffered_stream_fwd.hpp delete mode 100644 include/ylt/thirdparty/asio/buffered_write_stream.hpp delete mode 100644 include/ylt/thirdparty/asio/buffered_write_stream_fwd.hpp delete mode 100644 include/ylt/thirdparty/asio/buffers_iterator.hpp delete mode 100644 include/ylt/thirdparty/asio/cancellation_signal.hpp delete mode 100644 include/ylt/thirdparty/asio/cancellation_state.hpp delete mode 100644 include/ylt/thirdparty/asio/cancellation_type.hpp delete mode 100644 include/ylt/thirdparty/asio/co_spawn.hpp delete mode 100644 include/ylt/thirdparty/asio/completion_condition.hpp delete mode 100644 include/ylt/thirdparty/asio/compose.hpp delete mode 100644 include/ylt/thirdparty/asio/connect.hpp delete mode 100644 include/ylt/thirdparty/asio/connect_pipe.hpp delete mode 100644 include/ylt/thirdparty/asio/coroutine.hpp delete mode 100644 include/ylt/thirdparty/asio/deadline_timer.hpp delete mode 100644 include/ylt/thirdparty/asio/defer.hpp delete mode 100644 include/ylt/thirdparty/asio/deferred.hpp delete mode 100644 include/ylt/thirdparty/asio/detached.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/array.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/array_fwd.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/assert.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/atomic_count.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/base_from_cancellation_state.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/base_from_completion_cond.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/bind_handler.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/blocking_executor_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/buffer_resize_guard.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/buffer_sequence_adapter.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/buffered_stream_storage.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/bulk_executor_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/call_stack.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/chrono.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/chrono_time_traits.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/completion_handler.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/concurrency_hint.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/conditionally_enabled_event.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/conditionally_enabled_mutex.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/config.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/consuming_buffers.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/cstddef.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/cstdint.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/date_time_fwd.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/deadline_timer_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/dependent_type.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/descriptor_ops.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/descriptor_read_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/descriptor_write_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/dev_poll_reactor.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/epoll_reactor.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/event.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/eventfd_select_interrupter.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/exception.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/executor_function.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/executor_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/fd_set_adapter.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/fenced_block.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/functional.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/future.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/gcc_arm_fenced_block.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/gcc_hppa_fenced_block.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/gcc_sync_fenced_block.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/gcc_x86_fenced_block.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/global.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/handler_alloc_helpers.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/handler_cont_helpers.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/handler_invoke_helpers.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/handler_tracking.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/handler_type_requirements.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/handler_work.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/hash_map.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/buffer_sequence_adapter.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/descriptor_ops.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/dev_poll_reactor.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/dev_poll_reactor.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/epoll_reactor.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/epoll_reactor.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/eventfd_select_interrupter.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/handler_tracking.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/io_uring_descriptor_service.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/io_uring_file_service.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/io_uring_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/io_uring_service.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/io_uring_socket_service_base.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/kqueue_reactor.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/kqueue_reactor.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/null_event.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/pipe_select_interrupter.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/posix_event.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/posix_mutex.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/posix_serial_port_service.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/posix_thread.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/posix_tss_ptr.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/reactive_descriptor_service.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/reactive_socket_service_base.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/resolver_service_base.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/scheduler.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/select_reactor.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/select_reactor.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/service_registry.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/service_registry.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/signal_set_service.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/socket_ops.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/socket_select_interrupter.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/strand_executor_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/strand_executor_service.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/strand_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/strand_service.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/thread_context.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/throw_error.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/timer_queue_ptime.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/timer_queue_set.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/win_event.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/win_iocp_file_service.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/win_iocp_handle_service.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/win_iocp_io_context.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/win_iocp_io_context.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/win_iocp_serial_port_service.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/win_iocp_socket_service_base.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/win_mutex.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/win_object_handle_service.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/win_static_mutex.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/win_thread.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/win_tss_ptr.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/winrt_ssocket_service_base.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/winrt_timer_scheduler.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/winrt_timer_scheduler.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/impl/winsock_init.ipp delete mode 100644 include/ylt/thirdparty/asio/detail/io_control.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_object_impl.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_descriptor_read_at_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_descriptor_read_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_descriptor_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_descriptor_write_at_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_descriptor_write_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_file_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_null_buffers_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_operation.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_socket_accept_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_socket_connect_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_socket_recv_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_socket_recvfrom_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_socket_recvmsg_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_socket_send_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_socket_sendto_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_socket_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_socket_service_base.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/io_uring_wait_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/is_buffer_sequence.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/is_executor.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/keyword_tss_ptr.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/kqueue_reactor.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/limits.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/local_free_on_block_exit.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/macos_fenced_block.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/memory.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/mutex.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/non_const_lvalue.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/noncopyable.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/null_event.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/null_fenced_block.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/null_global.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/null_mutex.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/null_reactor.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/null_signal_blocker.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/null_socket_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/null_static_mutex.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/null_thread.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/null_tss_ptr.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/object_pool.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/old_win_sdk_compat.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/op_queue.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/operation.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/pipe_select_interrupter.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/pop_options.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/posix_event.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/posix_fd_set_adapter.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/posix_global.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/posix_mutex.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/posix_serial_port_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/posix_signal_blocker.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/posix_static_mutex.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/posix_thread.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/posix_tss_ptr.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/push_options.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactive_descriptor_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactive_null_buffers_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactive_socket_accept_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactive_socket_connect_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactive_socket_recv_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactive_socket_recvfrom_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactive_socket_recvmsg_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactive_socket_send_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactive_socket_sendto_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactive_socket_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactive_socket_service_base.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactive_wait_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactor.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactor_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/reactor_op_queue.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/recycling_allocator.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/regex_fwd.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/resolve_endpoint_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/resolve_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/resolve_query_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/resolver_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/resolver_service_base.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/scheduler.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/scheduler_operation.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/scheduler_task.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/scheduler_thread_info.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/scoped_lock.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/scoped_ptr.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/select_interrupter.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/select_reactor.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/service_registry.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/signal_blocker.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/signal_handler.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/signal_init.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/signal_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/signal_set_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/socket_holder.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/socket_ops.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/socket_option.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/socket_select_interrupter.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/socket_types.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/solaris_fenced_block.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/source_location.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/static_mutex.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/std_event.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/std_fenced_block.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/std_global.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/std_mutex.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/std_static_mutex.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/std_thread.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/strand_executor_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/strand_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/string_view.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/thread.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/thread_context.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/thread_group.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/thread_info_base.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/throw_error.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/throw_exception.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/timer_queue.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/timer_queue_base.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/timer_queue_ptime.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/timer_queue_set.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/timer_scheduler.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/timer_scheduler_fwd.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/tss_ptr.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/type_traits.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/utility.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/variadic_templates.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/wait_handler.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/wait_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_event.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_fd_set_adapter.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_fenced_block.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_global.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_file_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_handle_read_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_handle_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_handle_write_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_io_context.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_null_buffers_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_operation.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_overlapped_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_overlapped_ptr.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_serial_port_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_socket_accept_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_socket_connect_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_socket_recv_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_socket_recvfrom_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_socket_recvmsg_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_socket_send_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_socket_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_socket_service_base.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_thread_info.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_iocp_wait_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_mutex.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_object_handle_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_static_mutex.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_thread.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/win_tss_ptr.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/winapp_thread.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/wince_thread.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/winrt_async_manager.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/winrt_async_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/winrt_resolve_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/winrt_resolver_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/winrt_socket_connect_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/winrt_socket_recv_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/winrt_socket_send_op.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/winrt_ssocket_service.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/winrt_ssocket_service_base.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/winrt_timer_scheduler.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/winrt_utils.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/winsock_init.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/work_dispatcher.hpp delete mode 100644 include/ylt/thirdparty/asio/detail/wrapped_handler.hpp delete mode 100644 include/ylt/thirdparty/asio/dispatch.hpp delete mode 100644 include/ylt/thirdparty/asio/error.hpp delete mode 100644 include/ylt/thirdparty/asio/error_code.hpp delete mode 100644 include/ylt/thirdparty/asio/execution.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/allocator.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/any_executor.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/bad_executor.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/blocking.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/blocking_adaptation.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/bulk_execute.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/bulk_guarantee.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/connect.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/context.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/context_as.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/detail/as_invocable.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/detail/as_operation.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/detail/as_receiver.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/detail/bulk_sender.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/detail/submit_receiver.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/detail/void_receiver.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/execute.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/executor.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/impl/bad_executor.ipp delete mode 100644 include/ylt/thirdparty/asio/execution/impl/receiver_invocation_error.ipp delete mode 100644 include/ylt/thirdparty/asio/execution/invocable_archetype.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/mapping.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/occupancy.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/operation_state.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/outstanding_work.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/prefer_only.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/receiver.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/receiver_invocation_error.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/relationship.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/schedule.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/scheduler.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/sender.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/set_done.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/set_error.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/set_value.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/start.hpp delete mode 100644 include/ylt/thirdparty/asio/execution/submit.hpp delete mode 100644 include/ylt/thirdparty/asio/execution_context.hpp delete mode 100644 include/ylt/thirdparty/asio/executor.hpp delete mode 100644 include/ylt/thirdparty/asio/executor_work_guard.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/append.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/as_single.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/as_tuple.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/awaitable_operators.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/basic_channel.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/basic_concurrent_channel.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/cancellation_condition.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/channel.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/channel_error.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/channel_traits.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/co_spawn.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/concurrent_channel.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/coro.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/coro_traits.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/deferred.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/detail/channel_handler.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/detail/channel_message.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/detail/channel_operation.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/detail/channel_payload.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/detail/channel_receive_op.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/detail/channel_send_functions.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/detail/channel_send_op.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/detail/channel_service.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/detail/completion_handler_erasure.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/detail/coro_promise_allocator.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/detail/has_signature.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/detail/impl/channel_service.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/detail/partial_promise.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/impl/as_single.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/impl/channel_error.ipp delete mode 100644 include/ylt/thirdparty/asio/experimental/impl/coro.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/impl/parallel_group.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/impl/promise.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/impl/use_coro.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/parallel_group.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/prepend.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/promise.hpp delete mode 100644 include/ylt/thirdparty/asio/experimental/use_coro.hpp delete mode 100644 include/ylt/thirdparty/asio/file_base.hpp delete mode 100644 include/ylt/thirdparty/asio/generic/basic_endpoint.hpp delete mode 100644 include/ylt/thirdparty/asio/generic/datagram_protocol.hpp delete mode 100644 include/ylt/thirdparty/asio/generic/detail/endpoint.hpp delete mode 100644 include/ylt/thirdparty/asio/generic/detail/impl/endpoint.ipp delete mode 100644 include/ylt/thirdparty/asio/generic/raw_protocol.hpp delete mode 100644 include/ylt/thirdparty/asio/generic/seq_packet_protocol.hpp delete mode 100644 include/ylt/thirdparty/asio/generic/stream_protocol.hpp delete mode 100644 include/ylt/thirdparty/asio/handler_alloc_hook.hpp delete mode 100644 include/ylt/thirdparty/asio/handler_continuation_hook.hpp delete mode 100644 include/ylt/thirdparty/asio/handler_invoke_hook.hpp delete mode 100644 include/ylt/thirdparty/asio/high_resolution_timer.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/any_io_executor.ipp delete mode 100644 include/ylt/thirdparty/asio/impl/append.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/as_tuple.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/awaitable.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/buffered_read_stream.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/buffered_write_stream.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/cancellation_signal.ipp delete mode 100644 include/ylt/thirdparty/asio/impl/co_spawn.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/connect.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/connect_pipe.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/connect_pipe.ipp delete mode 100644 include/ylt/thirdparty/asio/impl/defer.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/deferred.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/detached.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/dispatch.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/error.ipp delete mode 100644 include/ylt/thirdparty/asio/impl/error_code.ipp delete mode 100644 include/ylt/thirdparty/asio/impl/execution_context.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/execution_context.ipp delete mode 100644 include/ylt/thirdparty/asio/impl/executor.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/executor.ipp delete mode 100644 include/ylt/thirdparty/asio/impl/handler_alloc_hook.ipp delete mode 100644 include/ylt/thirdparty/asio/impl/io_context.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/io_context.ipp delete mode 100644 include/ylt/thirdparty/asio/impl/multiple_exceptions.ipp delete mode 100644 include/ylt/thirdparty/asio/impl/post.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/prepend.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/read.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/read_at.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/read_until.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/redirect_error.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/serial_port_base.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/serial_port_base.ipp delete mode 100644 include/ylt/thirdparty/asio/impl/spawn.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/src.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/system_context.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/system_context.ipp delete mode 100644 include/ylt/thirdparty/asio/impl/system_executor.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/thread_pool.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/thread_pool.ipp delete mode 100644 include/ylt/thirdparty/asio/impl/use_awaitable.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/use_future.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/write.hpp delete mode 100644 include/ylt/thirdparty/asio/impl/write_at.hpp delete mode 100644 include/ylt/thirdparty/asio/io_context.hpp delete mode 100644 include/ylt/thirdparty/asio/io_context_strand.hpp delete mode 100644 include/ylt/thirdparty/asio/io_service.hpp delete mode 100644 include/ylt/thirdparty/asio/io_service_strand.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/address.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/address_v4.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/address_v4_iterator.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/address_v4_range.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/address_v6.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/address_v6_iterator.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/address_v6_range.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/bad_address_cast.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/basic_endpoint.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/basic_resolver.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/basic_resolver_entry.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/basic_resolver_iterator.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/basic_resolver_query.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/basic_resolver_results.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/detail/endpoint.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/detail/impl/endpoint.ipp delete mode 100644 include/ylt/thirdparty/asio/ip/detail/socket_option.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/host_name.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/icmp.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/impl/address.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/impl/address.ipp delete mode 100644 include/ylt/thirdparty/asio/ip/impl/address_v4.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/impl/address_v4.ipp delete mode 100644 include/ylt/thirdparty/asio/ip/impl/address_v6.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/impl/address_v6.ipp delete mode 100644 include/ylt/thirdparty/asio/ip/impl/basic_endpoint.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/impl/host_name.ipp delete mode 100644 include/ylt/thirdparty/asio/ip/impl/network_v4.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/impl/network_v4.ipp delete mode 100644 include/ylt/thirdparty/asio/ip/impl/network_v6.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/impl/network_v6.ipp delete mode 100644 include/ylt/thirdparty/asio/ip/multicast.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/network_v4.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/network_v6.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/resolver_base.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/resolver_query_base.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/tcp.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/udp.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/unicast.hpp delete mode 100644 include/ylt/thirdparty/asio/ip/v6_only.hpp delete mode 100644 include/ylt/thirdparty/asio/is_applicable_property.hpp delete mode 100644 include/ylt/thirdparty/asio/is_contiguous_iterator.hpp delete mode 100644 include/ylt/thirdparty/asio/is_executor.hpp delete mode 100644 include/ylt/thirdparty/asio/is_read_buffered.hpp delete mode 100644 include/ylt/thirdparty/asio/is_write_buffered.hpp delete mode 100644 include/ylt/thirdparty/asio/local/basic_endpoint.hpp delete mode 100644 include/ylt/thirdparty/asio/local/connect_pair.hpp delete mode 100644 include/ylt/thirdparty/asio/local/datagram_protocol.hpp delete mode 100644 include/ylt/thirdparty/asio/local/detail/endpoint.hpp delete mode 100644 include/ylt/thirdparty/asio/local/detail/impl/endpoint.ipp delete mode 100644 include/ylt/thirdparty/asio/local/stream_protocol.hpp delete mode 100644 include/ylt/thirdparty/asio/multiple_exceptions.hpp delete mode 100644 include/ylt/thirdparty/asio/packaged_task.hpp delete mode 100644 include/ylt/thirdparty/asio/placeholders.hpp delete mode 100644 include/ylt/thirdparty/asio/posix/basic_descriptor.hpp delete mode 100644 include/ylt/thirdparty/asio/posix/basic_stream_descriptor.hpp delete mode 100644 include/ylt/thirdparty/asio/posix/descriptor.hpp delete mode 100644 include/ylt/thirdparty/asio/posix/descriptor_base.hpp delete mode 100644 include/ylt/thirdparty/asio/posix/stream_descriptor.hpp delete mode 100644 include/ylt/thirdparty/asio/post.hpp delete mode 100644 include/ylt/thirdparty/asio/prefer.hpp delete mode 100644 include/ylt/thirdparty/asio/prepend.hpp delete mode 100644 include/ylt/thirdparty/asio/query.hpp delete mode 100644 include/ylt/thirdparty/asio/random_access_file.hpp delete mode 100644 include/ylt/thirdparty/asio/read.hpp delete mode 100644 include/ylt/thirdparty/asio/read_at.hpp delete mode 100644 include/ylt/thirdparty/asio/read_until.hpp delete mode 100644 include/ylt/thirdparty/asio/readable_pipe.hpp delete mode 100644 include/ylt/thirdparty/asio/recycling_allocator.hpp delete mode 100644 include/ylt/thirdparty/asio/redirect_error.hpp delete mode 100644 include/ylt/thirdparty/asio/registered_buffer.hpp delete mode 100644 include/ylt/thirdparty/asio/require.hpp delete mode 100644 include/ylt/thirdparty/asio/require_concept.hpp delete mode 100644 include/ylt/thirdparty/asio/serial_port.hpp delete mode 100644 include/ylt/thirdparty/asio/serial_port_base.hpp delete mode 100644 include/ylt/thirdparty/asio/signal_set.hpp delete mode 100644 include/ylt/thirdparty/asio/socket_base.hpp delete mode 100644 include/ylt/thirdparty/asio/spawn.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/context.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/context_base.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/detail/buffered_handshake_op.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/detail/engine.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/detail/handshake_op.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/detail/impl/engine.ipp delete mode 100644 include/ylt/thirdparty/asio/ssl/detail/impl/openssl_init.ipp delete mode 100644 include/ylt/thirdparty/asio/ssl/detail/io.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/detail/openssl_init.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/detail/openssl_types.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/detail/password_callback.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/detail/read_op.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/detail/shutdown_op.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/detail/stream_core.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/detail/verify_callback.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/detail/write_op.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/error.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/host_name_verification.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/impl/context.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/impl/context.ipp delete mode 100644 include/ylt/thirdparty/asio/ssl/impl/error.ipp delete mode 100644 include/ylt/thirdparty/asio/ssl/impl/host_name_verification.ipp delete mode 100644 include/ylt/thirdparty/asio/ssl/impl/rfc2818_verification.ipp delete mode 100644 include/ylt/thirdparty/asio/ssl/impl/src.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/rfc2818_verification.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/stream.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/stream_base.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/verify_context.hpp delete mode 100644 include/ylt/thirdparty/asio/ssl/verify_mode.hpp delete mode 100644 include/ylt/thirdparty/asio/static_thread_pool.hpp delete mode 100644 include/ylt/thirdparty/asio/steady_timer.hpp delete mode 100644 include/ylt/thirdparty/asio/strand.hpp delete mode 100644 include/ylt/thirdparty/asio/stream_file.hpp delete mode 100644 include/ylt/thirdparty/asio/streambuf.hpp delete mode 100644 include/ylt/thirdparty/asio/system_context.hpp delete mode 100644 include/ylt/thirdparty/asio/system_error.hpp delete mode 100644 include/ylt/thirdparty/asio/system_executor.hpp delete mode 100644 include/ylt/thirdparty/asio/system_timer.hpp delete mode 100644 include/ylt/thirdparty/asio/this_coro.hpp delete mode 100644 include/ylt/thirdparty/asio/thread.hpp delete mode 100644 include/ylt/thirdparty/asio/thread_pool.hpp delete mode 100644 include/ylt/thirdparty/asio/time_traits.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/bulk_execute_free.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/bulk_execute_member.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/connect_free.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/connect_member.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/equality_comparable.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/execute_free.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/execute_member.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/prefer_free.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/prefer_member.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/query_free.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/query_member.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/query_static_constexpr_member.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/require_concept_free.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/require_concept_member.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/require_free.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/require_member.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/schedule_free.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/schedule_member.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/set_done_free.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/set_done_member.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/set_error_free.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/set_error_member.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/set_value_free.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/set_value_member.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/start_free.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/start_member.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/static_query.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/static_require.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/static_require_concept.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/submit_free.hpp delete mode 100644 include/ylt/thirdparty/asio/traits/submit_member.hpp delete mode 100644 include/ylt/thirdparty/asio/ts/buffer.hpp delete mode 100644 include/ylt/thirdparty/asio/ts/executor.hpp delete mode 100644 include/ylt/thirdparty/asio/ts/internet.hpp delete mode 100644 include/ylt/thirdparty/asio/ts/io_context.hpp delete mode 100644 include/ylt/thirdparty/asio/ts/net.hpp delete mode 100644 include/ylt/thirdparty/asio/ts/netfwd.hpp delete mode 100644 include/ylt/thirdparty/asio/ts/socket.hpp delete mode 100644 include/ylt/thirdparty/asio/ts/timer.hpp delete mode 100644 include/ylt/thirdparty/asio/unyield.hpp delete mode 100644 include/ylt/thirdparty/asio/use_awaitable.hpp delete mode 100644 include/ylt/thirdparty/asio/use_future.hpp delete mode 100644 include/ylt/thirdparty/asio/uses_executor.hpp delete mode 100644 include/ylt/thirdparty/asio/version.hpp delete mode 100644 include/ylt/thirdparty/asio/wait_traits.hpp delete mode 100644 include/ylt/thirdparty/asio/windows/basic_object_handle.hpp delete mode 100644 include/ylt/thirdparty/asio/windows/basic_overlapped_handle.hpp delete mode 100644 include/ylt/thirdparty/asio/windows/basic_random_access_handle.hpp delete mode 100644 include/ylt/thirdparty/asio/windows/basic_stream_handle.hpp delete mode 100644 include/ylt/thirdparty/asio/windows/object_handle.hpp delete mode 100644 include/ylt/thirdparty/asio/windows/overlapped_handle.hpp delete mode 100644 include/ylt/thirdparty/asio/windows/overlapped_ptr.hpp delete mode 100644 include/ylt/thirdparty/asio/windows/random_access_handle.hpp delete mode 100644 include/ylt/thirdparty/asio/windows/stream_handle.hpp delete mode 100644 include/ylt/thirdparty/asio/writable_pipe.hpp delete mode 100644 include/ylt/thirdparty/asio/write.hpp delete mode 100644 include/ylt/thirdparty/asio/write_at.hpp delete mode 100644 include/ylt/thirdparty/asio/yield.hpp delete mode 100644 include/ylt/thirdparty/async_simple/CMakeLists.txt delete mode 100644 include/ylt/thirdparty/async_simple/Collect.h delete mode 100644 include/ylt/thirdparty/async_simple/Common.h delete mode 100644 include/ylt/thirdparty/async_simple/Executor.h delete mode 100644 include/ylt/thirdparty/async_simple/Future.h delete mode 100644 include/ylt/thirdparty/async_simple/FutureState.h delete mode 100644 include/ylt/thirdparty/async_simple/IOExecutor.h delete mode 100644 include/ylt/thirdparty/async_simple/LocalState.h delete mode 100644 include/ylt/thirdparty/async_simple/MoveWrapper.h delete mode 100644 include/ylt/thirdparty/async_simple/Promise.h delete mode 100644 include/ylt/thirdparty/async_simple/Traits.h delete mode 100644 include/ylt/thirdparty/async_simple/Try.h delete mode 100644 include/ylt/thirdparty/async_simple/Unit.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/Collect.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/ConditionVariable.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/CountEvent.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/DetachedCoroutine.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/FutureAwaiter.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/Generator.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/Latch.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/Lazy.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/Mutex.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/PromiseAllocator.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/Semaphore.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/SharedMutex.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/Sleep.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/SpinLock.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/SyncAwait.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/Traits.h delete mode 100644 include/ylt/thirdparty/async_simple/coro/ViaCoroutine.h delete mode 100644 include/ylt/thirdparty/async_simple/executors/SimpleExecutor.cpp delete mode 100644 include/ylt/thirdparty/async_simple/executors/SimpleExecutor.h delete mode 100644 include/ylt/thirdparty/async_simple/executors/SimpleIOExecutor.h delete mode 100644 include/ylt/thirdparty/async_simple/experimental/coroutine.h delete mode 100644 include/ylt/thirdparty/async_simple/uthread/Async.h delete mode 100644 include/ylt/thirdparty/async_simple/uthread/Await.h delete mode 100644 include/ylt/thirdparty/async_simple/uthread/Collect.h delete mode 100644 include/ylt/thirdparty/async_simple/uthread/Latch.h delete mode 100644 include/ylt/thirdparty/async_simple/uthread/Uthread.h delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Darwin/arm64/jump_arm64_aapcs_macho_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Darwin/arm64/make_arm64_aapcs_macho_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Darwin/arm64/ontop_arm64_aapcs_macho_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Darwin/x86_64/jump_x86_64_sysv_macho_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Darwin/x86_64/make_x86_64_sysv_macho_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Darwin/x86_64/ontop_x86_64_sysv_macho_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Linux/aarch64/jump_arm64_aapcs_elf_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Linux/aarch64/make_arm64_aapcs_elf_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Linux/aarch64/ontop_arm64_aapcs_elf_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Linux/ppc64le/jump_ppc64_sysv_elf_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Linux/ppc64le/make_ppc64_sysv_elf_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Linux/ppc64le/ontop_ppc64_sysv_elf_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Linux/x86_64/jump_x86_64_sysv_elf_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Linux/x86_64/make_x86_64_sysv_elf_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/Linux/x86_64/ontop_x86_64_sysv_elf_gas.S delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/thread.cc delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/thread.h delete mode 100644 include/ylt/thirdparty/async_simple/uthread/internal/thread_impl.h delete mode 100644 include/ylt/thirdparty/async_simple/util/Condition.h delete mode 100644 include/ylt/thirdparty/async_simple/util/Queue.h delete mode 100644 include/ylt/thirdparty/async_simple/util/ThreadPool.h delete mode 100644 include/ylt/thirdparty/cinatra/cinatra_log_wrapper.hpp delete mode 100644 include/ylt/thirdparty/cinatra/cookie.hpp delete mode 100644 include/ylt/thirdparty/cinatra/coro_http_client.hpp delete mode 100644 include/ylt/thirdparty/cinatra/coro_http_connection.hpp delete mode 100644 include/ylt/thirdparty/cinatra/coro_http_request.hpp delete mode 100644 include/ylt/thirdparty/cinatra/coro_http_response.hpp delete mode 100644 include/ylt/thirdparty/cinatra/coro_http_router.hpp delete mode 100644 include/ylt/thirdparty/cinatra/coro_http_server.hpp delete mode 100644 include/ylt/thirdparty/cinatra/coro_radix_tree.hpp delete mode 100644 include/ylt/thirdparty/cinatra/define.h delete mode 100644 include/ylt/thirdparty/cinatra/gzip.hpp delete mode 100644 include/ylt/thirdparty/cinatra/http_parser.hpp delete mode 100644 include/ylt/thirdparty/cinatra/io_service_pool.hpp delete mode 100644 include/ylt/thirdparty/cinatra/mime_types.hpp delete mode 100644 include/ylt/thirdparty/cinatra/multipart.hpp delete mode 100644 include/ylt/thirdparty/cinatra/picohttpparser.h delete mode 100644 include/ylt/thirdparty/cinatra/response_cv.hpp delete mode 100644 include/ylt/thirdparty/cinatra/session.hpp delete mode 100644 include/ylt/thirdparty/cinatra/session_manager.hpp delete mode 100644 include/ylt/thirdparty/cinatra/sha1.hpp delete mode 100644 include/ylt/thirdparty/cinatra/smtp_client.hpp delete mode 100644 include/ylt/thirdparty/cinatra/string_resize.hpp delete mode 100644 include/ylt/thirdparty/cinatra/time_util.hpp delete mode 100644 include/ylt/thirdparty/cinatra/uri.hpp delete mode 100644 include/ylt/thirdparty/cinatra/url_encode_decode.hpp delete mode 100644 include/ylt/thirdparty/cinatra/use_asio.hpp delete mode 100644 include/ylt/thirdparty/cinatra/utils.hpp delete mode 100644 include/ylt/thirdparty/cinatra/websocket.hpp delete mode 100644 include/ylt/thirdparty/cinatra/ws_define.h delete mode 100644 include/ylt/thirdparty/frozen/CMakeLists.txt delete mode 100644 include/ylt/thirdparty/frozen/algorithm.h delete mode 100644 include/ylt/thirdparty/frozen/bits/algorithms.h delete mode 100644 include/ylt/thirdparty/frozen/bits/basic_types.h delete mode 100644 include/ylt/thirdparty/frozen/bits/constexpr_assert.h delete mode 100644 include/ylt/thirdparty/frozen/bits/defines.h delete mode 100644 include/ylt/thirdparty/frozen/bits/elsa.h delete mode 100644 include/ylt/thirdparty/frozen/bits/elsa_std.h delete mode 100644 include/ylt/thirdparty/frozen/bits/exceptions.h delete mode 100644 include/ylt/thirdparty/frozen/bits/hash_string.h delete mode 100644 include/ylt/thirdparty/frozen/bits/pmh.h delete mode 100644 include/ylt/thirdparty/frozen/bits/version.h delete mode 100644 include/ylt/thirdparty/frozen/map.h delete mode 100644 include/ylt/thirdparty/frozen/random.h delete mode 100644 include/ylt/thirdparty/frozen/set.h delete mode 100644 include/ylt/thirdparty/frozen/string.h delete mode 100644 include/ylt/thirdparty/frozen/unordered_map.h delete mode 100644 include/ylt/thirdparty/frozen/unordered_set.h delete mode 100644 include/ylt/thirdparty/iguana/define.h delete mode 100644 include/ylt/thirdparty/iguana/detail/charconv.h delete mode 100644 include/ylt/thirdparty/iguana/detail/dragonbox.h delete mode 100644 include/ylt/thirdparty/iguana/detail/dragonbox_to_chars.h delete mode 100644 include/ylt/thirdparty/iguana/detail/fast_float.h delete mode 100644 include/ylt/thirdparty/iguana/detail/itoa.hpp delete mode 100644 include/ylt/thirdparty/iguana/detail/string_stream.hpp delete mode 100644 include/ylt/thirdparty/iguana/detail/traits.hpp delete mode 100644 include/ylt/thirdparty/iguana/detail/utf.hpp delete mode 100644 include/ylt/thirdparty/iguana/enum_reflection.hpp delete mode 100644 include/ylt/thirdparty/iguana/error_code.h delete mode 100644 include/ylt/thirdparty/iguana/json_reader.hpp delete mode 100644 include/ylt/thirdparty/iguana/json_util.hpp delete mode 100644 include/ylt/thirdparty/iguana/json_writer.hpp delete mode 100644 include/ylt/thirdparty/iguana/prettify.hpp delete mode 100644 include/ylt/thirdparty/iguana/reflection.hpp delete mode 100644 include/ylt/thirdparty/iguana/util.hpp delete mode 100644 include/ylt/thirdparty/iguana/value.hpp delete mode 100644 include/ylt/thirdparty/iguana/xml_reader.hpp delete mode 100644 include/ylt/thirdparty/iguana/xml_util.hpp delete mode 100644 include/ylt/thirdparty/iguana/xml_writer.hpp delete mode 100644 include/ylt/thirdparty/iguana/yaml_reader.hpp delete mode 100644 include/ylt/thirdparty/iguana/yaml_util.hpp delete mode 100644 include/ylt/thirdparty/iguana/yaml_writer.hpp delete mode 100644 include/ylt/util/concurrentqueue.h delete mode 100644 include/ylt/util/dragonbox.h delete mode 100644 include/ylt/util/dragonbox_to_chars.h delete mode 100644 include/ylt/util/expected.hpp delete mode 100644 include/ylt/util/function_name.h delete mode 100644 include/ylt/util/magic_names.hpp delete mode 100644 include/ylt/util/meta_string.hpp delete mode 100644 include/ylt/util/string_finder.hpp delete mode 100644 include/ylt/util/time_util.h delete mode 100644 include/ylt/util/type_traits.h delete mode 100644 include/ylt/util/utils.hpp delete mode 100644 src/coro_http/examples/CMakeLists.txt delete mode 100644 src/coro_http/examples/channel.cpp delete mode 100644 src/coro_http/examples/chat_room.cpp delete mode 100644 src/coro_http/examples/client.html delete mode 100644 src/coro_http/examples/example.cpp delete mode 100644 src/coro_io/examples/CMakeLists.txt delete mode 100644 src/coro_io/examples/main.cpp delete mode 100644 src/coro_io/tests/CMakeLists.txt delete mode 100644 src/coro_io/tests/main.cpp delete mode 100644 src/coro_io/tests/test_channel.cpp delete mode 100644 src/coro_io/tests/test_client_pool.cpp delete mode 100644 src/coro_io/tests/test_corofile.cpp delete mode 100644 src/coro_io/tests/test_rate_limiter.cpp delete mode 100644 src/coro_rpc/benchmark/CMakeLists.txt delete mode 100644 src/coro_rpc/benchmark/api/Monster.h delete mode 100644 src/coro_rpc/benchmark/api/Rect.h delete mode 100644 src/coro_rpc/benchmark/api/ValidateRequest.h delete mode 100644 src/coro_rpc/benchmark/api/rpc_functions.hpp delete mode 100644 src/coro_rpc/benchmark/client.cpp delete mode 100644 src/coro_rpc/benchmark/data_gen.cpp delete mode 100644 src/coro_rpc/benchmark/server.cpp delete mode 100644 src/coro_rpc/benchmark/server.hpp delete mode 100644 src/coro_rpc/examples/CMakeLists.txt delete mode 100644 src/coro_rpc/examples/base_examples/CMakeLists.txt delete mode 100644 src/coro_rpc/examples/base_examples/channel.cpp delete mode 100644 src/coro_rpc/examples/base_examples/client.cpp delete mode 100644 src/coro_rpc/examples/base_examples/client_pool.cpp delete mode 100644 src/coro_rpc/examples/base_examples/client_pools.cpp delete mode 100644 src/coro_rpc/examples/base_examples/concurrent_clients.cpp delete mode 100644 src/coro_rpc/examples/base_examples/rpc_service.cpp delete mode 100644 src/coro_rpc/examples/base_examples/rpc_service.h delete mode 100644 src/coro_rpc/examples/base_examples/server.cpp delete mode 100644 src/coro_rpc/examples/file_transfer/BUILD.bazel delete mode 100644 src/coro_rpc/examples/file_transfer/CMakeLists.txt delete mode 100644 src/coro_rpc/examples/file_transfer/file_client.cpp delete mode 100644 src/coro_rpc/examples/file_transfer/file_server.cpp delete mode 100644 src/coro_rpc/examples/file_transfer/rpc_service.cpp delete mode 100644 src/coro_rpc/examples/file_transfer/rpc_service.h delete mode 100644 src/coro_rpc/examples/user_defined_rpc_protocol/rest_rpc/CMakeLists.txt delete mode 100644 src/coro_rpc/examples/user_defined_rpc_protocol/rest_rpc/config/msgpack_protocol.hpp delete mode 100644 src/coro_rpc/examples/user_defined_rpc_protocol/rest_rpc/config/rest_rpc_protocol.hpp delete mode 100644 src/coro_rpc/examples/user_defined_rpc_protocol/rest_rpc/rpc_service.h delete mode 100644 src/coro_rpc/examples/user_defined_rpc_protocol/rest_rpc/server/main.cpp delete mode 100644 src/coro_rpc/examples/user_defined_rpc_protocol/rest_rpc/server/rpc_service.cpp delete mode 100644 src/coro_rpc/tests/BUILD.bazel delete mode 100644 src/coro_rpc/tests/CMakeLists.txt delete mode 100644 src/coro_rpc/tests/ServerTester.hpp delete mode 100644 src/coro_rpc/tests/inject_action.hpp delete mode 100644 src/coro_rpc/tests/main.cpp delete mode 100644 src/coro_rpc/tests/openssl_files/dh512.pem delete mode 100644 src/coro_rpc/tests/openssl_files/dhparam.pem delete mode 100644 src/coro_rpc/tests/openssl_files/fake_server.crt delete mode 100644 src/coro_rpc/tests/openssl_files/fake_server.key delete mode 100644 src/coro_rpc/tests/openssl_files/generate.txt delete mode 100644 src/coro_rpc/tests/openssl_files/server.crt delete mode 100644 src/coro_rpc/tests/openssl_files/server.csr delete mode 100644 src/coro_rpc/tests/openssl_files/server.key delete mode 100644 src/coro_rpc/tests/rpc_api.cpp delete mode 100644 src/coro_rpc/tests/rpc_api.hpp delete mode 100644 src/coro_rpc/tests/test_connection.cpp delete mode 100644 src/coro_rpc/tests/test_coro_rpc_client.cpp delete mode 100644 src/coro_rpc/tests/test_coro_rpc_server.cpp delete mode 100644 src/coro_rpc/tests/test_function_name.cpp delete mode 100644 src/coro_rpc/tests/test_register_duplication_1.cpp delete mode 100644 src/coro_rpc/tests/test_register_duplication_2.cpp delete mode 100644 src/coro_rpc/tests/test_register_duplication_3.cpp delete mode 100644 src/coro_rpc/tests/test_register_handler.cpp delete mode 100644 src/coro_rpc/tests/test_router.cpp delete mode 100644 src/coro_rpc/tests/test_variadic.cpp delete mode 100644 src/easylog/benchmark/CMakeLists.txt delete mode 100644 src/easylog/benchmark/main.cpp delete mode 100644 src/easylog/tests/CMakeLists.txt delete mode 100644 src/easylog/tests/main.cpp delete mode 100644 src/easylog/tests/test_easylog.cpp delete mode 100644 src/include/doctest.h delete mode 100644 src/struct_json/examples/BUILD.bazel delete mode 100644 src/struct_json/examples/CMakeLists.txt delete mode 100644 src/struct_json/examples/main.cpp delete mode 100644 src/struct_json/examples/user_defined_struct.cpp delete mode 100644 src/struct_pack/benchmark/.gitignore delete mode 100644 src/struct_pack/benchmark/BUILD.bazel delete mode 100644 src/struct_pack/benchmark/CMakeLists.txt delete mode 100644 src/struct_pack/benchmark/ScopedTimer.hpp delete mode 100644 src/struct_pack/benchmark/benchmark.cpp delete mode 100644 src/struct_pack/benchmark/config.hpp delete mode 100644 src/struct_pack/benchmark/data_def.fbs delete mode 100644 src/struct_pack/benchmark/data_def.hpp delete mode 100644 src/struct_pack/benchmark/data_def.proto delete mode 100644 src/struct_pack/benchmark/flatbuffer_sample.hpp delete mode 100644 src/struct_pack/benchmark/msgpack_sample.hpp delete mode 100644 src/struct_pack/benchmark/no_op.cpp delete mode 100644 src/struct_pack/benchmark/no_op.h delete mode 100644 src/struct_pack/benchmark/protobuf_sample.hpp delete mode 100644 src/struct_pack/benchmark/sample.hpp delete mode 100644 src/struct_pack/benchmark/struct_pack_sample.hpp delete mode 100644 src/struct_pack/benchmark/struct_pb_sample.hpp delete mode 100644 src/struct_pack/examples/BUILD.bazel delete mode 100644 src/struct_pack/examples/CMakeLists.txt delete mode 100644 src/struct_pack/examples/basic_usage.cpp delete mode 100644 src/struct_pack/examples/derived_class.cpp delete mode 100644 src/struct_pack/examples/main.cpp delete mode 100644 src/struct_pack/examples/non_aggregated_type.cpp delete mode 100644 src/struct_pack/examples/serialize_config.cpp delete mode 100644 src/struct_pack/examples/user_defined_serialization.cpp delete mode 100644 src/struct_pack/tests/BUILD.bazel delete mode 100644 src/struct_pack/tests/CMakeLists.txt delete mode 100644 src/struct_pack/tests/binary_data/BUILD.bazel delete mode 100644 src/struct_pack/tests/binary_data/test_cross_platform.dat delete mode 100644 src/struct_pack/tests/binary_data/test_cross_platform_without_debug_info.dat delete mode 100644 src/struct_pack/tests/main.cpp delete mode 100644 src/struct_pack/tests/test_alignas.cpp delete mode 100644 src/struct_pack/tests/test_compatible.cpp delete mode 100644 src/struct_pack/tests/test_compile_time_calculate.cpp delete mode 100644 src/struct_pack/tests/test_cross_platform.cpp delete mode 100644 src/struct_pack/tests/test_data_struct.cpp delete mode 100644 src/struct_pack/tests/test_data_struct2.cpp delete mode 100644 src/struct_pack/tests/test_derived.cpp delete mode 100644 src/struct_pack/tests/test_derived.hpp delete mode 100644 src/struct_pack/tests/test_disable_meta_info.cpp delete mode 100644 src/struct_pack/tests/test_fast_varint.cpp delete mode 100644 src/struct_pack/tests/test_non_aggregated_type.cpp delete mode 100644 src/struct_pack/tests/test_pragma_pack.cpp delete mode 100644 src/struct_pack/tests/test_pragma_pack_and_alignas_mix.cpp delete mode 100644 src/struct_pack/tests/test_serialize.cpp delete mode 100644 src/struct_pack/tests/test_stream.cpp delete mode 100644 src/struct_pack/tests/test_struct.hpp delete mode 100644 src/struct_pack/tests/test_tuplet.cpp delete mode 100644 src/struct_pack/tests/test_user_defined_type.cpp delete mode 100644 src/struct_pack/tests/test_varint.cpp delete mode 100644 src/struct_pb/CMakeLists.txt delete mode 100644 src/struct_pb/conformance/CMakeLists.txt delete mode 100644 src/struct_pb/conformance/absl/status/status.h delete mode 100644 src/struct_pb/conformance/absl/status/statusor.h delete mode 100644 src/struct_pb/conformance/absl/strings/str_cat.h delete mode 100644 src/struct_pb/conformance/absl/strings/str_format.h delete mode 100644 src/struct_pb/conformance/binary_json_conformance_suite.cc delete mode 100644 src/struct_pb/conformance/binary_json_conformance_suite.h delete mode 100644 src/struct_pb/conformance/conformance/conformance.proto delete mode 100644 src/struct_pb/conformance/conformance_cpp.cc delete mode 100644 src/struct_pb/conformance/conformance_struct_pb.cc delete mode 100644 src/struct_pb/conformance/conformance_test.cc delete mode 100644 src/struct_pb/conformance/conformance_test.h delete mode 100644 src/struct_pb/conformance/conformance_test_main.cc delete mode 100644 src/struct_pb/conformance/conformance_test_runner.cc delete mode 100644 src/struct_pb/conformance/failure_list_cpp.txt delete mode 100644 src/struct_pb/conformance/google/protobuf/any.proto delete mode 100644 src/struct_pb/conformance/google/protobuf/descriptor.proto delete mode 100644 src/struct_pb/conformance/google/protobuf/duration.proto delete mode 100644 src/struct_pb/conformance/google/protobuf/field_mask.proto delete mode 100644 src/struct_pb/conformance/google/protobuf/source_context.proto delete mode 100644 src/struct_pb/conformance/google/protobuf/struct.proto delete mode 100644 src/struct_pb/conformance/google/protobuf/test_messages_proto2.proto delete mode 100644 src/struct_pb/conformance/google/protobuf/test_messages_proto3.proto delete mode 100644 src/struct_pb/conformance/google/protobuf/timestamp.proto delete mode 100644 src/struct_pb/conformance/google/protobuf/type.proto delete mode 100644 src/struct_pb/conformance/google/protobuf/wrappers.proto delete mode 100644 src/struct_pb/examples/CMakeLists.txt delete mode 100644 src/struct_pb/examples/addressbook.proto delete mode 100644 src/struct_pb/examples/demo.proto delete mode 100644 src/struct_pb/examples/proto_to_struct.proto delete mode 100644 src/struct_pb/examples/tutorial.cpp delete mode 100644 src/struct_pb/tests/CMakeLists.txt delete mode 100644 src/struct_pb/tests/data_def.proto delete mode 100644 src/struct_pb/tests/helper.hpp delete mode 100644 src/struct_pb/tests/hex_printer.hpp delete mode 100644 src/struct_pb/tests/main.cpp delete mode 100644 src/struct_pb/tests/test_bad_identifiers.proto delete mode 100644 src/struct_pb/tests/test_large_enum_value.proto delete mode 100644 src/struct_pb/tests/test_pb.cpp delete mode 100644 src/struct_pb/tests/test_pb.proto delete mode 100644 src/struct_pb/tests/test_pb_bad_identifiers.cpp delete mode 100644 src/struct_pb/tests/test_pb_benchmark_struct.cpp delete mode 100644 src/struct_pb/tests/test_pb_oneof.cpp delete mode 100644 src/struct_xml/examples/CMakeLists.txt delete mode 100644 src/struct_xml/examples/main.cpp delete mode 100644 src/struct_yaml/examples/CMakeLists.txt delete mode 100644 src/struct_yaml/examples/main.cpp delete mode 100644 src/util/tests/CMakeLists.txt delete mode 100644 src/util/tests/test_meta_string.cpp delete mode 100644 src/util/tests/test_time_util.cpp delete mode 100644 website/.gitignore delete mode 100644 website/.vitepress/config/en_data.ts delete mode 100644 website/.vitepress/config/en_locale.ts delete mode 100644 website/.vitepress/config/index.ts delete mode 100644 website/.vitepress/config/zh_data.ts delete mode 100644 website/.vitepress/config/zh_locale.ts delete mode 100644 website/Doxyfile delete mode 100644 website/Doxyfile_cn delete mode 100644 website/README.md delete mode 100644 website/docs/en/coro_rpc/coro_rpc_introduction.md delete mode 100644 website/docs/en/coro_rpc/images/easy_to_use.png delete mode 100644 website/docs/en/coro_rpc/images/long_tail_qps.png delete mode 100644 website/docs/en/coro_rpc/images/long_tail_time.png delete mode 100644 website/docs/en/coro_rpc/images/max_qps.png delete mode 100644 website/docs/en/coro_rpc/images/pingpong_qps.png delete mode 100644 website/docs/en/coro_rpc/images/pingpong_time.png delete mode 100644 website/docs/en/guide/how_to_use_as_git_submodule.md delete mode 100644 website/docs/en/guide/how_to_use_by_cmake_find_package.md delete mode 100644 website/docs/en/guide/what_is_yalantinglibs.md delete mode 100644 website/docs/en/index.md delete mode 100644 website/docs/en/struct_pack/images/1byte_size.png delete mode 100644 website/docs/en/struct_pack/images/1byte_vec.png delete mode 100644 website/docs/en/struct_pack/images/2byte_size.png delete mode 100644 website/docs/en/struct_pack/images/2byte_vec.png delete mode 100644 website/docs/en/struct_pack/images/4byte_size.png delete mode 100644 website/docs/en/struct_pack/images/4byte_vec.png delete mode 100644 website/docs/en/struct_pack/images/layout/LEN_SIZE.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/array_layout.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/array_layout.svg delete mode 100644 website/docs/en/struct_pack/images/layout/debug_person.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/debug_person.svg delete mode 100644 website/docs/en/struct_pack/images/layout/expected.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/hash_info.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/hash_info.svg delete mode 100644 website/docs/en/struct_pack/images/layout/map_layout.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/map_layout.svg delete mode 100644 website/docs/en/struct_pack/images/layout/memory_layout1.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/memory_layout1.svg delete mode 100644 website/docs/en/struct_pack/images/layout/memory_layout2.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/memory_layout2.svg delete mode 100644 website/docs/en/struct_pack/images/layout/meta_info.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/meta_info.svg delete mode 100644 website/docs/en/struct_pack/images/layout/optional_has_value.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/optional_has_value.svg delete mode 100644 website/docs/en/struct_pack/images/layout/optional_null.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/optional_null.svg delete mode 100644 website/docs/en/struct_pack/images/layout/person_type_info.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/person_type_info.svg delete mode 100644 website/docs/en/struct_pack/images/layout/release_person.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/release_person.svg delete mode 100644 website/docs/en/struct_pack/images/layout/release_person_long_name.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/release_person_long_name.svg delete mode 100644 website/docs/en/struct_pack/images/layout/release_person_with_compatible.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/release_person_with_compatible.svg delete mode 100644 website/docs/en/struct_pack/images/layout/set_layout.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/set_layout.svg delete mode 100644 website/docs/en/struct_pack/images/layout/string_layout.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/string_layout.svg delete mode 100644 website/docs/en/struct_pack/images/layout/variant.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/variant.svg delete mode 100644 website/docs/en/struct_pack/images/layout/variant_with_error.drawio delete mode 100644 website/docs/en/struct_pack/images/layout/variant_with_error.svg delete mode 100644 website/docs/en/struct_pack/images/mem_layout_of_person.png delete mode 100644 website/docs/en/struct_pack/images/mem_layout_of_vec_int.png delete mode 100644 website/docs/en/struct_pack/images/mem_layout_of_vec_rect.png delete mode 100644 website/docs/en/struct_pack/images/struct_pack_bench_binary_size.png delete mode 100644 website/docs/en/struct_pack/images/struct_pack_bench_deserialize.png delete mode 100644 website/docs/en/struct_pack/images/struct_pack_bench_serialize.png delete mode 100644 website/docs/en/struct_pack/images/type_system/md5_generate.png delete mode 100644 website/docs/en/struct_pack/struct_pack_intro.md delete mode 100644 website/docs/en/struct_pack/struct_pack_layout.md delete mode 100644 website/docs/en/struct_pack/struct_pack_tips.md delete mode 100644 website/docs/en/struct_pack/struct_pack_type_system.md delete mode 100644 website/docs/en/struct_pb/images/pb_format.jpeg delete mode 100644 website/docs/en/struct_pb/images/struct_pb_overview.jpeg delete mode 100644 website/docs/en/struct_pb/struct_pb_api.md delete mode 100644 website/docs/en/struct_pb/struct_pb_generating_your_struct.md delete mode 100644 website/docs/en/struct_pb/struct_pb_guide_proto3.md delete mode 100644 website/docs/en/struct_pb/struct_pb_intro.md delete mode 100644 website/docs/en/struct_pb/struct_pb_quick_start.md delete mode 100644 website/docs/en/struct_pb/struct_pb_supported_features.md delete mode 100644 website/docs/public/icon/logo.svg delete mode 100644 website/docs/public/img/yalantinglibs_ding_talk_group.png delete mode 100644 website/docs/public/index.html delete mode 100644 website/docs/public/index.js delete mode 100644 website/docs/public/resource/A Faster Serialization Library Based on Compile-time Reflection and C++ 20.pdf delete mode 100644 website/docs/public/resource/CppSummit_struct_pack.pdf delete mode 100644 website/docs/public/resource/coro_rpc_introduction_purecpp_talk.pdf delete mode 100644 website/docs/zh/coro_http/coro_http_introduction.md delete mode 100644 website/docs/zh/coro_rpc/coro_rpc_doc.hpp delete mode 100644 website/docs/zh/coro_rpc/coro_rpc_introduction.md delete mode 100644 website/docs/zh/easylog/easylog_introduction.md delete mode 100644 website/docs/zh/guide/how_to_use_as_git_submodule.md delete mode 100644 website/docs/zh/guide/how_to_use_by_cmake_find_package.md delete mode 100644 website/docs/zh/guide/what_is_yalantinglibs.md delete mode 100644 website/docs/zh/index.md delete mode 100644 website/docs/zh/struct_pack/struct_pack_doc.hpp delete mode 100644 website/docs/zh/struct_pack/struct_pack_intro.md delete mode 100644 website/docs/zh/struct_pack/struct_pack_layout.md delete mode 100644 website/docs/zh/struct_pack/struct_pack_tips.md delete mode 100644 website/docs/zh/struct_pack/struct_pack_type_system.md delete mode 100644 website/docs/zh/struct_pb/struct_pb_api.md delete mode 100644 website/docs/zh/struct_pb/struct_pb_generating_your_struct.md delete mode 100644 website/docs/zh/struct_pb/struct_pb_guide_proto3.md delete mode 100644 website/docs/zh/struct_pb/struct_pb_intro.md delete mode 100644 website/docs/zh/struct_pb/struct_pb_quick_start.md delete mode 100644 website/docs/zh/struct_pb/struct_pb_supported_features.md delete mode 100644 website/docs/zh/struct_xxx/struct_xxx_introduction.md delete mode 100644 website/doxy/header.html delete mode 100755 website/generate.sh delete mode 100644 website/package.json delete mode 100644 website/yarn.lock diff --git a/CMakeLists.txt b/CMakeLists.txt index bc49e21c2..ea00c6173 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,38 +13,14 @@ project(yaLanTingLibs # set(SYSROOT_DIR /opt/zhito/sysroot) -set(CMAKE_PREFIX_PATH /home/gsk/pro/CyberRT/install/) +set(CMAKE_PREFIX_PATH "/home/gsk/pro/ubuntu2204_docker") find_package(Protobuf REQUIRED) -# load pack finder -list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/Find/) +add_subdirectory(src/protoc-plugin) -find_package(Threads REQUIRED) -link_libraries(Threads::Threads) +option(BUILD_EXAMPLES OFF) -include(cmake/install.cmake) - -if(CMAKE_PROJECT_NAME STREQUAL "yaLanTingLibs") # if ylt is top-level project - # add include path - # include_directories(include) - # include_directories(include/ylt/thirdparty) - # include_directories(src/include) - - # include(cmake/utils.cmake) - # include(cmake/struct_pb.cmake) - # include(cmake/build.cmake) - # include(cmake/develop.cmake) - # # add project config, such as enable_ssl. - # include(cmake/config.cmake) - # # add project's source such as unit test, example & benchmark - # include(cmake/subdir.cmake) +if(BUILD_EXAMPLES) + add_subdirectory(src/example) endif() - - -# 指定struct_pb库目录 - - - -# add_subdirectory(src/protoc-plugin) -add_subdirectory(src/example) \ No newline at end of file diff --git a/include/ylt/coro_http/coro_http_client.hpp b/include/ylt/coro_http/coro_http_client.hpp deleted file mode 100644 index e6fc026fd..000000000 --- a/include/ylt/coro_http/coro_http_client.hpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#ifdef YLT_ENABLE_SSL -#define CINATRA_ENABLE_SSL -#endif -#include -#define CINATRA_LOG_ERROR ELOG_ERROR -#define CINATRA_LOG_WARNING ELOG_WARN -#define CINATRA_LOG_INFO ELOG_INFO -#define CINATRA_LOG_DEBUG ELOG_DEBUG -#define CINATRA_LOG_TRACE ELOG_TRACE - -#include - -namespace coro_http = cinatra; \ No newline at end of file diff --git a/include/ylt/coro_http/coro_http_server.hpp b/include/ylt/coro_http/coro_http_server.hpp deleted file mode 100644 index 46269f8dd..000000000 --- a/include/ylt/coro_http/coro_http_server.hpp +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include "cinatra/uri.hpp" -#ifdef YLT_ENABLE_SSL -#define CINATRA_ENABLE_SSL -#endif -#include -#define CINATRA_LOG_ERROR ELOG_ERROR -#define CINATRA_LOG_WARNING ELOG_WARN -#define CINATRA_LOG_INFO ELOG_INFO -#define CINATRA_LOG_DEBUG ELOG_DEBUG -#define CINATRA_LOG_TRACE ELOG_TRACE - -#include - -namespace coro_http = cinatra; \ No newline at end of file diff --git a/include/ylt/coro_io/channel.hpp b/include/ylt/coro_io/channel.hpp deleted file mode 100644 index c9ee6d594..000000000 --- a/include/ylt/coro_io/channel.hpp +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include - -#include -#include -#include -#include - -#include "client_pool.hpp" -#include "io_context_pool.hpp" -namespace coro_io { - -enum class load_blance_algorithm { - RR = 0, // round-robin - WRR, // weight round-robin - random, -}; - -template -class channel { - using client_pool_t = client_pool; - using client_pools_t = client_pools; - - public: - struct channel_config { - typename client_pool_t::pool_config pool_config; - load_blance_algorithm lba = load_blance_algorithm::RR; - ~channel_config(){}; - }; - - private: - struct RRLoadBlancer { - std::unique_ptr> index = - std::make_unique>(); - async_simple::coro::Lazy> operator()( - const channel& channel) { - auto i = index->fetch_add(1, std::memory_order_relaxed); - co_return channel.client_pools_[i % channel.client_pools_.size()]; - } - }; - - /* - Supposing that there is a server set ''S'' = {S0, S1, …, Sn-1}; - W(Si) indicates the weight of Si; - ''i'' indicates the server selected last time, and ''i'' is initialized with - -1; - ''cw'' is the current weight in scheduling, and cw is initialized with zero; - max(S) is the maximum weight of all the servers in S; - gcd(S) is the greatest common divisor of all server weights in S; - - while (true) { - i = (i + 1) mod n; - if (i == 0) { - cw = cw - gcd(S); - if (cw <= 0) { - cw = max(S); - if (cw == 0) - return NULL; - } - } - if (W(Si) >= cw) - return Si; - } - */ - struct WRRLoadBlancer { - WRRLoadBlancer(const std::vector& weights) : weights_(weights) { - max_gcd_ = get_max_weight_gcd(); - max_weight_ = get_max_weight(); - } - - async_simple::coro::Lazy> operator()( - const channel& channel) { - int selected = select_host_with_weight_round_robin(); - if (selected == -1) { - selected = 0; - } - - wrr_current_ = selected; - co_return channel.client_pools_[selected % channel.client_pools_.size()]; - } - - private: - int select_host_with_weight_round_robin() { - while (true) { - wrr_current_ = (wrr_current_ + 1) % weights_.size(); - if (wrr_current_ == 0) { - weight_current_ = weight_current_ - max_gcd_; - if (weight_current_ <= 0) { - weight_current_ = max_weight_; - if (weight_current_ == 0) { - return -1; // can't find max weight server - } - } - } - - if (weights_[wrr_current_] >= weight_current_) { - return wrr_current_; - } - } - } - - int get_max_weight_gcd() { - int res = weights_[0]; - int cur_max = 0, cur_min = 0; - for (size_t i = 0; i < weights_.size(); i++) { - cur_max = (std::max)(res, weights_[i]); - cur_min = (std::min)(res, weights_[i]); - res = std::gcd(cur_max, cur_min); - } - return res; - } - - int get_max_weight() { - return *std::max_element(weights_.begin(), weights_.end()); - } - - std::vector weights_; - int max_gcd_ = 0; - int max_weight_ = 0; - int wrr_current_ = -1; - int weight_current_ = 0; - }; - - struct RandomLoadBlancer { - async_simple::coro::Lazy> operator()( - const channel& channel) { - static thread_local std::default_random_engine e; - std::uniform_int_distribution rnd{std::size_t{0}, - channel.client_pools_.size() - 1}; - co_return channel.client_pools_[rnd(e)]; - } - }; - channel() = default; - - public: - channel(channel&& o) - : config_(std::move(o.config_)), - lb_worker(std::move(o.lb_worker)), - client_pools_(std::move(o.client_pools_)){}; - channel& operator=(channel&& o) { - this->config_ = std::move(o.config_); - this->lb_worker = std::move(o.lb_worker); - this->client_pools_ = std::move(o.client_pools_); - } - channel(const channel& o) = delete; - channel& operator=(const channel& o) = delete; - - auto send_request(auto op, typename client_t::config& config) - -> decltype(std::declval().send_request(std::move(op), - std::string_view{}, - config)) { - std::shared_ptr client_pool; - if (client_pools_.size() > 1) { - client_pool = co_await std::visit( - [this](auto& worker) { - return worker(*this); - }, - lb_worker); - } - else { - client_pool = client_pools_[0]; - } - co_return co_await client_pool->send_request( - std::move(op), client_pool->get_host_name(), config); - } - auto send_request(auto op) { - return send_request(std::move(op), config_.pool_config.client_config); - } - - static channel create(const std::vector& hosts, - const channel_config& config = {}, - const std::vector& weights = {}, - client_pools_t& client_pools = - g_clients_pool()) { - channel ch; - ch.init(hosts, config, weights, client_pools); - return ch; - } - - /** - * @brief return the channel's hosts size. - * - * @return std::size_t - */ - std::size_t size() const noexcept { return client_pools_.size(); } - - private: - void init(const std::vector& hosts, - const channel_config& config, const std::vector& weights, - client_pools_t& client_pools) { - config_ = config; - client_pools_.reserve(hosts.size()); - for (auto& host : hosts) { - client_pools_.emplace_back(client_pools.at(host, config.pool_config)); - } - switch (config_.lba) { - case load_blance_algorithm::RR: - lb_worker = RRLoadBlancer{}; - break; - case load_blance_algorithm::WRR: { - if (hosts.empty() || weights.empty()) { - throw std::invalid_argument("host/weight list is empty!"); - } - if (hosts.size() != weights.size()) { - throw std::invalid_argument("hosts count is not equal with weights!"); - } - lb_worker = WRRLoadBlancer(weights); - } break; - case load_blance_algorithm::random: - default: - lb_worker = RandomLoadBlancer{}; - } - return; - } - channel_config config_; - std::variant lb_worker; - std::vector> client_pools_; -}; - -} // namespace coro_io diff --git a/include/ylt/coro_io/client_pool.hpp b/include/ylt/coro_io/client_pool.hpp deleted file mode 100644 index 062755890..000000000 --- a/include/ylt/coro_io/client_pool.hpp +++ /dev/null @@ -1,603 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#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 "async_simple/coro/Collect.h" -#include "coro_io.hpp" -#include "detail/client_queue.hpp" -#include "io_context_pool.hpp" -#include "ylt/easylog.hpp" -namespace coro_io { - -template -class client_pools; - -template -class channel; - -template -class client_pool : public std::enable_shared_from_this< - client_pool> { - using client_pools_t = client_pools; - static async_simple::coro::Lazy collect_idle_timeout_client( - std::weak_ptr self_weak, - coro_io::detail::client_queue>& clients, - std::chrono::milliseconds sleep_time, std::size_t clear_cnt) { - std::shared_ptr self = self_weak.lock(); - if (self == nullptr) { - co_return; - } - while (true) { - clients.reselect(); - self = nullptr; - co_await coro_io::sleep_for(sleep_time); - if ((self = self_weak.lock()) == nullptr) { - break; - } - while (true) { - ELOG_DEBUG << "start collect timeout client of pool{" - << self->host_name_ - << "}, now client count: " << clients.size(); - std::size_t is_all_cleared = clients.clear_old(clear_cnt); - ELOG_DEBUG << "finish collect timeout client of pool{" - << self->host_name_ - << "}, now client cnt: " << clients.size(); - if (is_all_cleared != 0) [[unlikely]] { - try { - co_await async_simple::coro::Yield{}; - } catch (std::exception& e) { - ELOG_ERROR << "unexcepted yield exception: " << e.what(); - } - } - else { - break; - } - } - --clients.collecter_cnt_; - if (clients.size() == 0) { - break; - } - std::size_t expected = 0; - if (!clients.collecter_cnt_.compare_exchange_strong(expected, 1)) - break; - } - co_return; - } - - struct client_connect_helper { - std::unique_ptr client; - std::weak_ptr pool_watcher; - std::weak_ptr spinlock_watcher; - client_connect_helper(std::unique_ptr&& client, - std::weak_ptr&& pool_watcher, - std::weak_ptr&& spinlock_watcher) - : client(std::move(client)), - pool_watcher(std::move(pool_watcher)), - spinlock_watcher(std::move(spinlock_watcher)) {} - client_connect_helper(client_connect_helper&& o) - : client(std::move(o.client)), - pool_watcher(std::move(o.pool_watcher)), - spinlock_watcher(std::move(o.spinlock_watcher)) {} - client_connect_helper& operator=(client_connect_helper&& o) { - client = std::move(o.client); - pool_watcher = std::move(o.pool_watcher); - spinlock_watcher = std::move(o.spinlock_watcher); - return *this; - } - ~client_connect_helper() { - if (client) { - if (auto pool = pool_watcher.lock(); pool) { - int cnt = 0; - while (spinlock_watcher.lock()) { - std::this_thread::yield(); - ++cnt; - if (cnt % 10000 == 0) { - ELOG_WARN << "spinlock of client{" << client.get() << "},host:{" - << client->get_host() << ":" << client->get_port() - << "}cost too much time, spin count: " << cnt; - } - } - pool->collect_free_client(std::move(client)); - } - } - } - }; - - async_simple::coro::Lazy reconnect(std::unique_ptr& client) { - for (unsigned int i = 0; i < pool_config_.connect_retry_count; ++i) { - ELOG_DEBUG << "try to reconnect client{" << client.get() << "},host:{" - << client->get_host() << ":" << client->get_port() - << "}, try count:" << i - << "max retry limit:" << pool_config_.connect_retry_count; - auto pre_time_point = std::chrono::steady_clock::now(); - bool ok = client_t::is_ok(co_await client->reconnect(host_name_)); - auto post_time_point = std::chrono::steady_clock::now(); - auto cost_time = post_time_point - pre_time_point; - ELOG_DEBUG << "reconnect client{" << client.get() - << "} cost time: " << cost_time / std::chrono::milliseconds{1} - << "ms"; - if (ok) { - ELOG_DEBUG << "reconnect client{" << client.get() << "} success"; - co_return; - } - ELOG_DEBUG << "reconnect client{" << client.get() - << "} failed. If client close:{" << client->has_closed() - << "}"; - auto wait_time = pool_config_.reconnect_wait_time - cost_time; - if (wait_time.count() > 0) - co_await coro_io::sleep_for(wait_time); - } - ELOG_WARN << "reconnect client{" << client.get() << "},host:{" - << client->get_host() << ":" << client->get_port() - << "} out of max limit, stop retry. connect failed"; - client = nullptr; - } - - async_simple::coro::Lazy connect_client( - client_connect_helper helper) { - ELOG_DEBUG << "try to connect client{" << helper.client.get() - << "} to host:" << host_name_; - auto result = co_await helper.client->connect(host_name_); - if (!client_t::is_ok(result)) { - ELOG_DEBUG << "connect client{" << helper.client.get() << "} to failed. "; - co_await reconnect(helper.client); - } - if (helper.client) { - ELOG_DEBUG << "connect client{" << helper.client.get() << "} successful!"; - } - - co_return std::move(helper); - } - - auto rand_time() { - static thread_local std::default_random_engine r; - std::uniform_int_distribution e(-25, 25); - return std::chrono::milliseconds{100 + e(r)}; - } - - async_simple::coro::Lazy> get_client( - const typename client_t::config& client_config) { - std::unique_ptr client; - - free_clients_.try_dequeue(client); - if (!client) { - short_connect_clients_.try_dequeue(client); - } - assert(client == nullptr || !client->has_closed()); - if (client == nullptr) { - client = std::make_unique(*io_context_pool_.get_executor()); - if (!client->init_config(client_config)) { - ELOG_ERROR << "init client config{" << client.get() << "} failed."; - co_return nullptr; - } - auto spinlock = std::make_shared(false); - auto client_ptr = client.get(); - auto result = co_await async_simple::coro::collectAny( - connect_client(client_connect_helper{ - std::move(client), this->shared_from_this(), spinlock}), - coro_io::sleep_for(rand_time())); - if (result.index() == 0) { // connect finish in 100ms - co_return std::move(std::get<0>(result).value().client); - } - else if (result.index() == 1) { // connect time cost more than 100ms - ELOG_DEBUG << "slow connection of client{" << client_ptr - << "}, try to get free client from pool."; - std::unique_ptr cli; - if (short_connect_clients_.try_dequeue(cli) || - free_clients_.try_dequeue(cli)) { - spinlock = nullptr; - ELOG_DEBUG << "get free client{" << cli.get() - << "} from pool. skip wait client{" << client_ptr - << "} connect"; - co_return std::move(cli); - } - else { - auto promise = std::make_unique< - async_simple::Promise>>(); - auto* promise_address = promise.get(); - promise_queue.enqueue(promise_address); - spinlock = nullptr; - if (short_connect_clients_.try_dequeue(cli) || - free_clients_.try_dequeue(cli)) { - collect_free_client(std::move(cli)); - } - ELOG_DEBUG << "wait for free client waiter promise{" - << promise_address << "} response because slow client{" - << client_ptr << "}"; - - auto res = co_await collectAny( - [](auto promise) - -> async_simple::coro::Lazy> { - co_return co_await promise->getFuture(); - }(std::move(promise)), - coro_io::sleep_for(this->pool_config_.max_connection_time)); - if (res.index() == 0) { - auto& res0 = std::get<0>(res); - if (!res0.hasError()) { - auto& cli = res0.value(); - ELOG_DEBUG << "get free client{" << cli.get() << "} from promise{" - << promise_address << "}. skip wait client{" - << client_ptr << "} connect"; - co_return std::move(cli); - } - else { - ELOG_ERROR << "Unexcepted branch"; - co_return nullptr; - } - } - else { - ELOG_ERROR << "Unexcepted branch. Out of max limitation of connect " - "time, connect " - "failed. skip wait client{" - << client_ptr << "} connect. " - << "skip wait promise {" << promise_address - << "} response"; - co_return nullptr; - } - } - } - else { - ELOG_ERROR << "unknown collectAny index while wait client{" - << client_ptr << "} connect"; - co_return nullptr; - } - } - else { - ELOG_DEBUG << "get free client{" << client.get() << "}. from queue"; - co_return std::move(client); - } - } - - void enqueue( - coro_io::detail::client_queue>& clients, - std::unique_ptr client, bool is_short_client) { - if (clients.enqueue(std::move(client)) == 1) { - std::size_t expected = 0; - if (clients.collecter_cnt_.compare_exchange_strong(expected, 1)) { - ELOG_DEBUG << "start timeout client collecter of client_pool{" - << host_name_ << "}"; - collect_idle_timeout_client( - this->shared_from_this(), clients, - (std::max)( - (is_short_client - ? (std::min)(pool_config_.idle_timeout, - pool_config_.short_connect_idle_timeout) - : pool_config_.idle_timeout), - std::chrono::milliseconds{50}), - pool_config_.idle_queue_per_max_clear_count) - .via(coro_io::get_global_executor()) - .start([](auto&&) { - }); - } - } - } - - void collect_free_client(std::unique_ptr client) { - ELOG_DEBUG << "collect free client{" << client.get() << "}"; - if (client && !client->has_closed()) { - async_simple::Promise>* promise = nullptr; - if (promise_queue.try_dequeue(promise)) { - promise->setValue(std::move(client)); - ELOG_DEBUG << "collect free client{" << client.get() - << "} wake up promise{" << promise << "}"; - } - else if (free_clients_.size() < pool_config_.max_connection) { - ELOG_DEBUG << "collect free client{" << client.get() << "} enqueue"; - enqueue(free_clients_, std::move(client), false); - } - else { - ELOG_DEBUG << "out of max connection limit <<" - << pool_config_.max_connection << ", collect free client{" - << client.get() << "} enqueue short connect queue"; - enqueue(short_connect_clients_, std::move(client), true); - } - } - else { - ELOG_DEBUG << "client{" << client.get() - << "} is nullptr or is closed. we won't collect it"; - } - - return; - }; - - template - struct lazy_hacker { - using type = void; - }; - template - struct lazy_hacker> { - using type = T; - }; - template - using return_type = - tl::expected()( - std::declval()))>::type, - std::errc>; - - template - using return_type_with_host = - tl::expected()( - std::declval(), std::string_view{}))>::type, - std::errc>; - - public: - struct pool_config { - uint32_t max_connection = 100; - uint32_t connect_retry_count = 3; - uint32_t idle_queue_per_max_clear_count = 1000; - std::chrono::milliseconds reconnect_wait_time{1000}; - std::chrono::milliseconds idle_timeout{30000}; - std::chrono::milliseconds short_connect_idle_timeout{1000}; - std::chrono::milliseconds max_connection_time{60000}; - typename client_t::config client_config; - }; - - private: - struct private_construct_token {}; - - public: - static std::shared_ptr create( - std::string_view host_name, const pool_config& pool_config = {}, - io_context_pool_t& io_context_pool = coro_io::g_io_context_pool()) { - return std::make_shared(private_construct_token{}, host_name, - pool_config, io_context_pool); - } - - client_pool(private_construct_token t, std::string_view host_name, - const pool_config& pool_config, - io_context_pool_t& io_context_pool) - : host_name_(host_name), - pool_config_(pool_config), - io_context_pool_(io_context_pool), - free_clients_(pool_config.max_connection){}; - - client_pool(private_construct_token t, client_pools_t* pools_manager_, - std::string_view host_name, const pool_config& pool_config, - io_context_pool_t& io_context_pool) - : pools_manager_(pools_manager_), - host_name_(host_name), - pool_config_(pool_config), - io_context_pool_(io_context_pool), - free_clients_(pool_config.max_connection){}; - - template - async_simple::coro::Lazy> send_request( - T op, typename client_t::config& client_config) { - // return type: Lazy> - ELOG_TRACE << "try send request to " << host_name_; - auto client = co_await get_client(client_config); - if (!client) { - ELOG_WARN << "send request to " << host_name_ - << " failed. connection refused."; - co_return return_type{tl::unexpect, std::errc::connection_refused}; - } - if constexpr (std::is_same_v::value_type, void>) { - co_await op(*client); - collect_free_client(std::move(client)); - co_return return_type{}; - } - else { - auto ret = co_await op(*client); - collect_free_client(std::move(client)); - co_return std::move(ret); - } - } - - template - decltype(auto) send_request(T op) { - return send_request(std::move(op), pool_config_.client_config); - } - - /** - * @brief approx connection of client pools - * - * @return std::size_t - */ - std::size_t free_client_count() const noexcept { - return free_clients_.size() + short_connect_clients_.size(); - } - - /** - * @brief approx connection of client pools - * - * @return std::size_t - */ - std::size_t size() const noexcept { return free_client_count(); } - - std::string_view get_host_name() const noexcept { return host_name_; } - - private: - template - friend class client_pools; - - template - friend class channel; - - template - async_simple::coro::Lazy> send_request( - T op, std::string_view endpoint, - typename client_t::config& client_config) { - // return type: Lazy> - ELOG_TRACE << "try send request to " << endpoint; - auto client = co_await get_client(client_config); - if (!client) { - ELOG_WARN << "send request to " << endpoint - << " failed. connection refused."; - co_return return_type_with_host{tl::unexpect, - std::errc::connection_refused}; - } - if constexpr (std::is_same_v::value_type, - void>) { - co_await op(*client, endpoint); - collect_free_client(std::move(client)); - co_return return_type_with_host{}; - } - else { - auto ret = co_await op(*client, endpoint); - collect_free_client(std::move(client)); - co_return std::move(ret); - } - } - - template - decltype(auto) send_request(T op, std::string_view sv) { - return send_request(std::move(op), sv, pool_config_.client_config); - } - - coro_io::detail::client_queue> free_clients_; - coro_io::detail::client_queue> - short_connect_clients_; - client_pools_t* pools_manager_ = nullptr; - moodycamel::ConcurrentQueue>*> - promise_queue; - async_simple::Promise idle_timeout_waiter; - std::string host_name_; - pool_config pool_config_; - io_context_pool_t& io_context_pool_; -}; - -template -class client_pools { - using client_pool_t = client_pool; - - public: - client_pools( - const typename client_pool_t::pool_config& pool_config = {}, - io_context_pool_t& io_context_pool = coro_io::g_io_context_pool()) - : io_context_pool_(io_context_pool), default_pool_config_(pool_config) {} - auto send_request(std::string_view host_name, auto op) - -> decltype(std::declval().send_request(std::move(op))) { - auto pool = get_client_pool(host_name, default_pool_config_); - auto ret = co_await pool->send_request(std::move(op)); - co_return ret; - } - auto send_request(std::string_view host_name, - typename client_pool_t::pool_config& pool_config, auto op) - -> decltype(std::declval().send_request(std::move(op))) { - auto pool = get_client_pool(host_name, pool_config); - auto ret = co_await pool->send_request(std::move(op)); - co_return ret; - } - auto at(std::string_view host_name) { - return get_client_pool(host_name, default_pool_config_); - } - auto at(std::string_view host_name, - const typename client_pool_t::pool_config& pool_config) { - return get_client_pool(host_name, pool_config); - } - auto operator[](std::string_view host_name) { return at(host_name); } - auto get_io_context_pool() { return io_context_pool_; } - - private: - std::shared_ptr get_client_pool( - std::string_view host_name, - const typename client_pool_t::pool_config& pool_config) { - decltype(client_pool_manager_.end()) iter; - bool has_inserted; - { -#ifdef __cpp_lib_generic_unordered_lookup - std::shared_lock shared_lock{mutex_}; - iter = client_pool_manager_.find(host_name); -#else - std::string host_name_copy = std::string{host_name}; - std::shared_lock shared_lock{mutex_}; - iter = client_pool_manager_.find(host_name_copy); -#endif - if (iter == client_pool_manager_.end()) { - shared_lock.unlock(); - auto pool = std::make_shared( - typename client_pool_t::private_construct_token{}, this, host_name, - pool_config, io_context_pool_); - { - std::lock_guard lock{mutex_}; - std::tie(iter, has_inserted) = - client_pool_manager_.emplace(host_name, nullptr); - if (has_inserted) { - iter->second = pool; - } - } - if (has_inserted) { - ELOG_DEBUG << "add new client pool of {" << host_name - << "} to hash table"; - } - else { - ELOG_DEBUG << "add new client pool of {" << host_name - << "} failed, element existed."; - } - } - return iter->second; - } - } - struct string_hash { - using hash_type = std::hash; - using is_transparent = void; - - std::size_t operator()(std::string_view str) const { - return hash_type{}(str); - } - std::size_t operator()(std::string const& str) const { - return hash_type{}(str); - } - }; - typename client_pool_t::pool_config default_pool_config_{}; - std::unordered_map, string_hash, - std::equal_to<>> - client_pool_manager_; - io_context_pool_t& io_context_pool_; - std::shared_mutex mutex_; -}; - -template -inline client_pools& g_clients_pool( - const typename client_pool::pool_config& - pool_config = {}, - io_context_pool_t& io_context_pool = coro_io::g_io_context_pool()) { - static client_pools _g_clients_pool( - pool_config, io_context_pool); - return _g_clients_pool; -} - -} // namespace coro_io diff --git a/include/ylt/coro_io/coro_file.hpp b/include/ylt/coro_io/coro_file.hpp deleted file mode 100644 index aa3342a90..000000000 --- a/include/ylt/coro_io/coro_file.hpp +++ /dev/null @@ -1,541 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include - -#include -#include -#include -#include - -#include "io_context_pool.hpp" -#if defined(YLT_ENABLE_FILE_IO_URING) -#include -#include -#endif -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "coro_io.hpp" - -#if defined(ASIO_WINDOWS) -#include -#include -#endif - -namespace coro_io { - -/* - ┌─────────────┬───────────────────────────────┐ - │fopen() mode │ open() flags │ - ├─────────────┼───────────────────────────────┤ - │ r │ O_RDONLY │ - ├─────────────┼───────────────────────────────┤ - │ w │ O_WRONLY | O_CREAT | O_TRUNC │ - ├─────────────┼───────────────────────────────┤ - │ a │ O_WRONLY | O_CREAT | O_APPEND │ - ├─────────────┼───────────────────────────────┤ - │ r+ │ O_RDWR │ - ├─────────────┼───────────────────────────────┤ - │ w+ │ O_RDWR | O_CREAT | O_TRUNC │ - ├─────────────┼───────────────────────────────┤ - │ a+ │ O_RDWR | O_CREAT | O_APPEND │ - └─────────────┴───────────────────────────────┘ -*/ -enum flags { -#if defined(ASIO_WINDOWS) - read_only = 1, - write_only = 2, - read_write = 4, - append = 8, - create = 16, - exclusive = 32, - truncate = 64, - create_write = create | write_only, - create_write_trunc = create | write_only | truncate, - create_read_write_trunc = read_write | create | truncate, - create_read_write_append = read_write | create | append, - sync_all_on_write = 128 -#else // defined(ASIO_WINDOWS) - read_only = O_RDONLY, - write_only = O_WRONLY, - read_write = O_RDWR, - append = O_APPEND, - create = O_CREAT, - exclusive = O_EXCL, - truncate = O_TRUNC, - create_write = O_CREAT | O_WRONLY, - create_write_trunc = O_WRONLY | O_CREAT | O_TRUNC, - create_read_write_trunc = O_RDWR | O_CREAT | O_TRUNC, - create_read_write_append = O_RDWR | O_CREAT | O_APPEND, - sync_all_on_write = O_SYNC -#endif // defined(ASIO_WINDOWS) -}; - -enum class read_type { - init, -#if defined(YLT_ENABLE_FILE_IO_URING) - uring, - uring_random, -#else - fread, -#endif - pread, -}; - -class coro_file { - public: -#if defined(YLT_ENABLE_FILE_IO_URING) - coro_file( - coro_io::ExecutorWrapper<>* executor = coro_io::get_global_executor()) - : coro_file(executor->get_asio_executor()) {} - - coro_file(asio::io_context::executor_type executor) - : executor_wrapper_(executor) {} -#else - - coro_file(coro_io::ExecutorWrapper<>* executor = - coro_io::get_global_block_executor()) - : coro_file(executor->get_asio_executor()) {} - - coro_file(asio::io_context::executor_type executor) - : executor_wrapper_(executor) {} -#endif - - bool is_open() { - if (type_ == read_type::pread) { - return fd_file_ != nullptr; - } - - return stream_file_ != nullptr; - } - - void flush() { -#if defined(YLT_ENABLE_FILE_IO_URING) - -#else - if (fd_file_) { -#if defined(__GNUC__) - fsync(*fd_file_); -#endif - } - else if (stream_file_) { - fflush(stream_file_.get()); - } -#endif - } - - bool eof() { return eof_; } - - void close() { - if (stream_file_) { - stream_file_.reset(); - } - else if (fd_file_) { - fd_file_.reset(); - } - } - - static size_t file_size(std::string_view filepath) { - std::error_code ec; - size_t size = std::filesystem::file_size(filepath, ec); - return size; - } - - async_simple::coro::Lazy> async_pread( - size_t offset, char* data, size_t size) { - if (type_ != read_type::pread) { - co_return std::make_pair( - std::make_error_code(std::errc::bad_file_descriptor), 0); - } -#if defined(ASIO_WINDOWS) - auto pread = [](int fd, void* buf, uint64_t count, - uint64_t offset) -> int64_t { - DWORD bytes_read = 0; - OVERLAPPED overlapped; - memset(&overlapped, 0, sizeof(OVERLAPPED)); - overlapped.Offset = offset & 0xFFFFFFFF; - overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; - - BOOL ok = ReadFile(reinterpret_cast(_get_osfhandle(fd)), buf, - count, &bytes_read, &overlapped); - if (!ok && (errno = GetLastError()) != ERROR_HANDLE_EOF) { - return -1; - } - - return bytes_read; - }; -#endif - co_return co_await async_prw(pread, true, offset, data, size); - } - - async_simple::coro::Lazy async_pwrite(size_t offset, - const char* data, - size_t size) { - if (type_ != read_type::pread) { - co_return std::make_error_code(std::errc::bad_file_descriptor); - } -#if defined(ASIO_WINDOWS) - auto pwrite = [](int fd, const void* buf, uint64_t count, - uint64_t offset) -> int64_t { - DWORD bytes_write = 0; - OVERLAPPED overlapped; - memset(&overlapped, 0, sizeof(OVERLAPPED)); - overlapped.Offset = offset & 0xFFFFFFFF; - overlapped.OffsetHigh = (offset >> 32) & 0xFFFFFFFF; - - BOOL ok = WriteFile(reinterpret_cast(_get_osfhandle(fd)), buf, - count, &bytes_write, &overlapped); - if (!ok) { - return -1; - } - - return bytes_write; - }; -#endif - auto result = co_await async_prw(pwrite, false, offset, (char*)data, size); - co_return result.first; - } - -#if defined(YLT_ENABLE_FILE_IO_URING) - async_simple::coro::Lazy async_open(std::string_view filepath, - int open_mode = flags::read_write, - read_type type = read_type::uring) { - type_ = type; - if (type_ == read_type::pread) { - co_return open_fd(filepath, open_mode); - } - - try { - if (type_ == read_type::uring) { - stream_file_ = std::make_shared( - executor_wrapper_.get_asio_executor()); - } - else { - stream_file_ = std::make_shared( - executor_wrapper_.get_asio_executor()); - } - } catch (std::exception& ex) { - stream_file_ = nullptr; - std::cout << "line " << __LINE__ << " coro_file create failed" - << ex.what() << "\n"; - co_return false; - } - - std::error_code ec; - stream_file_->open(filepath.data(), - static_cast(open_mode), ec); - - if (ec) { - stream_file_ = nullptr; - std::cout << "line " << __LINE__ << " coro_file open failed" - << ec.message() << "\n"; - co_return false; - } - - co_return true; - } - - bool seek(long offset, int whence) { - if (type_ != read_type::uring) { - return false; - } - - std::error_code seek_ec; - reinterpret_cast(stream_file_.get()) - ->seek(offset, static_cast(whence), - seek_ec); - if (seek_ec) { - return false; - } - return true; - } - - async_simple::coro::Lazy> async_read_at( - uint64_t offset, char* data, size_t size) { - if (type_ != read_type::uring_random) { - co_return std::make_pair( - std::make_error_code(std::errc::bad_file_descriptor), 0); - } - - auto [ec, read_size] = co_await coro_io::async_read_at( - offset, - *reinterpret_cast(stream_file_.get()), - asio::buffer(data, size)); - - if (ec == asio::error::eof) { - eof_ = true; - co_return std::make_pair(std::error_code{}, read_size); - } - - co_return std::make_pair(std::error_code{}, read_size); - } - - async_simple::coro::Lazy async_write_at(uint64_t offset, - const char* data, - size_t size) { - if (type_ != read_type::uring_random) { - co_return std::make_error_code(std::errc::bad_file_descriptor); - } - - auto [ec, write_size] = co_await coro_io::async_write_at( - offset, - *reinterpret_cast(stream_file_.get()), - asio::buffer(data, size)); - co_return ec; - } - - async_simple::coro::Lazy> async_read( - char* data, size_t size) { - if (type_ != read_type::uring) { - co_return std::make_pair( - std::make_error_code(std::errc::bad_file_descriptor), 0); - } - - auto [ec, read_size] = co_await coro_io::async_read( - *reinterpret_cast(stream_file_.get()), - asio::buffer(data, size)); - if (ec == asio::error::eof) { - eof_ = true; - co_return std::make_pair(std::error_code{}, read_size); - } - - co_return std::make_pair(std::error_code{}, read_size); - } - - async_simple::coro::Lazy async_write(const char* data, - size_t size) { - if (type_ != read_type::uring) { - co_return std::make_error_code(std::errc::bad_file_descriptor); - } - - auto [ec, write_size] = co_await coro_io::async_write( - *reinterpret_cast(stream_file_.get()), - asio::buffer(data, size)); - - co_return ec; - } -#else - std::string str_mode(int open_mode) { - switch (open_mode) { - case flags::read_only: - return "rb"; - case flags::create_write: - case flags::write_only: - return "wb+"; - case flags::read_write: - return "rb+"; - case flags::append: - return "ab+"; - case flags::create_read_write_append: - return "ab+"; - case flags::truncate: - return "w+"; - default: - return "rb+"; - } - } - - bool seek(long offset, int whence) { - if (stream_file_ == nullptr) { - return false; - } - - return fseek(stream_file_.get(), offset, whence) == 0; - } - - async_simple::coro::Lazy async_open(std::string filepath, - int open_mode = flags::read_write, - read_type type = read_type::fread) { - type_ = type; - if (type_ == read_type::pread) { - co_return open_fd(filepath, open_mode); - } - - if (stream_file_ != nullptr) { - co_return true; - } - - auto result = co_await coro_io::post( - [this, &filepath, open_mode] { - auto fptr = fopen(filepath.data(), str_mode(open_mode).data()); - if (fptr == nullptr) { - std::cout << "line " << __LINE__ << " coro_file open failed " - << filepath << "\n"; - return false; - } - stream_file_ = std::shared_ptr(fptr, [](FILE* ptr) { - fclose(ptr); - }); - return true; - }, - &executor_wrapper_); - co_return result.value(); - } - - async_simple::coro::Lazy> async_read( - char* data, size_t size) { - if (type_ != read_type::fread) { - co_return std::make_pair( - std::make_error_code(std::errc::bad_file_descriptor), 0); - } - auto result = co_await coro_io::post( - [this, data, size] { - auto fptr = stream_file_.get(); - size_t read_size = fread(data, sizeof(char), size, fptr); - if (ferror(fptr)) { - return std::pair( - std::make_error_code(std::errc::io_error), 0); - } - eof_ = feof(fptr); - return std::pair(std::error_code{}, - read_size); - }, - &executor_wrapper_); - - co_return result.value(); - } - - async_simple::coro::Lazy async_write(const char* data, - size_t size) { - if (type_ != read_type::fread) { - co_return std::make_error_code(std::errc::bad_file_descriptor); - } - auto result = co_await coro_io::post( - [this, data, size] { - auto fptr = stream_file_.get(); - fwrite(data, sizeof(char), size, fptr); - if (ferror(fptr)) { - return std::make_error_code(std::errc::io_error); - } - return std::error_code{}; - }, - &executor_wrapper_); - - co_return result.value(); - } -#endif - - private: - async_simple::coro::Lazy> async_prw( - auto io_func, bool is_read, size_t offset, char* buf, size_t size) { - std::function func = [=, this] { - int fd = *fd_file_; - return io_func(fd, buf, size, offset); - }; - - std::error_code ec{}; - size_t op_size = 0; - - auto len_val = co_await coro_io::post(std::move(func), &executor_wrapper_); - int len = len_val.value(); - if (len == 0) { - if (is_read) { - eof_ = true; - } - } - else if (len > 0) { - op_size = len; - } - else { - ec = std::make_error_code(std::errc::io_error); - } - - co_return std::make_pair(ec, op_size); - } - - bool open_fd(std::string_view filepath, int open_mode = flags::read_write) { - if (fd_file_) { - return true; - } - -#if defined(ASIO_WINDOWS) - int fd = _open(filepath.data(), adjust_open_mode(open_mode)); -#else - int fd = open(filepath.data(), open_mode); -#endif - if (fd < 0) { - return false; - } - - fd_file_ = std::shared_ptr(new int(fd), [](int* ptr) { -#if defined(ASIO_WINDOWS) - _close(*ptr); -#else - ::close(*ptr); -#endif - delete ptr; - }); - return true; - } - -#if defined(ASIO_WINDOWS) - static int adjust_open_mode(int open_mode) { - switch (open_mode) { - case flags::read_only: - return _O_RDONLY; - case flags::write_only: - return _O_WRONLY; - case flags::read_write: - return _O_RDWR; - case flags::append: - return _O_APPEND; - case flags::create: - return _O_CREAT; - case flags::exclusive: - return _O_EXCL; - case flags::truncate: - return _O_TRUNC; - case flags::create_write: - return _O_CREAT | _O_WRONLY; - case flags::create_write_trunc: - return _O_CREAT | _O_WRONLY | _O_TRUNC; - case flags::create_read_write_trunc: - return _O_RDWR | _O_CREAT | _O_TRUNC; - case flags::create_read_write_append: - return _O_RDWR | _O_CREAT | _O_APPEND; - case flags::sync_all_on_write: - default: - return open_mode; - break; - } - return open_mode; - } -#endif - private: - read_type type_ = read_type::init; -#if defined(YLT_ENABLE_FILE_IO_URING) - std::shared_ptr> stream_file_; -#else - std::shared_ptr stream_file_; -#endif - coro_io::ExecutorWrapper<> executor_wrapper_; - std::shared_ptr fd_file_; - std::atomic eof_ = false; -}; -} // namespace coro_io diff --git a/include/ylt/coro_io/coro_io.hpp b/include/ylt/coro_io/coro_io.hpp deleted file mode 100644 index c2bb0479c..000000000 --- a/include/ylt/coro_io/coro_io.hpp +++ /dev/null @@ -1,419 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include -#include -#include - -#if defined(YLT_ENABLE_SSL) || defined(CINATRA_ENABLE_SSL) -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "io_context_pool.hpp" -#include "ylt/util/type_traits.h" - -namespace coro_io { - -template -class callback_awaitor_base { - private: - template - class callback_awaitor_impl { - public: - callback_awaitor_impl(Derived &awaitor, const Op &op) noexcept - : awaitor(awaitor), op(op) {} - constexpr bool await_ready() const noexcept { return false; } - void await_suspend(std::coroutine_handle<> handle) noexcept { - awaitor.coro_ = handle; - op(awaitor_handler{&awaitor}); - } - auto coAwait(async_simple::Executor *executor) const noexcept { - return *this; - } - decltype(auto) await_resume() noexcept { - if constexpr (std::is_void_v) { - return; - } - else { - return std::move(awaitor.arg_); - } - } - - private: - Derived &awaitor; - const Op &op; - }; - - public: - class awaitor_handler { - public: - awaitor_handler(Derived *obj) : obj(obj) {} - awaitor_handler(awaitor_handler &&) = default; - awaitor_handler(const awaitor_handler &) = default; - awaitor_handler &operator=(const awaitor_handler &) = default; - awaitor_handler &operator=(awaitor_handler &&) = default; - template - void set_value_then_resume(Args &&...args) const { - set_value(std::forward(args)...); - resume(); - } - template - void set_value(Args &&...args) const { - if constexpr (!std::is_void_v) { - obj->arg_ = {std::forward(args)...}; - } - } - void resume() const { obj->coro_.resume(); } - - private: - Derived *obj; - }; - template - callback_awaitor_impl await_resume(const Op &op) noexcept { - return callback_awaitor_impl{static_cast(*this), op}; - } - - private: - std::coroutine_handle<> coro_; -}; - -template -class callback_awaitor - : public callback_awaitor_base> { - friend class callback_awaitor_base>; - - private: - Arg arg_; -}; - -template <> -class callback_awaitor - : public callback_awaitor_base> {}; - -inline async_simple::coro::Lazy async_accept( - asio::ip::tcp::acceptor &acceptor, asio::ip::tcp::socket &socket) noexcept { - callback_awaitor awaitor; - - co_return co_await awaitor.await_resume([&](auto handler) { - acceptor.async_accept(socket, [&, handler](const auto &ec) mutable { - handler.set_value_then_resume(ec); - }); - }); -} - -template -inline async_simple::coro::Lazy> -async_read_some(Socket &socket, AsioBuffer &&buffer) noexcept { - callback_awaitor> awaitor; - co_return co_await awaitor.await_resume([&](auto handler) { - socket.async_read_some(buffer, [&, handler](const auto &ec, auto size) { - handler.set_value_then_resume(ec, size); - }); - }); -} - -template -inline async_simple::coro::Lazy> -async_read_at(uint64_t offset, Socket &socket, AsioBuffer &&buffer) noexcept { - callback_awaitor> awaitor; - co_return co_await awaitor.await_resume([&](auto handler) { - asio::async_read_at(socket, offset, buffer, - [&, handler](const auto &ec, auto size) { - handler.set_value_then_resume(ec, size); - }); - }); -} - -template -inline async_simple::coro::Lazy> async_read( - Socket &socket, AsioBuffer &&buffer) noexcept { - callback_awaitor> awaitor; - co_return co_await awaitor.await_resume([&](auto handler) { - asio::async_read(socket, buffer, [&, handler](const auto &ec, auto size) { - handler.set_value_then_resume(ec, size); - }); - }); -} - -template -inline async_simple::coro::Lazy> async_read( - Socket &socket, AsioBuffer &buffer, size_t size_to_read) noexcept { - callback_awaitor> awaitor; - co_return co_await awaitor.await_resume([&](auto handler) { - asio::async_read(socket, buffer, asio::transfer_exactly(size_to_read), - [&, handler](const auto &ec, auto size) { - handler.set_value_then_resume(ec, size); - }); - }); -} - -template -inline async_simple::coro::Lazy> -async_read_until(Socket &socket, AsioBuffer &buffer, - asio::string_view delim) noexcept { - callback_awaitor> awaitor; - co_return co_await awaitor.await_resume([&](auto handler) { - asio::async_read_until(socket, buffer, delim, - [&, handler](const auto &ec, auto size) { - handler.set_value_then_resume(ec, size); - }); - }); -} - -template -inline async_simple::coro::Lazy> async_write( - Socket &socket, AsioBuffer &&buffer) noexcept { - callback_awaitor> awaitor; - co_return co_await awaitor.await_resume([&](auto handler) { - asio::async_write(socket, buffer, [&, handler](const auto &ec, auto size) { - handler.set_value_then_resume(ec, size); - }); - }); -} - -template -inline async_simple::coro::Lazy> -async_write_some(Socket &socket, AsioBuffer &&buffer) noexcept { - callback_awaitor> awaitor; - co_return co_await awaitor.await_resume([&](auto handler) { - socket.async_write_some(buffer, [&, handler](const auto &ec, auto size) { - handler.set_value_then_resume(ec, size); - }); - }); -} - -template -inline async_simple::coro::Lazy> -async_write_at(uint64_t offset, Socket &socket, AsioBuffer &&buffer) noexcept { - callback_awaitor> awaitor; - co_return co_await awaitor.await_resume([&](auto handler) { - asio::async_write_at(socket, offset, buffer, - [&, handler](const auto &ec, auto size) { - handler.set_value_then_resume(ec, size); - }); - }); -} - -template -inline async_simple::coro::Lazy async_connect( - executor_t *executor, asio::ip::tcp::socket &socket, - const std::string &host, const std::string &port) noexcept { - callback_awaitor awaitor; - asio::ip::tcp::resolver resolver(executor->get_asio_executor()); - asio::ip::tcp::resolver::iterator iterator; - auto ec = co_await awaitor.await_resume([&](auto handler) { - resolver.async_resolve(host, port, [&, handler](auto ec, auto it) { - iterator = it; - handler.set_value_then_resume(ec); - }); - }); - - if (ec) { - co_return ec; - } - - co_return co_await awaitor.await_resume([&](auto handler) { - asio::async_connect(socket, iterator, - [&, handler](const auto &ec, const auto &) mutable { - handler.set_value_then_resume(ec); - }); - }); -} - -template -inline async_simple::coro::Lazy async_close(Socket &socket) noexcept { - callback_awaitor awaitor; - auto executor = socket.get_executor(); - co_return co_await awaitor.await_resume([&](auto handler) { - asio::post(executor, [&, handler]() { - asio::error_code ignored_ec; - socket.shutdown(asio::ip::tcp::socket::shutdown_both, ignored_ec); - socket.close(ignored_ec); - handler.resume(); - }); - }); -} - -#if defined(YLT_ENABLE_SSL) || defined(CINATRA_ENABLE_SSL) -inline async_simple::coro::Lazy async_handshake( - auto &ssl_stream, asio::ssl::stream_base::handshake_type type) noexcept { - callback_awaitor awaitor; - co_return co_await awaitor.await_resume([&](auto handler) { - ssl_stream->async_handshake(type, [&, handler](const auto &ec) { - handler.set_value_then_resume(ec); - }); - }); -} -#endif -class period_timer : public asio::steady_timer { - public: - template - period_timer(coro_io::ExecutorWrapper *executor) - : asio::steady_timer(executor->get_asio_executor()) {} - template - period_timer(const executor_t &executor, - const std::chrono::duration &timeout_duration) - : asio::steady_timer(executor, timeout_duration) {} - async_simple::coro::Lazy async_await() noexcept { - callback_awaitor awaitor; - - co_return co_await awaitor.await_resume([&](auto handler) { - this->async_wait([&, handler](const auto &ec) { - handler.set_value_then_resume(!ec); - }); - }); - } -}; - -template -inline async_simple::coro::Lazy sleep_for(const Duration &d, - Executor *e) { - coro_io::period_timer timer(e); - timer.expires_after(d); - co_await timer.async_await(); -} -template -inline async_simple::coro::Lazy sleep_for(Duration d) { - if (auto executor = co_await async_simple::CurrentExecutor(); - executor != nullptr) { - co_await async_simple::coro::sleep(d); - } - else { - co_return co_await sleep_for(d, - coro_io::g_io_context_pool().get_executor()); - } -} - -template -struct post_helper { - void operator()(auto handler) const { - asio::dispatch(e->get_asio_executor(), [this, handler]() { - try { - if constexpr (std::is_same_v>) { - func(); - handler.resume(); - } - else { - auto r = func(); - handler.set_value_then_resume(std::move(r)); - } - } catch (const std::exception &e) { - R er; - er.setException(std::current_exception()); - handler.set_value_then_resume(std::move(er)); - } - }); - } - coro_io::ExecutorWrapper<> *e; - Func func; -}; - -template -inline async_simple::coro::Lazy< - async_simple::Try::return_type>> -post(Func func, - coro_io::ExecutorWrapper<> *e = coro_io::get_global_block_executor()) { - using R = - async_simple::Try::return_type>; - - callback_awaitor awaitor; - - post_helper helper{e, std::move(func)}; - co_return co_await awaitor.await_resume(helper); -} - -template -async_simple::coro::Lazy async_send( - asio::experimental::channel &channel, T val) { - callback_awaitor awaitor; - co_return co_await awaitor.await_resume( - [&, val = std::move(val)](auto handler) { - channel.async_send({}, std::move(val), [handler](const auto &ec) { - handler.set_value_then_resume(ec); - }); - }); -} - -template -async_simple::coro::Lazy> async_receive( - asio::experimental::channel &channel) { - callback_awaitor> awaitor; - co_return co_await awaitor.await_resume([&](auto handler) { - channel.async_receive([handler](auto ec, auto val) { - handler.set_value_then_resume(std::make_pair(ec, std::move(val))); - }); - }); -} - -template -std::pair read_some(Socket &sock, - AsioBuffer &&buffer) { - asio::error_code error; - size_t length = sock.read_some(std::forward(buffer), error); - return std::make_pair(error, length); -} - -template -std::pair read(Socket &sock, AsioBuffer &&buffer) { - asio::error_code error; - size_t length = asio::read(sock, buffer, error); - return std::make_pair(error, length); -} - -template -std::pair write(Socket &sock, AsioBuffer &&buffer) { - asio::error_code error; - auto length = asio::write(sock, std::forward(buffer), error); - return std::make_pair(error, length); -} - -inline std::error_code accept(asio::ip::tcp::acceptor &a, - asio::ip::tcp::socket &socket) { - std::error_code error; - a.accept(socket, error); - return error; -} - -template -inline std::error_code connect(executor_t &executor, - asio::ip::tcp::socket &socket, - const std::string &host, - const std::string &port) { - asio::ip::tcp::resolver resolver(executor); - std::error_code error; - auto endpoints = resolver.resolve(host, port, error); - if (error) { - return error; - } - asio::connect(socket, endpoints, error); - return error; -} - -} // namespace coro_io diff --git a/include/ylt/coro_io/detail/client_queue.hpp b/include/ylt/coro_io/detail/client_queue.hpp deleted file mode 100644 index 06bb6aab2..000000000 --- a/include/ylt/coro_io/detail/client_queue.hpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include - -#include "ylt/util/concurrentqueue.h" -namespace coro_io::detail { -template -class client_queue { - moodycamel::ConcurrentQueue queue_[2]; - std::atomic_int_fast16_t selected_index_ = 0; - std::atomic size_[2] = {}; - - public: - std::atomic collecter_cnt_ = 0; - - private: - struct fake_client { - template - fake_client& operator=(T&&) noexcept { - return *this; - } - }; - struct fake_iter { - fake_iter operator++() { return *this; } - fake_iter operator++(int) { return *this; } - fake_client& operator*() { - static fake_client c; - return c; - } - }; - - public: - client_queue(std::size_t reserve_size = 0) - : queue_{moodycamel::ConcurrentQueue{reserve_size}, - moodycamel::ConcurrentQueue{reserve_size}} {}; - std::size_t size() const noexcept { return size_[0] + size_[1]; } - void reselect() noexcept { selected_index_ ^= 1; } - std::size_t enqueue(client_t&& c) { - const int_fast16_t index = selected_index_; - auto cnt = ++size_[index]; - if (queue_[index].enqueue(std::move(c))) { - return cnt; - } - else { - --size_[index]; - return 0; - } - } - bool try_dequeue(client_t& c) { - const int_fast16_t index = selected_index_; - if (size_[index ^ 1]) { - if (queue_[index ^ 1].try_dequeue(c)) { - --size_[index ^ 1]; - return true; - } - } - if (queue_[index].try_dequeue(c)) { - --size_[index]; - return true; - } - return false; - } - std::size_t clear_old(std::size_t max_clear_cnt) { - const int_fast16_t index = selected_index_ ^ 1; - if (size_[index]) { - std::size_t result = - queue_[index].try_dequeue_bulk(fake_iter{}, max_clear_cnt); - size_[index] -= result; - return result; - } - return 0; - } -}; -}; // namespace coro_io::detail \ No newline at end of file diff --git a/include/ylt/coro_io/io_context_pool.hpp b/include/ylt/coro_io/io_context_pool.hpp deleted file mode 100644 index 81bce7d4a..000000000 --- a/include/ylt/coro_io/io_context_pool.hpp +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef __linux__ -#include -#include -#endif - -namespace coro_io { - -inline asio::io_context **get_current() { - static thread_local asio::io_context *current = nullptr; - return ¤t; -} - -template -class ExecutorWrapper : public async_simple::Executor { - private: - ExecutorImpl executor_; - - public: - ExecutorWrapper(ExecutorImpl executor) : executor_(executor) {} - - using context_t = std::remove_cvref_t; - - virtual bool schedule(Func func) override { - if constexpr (requires(ExecutorImpl e) { e.post(std::move(func)); }) { - executor_.post(std::move(func)); - } - else { - asio::post(executor_, std::move(func)); - } - - return true; - } - - virtual bool checkin(Func func, void *ctx) override { - using context_t = std::remove_cvref_t; - auto &executor = *(context_t *)ctx; - if constexpr (requires(ExecutorImpl e) { e.post(std::move(func)); }) { - executor.post(std::move(func)); - } - else { - asio::post(executor, std::move(func)); - } - return true; - } - virtual void *checkout() override { return &executor_.context(); } - - context_t &context() { return executor_.context(); } - - auto get_asio_executor() { return executor_; } - - operator ExecutorImpl() { return executor_; } - - bool currentThreadInExecutor() const override { - auto ctx = get_current(); - return *ctx == &executor_.context(); - } - - size_t currentContextId() const override { - auto ctx = get_current(); - auto ptr = *ctx; - return ptr ? (size_t)ptr : 0; - } - - private: - void schedule(Func func, Duration dur) override { - auto timer = std::make_unique(executor_, dur); - auto tm = timer.get(); - tm->async_wait([fn = std::move(func), timer = std::move(timer)](auto ec) { - fn(); - }); - } -}; - -template -inline async_simple::coro::Lazy -get_current_executor() { - auto executor = co_await async_simple::CurrentExecutor{}; - assert(executor != nullptr); - co_return static_cast(executor->checkout())->get_executor(); -} - -class io_context_pool { - public: - using executor_type = asio::io_context::executor_type; - explicit io_context_pool(std::size_t pool_size, bool cpu_affinity = false) - : next_io_context_(0), cpu_affinity_(cpu_affinity) { - if (pool_size == 0) { - pool_size = 1; // set default value as 1 - } - - for (std::size_t i = 0; i < pool_size; ++i) { - io_context_ptr io_context(new asio::io_context(1)); - work_ptr work(new asio::io_context::work(*io_context)); - io_contexts_.push_back(io_context); - auto executor = std::make_unique>( - io_context->get_executor()); - executors.push_back(std::move(executor)); - work_.push_back(work); - } - } - - void run() { - bool has_run_or_stop = false; - bool ok = has_run_or_stop_.compare_exchange_strong(has_run_or_stop, true); - if (!ok) { - return; - } - - std::vector> threads; - for (std::size_t i = 0; i < io_contexts_.size(); ++i) { - threads.emplace_back(std::make_shared( - [](io_context_ptr svr) { - auto ctx = get_current(); - *ctx = svr.get(); - svr->run(); - }, - io_contexts_[i])); - -#ifdef __linux__ - if (cpu_affinity_) { - cpu_set_t cpuset; - CPU_ZERO(&cpuset); - CPU_SET(i, &cpuset); - pthread_setaffinity_np(threads.back()->native_handle(), - sizeof(cpu_set_t), &cpuset); - } -#endif - } - - for (std::size_t i = 0; i < threads.size(); ++i) { - threads[i]->join(); - } - promise_.set_value(); - } - - void stop() { - std::call_once(flag_, [this] { - bool has_run_or_stop = false; - bool ok = has_run_or_stop_.compare_exchange_strong(has_run_or_stop, true); - - work_.clear(); - - if (ok) { - // clear all unfinished work - for (auto &e : io_contexts_) { - e->run(); - } - return; - } - - promise_.get_future().wait(); - }); - } - - ~io_context_pool() { - if (!has_stop()) - stop(); - } - - std::size_t pool_size() const noexcept { return io_contexts_.size(); } - - bool has_stop() const { return work_.empty(); } - - size_t current_io_context() { return next_io_context_ - 1; } - - coro_io::ExecutorWrapper<> *get_executor() { - auto i = next_io_context_.fetch_add(1, std::memory_order::relaxed); - auto *ret = executors[i % io_contexts_.size()].get(); - return ret; - } - - template - friend io_context_pool &g_io_context_pool(); - - private: - using io_context_ptr = std::shared_ptr; - using work_ptr = std::shared_ptr; - - std::vector io_contexts_; - std::vector>> executors; - std::vector work_; - std::atomic next_io_context_; - std::promise promise_; - std::atomic has_run_or_stop_ = false; - std::once_flag flag_; - bool cpu_affinity_ = false; -}; - -class multithread_context_pool { - public: - multithread_context_pool(size_t thd_num = std::thread::hardware_concurrency()) - : work_(std::make_unique(ioc_)), - executor_(ioc_.get_executor()), - thd_num_(thd_num) {} - - ~multithread_context_pool() { stop(); } - - void run() { - for (int i = 0; i < thd_num_; i++) { - thds_.emplace_back([this] { - ioc_.run(); - }); - } - - promise_.set_value(); - } - - void stop() { - if (thds_.empty()) { - return; - } - - work_.reset(); - for (auto &thd : thds_) { - thd.join(); - } - promise_.get_future().wait(); - thds_.clear(); - } - - coro_io::ExecutorWrapper<> *get_executor() { return &executor_; } - - private: - asio::io_context ioc_; - std::unique_ptr work_; - coro_io::ExecutorWrapper<> executor_; - size_t thd_num_; - std::vector thds_; - std::promise promise_; -}; - -template -inline T &g_io_context_pool( - unsigned pool_size = std::thread::hardware_concurrency()) { - static auto _g_io_context_pool = std::make_shared(pool_size); - [[maybe_unused]] static bool run_helper = [](auto pool) { - std::thread thrd{[pool] { - pool->run(); - }}; - thrd.detach(); - return true; - }(_g_io_context_pool); - return *_g_io_context_pool; -} - -template -inline T &g_block_io_context_pool( - unsigned pool_size = std::thread::hardware_concurrency()) { - static auto _g_io_context_pool = std::make_shared(pool_size); - [[maybe_unused]] static bool run_helper = [](auto pool) { - std::thread thrd{[pool] { - pool->run(); - }}; - thrd.detach(); - return true; - }(_g_io_context_pool); - return *_g_io_context_pool; -} - -template -inline auto get_global_executor( - unsigned pool_size = std::thread::hardware_concurrency()) { - return g_io_context_pool(pool_size).get_executor(); -} - -template -inline auto get_global_block_executor( - unsigned pool_size = std::thread::hardware_concurrency()) { - return g_block_io_context_pool(pool_size).get_executor(); -} - -} // namespace coro_io diff --git a/include/ylt/coro_io/rate_limiter.hpp b/include/ylt/coro_io/rate_limiter.hpp deleted file mode 100644 index bb2372770..000000000 --- a/include/ylt/coro_io/rate_limiter.hpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace coro_io { -class rate_limiter { - public: - async_simple::coro::Lazy acquire(int permits) { - std::chrono::milliseconds wait_mills; - { - auto scope = co_await this->lock_.coScopedLock(); - wait_mills = reserve_and_get_wait_length(permits, current_time_mills()); - } - co_await coro_io::sleep_for(wait_mills); - co_return wait_mills; - } - async_simple::coro::Lazy set_rate(double permitsPerSecond) { - auto scope = co_await this->lock_.coScopedLock(); - do_set_rate(permitsPerSecond, current_time_mills()); - } - - virtual ~rate_limiter() {} - - protected: - virtual void do_set_rate( - double permitsPerSecond, - std::chrono::steady_clock::time_point now_micros) = 0; - virtual std::chrono::steady_clock::time_point reserve_earliest_available( - int permits, std::chrono::steady_clock::time_point now_micros) = 0; - std::chrono::steady_clock::time_point current_time_mills() { - return std::chrono::steady_clock::now(); - } - - private: - std::chrono::milliseconds reserve_and_get_wait_length( - int permits, std::chrono::steady_clock::time_point now_micros) { - std::chrono::steady_clock::time_point moment_available = - reserve_earliest_available(permits, now_micros); - std::chrono::milliseconds diff_mills = - std::chrono::duration_cast(moment_available - - now_micros); - return std::max(diff_mills, std::chrono::milliseconds(0)); - } - - async_simple::coro::SpinLock lock_; -}; - -class abstract_smooth_rate_limiter : public rate_limiter { - public: - virtual ~abstract_smooth_rate_limiter() {} - - protected: - virtual void do_set_rate(double permits_per_second, - double stable_internal_micros) = 0; - virtual std::chrono::milliseconds stored_permits_to_wait_time( - double stored_permits, double permits_to_take) = 0; - virtual double cool_down_internal_micros() = 0; - void resync(std::chrono::steady_clock::time_point now_micros) { - // if next_free_ticket is in the past, resync to now - ELOG_DEBUG << "now micros: " - << std::chrono::duration_cast( - now_micros.time_since_epoch()) - .count() - << ", next_free_ticket_micros_: " - << std::chrono::duration_cast( - this->next_free_ticket_micros_.time_since_epoch()) - .count(); - if (now_micros > this->next_free_ticket_micros_) { - std::chrono::milliseconds diff_mills = - std::chrono::duration_cast( - now_micros - this->next_free_ticket_micros_); - double newPermits = diff_mills.count() / cool_down_internal_micros(); - this->stored_permits_ = - std::min(this->max_permits_, this->stored_permits_ + newPermits); - this->next_free_ticket_micros_ = now_micros; - } - } - void do_set_rate(double permits_per_second, - std::chrono::steady_clock::time_point now_micros) override { - resync(now_micros); - double stable_internal_micros = 1000 / permits_per_second; - this->stable_internal_micros_ = stable_internal_micros; - do_set_rate(permits_per_second, stable_internal_micros); - } - std::chrono::steady_clock::time_point reserve_earliest_available( - int required_permits, - std::chrono::steady_clock::time_point now_micros) override { - resync(now_micros); - std::chrono::steady_clock::time_point return_value = - this->next_free_ticket_micros_; - double stored_permits_to_spend = - std::min((double)required_permits, this->stored_permits_); - double fresh_permits = required_permits - stored_permits_to_spend; - std::chrono::milliseconds wait_micros = - stored_permits_to_wait_time(this->stored_permits_, - stored_permits_to_spend) + - std::chrono::milliseconds( - (int64_t)(fresh_permits * this->stable_internal_micros_)); - this->next_free_ticket_micros_ += wait_micros; - this->stored_permits_ -= stored_permits_to_spend; - return return_value; - } - - /** - * The currently stored permits. - */ - double stored_permits_ = 0; - /** - * The maximum number of stored permits. - */ - double max_permits_ = 0; - /** - * The interval between two unit requests, at our stable rate. E.g., a stable - * rate of 5 permits per second has a stable internal of 200ms. - */ - double stable_internal_micros_ = 0; - /** - * The time when the next request (no matter its size) will be granted. After - * granting a request, this is pushed further in the future. Large requests - * push this further than small requests. - */ - std::chrono::steady_clock::time_point next_free_ticket_micros_; -}; - -class smooth_bursty_rate_limiter : public abstract_smooth_rate_limiter { - public: - smooth_bursty_rate_limiter(double permits_per_second) { - this->max_burst_seconds_ = 1.0; - async_simple::coro::syncAwait(set_rate(permits_per_second)); - } - - protected: - void do_set_rate(double permits_per_second, double stable_internal_micros) { - double old_max_permits = this->max_permits_; - this->max_permits_ = this->max_burst_seconds_ * permits_per_second; - this->stored_permits_ = - (0 == old_max_permits) - ? 0 - : this->stored_permits_ * this->max_permits_ / old_max_permits; - ELOG_DEBUG << "max_permits_: " << this->max_permits_ - << ", stored_permits_:" << this->stored_permits_; - } - - std::chrono::milliseconds stored_permits_to_wait_time( - double stored_permits, double permits_to_take) { - return std::chrono::milliseconds(0); - } - - double cool_down_internal_micros() { return this->stable_internal_micros_; } - - private: - /** - * The work(permits) of how many seconds can be saved up if the rate_limiter - * is unused. - */ - double max_burst_seconds_ = 0; -}; -} // namespace coro_io \ No newline at end of file diff --git a/include/ylt/coro_rpc/coro_rpc_client.hpp b/include/ylt/coro_rpc/coro_rpc_client.hpp deleted file mode 100644 index 86fb2e947..000000000 --- a/include/ylt/coro_rpc/coro_rpc_client.hpp +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include "impl/coro_rpc_client.hpp" \ No newline at end of file diff --git a/include/ylt/coro_rpc/coro_rpc_context.hpp b/include/ylt/coro_rpc/coro_rpc_context.hpp deleted file mode 100644 index 2557e32bd..000000000 --- a/include/ylt/coro_rpc/coro_rpc_context.hpp +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include "impl/protocol/coro_rpc_protocol.hpp" diff --git a/include/ylt/coro_rpc/coro_rpc_server.hpp b/include/ylt/coro_rpc/coro_rpc_server.hpp deleted file mode 100644 index cdece4fde..000000000 --- a/include/ylt/coro_rpc/coro_rpc_server.hpp +++ /dev/null @@ -1,18 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include "impl/coro_rpc_server.hpp" -#include "impl/default_config/coro_rpc_config.hpp" diff --git a/include/ylt/coro_rpc/impl/common_service.hpp b/include/ylt/coro_rpc/impl/common_service.hpp deleted file mode 100644 index c081232ed..000000000 --- a/include/ylt/coro_rpc/impl/common_service.hpp +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include - -#ifdef YLT_ENABLE_SSL -#include -#endif - -namespace coro_rpc { -/*! - * \file common_service.hpp - */ - -/*! - * SSL config - */ -struct ssl_configure { - std::string base_path; //!< all config files base path - std::string cert_file; //!< relative path of certificate chain file - std::string key_file; //!< relative path of private key file - std::string dh_file; //!< relative path of tmp dh file (optional) -}; - -/*! - * Check file (not a folder) exist - * - * just a helper function - * - * @param path - * @return true if file exist, otherwise false - */ -inline bool file_exists(const auto &path) { - std::error_code ec; - if (!std::filesystem::is_directory(path, ec) && - std::filesystem::exists(path, ec)) { - return true; - } - return false; -}; - -#ifdef YLT_ENABLE_SSL -/*! - * Initialize SSL Context `context` with SSL Config `conf` - * - * If init fail, a log reported and return false. - * - * @param context instance of asio::ssl::context - * @param conf object of ssl_configure - * @return true if init success, otherwise false - */ -inline bool init_ssl_context_helper(asio::ssl::context &context, - const ssl_configure &conf) { - namespace fs = std::filesystem; - try { - context.set_options(asio::ssl::context::default_workarounds | - asio::ssl::context::no_sslv2 | - asio::ssl::context::single_dh_use); - context.set_password_callback( - [](std::size_t size, - asio::ssl::context_base::password_purpose purpose) { - return "test"; - }); - auto cert_file = fs::path(conf.base_path).append(conf.cert_file); - auto key_file = fs::path(conf.base_path).append(conf.key_file); - auto dh_file = fs::path(conf.base_path).append(conf.dh_file); - - ELOGV(INFO, "current path %s", fs::current_path().string().data()); - if (file_exists(cert_file)) { - ELOGV(INFO, "load %s", cert_file.string().data()); - context.use_certificate_chain_file(cert_file); - } - else { - ELOGV(ERROR, "no certificate file %s", cert_file.string().data()); - return false; - } - - if (file_exists(key_file)) { - ELOGV(INFO, "load %s", key_file.string().data()); - context.use_private_key_file(key_file, asio::ssl::context::pem); - } - else { - ELOGV(ERROR, "no private key file %s", key_file.string().data()); - return false; - } - - if (file_exists(dh_file)) { - ELOGV(INFO, "load %s", dh_file.string().data()); - context.use_tmp_dh_file(dh_file); - } - else { - ELOGV(INFO, "no temp dh file %s", dh_file.string().data()); - } - - return true; - } catch (std::exception &e) { - ELOGV(INFO, "%s", e.what()); - return false; - } -} -#endif -} // namespace coro_rpc \ No newline at end of file diff --git a/include/ylt/coro_rpc/impl/context.hpp b/include/ylt/coro_rpc/impl/context.hpp deleted file mode 100644 index 1d1b046ae..000000000 --- a/include/ylt/coro_rpc/impl/context.hpp +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "coro_connection.hpp" -#include "ylt/coro_rpc/impl/errno.h" -#include "ylt/util/type_traits.h" - -namespace coro_rpc { -/*! - * - * @tparam return_msg_type - * @tparam coro_connection - */ -template -class context_base { - protected: - std::shared_ptr> self_; - typename rpc_protocol::req_header &get_req_head() { return self_->req_head_; } - - bool check_status() { - auto old_flag = self_->has_response_.exchange(true); - if (old_flag != false) - AS_UNLIKELY { - ELOGV(ERROR, "response message more than one time"); - return false; - } - - if (has_closed()) - AS_UNLIKELY { - ELOGV(DEBUG, "response_msg failed: connection has been closed"); - return false; - } - return true; - } - - public: - /*! - * Construct a context by a share pointer of context Concept - * instance - * @param a share pointer for coro_connection - */ - context_base(std::shared_ptr> context_info) - : self_(std::move(context_info)) { - if (self_->conn_) { - self_->conn_->set_rpc_call_type( - coro_connection::rpc_call_type::callback_started); - } - }; - context_base() = default; - - using return_type = return_msg_type; - - void response_error(coro_rpc::err_code error_code, - std::string_view error_msg) { - if (!check_status()) - AS_UNLIKELY { return; }; - self_->conn_->template response_error( - error_code, error_msg, self_->req_head_, self_->is_delay_); - } - void response_error(coro_rpc::err_code error_code) { - response_error(error_code, error_code.message()); - } - /*! - * Send response message - * - * The `return_msg_type` must be constructed by these `args`. - * - * If the connection has already sent response message, - * an error log will be reported. - * - * @tparam Args - * @param args - */ - template - void response_msg(Args &&...args) { - if constexpr (std::is_same_v) { - static_assert(sizeof...(args) == 0, "illegal args"); - if (!check_status()) - AS_UNLIKELY { return; }; - std::visit( - [&](const serialize_proto &) { - self_->conn_->template response_msg( - serialize_proto::serialize(), - std::move(self_->resp_attachment_), self_->req_head_, - self_->is_delay_); - }, - *rpc_protocol::get_serialize_protocol(self_->req_head_)); - } - else { - static_assert( - requires { return_msg_type{std::forward(args)...}; }, - "constructed return_msg_type failed by illegal args"); - - if (!check_status()) - AS_UNLIKELY { return; }; - - return_msg_type ret{std::forward(args)...}; - std::visit( - [&](const serialize_proto &) { - self_->conn_->template response_msg( - serialize_proto::serialize(ret), - std::move(self_->resp_attachment_), self_->req_head_, - self_->is_delay_); - }, - *rpc_protocol::get_serialize_protocol(self_->req_head_)); - - // response_handler_(std::move(conn_), std::move(ret)); - } - } - - /*! - * Check connection closed or not - * - * @return true if closed, otherwise false - */ - bool has_closed() const { return self_->conn_->has_closed(); } - - /*! - * Close connection - */ - void close() { return self_->conn_->async_close(); } - - /*! - * Get the unique connection ID - * @return connection id - */ - uint64_t get_connection_id() { return self_->conn_->conn_id_; } - - /*! - * Set the response_attachment - * @return a ref of response_attachment - */ - void set_response_attachment(std::string attachment) { - set_response_attachment([attachment = std::move(attachment)] { - return std::string_view{attachment}; - }); - } - - /*! - * Set the response_attachment - * @return a ref of response_attachment - */ - void set_response_attachment(std::function attachment) { - self_->resp_attachment_ = std::move(attachment); - } - - /*! - * Get the request attachment - * @return connection id - */ - std::string_view get_request_attachment() const { - return self_->req_attachment_; - } - - /*! - * Release the attachment - * @return connection id - */ - std::string release_request_attachment() { - return std::move(self_->req_attachment_); - } - - void set_delay() { - self_->is_delay_ = true; - self_->conn_->set_rpc_call_type( - coro_connection::rpc_call_type::callback_with_delay); - } - std::any &tag() { return self_->conn_->tag(); } - const std::any &tag() const { return self_->conn_->tag(); } -}; - -template -struct get_type_t { - using type = T; -}; - -template -struct get_type_t> { - using type = T; -}; - -template -inline auto get_return_type() { - using T = decltype(func); - using param_type = util::function_parameters_t; - using return_type = - typename get_type_t>::type; - if constexpr (std::is_void_v) { - if constexpr (std::is_void_v) { - return; - } - else { - return return_type{}; - } - } - else { - using First = std::tuple_element_t<0, param_type>; - constexpr bool is_conn = - util::is_specialization::value; - - if constexpr (is_conn) { - using U = typename First::return_type; - if constexpr (std::is_void_v) { - return; - } - else { - return U{}; - } - } - else if constexpr (!std::is_same_v) { - return return_type{}; - } - else { - return; - } - } -} -} // namespace coro_rpc \ No newline at end of file diff --git a/include/ylt/coro_rpc/impl/coro_connection.hpp b/include/ylt/coro_rpc/impl/coro_connection.hpp deleted file mode 100644 index 349d20479..000000000 --- a/include/ylt/coro_rpc/impl/coro_connection.hpp +++ /dev/null @@ -1,556 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ylt/coro_io/coro_io.hpp" -#include "ylt/coro_rpc/impl/errno.h" -#ifdef UNIT_TEST_INJECT -#include "inject_action.hpp" -#endif -namespace coro_rpc { - -class coro_connection; -using rpc_conn = std::shared_ptr; - -template -struct context_info_t { - std::shared_ptr conn_; - typename rpc_protocol::req_header req_head_; - std::string req_body_; - std::string req_attachment_; - std::function resp_attachment_ = [] { - return std::string_view{}; - }; - std::atomic has_response_ = false; - bool is_delay_ = false; - context_info_t(std::shared_ptr &&conn) - : conn_(std::move(conn)) {} -}; -/*! - * TODO: add doc - */ - -[[noreturn]] inline void unreachable() { - // Uses compiler specific extensions if possible. - // Even if no extension is used, undefined behavior is still raised by - // an empty function body and the noreturn attribute. -#ifdef __GNUC__ // GCC, Clang, ICC - __builtin_unreachable(); -#elif defined(_MSC_VER) // msvc - __assume(false); -#endif -} - -class coro_connection : public std::enable_shared_from_this { - public: - enum rpc_call_type { - non_callback, - callback_with_delay, - callback_finished, - callback_started - }; - - /*! - * - * @param io_context - * @param socket - * @param timeout_duration - */ - template - coro_connection(executor_t *executor, asio::ip::tcp::socket socket, - std::chrono::steady_clock::duration timeout_duration = - std::chrono::seconds(0)) - : executor_(executor), - socket_(std::move(socket)), - resp_err_(), - timer_(executor->get_asio_executor()) { - if (timeout_duration == std::chrono::seconds(0)) { - return; - } - - enable_check_timeout_ = true; - keep_alive_timeout_duration_ = timeout_duration; - } - - ~coro_connection() { - if (!has_closed_) { -#ifdef UNIT_TEST_INJECT - ELOGV(INFO, "~async_connection conn_id %d, client_id %d", conn_id_, - client_id_); -#endif - close(); - } - } - -#ifdef YLT_ENABLE_SSL - void init_ssl(asio::ssl::context &ssl_ctx) { - ssl_stream_ = std::make_unique>( - socket_, ssl_ctx); - use_ssl_ = true; - } -#endif - - template - async_simple::coro::Lazy start( - typename rpc_protocol::router &router) noexcept { -#ifdef YLT_ENABLE_SSL - if (use_ssl_) { - assert(ssl_stream_); - ELOGV(INFO, "begin to handshake conn_id %d", conn_id_); - reset_timer(); - auto shake_ec = co_await coro_io::async_handshake( - ssl_stream_, asio::ssl::stream_base::server); - cancel_timer(); - if (shake_ec) { - ELOGV(ERROR, "handshake failed: %s conn_id %d", - shake_ec.message().data(), conn_id_); - close(); - } - else { - ELOGV(INFO, "handshake ok conn_id %d", conn_id_); - co_await start_impl(router, *ssl_stream_); - } - } - else { -#endif - co_await start_impl(router, socket_); -#ifdef YLT_ENABLE_SSL - } -#endif - } - template - async_simple::coro::Lazy start_impl( - typename rpc_protocol::router &router, Socket &socket) noexcept { - auto context_info = - std::make_shared>(shared_from_this()); - std::string resp_error_msg; - while (true) { - auto &req_head = context_info->req_head_; - auto &body = context_info->req_body_; - auto &req_attachment = context_info->req_attachment_; - reset_timer(); - auto ec = co_await rpc_protocol::read_head(socket, req_head); - cancel_timer(); - // `co_await async_read` uses asio::async_read underlying. - // If eof occurred, the bytes_transferred of `co_await async_read` must - // less than RPC_HEAD_LEN. Incomplete data will be discarded. - // So, no special handling of eof is required. - if (ec) { - ELOGV(INFO, "connection %d close: %s", conn_id_, ec.message().data()); - close(); - break; - } - -#ifdef UNIT_TEST_INJECT - client_id_ = req_head.seq_num; - ELOGV(INFO, "conn_id %d, client_id %d", conn_id_, client_id_); -#endif - -#ifdef UNIT_TEST_INJECT - if (g_action == inject_action::close_socket_after_read_header) { - ELOGV(WARN, - "inject action: close_socket_after_read_header, conn_id %d, " - "client_id %d", - conn_id_, client_id_); - close(); - break; - } -#endif - auto serialize_proto = rpc_protocol::get_serialize_protocol(req_head); - - if (!serialize_proto.has_value()) - AS_UNLIKELY { - ELOGV(ERROR, "bad serialize protocol type, conn_id %d", conn_id_); - close(); - break; - } - - std::string_view payload; - // rpc_protocol::buffer_type maybe from user, default from framework. - - ec = co_await rpc_protocol::read_payload(socket, req_head, body, - req_attachment); - payload = std::string_view{body}; - - if (ec) - AS_UNLIKELY { - ELOGV(ERROR, "read error: %s, conn_id %d", ec.message().data(), - conn_id_); - close(); - break; - } - - std::pair pair{}; - - auto key = rpc_protocol::get_route_key(req_head); - auto handler = router.get_handler(key); - if (!handler) { - auto coro_handler = router.get_coro_handler(key); - pair = co_await router.route_coro(coro_handler, payload, context_info, - serialize_proto.value(), key); - } - else { - pair = router.route(handler, payload, context_info, - serialize_proto.value(), key); - } - - auto &[resp_err, resp_buf] = pair; - switch (rpc_call_type_) { - default: - unreachable(); - case rpc_call_type::non_callback: - break; - case rpc_call_type::callback_with_delay: - ++delay_resp_cnt; - rpc_call_type_ = rpc_call_type::non_callback; - continue; - case rpc_call_type::callback_finished: - continue; - case rpc_call_type::callback_started: - coro_io::callback_awaitor awaitor; - rpc_call_type_ = rpc_call_type::callback_finished; - co_await awaitor.await_resume([this](auto handler) { - this->callback_awaitor_handler_ = std::move(handler); - }); - context_info->has_response_ = false; - context_info->resp_attachment_ = []() -> std::string_view { - return {}; - }; - rpc_call_type_ = rpc_call_type::non_callback; - continue; - } - resp_error_msg.clear(); - if (!!resp_err) - AS_UNLIKELY { std::swap(resp_buf, resp_error_msg); } - std::string header_buf = rpc_protocol::prepare_response( - resp_buf, req_head, 0, resp_err, resp_error_msg); - -#ifdef UNIT_TEST_INJECT - if (g_action == inject_action::close_socket_after_send_length) { - ELOGV(WARN, - "inject action: close_socket_after_send_length conn_id %d, " - "client_id %d", - conn_id_, client_id_); - co_await coro_io::async_write(socket, asio::buffer(header_buf)); - close(); - break; - } - if (g_action == inject_action::server_send_bad_rpc_result) { - ELOGV(WARN, - "inject action: server_send_bad_rpc_result conn_id %d, client_id " - "%d", - conn_id_, client_id_); - resp_buf[0] = resp_buf[0] + 1; - } -#endif - if (!resp_err_) - AS_LIKELY { - if (!resp_err) - AS_UNLIKELY { resp_err_ = resp_err; } - write_queue_.emplace_back(std::move(header_buf), std::move(resp_buf), - [] { - return std::string_view{}; - }); - if (write_queue_.size() == 1) { - send_data().start([self = shared_from_this()](auto &&) { - }); - } - if (!!resp_err) - AS_UNLIKELY { break; } - } - } - } - /*! - * send `ret` to RPC client - * - * @tparam R message type - * @param ret object of message type - */ - - template - void response_msg(std::string &&body_buf, - std::function &&resp_attachment, - const typename rpc_protocol::req_header &req_head, - bool is_delay) { - std::string header_buf = rpc_protocol::prepare_response( - body_buf, req_head, resp_attachment().size()); - response(std::move(header_buf), std::move(body_buf), - std::move(resp_attachment), shared_from_this(), is_delay) - .via(executor_) - .detach(); - } - - template - void response_error(coro_rpc::errc ec, std::string_view error_msg, - const typename rpc_protocol::req_header &req_head, - bool is_delay) { - std::function attach_ment = []() -> std::string_view { - return {}; - }; - std::string body_buf; - std::string header_buf = rpc_protocol::prepare_response( - body_buf, req_head, 0, ec, error_msg, true); - response(std::move(header_buf), std::move(body_buf), std::move(attach_ment), - shared_from_this(), is_delay) - .via(executor_) - .detach(); - } - - void set_rpc_call_type(enum rpc_call_type r) { rpc_call_type_ = r; } - - /*! - * Check the connection has closed or not - * - * @return true if closed, otherwise false. - */ - bool has_closed() const { return has_closed_; } - - /*! - * close connection asynchronously - * - * If the connection has already closed, nothing will happen. - * - * @param close_ssl whether to close the ssl stream - */ - void async_close() { - if (has_closed_) { - return; - } - executor_->schedule([this, self = shared_from_this()] { - this->close(); - }); - } - - void close_coro() {} - - using QuitCallback = std::function; - void set_quit_callback(QuitCallback callback, uint64_t conn_id) { - quit_callback_ = std::move(callback); - conn_id_ = conn_id; - } - - std::any &tag() { return tag_; } - const std::any &tag() const { return tag_; } - - auto &get_executor() { return *executor_; } - - private: - async_simple::coro::Lazy response( - std::string header_buf, std::string body_buf, - std::function resp_attachment, rpc_conn self, - bool is_delay) noexcept { - if (has_closed()) - AS_UNLIKELY { - ELOGV(DEBUG, "response_msg failed: connection has been closed"); - co_return; - } -#ifdef UNIT_TEST_INJECT - if (g_action == inject_action::close_socket_after_send_length) { - ELOGV(WARN, "inject action: close_socket_after_send_length"); - body_buf.clear(); - } -#endif - write_queue_.emplace_back(std::move(header_buf), std::move(body_buf), - std::move(resp_attachment)); - if (is_delay) { - --delay_resp_cnt; - assert(delay_resp_cnt >= 0); - reset_timer(); - } - if (write_queue_.size() == 1) { - co_await send_data(); - } - if (!is_delay) { - if (rpc_call_type_ == rpc_call_type::callback_finished) { - // the function start_impl is waiting for resume. - callback_awaitor_handler_.resume(); - } - else { - assert(rpc_call_type_ == rpc_call_type::callback_started); - // the function start_impl is not waiting for resume. - rpc_call_type_ = rpc_call_type::callback_finished; - } - } - } - - async_simple::coro::Lazy send_data() { - std::pair ret; - while (!write_queue_.empty()) { - auto &msg = write_queue_.front(); -#ifdef UNIT_TEST_INJECT - if (g_action == inject_action::force_inject_connection_close_socket) { - ELOGV( - WARN, - "inject action: force_inject_connection_close_socket, conn_id %d, " - "client_id %d", - conn_id_, client_id_); - close(); - co_return; - } -#endif - auto attachment = std::get<2>(msg)(); - if (attachment.empty()) { - std::array buffers{ - asio::buffer(std::get<0>(msg)), asio::buffer(std::get<1>(msg))}; -#ifdef YLT_ENABLE_SSL - if (use_ssl_) { - assert(ssl_stream_); - ret = co_await coro_io::async_write(*ssl_stream_, buffers); - } - else { -#endif - ret = co_await coro_io::async_write(socket_, buffers); -#ifdef YLT_ENABLE_SSL - } -#endif - } - else { - std::array buffers{ - asio::buffer(std::get<0>(msg)), asio::buffer(std::get<1>(msg)), - asio::buffer(attachment)}; -#ifdef YLT_ENABLE_SSL - if (use_ssl_) { - assert(ssl_stream_); - ret = co_await coro_io::async_write(*ssl_stream_, buffers); - } - else { -#endif - ret = co_await coro_io::async_write(socket_, buffers); -#ifdef YLT_ENABLE_SSL - } -#endif - } - if (ret.first) - AS_UNLIKELY { - ELOGV(ERROR, "%s, %s", ret.first.message().data(), - "async_write error"); - close(); - co_return; - } - write_queue_.pop_front(); - } - if (!!resp_err_) - AS_UNLIKELY { - ELOGV(ERROR, "%s, %s", make_error_message(resp_err_), "resp_err_"); - close(); - co_return; - } -#ifdef UNIT_TEST_INJECT - if (g_action == inject_action::close_socket_after_send_length) { - ELOGV(INFO, - "inject action: close_socket_after_send_length, conn_id %d, " - "client_id %d", - conn_id_, client_id_); - // Attention: close ssl stream after read error - // otherwise, server will crash - close(); - co_return; - } -#endif - } - - void close() { - if (has_closed_) { - return; - } - has_closed_ = true; - asio::error_code ignored_ec; - socket_.shutdown(asio::ip::tcp::socket::shutdown_both, ignored_ec); - socket_.close(ignored_ec); - if (quit_callback_) { - quit_callback_(conn_id_); - } - } - - void reset_timer() { - if (!enable_check_timeout_ || delay_resp_cnt != 0) { - return; - } - - timer_.expires_from_now(keep_alive_timeout_duration_); - timer_.async_wait( - [this, self = shared_from_this()](asio::error_code const &ec) { - if (!ec) { -#ifdef UNIT_TEST_INJECT - ELOGV(INFO, "close timeout client_id %d conn_id %d", client_id_, - conn_id_); -#else - ELOGV(INFO, "close timeout client conn_id %d", conn_id_); -#endif - - close(); - } - }); - } - - void cancel_timer() { - if (!enable_check_timeout_) { - return; - } - - asio::error_code ec; - timer_.cancel(ec); - } - - coro_io::callback_awaitor::awaitor_handler callback_awaitor_handler_{ - nullptr}; - async_simple::Executor *executor_; - asio::ip::tcp::socket socket_; - // FIXME: queue's performance can be imporved. - std::deque< - std::tuple>> - write_queue_; - coro_rpc::errc resp_err_; - rpc_call_type rpc_call_type_{non_callback}; - - // if don't get any message in keep_alive_timeout_duration_, the connection - // will be closed when enable_check_timeout_ is true. - std::chrono::steady_clock::duration keep_alive_timeout_duration_; - bool enable_check_timeout_{false}; - asio::steady_timer timer_; - std::atomic has_closed_{false}; - - QuitCallback quit_callback_{nullptr}; - uint64_t conn_id_{0}; - uint64_t delay_resp_cnt{0}; - - std::any tag_; - -#ifdef YLT_ENABLE_SSL - std::unique_ptr> ssl_stream_ = - nullptr; - bool use_ssl_ = false; -#endif -#ifdef UNIT_TEST_INJECT - uint32_t client_id_ = 0; -#endif -}; - -} // namespace coro_rpc diff --git a/include/ylt/coro_rpc/impl/coro_rpc_client.hpp b/include/ylt/coro_rpc/impl/coro_rpc_client.hpp deleted file mode 100644 index 9038fc391..000000000 --- a/include/ylt/coro_rpc/impl/coro_rpc_client.hpp +++ /dev/null @@ -1,849 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "asio/buffer.hpp" -#include "asio/dispatch.hpp" -#include "asio/registered_buffer.hpp" -#include "common_service.hpp" -#include "context.hpp" -#include "expected.hpp" -#include "protocol/coro_rpc_protocol.hpp" -#include "ylt/coro_io/coro_io.hpp" -#include "ylt/coro_io/io_context_pool.hpp" -#include "ylt/coro_rpc/impl/errno.h" -#include "ylt/struct_pack.hpp" -#include "ylt/struct_pack/util.h" -#include "ylt/util/function_name.h" -#include "ylt/util/type_traits.h" -#include "ylt/util/utils.hpp" -#ifdef UNIT_TEST_INJECT -#include "inject_action.hpp" -#endif - -#ifdef GENERATE_BENCHMARK_DATA -#include -#endif -namespace coro_io { -template -class client_pool; -} - -namespace coro_rpc { - -#ifdef GENERATE_BENCHMARK_DATA -std::string benchmark_file_path = "./"; -#endif - -class coro_connection; - -template -struct rpc_return_type { - using type = T; -}; -template <> -struct rpc_return_type { - using type = std::monostate; -}; -template -using rpc_return_type_t = typename rpc_return_type::type; -/*! - * ```cpp - * #include - * - * using namespace coro_rpc; - * using namespace async_simple::coro; - * - * Lazy show_rpc_call(coro_rpc_client &client) { - * auto ec = co_await client.connect("127.0.0.1", "8801"); - * assert(!ec); - * auto result = co_await client.call(); - * if (!result) { - * std::cout << "err: " << result.error().msg << std::endl; - * } - * assert(result.value() == "hello coro_rpc"s); - * } - * - * int main() { - * coro_rpc_client client; - * syncAwait(show_rpc_call(client)); - * } - * ``` - */ -class coro_rpc_client { - using coro_rpc_protocol = coro_rpc::protocol::coro_rpc_protocol; - - public: - const inline static coro_rpc_protocol::rpc_error connect_error = { - errc::io_error, "client has been closed"}; - struct config { - uint32_t client_id = 0; - std::chrono::milliseconds timeout_duration = - std::chrono::milliseconds{5000}; - std::string host; - std::string port; -#ifdef YLT_ENABLE_SSL - std::filesystem::path ssl_cert_path; - std::string ssl_domain; -#endif - }; - - /*! - * Create client with io_context - * @param io_context asio io_context, async event handler - */ - coro_rpc_client(asio::io_context::executor_type executor, - uint32_t client_id = 0) - : executor(executor), - socket_(std::make_shared(executor)) { - config_.client_id = client_id; - } - - /*! - * Create client with io_context - * @param io_context asio io_context, async event handler - */ - coro_rpc_client( - coro_io::ExecutorWrapper<> &executor = *coro_io::get_global_executor(), - uint32_t client_id = 0) - : executor(executor.get_asio_executor()), - socket_(std::make_shared( - executor.get_asio_executor())) { - config_.client_id = client_id; - } - - std::string_view get_host() const { return config_.host; } - - std::string_view get_port() const { return config_.port; } - - [[nodiscard]] bool init_config(const config &conf) { - config_ = conf; -#ifdef YLT_ENABLE_SSL - if (!config_.ssl_cert_path.empty()) - return init_ssl_impl(); - else -#endif - return true; - }; - - /*! - * Check the client closed or not - * - * @return true if client closed, otherwise false. - */ - [[nodiscard]] bool has_closed() { return has_closed_; } - - /*! - * Reconnect server - * - * If connect hasn't been closed, it will be closed first then connect to - * server, else the client will connect to server directly - * - * @param host server address - * @param port server port - * @param timeout_duration RPC call timeout - * @return error code - */ - [[nodiscard]] async_simple::coro::Lazy reconnect( - std::string host, std::string port, - std::chrono::steady_clock::duration timeout_duration = - std::chrono::seconds(5)) { - config_.host = std::move(host); - config_.port = std::move(port); - config_.timeout_duration = - std::chrono::duration_cast(timeout_duration); - reset(); - return connect(is_reconnect_t{true}); - } - - [[nodiscard]] async_simple::coro::Lazy reconnect( - std::string endpoint, - std::chrono::steady_clock::duration timeout_duration = - std::chrono::seconds(5)) { - auto pos = endpoint.find(':'); - config_.host = endpoint.substr(0, pos); - config_.port = endpoint.substr(pos + 1); - config_.timeout_duration = - std::chrono::duration_cast(timeout_duration); - reset(); - return connect(is_reconnect_t{true}); - } - /*! - * Connect server - * - * If connect hasn't been closed, it will be closed first then connect to - * server, else the client will connect to server directly - * - * @param host server address - * @param port server port - * @param timeout_duration RPC call timeout - * @return error code - */ - [[nodiscard]] async_simple::coro::Lazy connect( - std::string host, std::string port, - std::chrono::steady_clock::duration timeout_duration = - std::chrono::seconds(5)) { - config_.host = std::move(host); - config_.port = std::move(port); - config_.timeout_duration = - std::chrono::duration_cast(timeout_duration); - return connect(); - } - [[nodiscard]] async_simple::coro::Lazy connect( - std::string_view endpoint, - std::chrono::steady_clock::duration timeout_duration = - std::chrono::seconds(5)) { - auto pos = endpoint.find(':'); - config_.host = endpoint.substr(0, pos); - config_.port = endpoint.substr(pos + 1); - config_.timeout_duration = - std::chrono::duration_cast(timeout_duration); - return connect(); - } - -#ifdef YLT_ENABLE_SSL - - [[nodiscard]] bool init_ssl(std::string_view cert_base_path, - std::string_view cert_file_name, - std::string_view domain = "localhost") { - config_.ssl_cert_path = - std::filesystem::path(cert_base_path).append(cert_file_name); - config_.ssl_domain = domain; - return init_ssl_impl(); - } -#endif - - ~coro_rpc_client() { close(); } - - /*! - * Call RPC function with default timeout (5 second) - * - * @tparam func the address of RPC function - * @tparam Args the type of arguments - * @param args RPC function arguments - * @return RPC call result - */ - template - async_simple::coro::Lazy< - rpc_result()), coro_rpc_protocol>> - call(Args... args) { - return call_for(std::chrono::seconds(5), std::move(args)...); - } - - /*! - * Call RPC function - * - * Timeout must be set explicitly. - * - * @tparam func the address of RPC function - * @tparam Args the type of arguments - * @param duration RPC call timeout - * @param args RPC function arguments - * @return RPC call result - */ - template - async_simple::coro::Lazy< - rpc_result()), coro_rpc_protocol>> - call_for(auto duration, Args... args) { - using R = decltype(get_return_type()); - - if (has_closed_) - AS_UNLIKELY { - ELOGV(ERROR, "client has been closed, please re-connect"); - auto ret = rpc_result{ - unexpect_t{}, - coro_rpc_protocol::rpc_error{ - errc::io_error, "client has been closed, please re-connect"}}; - co_return ret; - } - - rpc_result ret; -#ifdef YLT_ENABLE_SSL - if (!ssl_init_ret_) { - ret = rpc_result{ - unexpect_t{}, - coro_rpc_protocol::rpc_error{ - errc::not_connected, - std::string{make_error_message(errc::not_connected)}}}; - co_return ret; - } -#endif - - static_check(); - - async_simple::Promise promise; - coro_io::period_timer timer(&executor); - timeout(timer, duration, promise, "rpc call timer canceled") - .via(&executor) - .detach(); - -#ifdef YLT_ENABLE_SSL - if (!config_.ssl_cert_path.empty()) { - assert(ssl_stream_); - ret = co_await call_impl(*ssl_stream_, std::move(args)...); - } - else { -#endif - ret = co_await call_impl(*socket_, std::move(args)...); -#ifdef YLT_ENABLE_SSL - } -#endif - - std::error_code err_code; - timer.cancel(err_code); - - if (is_timeout_) { - ret = rpc_result{ - unexpect_t{}, - coro_rpc_protocol::rpc_error{errc::timed_out, "rpc call timed out"}}; - } - - co_await promise.getFuture(); -#ifdef UNIT_TEST_INJECT - ELOGV(INFO, "client_id %d call %s %s", config_.client_id, - get_func_name().data(), ret ? "ok" : "failed"); -#endif - co_return ret; - } - - /*! - * Get inner executor - */ - auto &get_executor() { return executor; } - - uint32_t get_client_id() const { return config_.client_id; } - - void close() { - if (has_closed_) { - return; - } - has_closed_ = true; - ELOGV(INFO, "client_id %d close", config_.client_id); - close_socket(socket_); - } - - bool set_req_attachment(std::string_view attachment) { - if (attachment.size() > UINT32_MAX) { - ELOGV(ERROR, "too large rpc attachment"); - return false; - } - req_attachment_ = attachment; - return true; - } - - std::string_view get_resp_attachment() const { return resp_attachment_buf_; } - - std::string release_resp_attachment() { - return std::move(resp_attachment_buf_); - } - - template - friend class coro_io::client_pool; - - private: - // the const char * will convert to bool instead of std::string_view - // use this struct to prevent it. - struct is_reconnect_t { - bool value = false; - }; - - void reset() { - close_socket(socket_); - socket_ = - std::make_shared(executor.get_asio_executor()); - is_timeout_ = false; - has_closed_ = false; - } - static bool is_ok(coro_rpc::err_code ec) noexcept { return !ec; } - [[nodiscard]] async_simple::coro::Lazy connect( - is_reconnect_t is_reconnect = is_reconnect_t{false}) { -#ifdef YLT_ENABLE_SSL - if (!ssl_init_ret_) { - std::cout << "ssl_init_ret_: " << ssl_init_ret_ << std::endl; - co_return errc::not_connected; - } -#endif - if (!is_reconnect.value && has_closed_) - AS_UNLIKELY { - ELOGV(ERROR, - "a closed client is not allowed connect again, please use " - "reconnect function or create a new " - "client"); - co_return errc::io_error; - } - has_closed_ = false; - - ELOGV(INFO, "client_id %d begin to connect %s", config_.client_id, - config_.port.data()); - async_simple::Promise promise; - coro_io::period_timer timer(&executor); - timeout(timer, config_.timeout_duration, promise, "connect timer canceled") - .via(&executor) - .detach(); - - std::error_code ec = co_await coro_io::async_connect( - &executor, *socket_, config_.host, config_.port); - std::error_code err_code; - timer.cancel(err_code); - - co_await promise.getFuture(); - if (ec) { - if (is_timeout_) { - co_return errc::timed_out; - } - co_return errc::not_connected; - } - - if (is_timeout_) { - ELOGV(WARN, "client_id %d connect timeout", config_.client_id); - co_return errc::timed_out; - } - -#ifdef YLT_ENABLE_SSL - if (!config_.ssl_cert_path.empty()) { - assert(ssl_stream_); - auto shake_ec = co_await coro_io::async_handshake( - ssl_stream_, asio::ssl::stream_base::client); - if (shake_ec) { - ELOGV(WARN, "client_id %d handshake failed: %s", config_.client_id, - shake_ec.message().data()); - co_return errc::not_connected; - } - } -#endif - - co_return coro_rpc::err_code{}; - }; -#ifdef YLT_ENABLE_SSL - [[nodiscard]] bool init_ssl_impl() { - try { - ssl_init_ret_ = false; - ELOGV(INFO, "init ssl: %s", config_.ssl_domain.data()); - auto &cert_file = config_.ssl_cert_path; - ELOGV(INFO, "current path %s", - std::filesystem::current_path().string().data()); - if (file_exists(cert_file)) { - ELOGV(INFO, "load %s", cert_file.string().data()); - ssl_ctx_.load_verify_file(cert_file); - } - else { - ELOGV(INFO, "no certificate file %s", cert_file.string().data()); - return ssl_init_ret_; - } - ssl_ctx_.set_verify_mode(asio::ssl::verify_peer); - ssl_ctx_.set_verify_callback( - asio::ssl::host_name_verification(config_.ssl_domain)); - ssl_stream_ = - std::make_unique>( - *socket_, ssl_ctx_); - ssl_init_ret_ = true; - } catch (std::exception &e) { - ELOGV(ERROR, "init ssl failed: %s", e.what()); - } - return ssl_init_ret_; - } -#endif - async_simple::coro::Lazy timeout(auto &timer, auto duration, - auto &promise, std::string err_msg) { - timer.expires_after(duration); - bool is_timeout = co_await timer.async_await(); -#ifdef UNIT_TEST_INJECT - ELOGV(INFO, "client_id %d %s, is_timeout_ %d, %d , duration %d ms", - config_.client_id, err_msg.data(), is_timeout_, is_timeout, - std::chrono::duration_cast(duration) - .count()); -#endif - if (!is_timeout) { - promise.setValue(async_simple::Unit()); - co_return false; - } - - is_timeout_ = is_timeout; - close_socket(socket_); - promise.setValue(async_simple::Unit()); - co_return true; - } - - template - void static_check() { - using Function = decltype(func); - using param_type = util::function_parameters_t; - if constexpr (!std::is_void_v) { - using First = std::tuple_element_t<0, param_type>; - constexpr bool is_conn = requires { typename First::return_type; }; - - if constexpr (std::is_member_function_pointer_v) { - using Self = util::class_type_t; - if constexpr (is_conn) { - static_assert( - util::is_invocable::value, - "called rpc function and arguments are not match"); - } - else { - static_assert(util::is_invocable::value, - "called rpc function and arguments are not match"); - } - } - else { - if constexpr (is_conn) { - static_assert(util::is_invocable::value, - "called rpc function and arguments are not match"); - } - else { - static_assert(util::is_invocable::value, - "called rpc function and arguments are not match"); - } - } - } - else { - if constexpr (std::is_member_function_pointer_v) { - using Self = util::class_type_t; - static_assert(util::is_invocable::value, - "called rpc function and arguments are not match"); - } - else { - static_assert(util::is_invocable::value, - "called rpc function and arguments are not match"); - } - } - } - - template - async_simple::coro::Lazy< - rpc_result()), coro_rpc_protocol>> - call_impl(Socket &socket, Args... args) { - using R = decltype(get_return_type()); - - auto buffer = prepare_buffer(std::move(args)...); - - rpc_result r{}; - if (buffer.empty()) { - r = rpc_result{ - unexpect_t{}, - coro_rpc_protocol::rpc_error{errc::message_too_large, - "rpc body serialize size too big"}}; - co_return r; - } -#ifdef GENERATE_BENCHMARK_DATA - std::ofstream file( - benchmark_file_path + std::string{get_func_name()} + ".in", - std::ofstream::binary | std::ofstream::out); - file << std::string_view{(char *)buffer.data(), buffer.size()}; - file.close(); -#endif - std::pair ret; -#ifdef UNIT_TEST_INJECT - if (g_action == inject_action::client_send_bad_header) { - buffer[0] = (std::byte)(uint8_t(buffer[0]) + 1); - } - if (g_action == inject_action::client_close_socket_after_send_header) { - ret = co_await coro_io::async_write( - socket, asio::buffer(buffer.data(), coro_rpc_protocol::REQ_HEAD_LEN)); - ELOGV(INFO, "client_id %d close socket", config_.client_id); - close(); - r = rpc_result{ - unexpect_t{}, - coro_rpc_protocol::rpc_error{errc::io_error, ret.first.message()}}; - co_return r; - } - else if (g_action == - inject_action::client_close_socket_after_send_partial_header) { - ret = co_await coro_io::async_write( - socket, - asio::buffer(buffer.data(), coro_rpc_protocol::REQ_HEAD_LEN - 1)); - ELOGV(INFO, "client_id %d close socket", config_.client_id); - close(); - r = rpc_result{ - unexpect_t{}, - coro_rpc_protocol::rpc_error{errc::io_error, ret.first.message()}}; - co_return r; - } - else if (g_action == - inject_action::client_shutdown_socket_after_send_header) { - ret = co_await coro_io::async_write( - socket, asio::buffer(buffer.data(), coro_rpc_protocol::REQ_HEAD_LEN)); - ELOGV(INFO, "client_id %d shutdown", config_.client_id); - socket_->shutdown(asio::ip::tcp::socket::shutdown_send); - r = rpc_result{ - unexpect_t{}, - coro_rpc_protocol::rpc_error{errc::io_error, ret.first.message()}}; - co_return r; - } - else { -#endif - if (req_attachment_.empty()) { - ret = co_await coro_io::async_write( - socket, asio::buffer(buffer.data(), buffer.size())); - } - else { - std::array iov{ - asio::const_buffer{buffer.data(), buffer.size()}, - asio::const_buffer{req_attachment_.data(), req_attachment_.size()}}; - ret = co_await coro_io::async_write(socket, iov); - req_attachment_ = {}; - } -#ifdef UNIT_TEST_INJECT - } -#endif - if (!ret.first) { -#ifdef UNIT_TEST_INJECT - if (g_action == inject_action::client_close_socket_after_send_payload) { - ELOGV(INFO, "client_id %d client_close_socket_after_send_payload", - config_.client_id); - r = rpc_result{ - unexpect_t{}, - coro_rpc_protocol::rpc_error{errc::io_error, ret.first.message()}}; - close(); - co_return r; - } -#endif - coro_rpc_protocol::resp_header header; - ret = co_await coro_io::async_read( - socket, - asio::buffer((char *)&header, coro_rpc_protocol::RESP_HEAD_LEN)); - if (!ret.first) { - uint32_t body_len = header.length; - struct_pack::detail::resize(read_buf_, body_len); - if (header.attach_length == 0) { - ret = co_await coro_io::async_read( - socket, asio::buffer(read_buf_.data(), body_len)); - resp_attachment_buf_.clear(); - } - else { - struct_pack::detail::resize(resp_attachment_buf_, - header.attach_length); - std::array iov{ - asio::mutable_buffer{read_buf_.data(), body_len}, - asio::mutable_buffer{resp_attachment_buf_.data(), - resp_attachment_buf_.size()}}; - ret = co_await coro_io::async_read(socket, iov); - } - if (!ret.first) { -#ifdef GENERATE_BENCHMARK_DATA - std::ofstream file( - benchmark_file_path + std::string{get_func_name()} + ".out", - std::ofstream::binary | std::ofstream::out); - file << std::string_view{(char *)&header, - coro_rpc_protocol::RESP_HEAD_LEN}; - file << read_buf_; - file << resp_attachment_buf_; - file.close(); -#endif - bool ec = false; - r = handle_response_buffer(read_buf_, header.err_code, ec); - if (ec) { - close(); - } - co_return r; - } - } - } -#ifdef UNIT_TEST_INJECT - if (g_action == inject_action::force_inject_client_write_data_timeout) { - is_timeout_ = true; - } -#endif - if (is_timeout_) { - r = rpc_result{ - unexpect_t{}, - coro_rpc_protocol::rpc_error{.code = errc::timed_out, .msg = {}}}; - } - else { - r = rpc_result{ - unexpect_t{}, - coro_rpc_protocol::rpc_error{.code = errc::io_error, - .msg = ret.first.message()}}; - } - close(); - co_return r; - } - /* - * buffer layout - * ┌────────────────┬────────────────┐ - * │req_header │args │ - * ├────────────────┼────────────────┤ - * │REQ_HEADER_LEN │variable length │ - * └────────────────┴────────────────┘ - */ - template - std::vector prepare_buffer(Args &&...args) { - std::vector buffer; - std::size_t offset = coro_rpc_protocol::REQ_HEAD_LEN; - if constexpr (sizeof...(Args) > 0) { - using arg_types = util::function_parameters_t; - pack_to(buffer, offset, std::forward(args)...); - } - else { - buffer.resize(offset); - } - - auto &header = *(coro_rpc_protocol::req_header *)buffer.data(); - header = {}; - header.magic = coro_rpc_protocol::magic_number; - header.function_id = func_id(); - header.attach_length = req_attachment_.size(); -#ifdef UNIT_TEST_INJECT - header.seq_num = config_.client_id; - if (g_action == inject_action::client_send_bad_magic_num) { - header.magic = coro_rpc_protocol::magic_number + 1; - } - if (g_action == inject_action::client_send_header_length_0) { - header.length = 0; - } - else { -#endif - auto sz = buffer.size() - coro_rpc_protocol::REQ_HEAD_LEN; - if (sz > UINT32_MAX) { - ELOGV(ERROR, "too large rpc body"); - return {}; - } - header.length = sz; -#ifdef UNIT_TEST_INJECT - } -#endif - return buffer; - } - - template - rpc_result handle_response_buffer(std::string &buffer, - uint8_t rpc_errc, - bool &error_happen) { - rpc_return_type_t ret; - struct_pack::err_code ec; - coro_rpc_protocol::rpc_error err; - if (rpc_errc == 0) - AS_LIKELY { - ec = struct_pack::deserialize_to(ret, buffer); - if SP_LIKELY (!ec) { - if constexpr (std::is_same_v) { - return {}; - } - else { - return std::move(ret); - } - } - } - else { - err.val() = rpc_errc; - if (rpc_errc != UINT8_MAX) { - ec = struct_pack::deserialize_to(err.msg, buffer); - if SP_LIKELY (!ec) { - error_happen = true; - return rpc_result{unexpect_t{}, std::move(err)}; - } - } - else { - ec = struct_pack::deserialize_to(err, buffer); - if SP_LIKELY (!ec) { - return rpc_result{unexpect_t{}, std::move(err)}; - } - } - } - error_happen = true; - // deserialize failed. - err = {errc::invalid_argument, "failed to deserialize rpc return value"}; - return rpc_result{unexpect_t{}, std::move(err)}; - } - - template - auto get_func_args() { - using First = std::tuple_element_t<0, FuncArgs>; - constexpr bool has_conn_v = requires { typename First::return_type; }; - return util::get_args(); - } - - template - void pack_to_impl(Buffer &buffer, std::size_t offset, Args &&...args) { - struct_pack::serialize_to_with_offset( - buffer, offset, std::forward(std::forward(args))...); - } - - template - void pack_to_helper(std::index_sequence, Buffer &buffer, - std::size_t offset, Args &&...args) { - pack_to_impl...>( - buffer, offset, std::forward(args)...); - } - - template - void pack_to(Buffer &buffer, std::size_t offset, Args &&...args) { - using tuple_pack = decltype(get_func_args()); - pack_to_helper( - std::make_index_sequence>{}, buffer, - offset, std::forward(args)...); - } - - void close_socket(std::shared_ptr socket) { - asio::dispatch( - executor.get_asio_executor(), [socket = std::move(socket)]() { - asio::error_code ignored_ec; - socket->shutdown(asio::ip::tcp::socket::shutdown_both, ignored_ec); - socket->close(ignored_ec); - }); - } - -#ifdef UNIT_TEST_INJECT - public: - coro_rpc::err_code sync_connect(const std::string &host, - const std::string &port) { - return async_simple::coro::syncAwait(connect(host, port)); - } - - template - rpc_result()), coro_rpc_protocol> sync_call( - Args &&...args) { - return async_simple::coro::syncAwait( - call(std::forward(args)...)); - } -#endif - private: - coro_io::ExecutorWrapper<> executor; - std::shared_ptr socket_; - std::string read_buf_, resp_attachment_buf_; - std::string_view req_attachment_; - config config_; - constexpr static std::size_t default_read_buf_size_ = 256; -#ifdef YLT_ENABLE_SSL - asio::ssl::context ssl_ctx_{asio::ssl::context::sslv23}; - std::unique_ptr> ssl_stream_; - bool ssl_init_ret_ = true; -#endif - bool is_timeout_ = false; - std::atomic has_closed_ = false; -}; -} // namespace coro_rpc diff --git a/include/ylt/coro_rpc/impl/coro_rpc_server.hpp b/include/ylt/coro_rpc/impl/coro_rpc_server.hpp deleted file mode 100644 index 3498ede05..000000000 --- a/include/ylt/coro_rpc/impl/coro_rpc_server.hpp +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "async_simple/Common.h" -#include "async_simple/Promise.h" -#include "common_service.hpp" -#include "coro_connection.hpp" -#include "ylt/coro_io/coro_io.hpp" -#include "ylt/coro_io/io_context_pool.hpp" -#include "ylt/coro_rpc/impl/expected.hpp" -namespace coro_rpc { -/*! - * ```cpp - * #include - * inline std::string hello_coro_rpc() { return "hello coro_rpc"; } - * int main(){ - * register_handler(); - * coro_rpc_server server(std::thread::hardware_concurrency(), 9000); - * server.start(); - * return 0; - * } - * ``` - */ - -template -class coro_rpc_server_base { - //!< Server state - enum class stat { - init = 0, // server hasn't started/stopped. - started, // server is started - stop // server is stopping/stopped - }; - - public: - /*! - * TODO: add doc - * @param thread_num the number of io_context. - * @param port the server port to listen. - * @param conn_timeout_duration client connection timeout. 0 for no timeout. - * default no timeout. - */ - coro_rpc_server_base(size_t thread_num, unsigned short port, - std::chrono::steady_clock::duration - conn_timeout_duration = std::chrono::seconds(0)) - : pool_(thread_num), - acceptor_(pool_.get_executor()->get_asio_executor()), - port_(port), - conn_timeout_duration_(conn_timeout_duration), - flag_{stat::init} {} - - coro_rpc_server_base(const server_config &config = server_config{}) - : pool_(config.thread_num), - acceptor_(pool_.get_executor()->get_asio_executor()), - port_(config.port), - conn_timeout_duration_(config.conn_timeout_duration), - flag_{stat::init} {} - - ~coro_rpc_server_base() { - ELOGV(INFO, "coro_rpc_server will quit"); - stop(); - } - -#ifdef YLT_ENABLE_SSL - void init_ssl_context(const ssl_configure &conf) { - use_ssl_ = init_ssl_context_helper(context_, conf); - } -#endif - - /*! - * Start the server in blocking mode - * - * If the port is used, it will return a non-empty error code. - * - * @return error code if start failed, otherwise block until server stop. - */ - [[nodiscard]] coro_rpc::err_code start() noexcept { - auto ret = async_start(); - if (ret) { - ret.value().wait(); - return ret.value().value(); - } - else { - return ret.error(); - } - } - - [[nodiscard]] coro_rpc::expected, - coro_rpc::err_code> - async_start() noexcept { - coro_rpc::err_code ec{}; - { - std::unique_lock lock(start_mtx_); - if (flag_ != stat::init) { - if (flag_ == stat::started) { - ELOGV(INFO, "start again"); - } - else if (flag_ == stat::stop) { - ELOGV(INFO, "has stoped"); - } - return coro_rpc::unexpected{ - coro_rpc::errc::server_has_ran}; - } - ec = listen(); - if (!ec) { - if constexpr (requires(typename server_config::executor_pool_t & pool) { - pool.run(); - }) { - thd_ = std::thread([this] { - pool_.run(); - }); - } - flag_ = stat::started; - } - else { - flag_ = stat::stop; - } - } - if (!ec) { - async_simple::Promise promise; - auto future = promise.getFuture(); - accept().start([p = std::move(promise)](auto &&res) mutable { - if (res.hasError()) { - p.setValue(coro_rpc::err_code{coro_rpc::errc::io_error}); - } - else { - p.setValue(res.value()); - } - }); - return std::move(future); - } - else { - return coro_rpc::unexpected{ec}; - } - } - - /*! - * Stop server - * - * Block and wait server stops. - */ - void stop() { - std::unique_lock lock(start_mtx_); - if (flag_ == stat::stop) { - return; - } - - ELOGV(INFO, "begin to stop coro_rpc_server, conn size %d", conns_.size()); - - if (flag_ == stat::started) { - close_acceptor(); - { - std::unique_lock lock(conns_mtx_); - for (auto &conn : conns_) { - if (!conn.second->has_closed()) { - conn.second->async_close(); - } - } - - conns_.clear(); - } - - ELOGV(INFO, "wait for server's thread-pool finish all work."); - pool_.stop(); - ELOGV(INFO, "server's thread-pool finished."); - } - if (thd_.joinable()) { - thd_.join(); - } - - ELOGV(INFO, "stop coro_rpc_server ok"); - flag_ = stat::stop; - } - - /*! - * Get listening port - * @return - */ - uint16_t port() const { return port_; }; - - /*! - * Register RPC service functions (member function) - * - * Before RPC server started, all RPC service functions must be registered. - * All you need to do is fill in the template parameters with the address of - * your own RPC functions. If RPC function is registered twice, the program - * will be terminate with exit code `EXIT_FAILURE`. - * - * Note: All functions must be member functions of the same class. - * - * ```cpp - * class test_class { - * public: - * void plus_one(int val) {} - * std::string get_str(std::string str) { return str; } - * }; - * int main() { - * test_class obj{}; - * // register member functions - * register_handler<&test_class::plus_one, &test_class::get_str>(&obj); - * return 0; - * } - * ``` - * - * @tparam first the address of RPC function. e.g. `&foo::bar` - * @tparam func the address of RPC function. e.g. `&foo::bar` - * @param self the object pointer corresponding to these member functions - */ - - template - void register_handler(util::class_type_t *self) { - router_.template register_handler(self); - } - - template - void register_handler(util::class_type_t *self, - const auto &key) { - router_.template register_handler(self, key); - } - - /*! - * Register RPC service functions (non-member function) - * - * Before RPC server started, all RPC service functions must be registered. - * All you need to do is fill in the template parameters with the address of - * your own RPC functions. If RPC function is registered twice, the program - * will be terminate with exit code `EXIT_FAILURE`. - * - * ```cpp - * // RPC functions (non-member function) - * void hello() {} - * std::string get_str() { return ""; } - * int add(int a, int b) {return a + b; } - * int main() { - * register_handler(); // register one RPC function at once - * register_handler(); // register multiple RPC functions at - * once return 0; - * } - * ``` - * - * @tparam first the address of RPC function. e.g. `foo`, `bar` - * @tparam func the address of RPC function. e.g. `foo`, `bar` - */ - - template - void register_handler() { - router_.template register_handler(); - } - - template - void register_handler(const auto &key) { - router_.template register_handler(key); - } - - auto &get_io_context_pool() noexcept { return pool_; } - - private: - coro_rpc::err_code listen() { - ELOGV(INFO, "begin to listen"); - using asio::ip::tcp; - auto endpoint = tcp::endpoint(tcp::v4(), port_); - acceptor_.open(endpoint.protocol()); -#ifdef __GNUC__ - acceptor_.set_option(tcp::acceptor::reuse_address(true)); -#endif - asio::error_code ec; - acceptor_.bind(endpoint, ec); - if (ec) { - ELOGV(ERROR, "bind port %d error : %s", port_.load(), - ec.message().data()); - acceptor_.cancel(ec); - acceptor_.close(ec); - return coro_rpc::errc::address_in_use; - } -#ifdef _MSC_VER - acceptor_.set_option(tcp::acceptor::reuse_address(true)); -#endif - acceptor_.listen(); - - auto end_point = acceptor_.local_endpoint(ec); - if (ec) { - ELOGV(ERROR, "get local endpoint port %d error : %s", port_.load(), - ec.message().data()); - return coro_rpc::errc::address_in_use; - } - port_ = end_point.port(); - - ELOGV(INFO, "listen port %d successfully", port_.load()); - return {}; - } - - async_simple::coro::Lazy accept() { - for (;;) { - auto executor = pool_.get_executor(); - asio::ip::tcp::socket socket(executor->get_asio_executor()); - auto error = co_await coro_io::async_accept(acceptor_, socket); -#ifdef UNIT_TEST_INJECT - if (g_action == inject_action::force_inject_server_accept_error) { - asio::error_code ignored_ec; - socket.shutdown(asio::ip::tcp::socket::shutdown_both, ignored_ec); - socket.close(ignored_ec); - error = make_error_code(std::errc::io_error); - // only inject once - g_action = inject_action::nothing; - } -#endif - if (error) { - ELOGV(INFO, "accept failed, error: %s", error.message().data()); - if (error == asio::error::operation_aborted || - error == asio::error::bad_descriptor) { - acceptor_close_waiter_.set_value(); - co_return coro_rpc::errc::operation_canceled; - } - continue; - } - - int64_t conn_id = ++conn_id_; - ELOGV(INFO, "new client conn_id %d coming", conn_id); - auto conn = std::make_shared(executor, std::move(socket), - conn_timeout_duration_); - conn->set_quit_callback( - [this](const uint64_t &id) { - std::unique_lock lock(conns_mtx_); - conns_.erase(id); - }, - conn_id); - - { - std::unique_lock lock(conns_mtx_); - conns_.emplace(conn_id, conn); - } - start_one(conn).via(&conn->get_executor()).detach(); - } - } - - async_simple::coro::Lazy start_one(auto conn) noexcept { -#ifdef YLT_ENABLE_SSL - if (use_ssl_) { - conn->init_ssl(context_); - } -#endif - co_await conn->template start( - router_); - } - - void close_acceptor() { - asio::dispatch(acceptor_.get_executor(), [this]() { - asio::error_code ec; - (void)acceptor_.cancel(ec); - (void)acceptor_.close(ec); - }); - acceptor_close_waiter_.get_future().wait(); - } - - typename server_config::executor_pool_t pool_; - asio::ip::tcp::acceptor acceptor_; - std::promise acceptor_close_waiter_; - - std::thread thd_; - stat flag_; - - std::mutex start_mtx_; - uint64_t conn_id_ = 0; - std::unordered_map> conns_; - std::mutex conns_mtx_; - - typename server_config::rpc_protocol::router router_; - - std::atomic port_; - std::chrono::steady_clock::duration conn_timeout_duration_; - -#ifdef YLT_ENABLE_SSL - asio::ssl::context context_{asio::ssl::context::sslv23}; - bool use_ssl_ = false; -#endif -}; -} // namespace coro_rpc diff --git a/include/ylt/coro_rpc/impl/default_config/coro_rpc_config.hpp b/include/ylt/coro_rpc/impl/default_config/coro_rpc_config.hpp deleted file mode 100644 index cc9185eee..000000000 --- a/include/ylt/coro_rpc/impl/default_config/coro_rpc_config.hpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include - -#include "ylt/coro_io/io_context_pool.hpp" -#include "ylt/coro_rpc/coro_rpc_server.hpp" -#include "ylt/coro_rpc/impl/context.hpp" -#include "ylt/coro_rpc/impl/protocol/coro_rpc_protocol.hpp" - -namespace coro_rpc { - -namespace config { -struct coro_rpc_config_base { - uint16_t port = 8801; - unsigned thread_num = std::thread::hardware_concurrency(); - std::chrono::steady_clock::duration conn_timeout_duration = - std::chrono::seconds{0}; -}; - -struct coro_rpc_default_config : public coro_rpc_config_base { - using rpc_protocol = coro_rpc::protocol::coro_rpc_protocol; - using executor_pool_t = coro_io::io_context_pool; -}; -} // namespace config - -using coro_rpc_server = coro_rpc_server_base; -} // namespace coro_rpc diff --git a/include/ylt/coro_rpc/impl/errno.h b/include/ylt/coro_rpc/impl/errno.h deleted file mode 100644 index d785b30db..000000000 --- a/include/ylt/coro_rpc/impl/errno.h +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#include - -#include -#pragma once -namespace coro_rpc { -enum class errc : uint16_t { - ok, - io_error, - not_connected, - timed_out, - invalid_argument, - address_in_use, - operation_canceled, - interrupted, - function_not_registered, - protocol_error, - unknown_protocol_version, - message_too_large, - server_has_ran, -}; -inline constexpr std::string_view make_error_message(errc ec) noexcept { - switch (ec) { - case errc::ok: - return "ok"; - case errc::io_error: - return "io_error"; - case errc::not_connected: - return "not_connected"; - case errc::timed_out: - return "timed_out"; - case errc::invalid_argument: - return "invalid_argument"; - case errc::address_in_use: - return "address_in_use"; - case errc::operation_canceled: - return "operation_canceled"; - case errc::interrupted: - return "interrupted"; - case errc::function_not_registered: - return "function_not_registered"; - case errc::protocol_error: - return "protocol_error"; - case errc::message_too_large: - return "message_too_large"; - case errc::server_has_ran: - return "server_has_ran"; - default: - return "unknown_user-defined_error"; - } -} -struct err_code { - public: - errc ec; - constexpr err_code() noexcept : ec(errc::ok) {} - explicit constexpr err_code(uint16_t ec) noexcept : ec{ec} {}; - constexpr err_code(errc ec) noexcept : ec(ec){}; - constexpr err_code& operator=(errc ec) noexcept { - this->ec = ec; - return *this; - } - constexpr err_code(const err_code& err_code) noexcept = default; - constexpr err_code& operator=(const err_code& o) noexcept = default; - constexpr operator errc() const noexcept { return ec; } - constexpr operator bool() const noexcept { return static_cast(ec); } - constexpr explicit operator uint16_t() const noexcept { - return static_cast(ec); - } - constexpr uint16_t val() const noexcept { return static_cast(ec); } - constexpr std::string_view message() const noexcept { - return make_error_message(ec); - } -}; - -inline bool operator!(err_code ec) noexcept { return ec == errc::ok; } -inline bool operator!(errc ec) noexcept { return ec == errc::ok; } - -}; // namespace coro_rpc \ No newline at end of file diff --git a/include/ylt/coro_rpc/impl/expected.hpp b/include/ylt/coro_rpc/impl/expected.hpp deleted file mode 100644 index e6d4c1082..000000000 --- a/include/ylt/coro_rpc/impl/expected.hpp +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#if __has_include() && __cplusplus > 202002L -#include -#if __cpp_lib_expected >= 202202L -#else -#include -#endif -#else -#include -#endif - -namespace coro_rpc { -#if __cpp_lib_expected >= 202202L && __cplusplus > 202002L -template -using expected = std::expected; - -template -using unexpected = std::unexpected; - -using unexpect_t = std::unexpect_t; - -#else -template -using expected = tl::expected; - -template -using unexpected = tl::unexpected; - -using unexpect_t = tl::unexpect_t; -#endif - -template -using rpc_result = expected; - -} // namespace coro_rpc \ No newline at end of file diff --git a/include/ylt/coro_rpc/impl/protocol/coro_rpc_protocol.hpp b/include/ylt/coro_rpc/impl/protocol/coro_rpc_protocol.hpp deleted file mode 100644 index ee20bd5b2..000000000 --- a/include/ylt/coro_rpc/impl/protocol/coro_rpc_protocol.hpp +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "asio/buffer.hpp" -#include "struct_pack_protocol.hpp" -#include "ylt/coro_io/coro_io.hpp" -#include "ylt/coro_rpc/impl/context.hpp" -#include "ylt/coro_rpc/impl/errno.h" -#include "ylt/coro_rpc/impl/expected.hpp" -#include "ylt/coro_rpc/impl/router.hpp" - -namespace coro_rpc { -namespace protocol { - -struct coro_rpc_protocol { - public: - constexpr static inline uint8_t VERSION_NUMBER = 0; - /*! - * RPC header - * - * memory layout - * ``` - * ┌────────┬───────────┬────────────────┬──────────┬─────────┬─────────┐─────────┐ - * │ magic │ version │ serialize_type │ msg_type │ seq_num │ length - * │reserved - * ├────────┼───────────┼────────────────┼──────────┼─────────┼─────────┤─────────┤ - * │ 1 │ 1 │ 1 │ 1 │ 4 │ 4 │ 4 - * │ - * └────────┴───────────┴────────────────┴──────────┴─────────┴─────────┘─────────┘ - * ``` - */ - struct req_header { - uint8_t magic; //!< magic number - uint8_t version; //!< rpc protocol version - uint8_t serialize_type; //!< serialization type - uint8_t msg_type; //!< message type - uint32_t seq_num; //!< sequence number - uint32_t function_id; //!< rpc function ID - uint32_t length; //!< length of RPC body - uint32_t attach_length; //!< reserved field - }; - - struct resp_header { - uint8_t magic; //!< magic number - uint8_t version; //!< rpc protocol version - uint8_t err_code; //!< rpc error type - uint8_t msg_type; //!< message type - uint32_t seq_num; //!< sequence number - uint32_t length; //!< length of RPC body - uint32_t attach_length; //!< reserved field - }; - - using supported_serialize_protocols = std::variant; - using route_key_t = uint32_t; - using router = coro_rpc::protocol::router; - - static std::optional get_serialize_protocol( - req_header& req_header) { - if (req_header.serialize_type == 0) - AS_LIKELY { return struct_pack_protocol{}; } - else { - return std::nullopt; - } - }; - - static route_key_t get_route_key(req_header& req_header) { - return req_header.function_id; - }; - - template - static async_simple::coro::Lazy read_head( - Socket& socket, req_header& req_head) { - // TODO: add a connection-level buffer in parameter to reuse memory - auto [ec, _] = co_await coro_io::async_read( - socket, asio::buffer((char*)&req_head, sizeof(req_header))); - if (ec) - AS_UNLIKELY { co_return std::move(ec); } - else if (req_head.magic != magic_number || - req_head.version > VERSION_NUMBER) - AS_UNLIKELY { co_return std::make_error_code(std::errc::protocol_error); } - co_return std::error_code{}; - } - - template - static async_simple::coro::Lazy read_payload( - Socket& socket, req_header& req_head, std::string& buffer, - std::string& attchment) { - struct_pack::detail::resize(buffer, req_head.length); - if (req_head.attach_length > 0) { - struct_pack::detail::resize(attchment, req_head.attach_length); - - if (req_head.length > 0) { - std::array buffers{asio::buffer(buffer), - asio::buffer(attchment)}; - auto [ec, _] = co_await coro_io::async_read(socket, buffers); - co_return ec; - } - - auto [ec, _] = - co_await coro_io::async_read(socket, asio::buffer(attchment)); - co_return ec; - } - - auto [ec, _] = co_await coro_io::async_read(socket, asio::buffer(buffer)); - co_return ec; - } - - static std::string prepare_response(std::string& rpc_result, - const req_header& req_header, - std::size_t attachment_len, - coro_rpc::errc rpc_err_code = {}, - std::string_view err_msg = {}, - bool is_user_defined_error = false) { - std::string err_msg_buf; - std::string header_buf; - header_buf.resize(RESP_HEAD_LEN); - auto& resp_head = *(resp_header*)header_buf.data(); - resp_head.magic = magic_number; - resp_head.version = VERSION_NUMBER; - resp_head.seq_num = req_header.seq_num; - resp_head.attach_length = attachment_len; - if (attachment_len > UINT32_MAX) - AS_UNLIKELY { - ELOGV(ERROR, "attachment larger than 4G:%d", attachment_len); - rpc_err_code = coro_rpc::errc::message_too_large; - err_msg_buf = - "attachment larger than 4G:" + std::to_string(attachment_len) + "B"; - err_msg = err_msg_buf; - is_user_defined_error = false; - } - else if (rpc_result.size() > UINT32_MAX) - AS_UNLIKELY { - auto sz = rpc_result.size(); - ELOGV(ERROR, "body larger than 4G:%d", sz); - rpc_err_code = coro_rpc::errc::message_too_large; - err_msg_buf = - "body larger than 4G:" + std::to_string(attachment_len) + "B"; - err_msg = err_msg_buf; - is_user_defined_error = false; - } - if (rpc_err_code != coro_rpc::errc{}) - AS_UNLIKELY { - rpc_result.clear(); - if (is_user_defined_error) { - struct_pack::serialize_to( - rpc_result, - std::pair{static_cast(rpc_err_code), err_msg}); - resp_head.err_code = static_cast(255); - } - else { - struct_pack::serialize_to(rpc_result, err_msg); - resp_head.err_code = static_cast(rpc_err_code); - } - } - resp_head.length = rpc_result.size(); - return header_buf; - } - - /*! - * The RPC error for client - * - * The `rpc_error` struct holds the error code `code` and error message - * `msg`. - */ - struct rpc_error { - coro_rpc::err_code code; //!< error code - std::string msg; //!< error message - uint16_t& val() { return *(uint16_t*)&(code.ec); } - const uint16_t& val() const { return *(uint16_t*)&(code.ec); } - }; - - // internal variable - constexpr static inline int8_t magic_number = 21; - - static constexpr auto REQ_HEAD_LEN = sizeof(req_header{}); - static_assert(REQ_HEAD_LEN == 20); - - static constexpr auto RESP_HEAD_LEN = sizeof(resp_header{}); - static_assert(RESP_HEAD_LEN == 16); -}; - -STRUCT_PACK_REFL(coro_rpc_protocol::rpc_error, val(), msg); -} // namespace protocol -template -using context = coro_rpc::context_base; -using rpc_error = protocol::coro_rpc_protocol::rpc_error; -} // namespace coro_rpc \ No newline at end of file diff --git a/include/ylt/coro_rpc/impl/protocol/struct_pack_protocol.hpp b/include/ylt/coro_rpc/impl/protocol/struct_pack_protocol.hpp deleted file mode 100644 index 1f50752e9..000000000 --- a/include/ylt/coro_rpc/impl/protocol/struct_pack_protocol.hpp +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -namespace coro_rpc::protocol { - -struct struct_pack_protocol { - template - static bool deserialize_to(T& t, std::string_view buffer) { - if constexpr (std::tuple_size_v == 1) { - return !struct_pack::deserialize_to(std::get<0>(t), buffer); - } - else { - return !struct_pack::deserialize_to(t, buffer); - } - } - template - static std::string serialize(const T& t) { - return struct_pack::serialize(t); - } - static std::string serialize() { - return struct_pack::serialize(std::monostate{}); - } -}; -} // namespace coro_rpc::protocol \ No newline at end of file diff --git a/include/ylt/coro_rpc/impl/router.hpp b/include/ylt/coro_rpc/impl/router.hpp deleted file mode 100644 index c2439997c..000000000 --- a/include/ylt/coro_rpc/impl/router.hpp +++ /dev/null @@ -1,405 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "rpc_execute.hpp" - -namespace coro_rpc { - -template -using rpc_context = std::shared_ptr>; - -namespace protocol { -template -concept has_gen_register_key = requires() { - T::template gen_register_key(); -}; - -template typename map_t = std::unordered_map> - -class router { - using router_handler_t = std::function( - std::string_view, rpc_context &context_info, - typename rpc_protocol::supported_serialize_protocols protocols)>; - - using coro_router_handler_t = - std::function>( - std::string_view, rpc_context &context_info, - typename rpc_protocol::supported_serialize_protocols protocols)>; - - using route_key = typename rpc_protocol::route_key_t; - std::unordered_map handlers_; - std::unordered_map coro_handlers_; - std::unordered_map id2name_; - - private: - const std::string &get_name(const route_key &key) { - static std::string empty_string; - if (auto it = id2name_.find(key); it != id2name_.end()) { - return it->second; - } - else - return empty_string; - } - - // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100611 - // We use this struct instead of lambda for workaround - template - struct execute_visitor { - std::string_view data; - rpc_context &context_info; - Self *self; - template - async_simple::coro::Lazy> operator()( - const serialize_protocol &) { - return internal::execute_coro( - data, context_info, self); - } - }; - - template - struct execute_visitor { - std::string_view data; - rpc_context &context_info; - template - async_simple::coro::Lazy> operator()( - const serialize_protocol &) { - return internal::execute_coro( - data, context_info); - } - }; - - template - void regist_one_handler(Self *self) { - if (self == nullptr) - AS_UNLIKELY { ELOGV(CRITICAL, "null connection!"); } - - route_key key{}; - - if constexpr (has_gen_register_key) { - key = rpc_protocol::template gen_register_key(); - } - else { - key = auto_gen_register_key(); - } - - regist_one_handler_impl(self, key); - } - - template - static constexpr route_key auto_gen_register_key() { - constexpr auto name = get_func_name(); - constexpr auto id = - struct_pack::MD5::MD5Hash32Constexpr(name.data(), name.length()); - return id; - } - - template - void regist_one_handler_impl(Self *self, const route_key &key) { - if (self == nullptr) - AS_UNLIKELY { ELOGV(CRITICAL, "null connection!"); } - - constexpr auto name = get_func_name(); - using return_type = util::function_return_type_t; - if constexpr (util::is_specialization_v) { - auto it = coro_handlers_.emplace( - key, - [self]( - std::string_view data, rpc_context &context_info, - typename rpc_protocol::supported_serialize_protocols protocols) { - execute_visitor visitor{data, context_info, self}; - return std::visit(visitor, protocols); - }); - if (!it.second) { - ELOGV(CRITICAL, "duplication function %s register!", name.data()); - } - } - else { - auto it = handlers_.emplace( - key, - [self]( - std::string_view data, rpc_context &context_info, - typename rpc_protocol::supported_serialize_protocols protocols) { - return std::visit( - [data, &context_info, self]( - const serialize_protocol &obj) mutable { - return internal::execute(data, context_info, self); - }, - protocols); - }); - if (!it.second) { - ELOGV(CRITICAL, "duplication function %s register!", name.data()); - } - } - - id2name_.emplace(key, name); - } - - template - void regist_one_handler() { - route_key key{}; - if constexpr (has_gen_register_key) { - key = rpc_protocol::template gen_register_key(); - } - else { - key = auto_gen_register_key(); - } - regist_one_handler_impl(key); - } - - template - void regist_one_handler_impl(const route_key &key) { - static_assert(!std::is_member_function_pointer_v, - "register member function but lack of the parent object"); - using return_type = util::function_return_type_t; - - constexpr auto name = get_func_name(); - if constexpr (util::is_specialization_v) { - auto it = coro_handlers_.emplace( - key, - [](std::string_view data, rpc_context &context_info, - typename rpc_protocol::supported_serialize_protocols protocols) { - execute_visitor visitor{data, context_info}; - return std::visit(visitor, protocols); - }); - if (!it.second) { - ELOGV(CRITICAL, "duplication function %s register!", name.data()); - } - } - else { - auto it = handlers_.emplace( - key, - [](std::string_view data, rpc_context &context_info, - typename rpc_protocol::supported_serialize_protocols protocols) { - return std::visit( - [data, &context_info]( - const serialize_protocol &obj) mutable { - return internal::execute(data, context_info); - }, - protocols); - }); - if (!it.second) { - ELOGV(CRITICAL, "duplication function %s register!", name.data()); - } - } - id2name_.emplace(key, name); - } - - public: - router_handler_t *get_handler(uint32_t id) { - if (auto it = handlers_.find(id); it != handlers_.end()) { - return &it->second; - } - return nullptr; - } - - coro_router_handler_t *get_coro_handler(uint32_t id) { - if (auto it = coro_handlers_.find(id); it != coro_handlers_.end()) { - return &it->second; - } - return nullptr; - } - - async_simple::coro::Lazy> route_coro( - auto handler, std::string_view data, - rpc_context &context_info, - typename rpc_protocol::supported_serialize_protocols protocols, - const typename rpc_protocol::route_key_t &route_key) { - using namespace std::string_literals; - if (handler) - AS_LIKELY { - try { -#ifndef NDEBUG - ELOGV(INFO, "route function name: %s", get_name(route_key).data()); - -#endif - // clang-format off - auto res = co_await (*handler)(data, context_info, protocols); - // clang-format on - if (res.has_value()) - AS_LIKELY { - co_return std::make_pair(coro_rpc::errc{}, - std::move(res.value())); - } - else { // deserialize failed - ELOGV(ERROR, "payload deserialize failed in rpc function: %s", - get_name(route_key).data()); - co_return std::make_pair(coro_rpc::errc::invalid_argument, - "invalid rpc function arguments"s); - } - } catch (const std::exception &e) { - ELOGV(ERROR, "exception: %s in rpc function: %s", e.what(), - get_name(route_key).data()); - co_return std::make_pair(coro_rpc::errc::interrupted, e.what()); - } catch (...) { - ELOGV(ERROR, "unknown exception in rpc function: %s", - get_name(route_key).data()); - co_return std::make_pair(coro_rpc::errc::interrupted, - "unknown exception"s); - } - } - else { - std::ostringstream ss; - ss << route_key; - ELOGV(ERROR, "the rpc function not registered, function ID: %s", - ss.str().data()); - co_return std::make_pair(coro_rpc::errc::function_not_registered, - "the rpc function not registered"s); - } - } - - std::pair route( - auto handler, std::string_view data, - rpc_context &context_info, - typename rpc_protocol::supported_serialize_protocols protocols, - const typename rpc_protocol::route_key_t &route_key) { - using namespace std::string_literals; - if (handler) - AS_LIKELY { - try { -#ifndef NDEBUG - ELOGV(INFO, "route function name: %s", get_name(route_key).data()); -#endif - auto res = (*handler)(data, context_info, protocols); - if (res.has_value()) - AS_LIKELY { - return std::make_pair(coro_rpc::errc{}, std::move(res.value())); - } - else { // deserialize failed - ELOGV(ERROR, "payload deserialize failed in rpc function: %s", - get_name(route_key).data()); - return std::make_pair(coro_rpc::errc::invalid_argument, - "invalid rpc function arguments"s); - } - } catch (const std::exception &e) { - ELOGV(ERROR, "exception: %s in rpc function: %s", e.what(), - get_name(route_key).data()); - return std::make_pair(coro_rpc::errc::interrupted, e.what()); - } catch (...) { - ELOGV(ERROR, "unknown exception in rpc function: %s", - get_name(route_key).data()); - return std::make_pair(coro_rpc::errc::interrupted, - "unknown rpc function exception"s); - } - } - else { - std::ostringstream ss; - ss << route_key; - ELOGV(ERROR, "the rpc function not registered, function ID: %s", - ss.str().data()); - return std::make_pair(coro_rpc::errc::function_not_registered, - "the rpc function not registered"s); - } - } - - /*! - * Register RPC service functions (member function) - * - * Before RPC server started, all RPC service functions must be registered. - * All you need to do is fill in the template parameters with the address of - * your own RPC functions. If RPC function is registered twice, the program - * will be terminate with exit code `EXIT_FAILURE`. - * - * Note: All functions must be member functions of the same class. - * - * ```cpp - * class test_class { - * public: - * void plus_one(int val) {} - * std::string get_str(std::string str) { return str; } - * }; - * int main() { - * test_class obj{}; - * // register member functions - * register_handler<&test_class::plus_one, &test_class::get_str>(&obj); - * return 0; - * } - * ``` - * - * @tparam first the address of RPC function. e.g. `&foo::bar` - * @tparam func the address of RPC function. e.g. `&foo::bar` - * @param self the object pointer corresponding to these member functions - */ - - template - void register_handler(util::class_type_t *self) { - regist_one_handler(self); - (regist_one_handler(self), ...); - } - - template - void register_handler(util::class_type_t *self, - const route_key &key) { - regist_one_handler_impl(self, key); - } - - /*! - * Register RPC service functions (non-member function) - * - * Before RPC server started, all RPC service functions must be registered. - * All you need to do is fill in the template parameters with the address of - * your own RPC functions. If RPC function is registered twice, the program - * will be terminate with exit code `EXIT_FAILURE`. - * - * ```cpp - * // RPC functions (non-member function) - * void hello() {} - * std::string get_str() { return ""; } - * int add(int a, int b) {return a + b; } - * int main() { - * register_handler(); // register one RPC function at once - * register_handler(); // register multiple RPC functions at - * once return 0; - * } - * ``` - * - * @tparam first the address of RPC function. e.g. `foo`, `bar` - * @tparam func the address of RPC function. e.g. `foo`, `bar` - */ - - template - void register_handler() { - regist_one_handler(); - (regist_one_handler(), ...); - } - - template - void register_handler(const route_key &key) { - regist_one_handler_impl(key); - } -}; - -} // namespace protocol -} // namespace coro_rpc \ No newline at end of file diff --git a/include/ylt/coro_rpc/impl/rpc_execute.hpp b/include/ylt/coro_rpc/impl/rpc_execute.hpp deleted file mode 100644 index 0a93a2338..000000000 --- a/include/ylt/coro_rpc/impl/rpc_execute.hpp +++ /dev/null @@ -1,253 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include -#include -#include -#include -#include - -#include "context.hpp" -#include "coro_connection.hpp" -#include "ylt/util/type_traits.h" - -namespace coro_rpc::internal { -// TODO: remove this later -template -auto get_return_type() { - if constexpr (is_conn) { - using T = typename First::return_type; - if constexpr (std::is_void_v) { - return; - } - else { - return T{}; - } - } - else { - return First{}; - } -} - -template -using rpc_context = std::shared_ptr>; - -using rpc_conn = std::shared_ptr; -template -inline std::optional execute( - std::string_view data, rpc_context &context_info, - Self *self = nullptr) { - using T = decltype(func); - using param_type = util::function_parameters_t; - using return_type = util::function_return_type_t; - - if constexpr (!std::is_void_v) { - using First = std::tuple_element_t<0, param_type>; - constexpr bool is_conn = requires { typename First::return_type; }; - if constexpr (is_conn) { - static_assert(std::is_void_v, - "The return_type must be void"); - } - - using conn_return_type = decltype(get_return_type()); - constexpr bool has_coro_conn_v = - std::is_convertible_v, - First>; - auto args = util::get_args(); - - bool is_ok = true; - constexpr size_t size = std::tuple_size_v; - if constexpr (size > 0) { - is_ok = serialize_proto::deserialize_to(args, data); - } - - if (!is_ok) - AS_UNLIKELY { return std::nullopt; } - - if constexpr (std::is_void_v) { - if constexpr (std::is_void_v) { - if constexpr (has_coro_conn_v) { - // call void func(coro_conn, args...) - std::apply(func, std::tuple_cat( - std::forward_as_tuple( - context_base( - context_info)), - std::move(args))); - } - else { - // call void func(args...) - std::apply(func, std::move(args)); - } - } - else { - auto &o = *self; - if constexpr (has_coro_conn_v) { - // call void o.func(coro_conn, args...) - std::apply(func, - std::tuple_cat( - std::forward_as_tuple( - o, context_base( - context_info)), - std::move(args))); - } - else { - // call void o.func(args...) - std::apply(func, - std::tuple_cat(std::forward_as_tuple(o), std::move(args))); - } - } - } - else { - if constexpr (std::is_void_v) { - // call return_type func(args...) - - return serialize_proto::serialize(std::apply(func, std::move(args))); - } - else { - auto &o = *self; - // call return_type o.func(args...) - - return serialize_proto::serialize(std::apply( - func, std::tuple_cat(std::forward_as_tuple(o), std::move(args)))); - } - } - } - else { - if constexpr (std::is_void_v) { - if constexpr (std::is_void_v) { - func(); - } - else { - (self->*func)(); - } - } - else { - if constexpr (std::is_void_v) { - return serialize_proto::serialize(func()); - } - else { - return serialize_proto::serialize((self->*func)()); - } - } - } - return serialize_proto::serialize(); -} - -template -inline async_simple::coro::Lazy> execute_coro( - std::string_view data, rpc_context &context_info, - Self *self = nullptr) { - using T = decltype(func); - using param_type = util::function_parameters_t; - using return_type = typename get_type_t< - typename util::function_return_type_t::ValueType>::type; - - if constexpr (!std::is_void_v) { - using First = std::tuple_element_t<0, param_type>; - constexpr bool is_conn = requires { typename First::return_type; }; - if constexpr (is_conn) { - static_assert(std::is_void_v, - "The return_type must be void"); - } - - using conn_return_type = decltype(get_return_type()); - constexpr bool has_coro_conn_v = - std::is_same_v, First>; - auto args = util::get_args(); - - bool is_ok = true; - constexpr size_t size = std::tuple_size_v; - if constexpr (size > 0) { - is_ok = serialize_proto::deserialize_to(args, data); - } - - if constexpr (std::is_void_v) { - if constexpr (std::is_void_v) { - if constexpr (has_coro_conn_v) { - // call void func(coro_conn, args...) - co_await std::apply( - func, - std::tuple_cat(std::forward_as_tuple( - context_base( - context_info)), - std::move(args))); - } - else { - // call void func(args...) - co_await std::apply(func, std::move(args)); - } - } - else { - auto &o = *self; - if constexpr (has_coro_conn_v) { - // call void o.func(coro_conn, args...) - co_await std::apply( - func, std::tuple_cat( - std::forward_as_tuple( - o, context_base( - context_info)), - std::move(args))); - } - else { - // call void o.func(args...) - co_await std::apply( - func, std::tuple_cat(std::forward_as_tuple(o), std::move(args))); - } - } - } - else { - if constexpr (std::is_void_v) { - // call return_type func(args...) - co_return serialize_proto::serialize( - co_await std::apply(func, std::move(args))); - } - else { - auto &o = *self; - // call return_type o.func(args...) - co_return serialize_proto::serialize(co_await std::apply( - func, std::tuple_cat(std::forward_as_tuple(o), std::move(args)))); - } - } - } - else { - if constexpr (std::is_void_v) { - if constexpr (std::is_void_v) { - co_await func(); - } - else { - // clang-format off - co_await (self->*func)(); - // clang-format on - } - } - else { - if constexpr (std::is_void_v) { - co_return serialize_proto::serialize(co_await func()); - } - else { - // clang-format off - co_return serialize_proto::serialize(co_await (self->*func)()); - // clang-format on - } - } - } - co_return serialize_proto::serialize(); -} -} // namespace coro_rpc::internal \ No newline at end of file diff --git a/include/ylt/easylog.hpp b/include/ylt/easylog.hpp deleted file mode 100644 index c564bb2ab..000000000 --- a/include/ylt/easylog.hpp +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include -#include - -#if __has_include() -#include -#endif - -#if __has_include() -#ifndef FMT_HEADER_ONLY -#define FMT_HEADER_ONLY -#include -#endif -#endif - -#include "easylog/appender.hpp" - -namespace easylog { - -template -class logger { - public: - static logger &instance() { - static logger instance; - return instance; - } - - void operator+=(record_t &record) { write(record); } - - void write(record_t &record) { - if (async_ && appender_) { - append_record(std::move(record)); - } - else { - append_format(record); - } - - if (record.get_severity() == Severity::CRITICAL) { - flush(); - std::exit(EXIT_FAILURE); - } - } - - void flush() { - if (appender_) { - appender_->flush(); - } - } - - void init(Severity min_severity, bool async, bool enable_console, - const std::string &filename, size_t max_file_size, size_t max_files, - bool flush_every_time) { - static appender appender(filename, async, enable_console, max_file_size, - max_files, flush_every_time); - async_ = async; - appender_ = &appender; - min_severity_ = min_severity; - enable_console_ = enable_console; - } - - bool check_severity(Severity severity) { return severity >= min_severity_; } - - void add_appender(std::function fn) { - appenders_.emplace_back(std::move(fn)); - } - - void stop_async_log() { appender_->stop(); } - - // set and get - void set_min_severity(Severity severity) { min_severity_ = severity; } - Severity get_min_severity() { return min_severity_; } - - void set_console(bool enable) { - enable_console_ = enable; - if (appender_) { - appender_->enable_console(enable); - } - } - bool get_console() { return enable_console_; } - - void set_async(bool enable) { async_ = enable; } - bool get_async() { return async_; } - - private: - logger() { - static appender appender{}; - appender.start_thread(); - appender.enable_console(true); - async_ = true; - appender_ = &appender; - } - - logger(const logger &) = default; - - void append_record(record_t record) { appender_->write(std::move(record)); } - - void append_format(record_t &record) { - if (appender_) { - if (enable_console_) { - appender_->write_record(record); - } - else { - appender_->write_record(record); - } - } - } - - Severity min_severity_ = -#if NDEBUG - Severity::WARN; -#else - Severity::TRACE; -#endif - bool async_ = false; - bool enable_console_ = true; - appender *appender_ = nullptr; - std::vector> appenders_; -}; - -template -inline void init_log(Severity min_severity, const std::string &filename = "", - bool async = true, bool enable_console = true, - size_t max_file_size = 0, size_t max_files = 0, - bool flush_every_time = false) { - logger::instance().init(min_severity, async, enable_console, filename, - max_file_size, max_files, flush_every_time); -} - -template -inline void set_min_severity(Severity severity) { - logger::instance().set_min_severity(severity); -} - -template -inline Severity get_min_severity() { - return logger::instance().get_min_severity(); -} - -template -inline void set_console(bool enable) { - logger::instance().set_console(enable); -} - -template -inline bool get_console() { - return logger::instance().get_console(); -} - -template -inline void set_async(bool enable) { - logger::instance().set_async(enable); -} - -template -inline bool get_async() { - return logger::instance().get_async(); -} - -template -inline void flush() { - logger::instance().flush(); -} - -template -inline void stop_async_log() { - logger::instance().stop_async_log(); -} - -template -inline void add_appender(std::function fn) { - logger::instance().add_appender(std::move(fn)); -} -} // namespace easylog - -#define ELOG_IMPL(severity, Id, ...) \ - if (!easylog::logger::instance().check_severity(severity)) { \ - ; \ - } \ - else \ - easylog::logger::instance() += \ - easylog::record_t(std::chrono::system_clock::now(), severity, \ - GET_STRING(__FILE__, __LINE__)) \ - .ref() - -#ifndef ELOG -#define ELOG(severity, ...) \ - ELOG_IMPL(easylog::Severity::severity, __VA_ARGS__, 0) -#endif - -#define ELOGV_IMPL(severity, Id, fmt, ...) \ - if (!easylog::logger::instance().check_severity(severity)) { \ - ; \ - } \ - else { \ - easylog::logger::instance() += \ - easylog::record_t(std::chrono::system_clock::now(), severity, \ - GET_STRING(__FILE__, __LINE__)) \ - .sprintf(fmt, __VA_ARGS__); \ - if constexpr (severity == easylog::Severity::CRITICAL) { \ - easylog::flush(); \ - std::exit(EXIT_FAILURE); \ - } \ - } - -#ifndef ELOGV -#define ELOGV(severity, ...) \ - ELOGV_IMPL(easylog::Severity::severity, 0, __VA_ARGS__, "\n") -#endif - -#ifndef MELOGV -#define MELOGV(severity, Id, ...) \ - ELOGV_IMPL(easylog::Severity::severity, Id, __VA_ARGS__, "\n") -#endif - -#if __has_include() || __has_include() - -#define ELOGFMT_IMPL0(severity, Id, prefix, format_str, ...) \ - if (!easylog::logger::instance().check_severity(severity)) { \ - ; \ - } \ - else { \ - easylog::logger::instance() += \ - easylog::record_t(std::chrono::system_clock::now(), severity, \ - GET_STRING(__FILE__, __LINE__)) \ - .format(prefix::format(format_str, __VA_ARGS__)); \ - if constexpr (severity == easylog::Severity::CRITICAL) { \ - easylog::flush(); \ - std::exit(EXIT_FAILURE); \ - } \ - } - -#if __has_include() -#define ELOGFMT_IMPL(severity, Id, ...) \ - ELOGFMT_IMPL0(severity, Id, fmt, __VA_ARGS__) -#else -#define ELOGFMT_IMPL(severity, Id, ...) \ - ELOGFMT_IMPL0(severity, Id, std, __VA_ARGS__) -#endif - -#ifndef ELOGFMT -#define ELOGFMT(severity, ...) \ - ELOGFMT_IMPL(easylog::Severity::severity, 0, __VA_ARGS__) -#endif - -#ifndef MELOGFMT -#define MELOGFMT(severity, Id, ...) \ - ELOGFMT_IMPL(easylog::Severity::severity, Id, __VA_ARGS__) -#endif -#endif - -#ifndef ELOG_TRACE -#define ELOG_TRACE ELOG(TRACE) -#endif -#ifndef ELOG_DEBUG -#define ELOG_DEBUG ELOG(DEBUG) -#endif -#ifndef ELOG_INFO -#define ELOG_INFO ELOG(INFO) -#endif -#ifndef ELOG_WARN -#define ELOG_WARN ELOG(WARN) -#endif -#ifndef ELOG_ERROR -#define ELOG_ERROR ELOG(ERROR) -#endif -#ifndef ELOG_CRITICAL -#define ELOG_CRITICAL ELOG(CRITICAL) -#endif -#ifndef ELOG_FATAL -#define ELOG_FATAL ELOG(FATAL) -#endif - -#ifndef MELOG_TRACE -#define MELOG_TRACE(id) ELOG(INFO, id) -#endif -#ifndef MELOG_DEBUG -#define MELOG_DEBUG(id) ELOG(DEBUG, id) -#endif -#ifndef MELOG_INFO -#define MELOG_INFO(id) ELOG(INFO, id) -#endif -#ifndef MELOG_WARN -#define MELOG_WARN(id) ELOG(WARN, id) -#endif -#ifndef MELOG_ERROR -#define MELOG_ERROR(id) ELOG(ERROR, id) -#endif -#ifndef MELOG_FATAL -#define MELOG_FATAL(id) ELOG(FATAL, id) -#endif - -#ifndef ELOGT -#define ELOGT ELOG_TRACE -#endif -#ifndef ELOGD -#define ELOGD ELOG_DEBUG -#endif -#ifndef ELOGI -#define ELOGI ELOG_INFO -#endif -#ifndef ELOGW -#define ELOGW ELOG_WARN -#endif -#ifndef ELOGE -#define ELOGE ELOG_ERROR -#endif -#ifndef ELOGC -#define ELOGC ELOG_CRITICAL -#endif -#ifndef ELOGF -#define ELOGF ELOG_FATAL -#endif \ No newline at end of file diff --git a/include/ylt/easylog/appender.hpp b/include/ylt/easylog/appender.hpp deleted file mode 100644 index 9118bd774..000000000 --- a/include/ylt/easylog/appender.hpp +++ /dev/null @@ -1,409 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "record.hpp" -#include "ylt/util/concurrentqueue.h" - -namespace easylog { -struct empty_mutex { - void lock() {} - void unlock() {} -}; -constexpr inline std::string_view BOM_STR = "\xEF\xBB\xBF"; - -constexpr char digits[10] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'}; - -template -inline void to_int(int num, char *p, int &size) { - for (int i = 0; i < N; i++) { - p[--size] = digits[num % 10]; - num = num / 10; - } - - if constexpr (N != 4) - p[--size] = c; -} - -inline char *get_time_str(const auto &now) { - static thread_local char buf[33]; - static thread_local std::chrono::seconds last_sec_{}; - - std::chrono::system_clock::duration d = now.time_since_epoch(); - std::chrono::seconds s = std::chrono::duration_cast(d); - auto mill_sec = - std::chrono::duration_cast(d - s).count(); - int size = 23; - if (last_sec_ == s) { - to_int<3, '.'>(mill_sec, buf, size); - return buf; - } - - last_sec_ = s; - auto tm = std::chrono::system_clock::to_time_t(now); - auto gmt = localtime(&tm); - - to_int<3, '.'>(mill_sec, buf, size); - to_int<2, ':'>(gmt->tm_sec, buf, size); - to_int<2, ':'>(gmt->tm_min, buf, size); - to_int<2, ' '>(gmt->tm_hour, buf, size); - - to_int<2, '-'>(gmt->tm_mday, buf, size); - to_int<2, '-'>(gmt->tm_mon + 1, buf, size); - to_int<4, ' '>(gmt->tm_year + 1900, buf, size); - return buf; -} - -class appender { - public: - appender() = default; - appender(const std::string &filename, bool async, bool enable_console, - size_t max_file_size, size_t max_files, bool flush_every_time) - : has_init_(true), - flush_every_time_(flush_every_time), - enable_console_(enable_console), - max_file_size_(max_file_size) { - filename_ = filename; - max_files_ = (std::min)(max_files, static_cast(1000)); - open_log_file(); - if (async) { - start_thread(); - } - } - - void enable_console(bool b) { enable_console_ = b; } - - void start_thread() { - write_thd_ = std::thread([this] { - while (!stop_) { - if (max_files_ > 0 && file_size_ > max_file_size_ && - static_cast(-1) != file_size_) { - roll_log_files(); - } - - record_t record; - if (queue_.try_dequeue(record)) { - enable_console_ ? write_record(record) - : write_record(record); - } - - if (queue_.size_approx() == 0) { - std::unique_lock lock(que_mtx_); - cnd_.wait(lock, [&]() { - return queue_.size_approx() > 0 || stop_; - }); - } - - if (stop_) { - if (queue_.size_approx() > 0) { - while (queue_.try_dequeue(record)) { - if (max_files_ > 0 && file_size_ > max_file_size_ && - static_cast(-1) != file_size_) { - roll_log_files(); - } - - enable_console_ ? write_record(record) - : write_record(record); - } - } - } - } - }); - } - - std::string_view get_tid_buf(unsigned int tid) { - static thread_local char buf[24]; - static thread_local unsigned int last_tid; - static thread_local size_t last_len; - if (tid == last_tid) { - return {buf, last_len}; - } - - buf[0] = '['; - auto [ptr, ec] = std::to_chars(buf + 1, buf + 21, tid); - buf[22] = ']'; - buf[23] = ' '; - last_len = ptr - buf; - buf[last_len++] = ']'; - buf[last_len++] = ' '; - return {buf, last_len}; - } - - template - auto &get_mutex() { - if constexpr (sync) { - return mtx_; - } - else { - return empty_mtx_; - } - } - - template - void write_record(record_t &record) { - std::lock_guard guard(get_mutex()); - if constexpr (sync == true) { - if (max_files_ > 0 && file_size_ > max_file_size_ && - static_cast(-1) != file_size_) { - roll_log_files(); - } - } - - auto buf = get_time_str(record.get_time_point()); - - buf[23] = ' '; - memcpy(buf + 24, severity_str(record.get_severity()).data(), 8); - buf[32] = ' '; - - auto time_str = std::string_view(buf, 33); - auto tid_str = get_tid_buf(record.get_tid()); - auto file_str = record.get_file_str(); - auto msg = record.get_message(); - - write_file(time_str); - write_file(tid_str); - write_file(file_str); - write_file(msg); - - if constexpr (enable_console) { - add_color(record.get_severity()); - std::cout << time_str; - clean_color(record.get_severity()); - std::cout << tid_str; - std::cout << file_str; - std::cout << msg; - std::cout << std::flush; - } - } - -#ifdef _WIN32 - enum class color_type : int { - none = -1, - black = 0, - blue, - green, - cyan, - red, - magenta, - yellow, - white, - black_bright, - blue_bright, - green_bright, - cyan_bright, - red_bright, - magenta_bright, - yellow_bright, - white_bright - }; - - void windows_set_color(color_type fg, color_type bg) { - auto handle = GetStdHandle(STD_OUTPUT_HANDLE); - if (handle != nullptr) { - CONSOLE_SCREEN_BUFFER_INFO info{}; - auto status = GetConsoleScreenBufferInfo(handle, &info); - if (status) { - WORD color = info.wAttributes; - if (fg != color_type::none) { - color = (color & 0xFFF0) | int(fg); - } - if (bg != color_type::none) { - color = (color & 0xFF0F) | int(bg) << 4; - } - SetConsoleTextAttribute(handle, color); - } - } - } -#endif - - void add_color(Severity severity) { -#if defined(_WIN32) - if (severity == Severity::WARN) - windows_set_color(color_type::black, color_type::yellow); - if (severity == Severity::ERROR) - windows_set_color(color_type::black, color_type::red); - if (severity == Severity::CRITICAL) - windows_set_color(color_type::white_bright, color_type::red); -#elif __APPLE__ -#else - if (severity == Severity::WARN) - std::cout << "\x1B[93m"; - if (severity == Severity::ERROR) - std::cout << "\x1B[91m"; - if (severity == Severity::CRITICAL) - std::cout << "\x1B[97m\x1B[41m"; -#endif - } - - void clean_color(Severity severity) { -#if defined(_WIN32) - if (severity >= Severity::WARN) - windows_set_color(color_type::white, color_type::black); -#elif __APPLE__ -#else - if (severity >= Severity::WARN) - std::cout << "\x1B[0m\x1B[0K"; -#endif - } - - void write(record_t &&r) { - queue_.enqueue(std::move(r)); - cnd_.notify_one(); - } - - void flush() { - std::lock_guard guard(mtx_); - if (file_.is_open()) { - file_.flush(); - file_.sync_with_stdio(); - } - } - - void stop() { - std::lock_guard guard(mtx_); - if (!write_thd_.joinable()) { - return; - } - - if (stop_) { - return; - } - stop_ = true; - cnd_.notify_one(); - } - - ~appender() { - stop(); - if (write_thd_.joinable()) - write_thd_.join(); - } - - private: - void open_log_file() { - file_size_ = 0; - std::string filename = build_filename(); - - if (std::filesystem::path(filename).has_parent_path()) { - std::error_code ec; - auto parant_path = std::filesystem::path(filename).parent_path(); - std::filesystem::create_directories(parant_path, ec); - if (ec) { - std::cout << "create directories error: " << ec.message() << std::flush; - abort(); - } - } - - file_.open(filename, std::ios::binary | std::ios::out | std::ios::app); - if (file_) { - std::error_code ec; - size_t file_size = std::filesystem::file_size(filename, ec); - if (ec) { - std::cout << "get file size error" << std::flush; - abort(); - } - - if (file_size == 0) { - if (file_.write(BOM_STR.data(), BOM_STR.size())) { - file_size_ += BOM_STR.size(); - } - } - } - } - - std::string build_filename(int file_number = 0) { - if (file_number == 0) { - return filename_; - } - - auto file_path = std::filesystem::path(filename_); - std::string filename = file_path.stem().string(); - - if (file_number > 0) { - char buf[32]; - auto [ptr, ec] = std::to_chars(buf, buf + 32, file_number); - filename.append(".").append(std::string_view(buf, ptr - buf)); - } - - if (file_path.has_extension()) { - filename.append(file_path.extension().string()); - } - - if (std::filesystem::path(file_path).has_parent_path()) { - return file_path.parent_path().append(filename).string(); - } - - return filename; - } - - void roll_log_files() { - file_.close(); - std::string last_filename = build_filename(max_files_ - 1); - - std::error_code ec; - std::filesystem::remove(last_filename, ec); - - for (int file_number = max_files_ - 2; file_number >= 0; --file_number) { - std::string current_fileName = build_filename(file_number); - std::string next_fileName = build_filename(file_number + 1); - - std::filesystem::rename(current_fileName, next_fileName, ec); - } - - open_log_file(); - } - - void write_file(std::string_view str) { - if (has_init_) { - if (file_.write(str.data(), str.size())) { - if (flush_every_time_) { - file_.flush(); - } - - file_size_ += str.size(); - } - } - } - - bool has_init_ = false; - std::string filename_; - - bool enable_console_ = false; - bool flush_every_time_; - size_t file_size_ = 0; - size_t max_file_size_ = 0; - size_t max_files_ = 0; - - std::shared_mutex mtx_; - empty_mutex empty_mtx_; - std::ofstream file_; - - std::mutex que_mtx_; - - moodycamel::ConcurrentQueue queue_; - std::thread write_thd_; - std::condition_variable cnd_; - std::atomic stop_ = false; -}; -} // namespace easylog diff --git a/include/ylt/easylog/record.hpp b/include/ylt/easylog/record.hpp deleted file mode 100644 index f5dacdd42..000000000 --- a/include/ylt/easylog/record.hpp +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include -#include - -#include "ylt/util/time_util.h" -#ifdef __linux__ -#include -#include -#endif -#if __has_include() -#include -#endif -#include -#include -#include -#include - -#include "ylt/util/dragonbox_to_chars.h" -#include "ylt/util/meta_string.hpp" -#include "ylt/util/type_traits.h" - -#if defined(_WIN32) -#ifndef _WINDOWS_ -#ifndef WIN32_LEAN_AND_MEAN // Sorry for the inconvenience. Please include any - // related headers you need manually. - // (https://stackoverflow.com/a/8294669) -#define WIN32_LEAN_AND_MEAN // Prevent inclusion of WinSock2.h -#endif -#include // Force inclusion of WinGDI here to resolve name conflict -#endif -#ifdef ERROR // Should be true unless someone else undef'd it already -#undef ERROR // Windows GDI defines this macro; make it a global enum so it - // doesn't conflict with our code -enum { ERROR = 0 }; -#endif -#endif - -namespace easylog { - -namespace detail { -template -constexpr inline bool c_array_v = std::is_array_v> && - (std::extent_v> > 0); - -template -struct has_data : std::false_type {}; - -template -struct has_data().data())>> - : std::true_type {}; - -template -constexpr inline bool has_data_v = has_data>::value; - -template -struct has_str : std::false_type {}; - -template -struct has_str().str())>> - : std::true_type {}; - -template -constexpr inline bool has_str_v = has_str>::value; -} // namespace detail - -enum class Severity { - NONE, - TRACE, - DEBUG, - INFO, - WARN, - WARNING = WARN, - ERROR, - CRITICAL, - FATAL = CRITICAL, -}; - -inline std::string_view severity_str(Severity severity) { - switch (severity) { - case Severity::TRACE: - return "TRACE "; - case Severity::DEBUG: - return "DEBUG "; - case Severity::INFO: - return "INFO "; - case Severity::WARN: - return "WARNING "; - case Severity::ERROR: - return "ERROR "; - case Severity::CRITICAL: - return "CRITICAL"; - default: - return "NONE "; - } -} - -class record_t { - public: - record_t() = default; - record_t(auto tm_point, Severity severity, std::string_view str) - : tm_point_(tm_point), - severity_(severity), - tid_(_get_tid()), - file_str_(str) { - ss_.reserve(64); - } - record_t(record_t &&) = default; - record_t &operator=(record_t &&) = default; - - Severity get_severity() const { return severity_; } - - const char *get_message() { - ss_.push_back('\n'); - return ss_.data(); - } - - std::string_view get_file_str() const { return file_str_; } - - unsigned int get_tid() const { return tid_; } - - auto get_time_point() const { return tm_point_; } - - record_t &ref() { return *this; } - - template - record_t &operator<<(const T &data) { - using U = std::remove_cvref_t; - if constexpr (std::is_floating_point_v) { - char temp[40]; - const auto end = jkj::dragonbox::to_chars(data, temp); - ss_.append(temp, std::distance(temp, end)); - } - else if constexpr (std::is_same_v) { - data ? ss_.append("true") : ss_.append("false"); - } - else if constexpr (std::is_same_v) { - ss_.push_back(data); - } - else if constexpr (std::is_enum_v) { - int val = (int)data; - *this << val; - } - else if constexpr (std::is_integral_v) { - char buf[32]; - auto [ptr, ec] = std::to_chars(buf, buf + 32, data); - ss_.append(buf, std::distance(buf, ptr)); - } - else if constexpr (std::is_pointer_v) { - char buf[32] = {"0x"}; - auto [ptr, ec] = std::to_chars(buf + 2, buf + 32, (uintptr_t)data, 16); - ss_.append(buf, std::distance(buf, ptr)); - } - else if constexpr (std::is_same_v || - std::is_same_v) { - ss_.append(data.data(), data.size()); - } - else if constexpr (detail::c_array_v) { - ss_.append(data); - } - else if constexpr (detail::has_data_v) { - ss_.append(data.data()); - } - else if constexpr (detail::has_str_v) { - ss_.append(data.str()); - } - else if constexpr (std::is_same_v) { - ss_.append(ylt::time_util::get_local_time_str(data)); - } - else { - std::stringstream ss; - ss << data; - ss_.append(ss.str()); - } - - return *this; - } - - template - record_t &sprintf(const char *fmt, Args &&...args) { - printf_string_format(fmt, std::forward(args)...); - return *this; - } - - template - record_t &format(String &&str) { - ss_.append(str.data()); - return *this; - } - - private: - template - void printf_string_format(const char *fmt, Args &&...args) { - size_t size = snprintf(nullptr, 0, fmt, std::forward(args)...); - -#ifdef YLT_ENABLE_PMR -#if __has_include() - char arr[1024]; - std::pmr::monotonic_buffer_resource resource(arr, 1024); - std::pmr::string buf{&resource}; -#endif -#else - std::string buf; -#endif - buf.reserve(size + 1); - buf.resize(size); - - snprintf(&buf[0], size + 1, fmt, args...); - - ss_.append(buf); - } - - unsigned int _get_tid() { - static thread_local unsigned int tid = get_tid_impl(); - return tid; - } - - unsigned int get_tid_impl() { -#ifdef _WIN32 - return std::hash{}(std::this_thread::get_id()); -#elif defined(__linux__) - return static_cast(::syscall(__NR_gettid)); -#elif defined(__FreeBSD__) - long tid; - syscall(SYS_thr_self, &tid); - return static_cast(tid); -#elif defined(__rtems__) - return rtems_task_self(); -#elif defined(__APPLE__) - uint64_t tid64; - pthread_threadid_np(NULL, &tid64); - return static_cast(tid64); -#else - return 0; -#endif - } - - std::chrono::system_clock::time_point tm_point_; - Severity severity_; - unsigned int tid_; - std::string file_str_; - -#ifdef YLT_ENABLE_PMR -#if __has_include() - char arr_[1024]; - std::pmr::monotonic_buffer_resource resource_; - std::pmr::string ss_{&resource_}; -#endif -#else - std::string ss_; -#endif -}; - -#define TO_STR(s) #s - -#define GET_STRING(filename, line) \ - [] { \ - constexpr auto path = refvalue::meta_string{filename}; \ - constexpr size_t pos = \ - path.rfind(std::filesystem::path::preferred_separator); \ - constexpr auto name = path.substr(); \ - constexpr auto prefix = name + ":" + TO_STR(line); \ - return "[" + prefix + "] "; \ - }() - -} // namespace easylog \ No newline at end of file diff --git a/include/ylt/struct_json/json_reader.h b/include/ylt/struct_json/json_reader.h deleted file mode 100644 index a98e9eb37..000000000 --- a/include/ylt/struct_json/json_reader.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -namespace struct_json = iguana; \ No newline at end of file diff --git a/include/ylt/struct_json/json_writer.h b/include/ylt/struct_json/json_writer.h deleted file mode 100644 index 541ec6663..000000000 --- a/include/ylt/struct_json/json_writer.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include - -namespace struct_json = iguana; \ No newline at end of file diff --git a/include/ylt/struct_pack.hpp b/include/ylt/struct_pack.hpp deleted file mode 100644 index 9e3d229fc..000000000 --- a/include/ylt/struct_pack.hpp +++ /dev/null @@ -1,714 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include -#include -#include - -#include "struct_pack/alignment.hpp" -#include "struct_pack/calculate_size.hpp" -#include "struct_pack/compatible.hpp" -#include "struct_pack/derived_helper.hpp" -#include "struct_pack/derived_marco.hpp" -#include "struct_pack/error_code.hpp" -#include "struct_pack/md5_constexpr.hpp" -#include "struct_pack/packer.hpp" -#include "struct_pack/reflection.hpp" -#include "struct_pack/trivial_view.hpp" -#include "struct_pack/type_calculate.hpp" -#include "struct_pack/type_id.hpp" -#include "struct_pack/type_trait.hpp" -#include "struct_pack/unpacker.hpp" -#include "struct_pack/user_helper.hpp" -#include "struct_pack/varint.hpp" - -#if __has_include() && __cplusplus > 202002L -#include -#if __cpp_lib_expected >= 202202L -#else -#include "util/expected.hpp" -#endif -#else -#include "util/expected.hpp" -#endif - -namespace struct_pack { - -#if __cpp_lib_expected >= 202202L && __cplusplus > 202002L -template -using expected = std::expected; - -template -using unexpected = std::unexpected; - -using unexpect_t = std::unexpect_t; - -#else -template -using expected = tl::expected; - -template -using unexpected = tl::unexpected; - -using unexpect_t = tl::unexpect_t; -#endif - -inline std::error_code make_error_code(struct_pack::errc err) { - return std::error_code(static_cast(err), - struct_pack::detail::category()); -} - -/*! - * \defgroup struct_pack struct_pack - * - * \brief yaLanTingLibs struct_pack - * - * - * - */ - -/*! - * \ingroup struct_pack - * Get the error message corresponding to the error code `err`. - * @param err error code. - * @return error message. - */ -inline std::string_view error_message(struct_pack::errc err) noexcept { - return struct_pack::detail::make_error_message(err); -} - -template -constexpr std::uint32_t get_type_code() { - static_assert(sizeof...(Args) > 0); - std::uint32_t ret = 0; - if constexpr (sizeof...(Args) == 1) { - if constexpr (std::is_abstract_v) { - struct_pack::detail::unreachable(); - } - else { - ret = detail::get_types_code(); - } - } - else { - ret = detail::get_types_code...>>(); - } - ret = ret - ret % 2; - return ret; -} - -template -constexpr decltype(auto) get_type_literal() { - static_assert(sizeof...(Args) > 0); - if constexpr (sizeof...(Args) == 1) { - using Types = decltype(detail::get_types()); - return detail::get_types_literal( - std::make_index_sequence>()); - } - else { - return detail::get_types_literal< - std::tuple...>, - detail::remove_cvref_t...>(); - } -} - -/*! - * \ingroup struct_pack - * Get the byte size of the packing objects. - * TODO: add doc - * @tparam Args the types of packing objects. - * @param args the packing objects. - * @return byte size. - */ - -template -[[nodiscard]] constexpr struct_pack::serialize_buffer_size get_needed_size( - const Args &...args) { - return detail::get_serialize_runtime_info(args...); -} - -template -void serialize_to(Writer &writer, const Args &...args) { - static_assert(sizeof...(args) > 0); - if constexpr (struct_pack::writer_t) { - auto info = detail::get_serialize_runtime_info(args...); - struct_pack::detail::serialize_to(writer, info, args...); - } - else if constexpr (detail::struct_pack_buffer) { - static_assert(sizeof...(args) > 0); - auto data_offset = writer.size(); - auto info = detail::get_serialize_runtime_info(args...); - auto total = data_offset + info.size(); - detail::resize(writer, total); - auto real_writer = - struct_pack::detail::memory_writer{(char *)writer.data() + data_offset}; - struct_pack::detail::serialize_to(real_writer, info, args...); - } - else { - static_assert(!sizeof(Writer), - "The Writer is not satisfied struct_pack::writer_t or " - "struct_pack_buffer requirement!"); - } -} - -template -void serialize_to(char *buffer, serialize_buffer_size info, - const Args &...args) { - static_assert(sizeof...(args) > 0); - auto writer = struct_pack::detail::memory_writer{(char *)buffer}; - struct_pack::detail::serialize_to(writer, info, args...); -} - -template = 201907L - detail::struct_pack_buffer Buffer, -#else - typename Buffer, -#endif - typename... Args> -void serialize_to_with_offset(Buffer &buffer, std::size_t offset, - const Args &...args) { -#if __cpp_concepts < 201907L - static_assert(detail::struct_pack_buffer, - "The buffer is not satisfied struct_pack_buffer requirement!"); -#endif - static_assert(sizeof...(args) > 0); - auto info = detail::get_serialize_runtime_info(args...); - auto old_size = buffer.size(); - detail::resize(buffer, old_size + offset + info.size()); - auto writer = struct_pack::detail::memory_writer{(char *)buffer.data() + - old_size + offset}; - struct_pack::detail::serialize_to(writer, info, args...); -} - -template < -#if __cpp_concepts >= 201907L - detail::struct_pack_buffer Buffer = std::vector, -#else - typename Buffer = std::vector, -#endif - typename... Args> -[[nodiscard]] Buffer serialize(const Args &...args) { -#if __cpp_concepts < 201907L - static_assert(detail::struct_pack_buffer, - "The buffer is not satisfied struct_pack_buffer requirement!"); -#endif - static_assert(sizeof...(args) > 0); - Buffer buffer; - serialize_to(buffer, args...); - return buffer; -} - -template < -#if __cpp_concepts >= 201907L - detail::struct_pack_buffer Buffer = std::vector, -#else - typename Buffer = std::vector, -#endif - typename... Args> -[[nodiscard]] Buffer serialize_with_offset(std::size_t offset, - const Args &...args) { -#if __cpp_concepts < 201907L - static_assert(detail::struct_pack_buffer, - "The buffer is not satisfied struct_pack_buffer requirement!"); -#endif - static_assert(sizeof...(args) > 0); - Buffer buffer; - serialize_to_with_offset(buffer, offset, args...); - return buffer; -} - -template = 201907L - detail::struct_pack_buffer Buffer = std::vector, -#else - typename Buffer = std::vector, -#endif - typename... Args> -[[nodiscard]] Buffer serialize(const Args &...args) { -#if __cpp_concepts < 201907L - static_assert(detail::struct_pack_buffer, - "The buffer is not satisfied struct_pack_buffer requirement!"); -#endif - static_assert(sizeof...(args) > 0); - Buffer buffer; - serialize_to(buffer, args...); - return buffer; -} - -template = 201907L - detail::struct_pack_buffer Buffer = std::vector, -#else - typename Buffer = std::vector, -#endif - typename... Args> -[[nodiscard]] Buffer serialize_with_offset(std::size_t offset, - const Args &...args) { -#if __cpp_concepts < 201907L - static_assert(detail::struct_pack_buffer, - "The buffer is not satisfied struct_pack_buffer requirement!"); -#endif - static_assert(sizeof...(args) > 0); - Buffer buffer; - serialize_to_with_offset(buffer, offset, args...); - return buffer; -} - -#if __cpp_concepts >= 201907L -template -#else -template < - uint64_t conf = sp_config::DEFAULT, typename T, typename... Args, - typename View, - typename = std::enable_if_t>> -#endif -[[nodiscard]] struct_pack::err_code deserialize_to(T &t, const View &v, - Args &...args) { - detail::memory_reader reader{(const char *)v.data(), - (const char *)v.data() + v.size()}; - detail::unpacker in(reader); - return in.deserialize(t, args...); -} - -template -[[nodiscard]] struct_pack::err_code deserialize_to(T &t, const char *data, - size_t size, Args &...args) { - detail::memory_reader reader{data, data + size}; - detail::unpacker in(reader); - return in.deserialize(t, args...); -} - -#if __cpp_concepts >= 201907L -template -#else -template >> -#endif -[[nodiscard]] struct_pack::err_code deserialize_to(T &t, Reader &reader, - Args &...args) { - detail::unpacker in(reader); - std::size_t consume_len; - auto old_pos = reader.tellg(); - auto ret = in.deserialize_with_len(consume_len, t, args...); - std::size_t delta = reader.tellg() - old_pos; - if SP_LIKELY (consume_len > 0) { - if SP_UNLIKELY (delta > consume_len) { - // TODO test this branch - ret = struct_pack::errc::invalid_buffer; - } - else { - reader.ignore(consume_len - delta); - } - } - - return ret; -} -#if __cpp_concepts >= 201907L -template -#else -template < - uint64_t conf = sp_config::DEFAULT, typename T, typename... Args, - typename View, - typename = std::enable_if_t>> -#endif -[[nodiscard]] struct_pack::err_code deserialize_to(T &t, const View &v, - size_t &consume_len, - Args &...args) { - detail::memory_reader reader{(const char *)v.data(), - (const char *)v.data() + v.size()}; - detail::unpacker in(reader); - auto ret = in.deserialize_with_len(consume_len, t, args...); - if SP_LIKELY (!ret) { - consume_len = (std::max)((size_t)(reader.now - v.data()), consume_len); - } - else { - consume_len = 0; - } - return ret; -} - -template -[[nodiscard]] struct_pack::err_code deserialize_to(T &t, const char *data, - size_t size, - size_t &consume_len, - Args &...args) { - detail::memory_reader reader{data, data + size}; - detail::unpacker in(reader); - auto ret = in.deserialize_with_len(consume_len, t, args...); - if SP_LIKELY (!ret) { - consume_len = (std::max)((size_t)(reader.now - data), consume_len); - } - else { - consume_len = 0; - } - return ret; -} - -#if __cpp_concepts >= 201907L -template -#else -template -#endif -[[nodiscard]] struct_pack::err_code deserialize_to_with_offset(T &t, - const View &v, - size_t &offset, - Args &...args) { - size_t sz; - auto ret = - deserialize_to(t, v.data() + offset, v.size() - offset, sz, args...); - offset += sz; - return ret; -} - -template -[[nodiscard]] struct_pack::err_code deserialize_to_with_offset( - T &t, const char *data, size_t size, size_t &offset, Args &...args) { - size_t sz; - auto ret = deserialize_to(t, data + offset, size - offset, sz, args...); - offset += sz; - return ret; -} - -#if __cpp_concepts >= 201907L -template -#else -template < - typename... Args, typename View, - typename = std::enable_if_t>> -#endif -[[nodiscard]] auto deserialize(const View &v) { - expected, struct_pack::err_code> ret; - auto errc = deserialize_to(ret.value(), v); - if SP_UNLIKELY (errc) { - ret = unexpected{errc}; - } - return ret; -} - -template -[[nodiscard]] auto deserialize(const char *data, size_t size) { - expected, struct_pack::err_code> ret; - if (auto errc = deserialize_to(ret.value(), data, size); errc) { - ret = unexpected{errc}; - } - return ret; -} -#if __cpp_concepts >= 201907L -template -#else -template >> -#endif -[[nodiscard]] auto deserialize(Reader &v) { - expected, struct_pack::err_code> ret; - auto errc = deserialize_to(ret.value(), v); - if SP_UNLIKELY (errc) { - ret = unexpected{errc}; - } - return ret; -} - -#if __cpp_concepts >= 201907L -template -#else -template -#endif -[[nodiscard]] auto deserialize(const View &v, size_t &consume_len) { - expected, struct_pack::err_code> ret; - auto errc = deserialize_to(ret.value(), v, consume_len); - if SP_UNLIKELY (errc) { - ret = unexpected{errc}; - } - return ret; -} - -template -[[nodiscard]] auto deserialize(const char *data, size_t size, - size_t &consume_len) { - expected, struct_pack::err_code> ret; - auto errc = deserialize_to(ret.value(), data, size, consume_len); - if SP_UNLIKELY (errc) { - ret = unexpected{errc}; - } - return ret; -} - -#if __cpp_concepts >= 201907L -template -#else -template < - uint64_t conf, typename... Args, typename View, - typename = std::enable_if_t>> -#endif -[[nodiscard]] auto deserialize(const View &v) { - expected, struct_pack::err_code> ret; - auto errc = deserialize_to(ret.value(), v); - if SP_UNLIKELY (errc) { - ret = unexpected{errc}; - } - return ret; -} - -template -[[nodiscard]] auto deserialize(const char *data, size_t size) { - expected, struct_pack::err_code> ret; - if (auto errc = deserialize_to(ret.value(), data, size); errc) { - ret = unexpected{errc}; - } - return ret; -} - -#if __cpp_concepts >= 201907L -template -#else -template >> -#endif -[[nodiscard]] auto deserialize(Reader &v) { - expected, struct_pack::err_code> ret; - auto errc = deserialize_to(ret.value(), v); - if SP_UNLIKELY (errc) { - ret = unexpected{errc}; - } - return ret; -} - -#if __cpp_concepts >= 201907L -template -#else -template -#endif -[[nodiscard]] auto deserialize(const View &v, size_t &consume_len) { - expected, struct_pack::err_code> ret; - auto errc = deserialize_to(ret.value(), v, consume_len); - if SP_UNLIKELY (errc) { - ret = unexpected{errc}; - } - return ret; -} - -template -[[nodiscard]] auto deserialize(const char *data, size_t size, - size_t &consume_len) { - expected, struct_pack::err_code> ret; - auto errc = deserialize_to(ret.value(), data, size, consume_len); - if SP_UNLIKELY (errc) { - ret = unexpected{errc}; - } - return ret; -} - -#if __cpp_concepts >= 201907L -template -#else -template -#endif -[[nodiscard]] auto deserialize_with_offset(const View &v, size_t &offset) { - expected, struct_pack::err_code> ret; - auto errc = deserialize_to_with_offset(ret.value(), v, offset); - if SP_UNLIKELY (errc) { - ret = unexpected{errc}; - } - return ret; -} - -template -[[nodiscard]] auto deserialize_with_offset(const char *data, size_t size, - size_t &offset) { - expected, struct_pack::err_code> ret; - auto errc = deserialize_to_with_offset(ret.value(), data, size, offset); - if SP_UNLIKELY (errc) { - ret = unexpected{errc}; - } - return ret; -} - -#if __cpp_concepts >= 201907L -template -#else -template < - typename T, size_t I, uint64_t conf = sp_config::DEFAULT, typename Field, - typename View, - typename = std::enable_if_t>> -#endif -[[nodiscard]] struct_pack::err_code get_field_to(Field &dst, const View &v) { - using T_Field = std::tuple_element_t())>; - static_assert(std::is_same_v, - "The dst's type is not correct. It should be as same as the " - "T's Ith field's type"); - detail::memory_reader reader((const char *)v.data(), - (const char *)v.data() + v.size()); - detail::unpacker in(reader); - return in.template get_field(dst); -} - -template -[[nodiscard]] struct_pack::err_code get_field_to(Field &dst, const char *data, - size_t size) { - using T_Field = std::tuple_element_t())>; - static_assert(std::is_same_v, - "The dst's type is not correct. It should be as same as the " - "T's Ith field's type"); - detail::memory_reader reader{data, data + size}; - detail::unpacker in(reader); - return in.template get_field(dst); -} - -#if __cpp_concepts >= 201907L -template -#else -template >> -#endif -[[nodiscard]] struct_pack::err_code get_field_to(Field &dst, Reader &reader) { - using T_Field = std::tuple_element_t())>; - static_assert(std::is_same_v, - "The dst's type is not correct. It should be as same as the " - "T's Ith field's type"); - detail::unpacker in(reader); - return in.template get_field(dst); -} - -#if __cpp_concepts >= 201907L -template -#else -template < - typename T, size_t I, uint64_t conf = sp_config::DEFAULT, typename View, - typename = std::enable_if_t>> -#endif -[[nodiscard]] auto get_field(const View &v) { - using T_Field = std::tuple_element_t())>; - expected ret; - auto ec = get_field_to(ret.value(), v); - if SP_UNLIKELY (ec) { - ret = unexpected{ec}; - } - return ret; -} - -template -[[nodiscard]] auto get_field(const char *data, size_t size) { - using T_Field = std::tuple_element_t())>; - expected ret; - auto ec = get_field_to(ret.value(), data, size); - if SP_UNLIKELY (ec) { - ret = unexpected{ec}; - } - return ret; -} -#if __cpp_concepts >= 201907L -template -#else -template >> -#endif -[[nodiscard]] auto get_field(Reader &reader) { - using T_Field = std::tuple_element_t())>; - expected ret; - auto ec = get_field_to(ret.value(), reader); - if SP_UNLIKELY (ec) { - ret = unexpected{ec}; - } - return ret; -} -#if __cpp_concepts >= 201907L -template -#else -template >> -#endif -[[nodiscard]] struct_pack::expected, - struct_pack::err_code> -deserialize_derived_class(Reader &reader) { - static_assert(sizeof...(DerivedClasses) > 0, - "There must have a least one derived class"); - static_assert( - struct_pack::detail::public_base_class_checker< - BaseClass, std::tuple>::value, - "the First type should be the base class of all derived class "); - constexpr auto has_hash_collision = struct_pack::detail::MD5_set< - std::tuple>::has_hash_collision; - if constexpr (has_hash_collision != 0) { - static_assert(!sizeof(std::tuple_element_t>), - "ID collision happened, consider add member `static " - "constexpr uint64_t struct_pack_id` for collision type. "); - } - else { - struct_pack::expected, struct_pack::err_code> - ret; - auto ec = struct_pack::detail::deserialize_derived_class( - ret.value(), reader); - if SP_UNLIKELY (ec) { - ret = unexpected{ec}; - } - return ret; - } -} -#if __cpp_concepts >= 201907L -template -#else -template < - typename BaseClass, typename... DerivedClasses, typename View, - typename = std::enable_if_t>> -#endif -[[nodiscard]] struct_pack::expected, - struct_pack::err_code> -deserialize_derived_class(const View &v) { - detail::memory_reader reader{v.data(), v.data() + v.size()}; - if constexpr (std::is_abstract_v) { - return deserialize_derived_class(reader); - } - else { - return deserialize_derived_class( - reader); - } -} -template -[[nodiscard]] struct_pack::expected, - struct_pack::err_code> -deserialize_derived_class(const char *data, size_t size) { - detail::memory_reader reader{data, data + size}; - if constexpr (std::is_abstract_v) { - return deserialize_derived_class(reader); - } - else { - return deserialize_derived_class( - reader); - } -} - -} // namespace struct_pack \ No newline at end of file diff --git a/include/ylt/struct_pack/alignment.hpp b/include/ylt/struct_pack/alignment.hpp deleted file mode 100644 index df0c801b3..000000000 --- a/include/ylt/struct_pack/alignment.hpp +++ /dev/null @@ -1,212 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include - -#include "reflection.hpp" -#include "util.h" - -namespace struct_pack::detail { -namespace align { - -template -constexpr std::size_t alignment_impl(); - -template -constexpr std::size_t alignment_v = alignment_impl(); - -template -constexpr std::size_t default_alignment_helper(std::index_sequence) { - return (std::max)( - {(is_compatible_v>> - ? std::size_t{0} - : align::alignment_v< - remove_cvref_t>>)...}); -} - -template -constexpr std::size_t default_alignment() { - if constexpr (!is_trivial_serializable::value && !is_trivial_view_v) { - using type = decltype(get_types()); - return default_alignment_helper( - std::make_index_sequence>()); - } - else if constexpr (is_trivial_view_v) { - return std::alignment_of_v; - } - else { - return std::alignment_of_v; - } -} -template -constexpr std::size_t default_alignment_v = default_alignment(); - -template -constexpr std::size_t alignment_impl(); - -template -constexpr std::size_t pack_alignment_impl_helper(std::index_sequence) { - return (std::max)( - {(is_compatible_v>> - ? std::size_t{0} - : align::alignment_v< - remove_cvref_t>>)...}); -} - -template -constexpr std::size_t pack_alignment_impl() { - static_assert(std::is_class_v); - static_assert(!is_trivial_view_v); - constexpr auto ret = struct_pack::pack_alignment_v; - static_assert(ret == 0 || ret == 1 || ret == 2 || ret == 4 || ret == 8 || - ret == 16); - if constexpr (ret == 0) { - using type = decltype(get_types()); - return pack_alignment_impl_helper( - std::make_index_sequence>()); - } - else { - return ret; - } -} - -template -constexpr std::size_t pack_alignment_v = pack_alignment_impl(); - -template -constexpr std::size_t alignment_impl() { - if constexpr (struct_pack::alignment_v == 0 && - struct_pack::pack_alignment_v == 0) { - return default_alignment_v; - } - else if constexpr (struct_pack::alignment_v != 0) { - if constexpr (is_trivial_serializable::value) { - static_assert(default_alignment_v == alignment_v); - } - constexpr auto ret = struct_pack::alignment_v; - static_assert( - [](std::size_t align) constexpr { - while (align % 2 == 0) { - align /= 2; - } - return align == 1; - }(ret), - "alignment should be power of 2"); - return ret; - } - else { - if constexpr (is_trivial_serializable::value) { - return default_alignment_v; - } - else { - return pack_alignment_v; - } - } -} -template -struct calculate_trival_obj_size { - constexpr void operator()(std::size_t &total); -}; - -template -struct calculate_padding_size_impl { - constexpr void operator()( - std::size_t &offset, - std::array + 1> - &padding_size) { - if constexpr (is_compatible_v) { - padding_size[I] = 0; - } - else if constexpr (is_trivial_view_v) { - calculate_padding_size_impl{}(offset, - padding_size); - } - else { - if (offset % align::alignment_v) { - padding_size[I] = - (std::min)(align::pack_alignment_v

- 1, - align::alignment_v - offset % align::alignment_v); - } - else { - padding_size[I] = 0; - } - offset += padding_size[I]; - if constexpr (is_trivial_serializable::value) - offset += sizeof(T); - else { - for_each(offset); - static_assert(is_trivial_serializable::value); - } - } - } -}; - -template -constexpr auto calculate_padding_size() { - std::array + 1> padding_size{}; - std::size_t offset = 0; - for_each(offset, padding_size); - if (offset % align::alignment_v) { - padding_size[struct_pack::members_count] = - align::alignment_v - offset % align::alignment_v; - } - else { - padding_size[struct_pack::members_count] = 0; - } - return padding_size; -} -template -constexpr std::array + 1> - padding_size = calculate_padding_size(); -template -constexpr std::size_t get_total_padding_size() { - std::size_t sum = 0; - for (auto &e : padding_size) { - sum += e; - } - return sum; -}; -template -constexpr std::size_t total_padding_size = get_total_padding_size(); - -template -using calculate_trival_obj_size_wrapper = calculate_trival_obj_size; - -template -constexpr void calculate_trival_obj_size::operator()( - std::size_t &total) { - if constexpr (I == 0) { - total += total_padding_size

; - } - if constexpr (!is_compatible_v) { - if constexpr (is_trivial_serializable::value) { - total += sizeof(T); - } - else if constexpr (is_trivial_view_v) { - total += sizeof(typename T::value_type); - } - else { - static_assert(is_trivial_serializable::value); - std::size_t offset = 0; - for_each(offset); - total += offset; - } - } -} - -} // namespace align -} // namespace struct_pack::detail \ No newline at end of file diff --git a/include/ylt/struct_pack/calculate_size.hpp b/include/ylt/struct_pack/calculate_size.hpp deleted file mode 100644 index 93124b62e..000000000 --- a/include/ylt/struct_pack/calculate_size.hpp +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include "alignment.hpp" -#include "marco.h" -#include "reflection.hpp" -#include "size_info.hpp" -#include "type_id.hpp" -#include "type_trait.hpp" -#include "util.h" -#include "varint.hpp" - -namespace struct_pack { - -struct serialize_buffer_size; -namespace detail { -template -constexpr size_info STRUCT_PACK_INLINE -calculate_payload_size(const Args &...items); - -template -constexpr std::size_t STRUCT_PACK_INLINE -calculate_fast_varint_size(const Args &...items); - -template -constexpr size_info inline calculate_one_size(const T &item) { - constexpr auto id = get_type_id, parent_tag>(); - static_assert(id != detail::type_id::type_end_flag); - using type = remove_cvref_t; - static_assert(!std::is_pointer_v); - size_info ret{}; - if constexpr (id == type_id::monostate_t) { - } - else if constexpr (id == type_id::user_defined_type) { - ret.total = sp_get_needed_size(item); - } - else if constexpr (detail::varint_t) { - if constexpr (is_enable_fast_varint_coding(parent_tag)) { - // skip it. It has been calculated in parent. - } - else { - ret.total = detail::calculate_varint_size(item); - } - } - else if constexpr (std::is_fundamental_v || std::is_enum_v || - id == type_id::int128_t || id == type_id::uint128_t || - id == type_id::bitset_t) { - ret.total = sizeof(type); - } - else if constexpr (is_trivial_view_v) { - return calculate_one_size(item.get()); - } - else if constexpr (id == type_id::array_t) { - if constexpr (is_trivial_serializable::value) { - ret.total = sizeof(type); - } - else { - for (auto &i : item) { - ret += calculate_one_size(i); - } - } - } - else if constexpr (container) { - ret.size_cnt += 1; - ret.max_size = item.size(); - if constexpr (trivially_copyable_container) { - using value_type = typename type::value_type; - ret.total = item.size() * sizeof(value_type); - } - else { - for (auto &&i : item) { - ret += calculate_one_size(i); - } - } - } - else if constexpr (container_adapter) { - static_assert(!sizeof(type), "the container adapter type is not supported"); - } - else if constexpr (!pair && tuple && !is_trivial_tuple) { - std::apply( - [&](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - ret += calculate_payload_size(items...); - }, - item); - } - else if constexpr (optional) { - ret.total = sizeof(char); - if (item) { - ret += calculate_one_size(*item); - } - } - else if constexpr (unique_ptr) { - ret.total = sizeof(char); - if (item) { - if constexpr (is_base_class) { - ret.total += sizeof(uint32_t); - bool is_ok = false; - auto index = search_type_by_md5( - item->get_struct_pack_id(), is_ok); - if SP_UNLIKELY (!is_ok) { - throw std::runtime_error{ - "illegal struct_pack_id in virtual function."}; - } - ret += template_switch>>(index, - item.get()); - } - else { - ret += calculate_one_size(*item); - } - } - } - else if constexpr (is_variant_v) { - ret.total = sizeof(uint8_t); - ret += std::visit( - [](const auto &e) { - return calculate_one_size(e); - }, - item); - } - else if constexpr (expected) { - ret.total = sizeof(bool); - if (item.has_value()) { - if constexpr (!std::is_same_v) - ret += calculate_one_size(item.value()); - } - else { - ret += calculate_one_size(item.error()); - } - } - else if constexpr (std::is_class_v) { - if constexpr (!pair && !is_trivial_tuple) { - if constexpr (!user_defined_refl) - static_assert(std::is_aggregate_v>, - "struct_pack only support aggregated type, or you should " - "add macro STRUCT_PACK_REFL(Type,field1,field2...)"); - } - if constexpr (is_trivial_serializable::value) { - ret.total = sizeof(type); - } - else if constexpr (is_trivial_serializable::value) { - visit_members(item, [&](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - ret += calculate_payload_size(items...); - ret.total += align::total_padding_size; - }); - } - else { - constexpr uint64_t tag = get_parent_tag(); - if constexpr (is_enable_fast_varint_coding(tag)) { - ret.total += - visit_members(item, [](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - constexpr uint64_t tag = - get_parent_tag(); // to pass msvc with c++17 - return calculate_fast_varint_size(items...); - }); - } - ret += visit_members(item, [](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - constexpr uint64_t tag = - get_parent_tag(); // to pass msvc with c++17 - return calculate_payload_size(items...); - }); - } - } - else { - static_assert(!sizeof(type), "the type is not supported yet"); - } - return ret; -} - -template -constexpr size_info STRUCT_PACK_INLINE -calculate_payload_size(const Args &...items) { - return (calculate_one_size(items) + ...); -} - -struct fast_varint_result {}; - -template -constexpr std::size_t STRUCT_PACK_INLINE calculate_fast_varint_count() { - if constexpr (sizeof...(Args) == 0) { - return varint_t ? 1 : 0; - } - else { - return calculate_fast_varint_count() + - (varint_t ? 1 : 0); - } -} - -template -constexpr bool STRUCT_PACK_INLINE has_signed_varint() { - if constexpr (sizeof...(Args) == 0) { - if constexpr (varint_t) { - return std::is_signed_v< - remove_cvref_t()))>>; - } - else { - return false; - } - } - else { - if constexpr (varint_t) { - return std::is_signed_v< - remove_cvref_t()))>> || - has_signed_varint(); - } - else { - return has_signed_varint(); - } - } -} - -template -constexpr bool STRUCT_PACK_INLINE has_unsigned_varint() { - if constexpr (sizeof...(Args) == 0) { - if constexpr (varint_t) { - return std::is_unsigned_v< - remove_cvref_t()))>>; - } - else { - return false; - } - } - else { - if constexpr (varint_t) { - return std::is_unsigned_v< - remove_cvref_t()))>> || - has_unsigned_varint(); - } - else { - return has_unsigned_varint(); - } - } -} - -template -constexpr bool STRUCT_PACK_INLINE has_64bits_varint() { - if constexpr (sizeof...(Args) == 0) { - if constexpr (varint_t) { - return sizeof(Arg) == 8; - } - else { - return false; - } - } - else { - if constexpr (varint_t) { - return sizeof(Arg) == 8 || has_64bits_varint(); - } - else { - return has_64bits_varint(); - } - } -} - -template -constexpr std::size_t STRUCT_PACK_INLINE get_int_len() { - if (has_64bits_varint()) { - return 8; - } - else { - return 4; - } -} - -template -constexpr void STRUCT_PACK_INLINE get_fast_varint_width_impl( - const Arg &item, int &non_zero_cnt32, int &non_zero_cnt64, - unsigned_t &unsigned_max, signed_t &signed_max) { - if constexpr (varint_t) { - if (get_varint_value(item)) { - if constexpr (sizeof(Arg) == 4) { - ++non_zero_cnt32; - } - else if constexpr (sizeof(Arg) == 8) { - ++non_zero_cnt64; - } - else { - static_assert(!sizeof(Arg), "illegal branch"); - } - if constexpr (std::is_unsigned_v>) { - unsigned_max = - std::max(unsigned_max, get_varint_value(item)); - } - else { - signed_max = - std::max(signed_max, get_varint_value(item) > 0 - ? get_varint_value(item) - : -(get_varint_value(item) + 1)); - } - } - } -} - -template -constexpr int STRUCT_PACK_INLINE -get_fast_varint_width_from_max(unsigned_t unsigned_max, signed_t signed_max) { - int width_unsigned = 0, width_signed = 0; - if constexpr (has_unsigned_varint()) { - if SP_LIKELY (unsigned_max <= UINT8_MAX) { - width_unsigned = 0; - } - else if SP_LIKELY (unsigned_max <= UINT16_MAX) { - width_unsigned = 1; - } - else if (unsigned_max <= UINT32_MAX) { - width_unsigned = 2; - } - else { - width_unsigned = 3; - } - } - if constexpr (has_signed_varint()) { - if SP_LIKELY (signed_max <= INT8_MAX) { - width_signed = 0; - } - else if SP_LIKELY (signed_max <= INT16_MAX) { - width_signed = 1; - } - else if (signed_max <= INT32_MAX) { - width_signed = 2; - } - else { - width_signed = 3; - } - } - if constexpr (has_signed_varint() && - has_unsigned_varint()) { - return (std::max)(width_unsigned, width_signed); - } - else if constexpr (has_signed_varint()) { - return width_signed; - } - else if constexpr (has_unsigned_varint()) { - return width_unsigned; - } - else { - static_assert(sizeof...(Args), "there should has a varint"); - return 0; - } -} - -template -constexpr int STRUCT_PACK_INLINE get_fast_varint_width(const Args &...items) { - typename uint_t()>::type unsigned_max = 0; - typename int_t()>::type signed_max = 0; - int non_zero_cnt32 = 0, non_zero_cnt64 = 0; - (get_fast_varint_width_impl(items, non_zero_cnt32, non_zero_cnt64, - unsigned_max, signed_max), - ...); - auto width = (1 << struct_pack::detail::get_fast_varint_width_from_max< - parent_tag, Args...>(unsigned_max, signed_max)); - return width * non_zero_cnt64 + (width > 4 ? 4 : width) * non_zero_cnt32; -} - -template -constexpr std::size_t STRUCT_PACK_INLINE -calculate_fast_varint_size(const Args &...items) { - constexpr auto cnt = calculate_fast_varint_count(); - constexpr auto bitset_size = ((cnt + 2) + 7) / 8; - if constexpr (cnt == 0) { - return 0; - } - else { - auto width = get_fast_varint_width(items...); - return width + bitset_size; - } -} - -template -STRUCT_PACK_INLINE constexpr serialize_buffer_size get_serialize_runtime_info( - const Args &...args); -} // namespace detail -struct serialize_buffer_size { - private: - std::size_t len_; - unsigned char metainfo_; - - public: - constexpr serialize_buffer_size() : len_(0), metainfo_(0) {} - constexpr std::size_t size() const { return len_; } - constexpr unsigned char metainfo() const { return metainfo_; } - constexpr operator std::size_t() const { return len_; } - - template - friend STRUCT_PACK_INLINE constexpr serialize_buffer_size - struct_pack::detail::get_serialize_runtime_info(const Args &...args); -}; -namespace detail { -template -[[nodiscard]] STRUCT_PACK_INLINE constexpr serialize_buffer_size -get_serialize_runtime_info(const Args &...args) { - using Type = get_args_type; - constexpr bool has_compatible = serialize_static_config::has_compatible; - constexpr bool has_type_literal = check_if_add_type_literal(); - constexpr bool disable_hash_head = check_if_disable_hash_head(); - constexpr bool has_container = check_if_has_container(); - constexpr bool has_compile_time_determined_meta_info = - check_has_metainfo(); - serialize_buffer_size ret; - auto sz_info = calculate_payload_size(args...); - if constexpr (has_compile_time_determined_meta_info) { - ret.len_ = sizeof(unsigned char); - } - if constexpr (!has_container) { - ret.len_ += sz_info.total; - } - else { - if SP_LIKELY (sz_info.max_size < (int64_t{1} << 8)) { - ret.len_ += sz_info.total + sz_info.size_cnt; - } - else { - if (sz_info.max_size < (int64_t{1} << 16)) { - ret.len_ += sz_info.total + sz_info.size_cnt * 2; - ret.metainfo_ = 0b01000; - } - else if (sz_info.max_size < (int64_t{1} << 32)) { - ret.len_ += sz_info.total + sz_info.size_cnt * 4; - ret.metainfo_ = 0b10000; - } - else { - ret.len_ += sz_info.total + sz_info.size_cnt * 8; - ret.metainfo_ = 0b11000; - } - if constexpr (!has_compile_time_determined_meta_info) { - ret.len_ += sizeof(unsigned char); - } - // size_type >= 1 , has metainfo - } - } - if constexpr (!disable_hash_head) { - ret.len_ += sizeof(uint32_t); // for record hash code - if constexpr (has_type_literal) { - constexpr auto type_literal = struct_pack::get_type_literal(); - // struct_pack::get_type_literal().size() crash in clang13. - // Bug? - ret.len_ += type_literal.size() + 1; - ret.metainfo_ |= 0b100; - } - if constexpr (has_compatible) { // calculate bytes count of serialize - // length - if SP_LIKELY (ret.len_ + 2 < (int64_t{1} << 16)) { - ret.len_ += 2; - ret.metainfo_ |= 0b01; - } - else if (ret.len_ + 4 < (int64_t{1} << 32)) { - ret.len_ += 4; - ret.metainfo_ |= 0b10; - } - else { - ret.len_ += 8; - ret.metainfo_ |= 0b11; - } - } - } - return ret; -} -} // namespace detail -} // namespace struct_pack \ No newline at end of file diff --git a/include/ylt/struct_pack/compatible.hpp b/include/ylt/struct_pack/compatible.hpp deleted file mode 100644 index 0522ec37e..000000000 --- a/include/ylt/struct_pack/compatible.hpp +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include -#include - -namespace struct_pack { -/*! - * \ingroup struct_pack - * \brief similar to std::optional. - * However, its semantics are forward compatible field. - * - * For example, - * - * ```cpp - * struct person_v1 { - * int age; - * std::string name; - * }; - * - * struct person_v2 { - * int age; - * struct_pack::compatible id; // version number is 20210101 - * struct_pack::compatible salary; - * std::string name; - * }; - * - * struct person_v3 { - * int age; - * struct_pack::compatible nickname; // new version - * number is bigger than 20210101 struct_pack::compatible id; - * struct_pack::compatible salary; - * std::string name; - * }; - * ``` - * - * `struct_pack::compatible` can be null, thus ensuring - * forward and backward compatibility. - * - * For example, serialize person_v2, and then deserialize it according to - * person_v1, the extra fields will be directly ignored during deserialization. - * If person_v1 is serialized and then deserialized according to person_v2, the - * compatibale fields in person_v2 are all null values. - * - * The default value of version_number in `struct_pack::compatible` is 0. - * - * ```cpp - * person_v2 p2{20, "tom", 114.1, "tom"}; - * auto buf = struct_pack::serialize(p2); - * - * person_v1 p1; - * // deserialize person_v2 as person_v1 - * auto ec = struct_pack::deserialize_to(p1, buf.data(), buf.size()); - * CHECK(ec == std::errc{}); - * - * auto buf1 = struct_pack::serialize(p1); - * person_v2 p3; - * // deserialize person_v1 as person_v2 - * auto ec = struct_pack::deserialize_to(p3, buf1.data(), buf1.size()); - * CHECK(ec == std::errc{}); - * ``` - * - * When you update your struct: - * 1. The new compatible field's version number should bigger than last changed. - * 2. Don't remove or change any old field. - * - * For example, - * - * ```cpp - * struct loginRequest_V1 - * { - * string user_name; - * string pass_word; - * struct_pack::compatible verification_code; - * }; - * - * struct loginRequest_V2 - * { - * string user_name; - * string pass_word; - * struct_pack::compatible ip_address; - * }; - * - * auto data=struct_pack::serialize(loginRequest_V1{}); - * loginRequest_V2 req; - * struct_pack::deserialize_to(req, data); // undefined behavior! - * - * ``` - * - * ```cpp - * struct loginRequest_V1 - * { - * string user_name; - * string pass_word; - * struct_pack::compatible verification_code; - * }; - * - * struct loginRequest_V2 - * { - * string user_name; - * string pass_word; - * struct_pack::compatible verification_code; - * struct_pack::compatible ip_address; - * }; - * - * auto data=struct_pack::serialize(loginRequest_V1{}); - * loginRequest_V2 req; - * struct_pack::deserialize_to(req, data); // undefined behavior! - * - * The value of compatible can be empty. - * - * TODO: add doc - * - * @tparam T field type - */ - -template -struct compatible : public std::optional { - constexpr compatible() = default; - constexpr compatible(const compatible &other) = default; - constexpr compatible(compatible &&other) = default; - constexpr compatible(std::optional &&other) - : std::optional(std::move(other)){}; - constexpr compatible(const std::optional &other) - : std::optional(other){}; - constexpr compatible &operator=(const compatible &other) = default; - constexpr compatible &operator=(compatible &&other) = default; - using std::optional::optional; - friend bool operator==(const compatible &self, - const compatible &other) { - return static_cast(self) == static_cast(other) && - (!self || *self == *other); - } - static constexpr uint64_t version_number = version; -}; -} // namespace struct_pack diff --git a/include/ylt/struct_pack/derived_helper.hpp b/include/ylt/struct_pack/derived_helper.hpp deleted file mode 100644 index 8a78f06f9..000000000 --- a/include/ylt/struct_pack/derived_helper.hpp +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include -#include - -#include "error_code.hpp" -#include "marco.h" -#include "size_info.hpp" -#include "util.h" -namespace struct_pack { - -template -STRUCT_PACK_INLINE constexpr std::uint32_t get_type_code(); -namespace detail { -struct MD5_pair { - uint32_t md5; - uint32_t index; - constexpr friend bool operator<(const MD5_pair &l, const MD5_pair &r) { - return l.md5 < r.md5; - } - constexpr friend bool operator>(const MD5_pair &l, const MD5_pair &r) { - return l.md5 > r.md5; - } - constexpr friend bool operator==(const MD5_pair &l, const MD5_pair &r) { - return l.md5 == r.md5; - } -}; - -template -constexpr uint32_t get_types_code(); - -template -struct MD5_set { - static constexpr int size = std::tuple_size_v; - static_assert(size <= 256); - - private: - template - static constexpr std::array calculate_md5( - std::index_sequence) { - std::array md5{}; - ((md5[Index] = - MD5_pair{ - get_types_code>(), - Index}), - ...); - compile_time_sort(md5); - return md5; - } - static constexpr std::size_t has_hash_collision_impl() { - for (std::size_t i = 1; i < size; ++i) { - if (value[i - 1] == value[i]) { - return value[i].index; - } - } - return 0; - } - - public: - static constexpr std::array value = - calculate_md5(std::make_index_sequence()); - static constexpr std::size_t has_hash_collision = has_hash_collision_impl(); -}; - -template -struct public_base_class_checker { - static_assert(std::tuple_size_v <= 256); - - private: - template - static constexpr bool calculate_md5(std::index_sequence) { - return (std::is_base_of_v> && - ...); - } - - public: - static constexpr bool value = public_base_class_checker::calculate_md5( - std::make_index_sequence>()); -}; - -template -struct deserialize_derived_class_helper { - template - static STRUCT_PACK_INLINE constexpr struct_pack::err_code run( - std::unique_ptr &base, unpack &unpacker) { - if constexpr (index >= std::tuple_size_v) { - unreachable(); - } - else { - using derived_class = std::tuple_element_t; - base = std::make_unique(); - return unpacker.deserialize(*(derived_class *)base.get()); - } - } -}; - -template -constexpr size_info inline calculate_one_size(const T &item); - -template -struct calculate_one_size_derived_class_helper { - template - static STRUCT_PACK_INLINE constexpr size_info run(BaseClass *base) { - if constexpr (index >= std::tuple_size_v) { - unreachable(); - } - else { - using derived_class = std::tuple_element_t; -#ifdef STRUCT_PACK_RTTI_ENABLED - assert(dynamic_cast(base)); -#endif - return calculate_one_size(*(derived_class *)base); - } - } -}; - -template -struct serialize_one_derived_class_helper { - template - static STRUCT_PACK_INLINE constexpr void run(packer *self, BaseClass *base) { - if constexpr (index >= std::tuple_size_v) { - unreachable(); - } - else { - using derived_class = std::tuple_element_t; -#ifdef STRUCT_PACK_RTTI_ENABLED - assert(dynamic_cast(base)); -#endif - self->template serialize_one( - *(derived_class *)base); - } - } -}; - -template -struct deserialize_one_derived_class_helper { - template - static STRUCT_PACK_INLINE constexpr struct_pack::err_code run(unpacker *self, - Pointer &base) { - if constexpr (index >= std::tuple_size_v) { - unreachable(); - } - else { - using derived_class = std::tuple_element_t; - base = std::make_unique(); - return self->template deserialize_one( - *(derived_class *)base.get()); - } - } -}; - -template -using derived_class_set_t = decltype(struct_pack_derived_decl((Base *)nullptr)); - -template -constexpr std::size_t search_type_by_md5(uint32_t id, bool &ok) { - constexpr auto &MD5s = MD5_set>::value; - auto result = std::lower_bound(MD5s.begin(), MD5s.end(), MD5_pair{id, 0}); - ok = (result != MD5s.end() && result->md5 == id); - if (!ok) - return MD5s.size(); - else - return result->index; -} - -template -std::uint32_t get_struct_pack_id_impl() { - if constexpr (std::is_abstract_v) { - struct_pack::detail::unreachable(); - } - else { - return struct_pack::get_type_code(); - } -} - -template -constexpr auto derived_decl_impl() { - if constexpr (std::is_abstract_v) { - return struct_pack::detail::declval>(); - } - else { - return struct_pack::detail::declval>(); - } -} - -template -constexpr bool check_ID_collision() { - if constexpr (std::is_abstract_v) { - constexpr auto has_collision = struct_pack::detail::MD5_set< - std::tuple>::has_hash_collision; - if constexpr (has_collision != 0) { - static_assert( - !sizeof(std::tuple_element_t>), - "ID collision happened, consider add member `static " - "constexpr uint64_t struct_pack_id` for collision type. "); - } - } - else { - constexpr auto has_collision = struct_pack::detail::MD5_set< - std::tuple>::has_hash_collision; - if constexpr (has_collision != 0) { - static_assert(!sizeof(std::tuple_element_t>), - "ID collision happened, consider add member `static " - "constexpr uint64_t struct_pack_id` for collision type. "); - } - } - return true; -} -} // namespace detail -} // namespace struct_pack \ No newline at end of file diff --git a/include/ylt/struct_pack/derived_marco.hpp b/include/ylt/struct_pack/derived_marco.hpp deleted file mode 100644 index af50399f3..000000000 --- a/include/ylt/struct_pack/derived_marco.hpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "foreach_macro.h" - -#pragma once - -#define GET_STRUCT_PACK_ID_IMPL_FOR_LOOP(idx, type) \ - inline uint32_t type::get_struct_pack_id() const { \ - return struct_pack::detail::get_struct_pack_id_impl(); \ - } - -#define STRUCT_PACK_DERIVED_DECL(base, ...) \ - \ - inline decltype(struct_pack::detail::derived_decl_impl()) \ - struct_pack_derived_decl(base*); - -#define STRUCT_PACK_DERIVED_IMPL(base, ...) \ - STRUCT_PACK_EXPAND_EACH(, GET_STRUCT_PACK_ID_IMPL_FOR_LOOP, base, \ - __VA_ARGS__) \ - STRUCT_PACK_DERIVED_DECL(base, __VA_ARGS__); \ - static_assert(struct_pack::detail::check_ID_collision()); diff --git a/include/ylt/struct_pack/endian_wrapper.hpp b/include/ylt/struct_pack/endian_wrapper.hpp deleted file mode 100644 index dd683a7b8..000000000 --- a/include/ylt/struct_pack/endian_wrapper.hpp +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include - -#include "reflection.hpp" -#include "ylt/struct_pack/error_code.hpp" -#include "ylt/struct_pack/marco.h" -#include "ylt/struct_pack/util.h" - -namespace struct_pack { -namespace detail { -#if __cpp_lib_endian >= 201907L -constexpr inline bool is_system_little_endian = - (std::endian::little == std::endian::native); -static_assert(std::endian::native == std::endian::little || - std::endian::native == std::endian::big, - "struct_pack don't support middle-endian"); -#else -#define BYTEORDER_LITTLE_ENDIAN 0 // Little endian machine. -#define BYTEORDER_BIG_ENDIAN 1 // Big endian machine. - -//#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN - -#ifndef BYTEORDER_ENDIAN -// Detect with GCC 4.6's macro. -#if defined(__BYTE_ORDER__) -#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) -#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN -#elif (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) -#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN -#else -#error \ - "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN." -#endif -// Detect with GLIBC's endian.h. -#elif defined(__GLIBC__) -#include -#if (__BYTE_ORDER == __LITTLE_ENDIAN) -#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN -#elif (__BYTE_ORDER == __BIG_ENDIAN) -#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN -#else -#error \ - "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN." -#endif -// Detect with _LITTLE_ENDIAN and _BIG_ENDIAN macro. -#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) -#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN -#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) -#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN -// Detect with architecture macros. -#elif defined(__sparc) || defined(__sparc__) || defined(_POWER) || \ - defined(__powerpc__) || defined(__ppc__) || defined(__hpux) || \ - defined(__hppa) || defined(_MIPSEB) || defined(_POWER) || \ - defined(__s390__) -#define BYTEORDER_ENDIAN BYTEORDER_BIG_ENDIAN -#elif defined(__i386__) || defined(__alpha__) || defined(__ia64) || \ - defined(__ia64__) || defined(_M_IX86) || defined(_M_IA64) || \ - defined(_M_ALPHA) || defined(__amd64) || defined(__amd64__) || \ - defined(_M_AMD64) || defined(__x86_64) || defined(__x86_64__) || \ - defined(_M_X64) || defined(__bfin__) -#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN -#elif defined(_MSC_VER) && (defined(_M_ARM) || defined(_M_ARM64)) -#define BYTEORDER_ENDIAN BYTEORDER_LITTLE_ENDIAN -#else -#error \ - "Unknown machine byteorder endianness detected. User needs to define BYTEORDER_ENDIAN." -#endif -#endif -constexpr inline bool is_system_little_endian = - (BYTEORDER_ENDIAN == BYTEORDER_LITTLE_ENDIAN); -#endif - -template -constexpr inline bool is_little_endian_copyable = - is_system_little_endian || block_size == 1; - -template -T swap_endian(T u) { - union { - T u; - unsigned char u8[sizeof(T)]; - } source, dest; - source.u = u; - for (size_t k = 0; k < sizeof(T); k++) - dest.u8[k] = source.u8[sizeof(T) - k - 1]; - return dest.u; -} - -inline uint16_t bswap16(uint16_t raw) { -#ifdef _MSC_VER - return _byteswap_ushort(raw); -#elif defined(__clang__) || defined(__GNUC__) - return __builtin_bswap16(raw); -#else - return swap_endian(raw); -#endif -}; - -inline uint32_t bswap32(uint32_t raw) { -#ifdef _MSC_VER - return _byteswap_ulong(raw); -#elif defined(__clang__) || defined(__GNUC__) - return __builtin_bswap32(raw); -#else - return swap_endian(raw); -#endif -}; - -inline uint64_t bswap64(uint64_t raw) { -#ifdef _MSC_VER - return _byteswap_uint64(raw); -#elif defined(__clang__) || defined(__GNUC__) - return __builtin_bswap64(raw); -#else - return swap_endian(raw); -#endif -}; - -template -STRUCT_PACK_INLINE void write_wrapper(writer_t& writer, - const char* SP_RESTRICT data) { - if constexpr (is_system_little_endian || block_size == 1) { - writer.write(data, block_size); - } - else if constexpr (block_size == 2) { - auto tmp = bswap16(*(uint16_t*)data); - writer.write((char*)&tmp, block_size); - } - else if constexpr (block_size == 4) { - auto tmp = bswap32(*(uint32_t*)data); - writer.write((char*)&tmp, block_size); - } - else if constexpr (block_size == 8) { - auto tmp = bswap64(*(uint64_t*)data); - writer.write((char*)&tmp, block_size); - } - else if constexpr (block_size == 16) { - auto tmp1 = bswap64(*(uint64_t*)data), - tmp2 = bswap64(*(uint64_t*)(data + 8)); - writer.write((char*)&tmp2, block_size); - writer.write((char*)&tmp1, block_size); - } - else { - static_assert(!sizeof(writer), "illegal block size(should be 1,2,4,8,16)"); - } -} -template -STRUCT_PACK_INLINE void write_bytes_array(writer_t& writer, const char* data, - std::size_t length) { - if SP_UNLIKELY (length >= PTRDIFF_MAX) - unreachable(); - else - writer.write(data, length); -} -template -STRUCT_PACK_INLINE void low_bytes_write_wrapper(writer_t& writer, - const T& elem) { - static_assert(sizeof(T) >= block_size); - if constexpr (is_system_little_endian) { - const char* data = (const char*)&elem; - writer.write(data, block_size); - } - else if constexpr (block_size == sizeof(T)) { - write_wrapper(writer, (const char*)&elem); - } - else { - const char* data = sizeof(T) - block_size + (const char*)&elem; - if constexpr (block_size == 1) { - writer.write(data, block_size); - } - else if constexpr (block_size == 2) { - auto tmp = bswap16(*(uint16_t*)data); - writer.write((char*)&tmp, block_size); - } - else if constexpr (block_size == 4) { - auto tmp = bswap32(*(uint32_t*)data); - writer.write((char*)&tmp, block_size); - } - else { - static_assert(!sizeof(writer), "illegal block size(should be 1,2,4)"); - } - } -} -template -STRUCT_PACK_INLINE bool read_wrapper(reader_t& reader, char* SP_RESTRICT data) { - if constexpr (is_system_little_endian || block_size == 1) { - return static_cast(reader.read(data, block_size)); - } - else { - std::array tmp; - bool res = static_cast(reader.read((char*)&tmp, block_size)); - if SP_UNLIKELY (!res) { - return res; - } - if constexpr (block_size == 2) { - *(uint16_t*)data = bswap16(*(uint16_t*)&tmp); - } - else if constexpr (block_size == 4) { - *(uint32_t*)data = bswap32(*(uint32_t*)&tmp); - } - else if constexpr (block_size == 8) { - *(uint64_t*)data = bswap64(*(uint64_t*)&tmp); - } - else if constexpr (block_size == 16) { - *(uint64_t*)(data + 8) = bswap64(*(uint64_t*)&tmp); - *(uint64_t*)data = bswap64(*(uint64_t*)(&tmp + 8)); - } - else { - static_assert(!sizeof(reader), - "illegal block size(should be 1,2,4,8,16)"); - } - return true; - } -} -template -STRUCT_PACK_INLINE bool read_bytes_array(reader_t& reader, - char* SP_RESTRICT data, - std::size_t length) { - return static_cast(reader.read(data, length)); -} -template -STRUCT_PACK_INLINE bool low_bytes_read_wrapper(reader_t& reader, T& elem) { - static_assert(sizeof(T) >= block_size); - if constexpr (is_system_little_endian) { - char* data = (char*)&elem; - return static_cast(reader.read(data, block_size)); - } - else if constexpr (block_size == sizeof(T)) { - return read_wrapper(reader, (char*)&elem); - } - else { - char* data = (char*)&elem + sizeof(T) - block_size; - if constexpr (block_size > 1) { - char tmp[block_size]; - bool res = static_cast(reader.read(tmp, block_size)); - if SP_UNLIKELY (!res) { - return res; - } - if constexpr (block_size == 2) { - *(uint16_t*)data = bswap16(*(uint16_t*)tmp); - } - else if constexpr (block_size == 4) { - *(uint32_t*)data = bswap32(*(uint32_t*)tmp); - } - else { - static_assert(!sizeof(reader), "illegal block size(should be 1,2,4)"); - } - return true; - } - else { - return static_cast(reader.read(data, block_size)); - } - } -} -} // namespace detail -}; // namespace struct_pack \ No newline at end of file diff --git a/include/ylt/struct_pack/error_code.hpp b/include/ylt/struct_pack/error_code.hpp deleted file mode 100644 index 8fd9acadc..000000000 --- a/include/ylt/struct_pack/error_code.hpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include - -namespace struct_pack { -enum class errc { - ok = 0, - no_buffer_space, - invalid_buffer, - hash_conflict, - invalid_width_of_container_length, -}; -namespace detail { -inline constexpr std::string_view make_error_message(errc ec) noexcept { - switch (ec) { - case errc::ok: - return "ok"; - case errc::no_buffer_space: - return "no buffer space"; - case errc::invalid_buffer: - return "invalid argument"; - case errc::hash_conflict: - return "hash conflict"; - case errc::invalid_width_of_container_length: - return "invalid width of container length"; - default: - return "(unrecognized error)"; - } -} -} // namespace detail - -struct err_code { - public: - errc ec; - constexpr err_code() noexcept : ec(errc::ok) {} - constexpr err_code(errc ec) noexcept : ec(ec){}; - constexpr err_code& operator=(errc ec) noexcept { - this->ec = ec; - return *this; - } - constexpr err_code(const err_code& err_code) noexcept = default; - constexpr err_code& operator=(const err_code& o) noexcept = default; - constexpr operator errc() const noexcept { return ec; } - constexpr operator bool() const noexcept { return ec != errc::ok; } - constexpr int val() const noexcept { return static_cast(ec); } - constexpr std::string_view message() const noexcept { - return detail::make_error_message(ec); - } -}; - -namespace detail { -class struct_pack_category : public std::error_category { - public: - virtual const char* name() const noexcept override { - return "struct_pack::category"; - } - - virtual std::string message(int err_val) const override { - return std::string{make_error_message(static_cast(err_val))}; - } -}; - -inline const std::error_category& category() { - static struct_pack::detail::struct_pack_category instance; - return instance; -} -} // namespace detail - -} // namespace struct_pack \ No newline at end of file diff --git a/include/ylt/struct_pack/foreach_macro.h b/include/ylt/struct_pack/foreach_macro.h deleted file mode 100644 index 87ba6dc04..000000000 --- a/include/ylt/struct_pack/foreach_macro.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -// clang-format off -#define STRUCT_PACK_ARG_COUNT(...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_INTERNAL_ARG_COUNT(0, ##__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, 0)) - -#define STRUCT_PACK_INTERNAL_ARG_COUNT(\ - _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, \ - _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, \ - _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, \ - _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, \ - _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, \ - _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, \ - _60, _61, _62, _63, _64, N, ...) N - -#define STRUCT_PACK_CONCAT_(l, r) l ## r -#define STRUCT_PACK_CONCAT(l, r) STRUCT_PACK_CONCAT_(l, r) - -#define STRUCT_PACK_MARCO_EXPAND(...) __VA_ARGS__ - -#define STRUCT_PACK_DOARG0(s,f,o) -#define STRUCT_PACK_DOARG1(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG0(s,f,__VA_ARGS__)) s f(0,t) -#define STRUCT_PACK_DOARG2(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG1(s,f,__VA_ARGS__)) s f(1,t) -#define STRUCT_PACK_DOARG3(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG2(s,f,__VA_ARGS__)) s f(2,t) -#define STRUCT_PACK_DOARG4(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG3(s,f,__VA_ARGS__)) s f(3,t) -#define STRUCT_PACK_DOARG5(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG4(s,f,__VA_ARGS__)) s f(4,t) -#define STRUCT_PACK_DOARG6(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG5(s,f,__VA_ARGS__)) s f(5,t) -#define STRUCT_PACK_DOARG7(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG6(s,f,__VA_ARGS__)) s f(6,t) -#define STRUCT_PACK_DOARG8(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG7(s,f,__VA_ARGS__)) s f(7,t) -#define STRUCT_PACK_DOARG9(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG8(s,f,__VA_ARGS__)) s f(8,t) -#define STRUCT_PACK_DOARG10(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG9(s,f,__VA_ARGS__)) s f(9,t) -#define STRUCT_PACK_DOARG11(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG10(s,f,__VA_ARGS__)) s f(10,t) -#define STRUCT_PACK_DOARG12(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG11(s,f,__VA_ARGS__)) s f(11,t) -#define STRUCT_PACK_DOARG13(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG12(s,f,__VA_ARGS__)) s f(12,t) -#define STRUCT_PACK_DOARG14(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG13(s,f,__VA_ARGS__)) s f(13,t) -#define STRUCT_PACK_DOARG15(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG14(s,f,__VA_ARGS__)) s f(14,t) -#define STRUCT_PACK_DOARG16(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG15(s,f,__VA_ARGS__)) s f(15,t) -#define STRUCT_PACK_DOARG17(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG16(s,f,__VA_ARGS__)) s f(16,t) -#define STRUCT_PACK_DOARG18(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG17(s,f,__VA_ARGS__)) s f(17,t) -#define STRUCT_PACK_DOARG19(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG18(s,f,__VA_ARGS__)) s f(18,t) -#define STRUCT_PACK_DOARG20(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG19(s,f,__VA_ARGS__)) s f(19,t) -#define STRUCT_PACK_DOARG21(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG20(s,f,__VA_ARGS__)) s f(20,t) -#define STRUCT_PACK_DOARG22(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG21(s,f,__VA_ARGS__)) s f(21,t) -#define STRUCT_PACK_DOARG23(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG22(s,f,__VA_ARGS__)) s f(22,t) -#define STRUCT_PACK_DOARG24(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG23(s,f,__VA_ARGS__)) s f(23,t) -#define STRUCT_PACK_DOARG25(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG24(s,f,__VA_ARGS__)) s f(24,t) -#define STRUCT_PACK_DOARG26(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG25(s,f,__VA_ARGS__)) s f(25,t) -#define STRUCT_PACK_DOARG27(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG26(s,f,__VA_ARGS__)) s f(26,t) -#define STRUCT_PACK_DOARG28(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG27(s,f,__VA_ARGS__)) s f(27,t) -#define STRUCT_PACK_DOARG29(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG28(s,f,__VA_ARGS__)) s f(28,t) -#define STRUCT_PACK_DOARG30(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG29(s,f,__VA_ARGS__)) s f(29,t) -#define STRUCT_PACK_DOARG31(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG30(s,f,__VA_ARGS__)) s f(30,t) -#define STRUCT_PACK_DOARG32(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG31(s,f,__VA_ARGS__)) s f(31,t) -#define STRUCT_PACK_DOARG33(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG32(s,f,__VA_ARGS__)) s f(32,t) -#define STRUCT_PACK_DOARG34(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG33(s,f,__VA_ARGS__)) s f(33,t) -#define STRUCT_PACK_DOARG35(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG34(s,f,__VA_ARGS__)) s f(34,t) -#define STRUCT_PACK_DOARG36(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG35(s,f,__VA_ARGS__)) s f(35,t) -#define STRUCT_PACK_DOARG37(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG36(s,f,__VA_ARGS__)) s f(36,t) -#define STRUCT_PACK_DOARG38(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG37(s,f,__VA_ARGS__)) s f(37,t) -#define STRUCT_PACK_DOARG39(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG38(s,f,__VA_ARGS__)) s f(38,t) -#define STRUCT_PACK_DOARG40(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG39(s,f,__VA_ARGS__)) s f(39,t) -#define STRUCT_PACK_DOARG41(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG40(s,f,__VA_ARGS__)) s f(40,t) -#define STRUCT_PACK_DOARG42(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG41(s,f,__VA_ARGS__)) s f(41,t) -#define STRUCT_PACK_DOARG43(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG42(s,f,__VA_ARGS__)) s f(42,t) -#define STRUCT_PACK_DOARG44(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG43(s,f,__VA_ARGS__)) s f(43,t) -#define STRUCT_PACK_DOARG45(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG44(s,f,__VA_ARGS__)) s f(44,t) -#define STRUCT_PACK_DOARG46(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG45(s,f,__VA_ARGS__)) s f(45,t) -#define STRUCT_PACK_DOARG47(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG46(s,f,__VA_ARGS__)) s f(46,t) -#define STRUCT_PACK_DOARG48(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG47(s,f,__VA_ARGS__)) s f(47,t) -#define STRUCT_PACK_DOARG49(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG48(s,f,__VA_ARGS__)) s f(48,t) -#define STRUCT_PACK_DOARG50(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG49(s,f,__VA_ARGS__)) s f(49,t) -#define STRUCT_PACK_DOARG51(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG50(s,f,__VA_ARGS__)) s f(50,t) -#define STRUCT_PACK_DOARG52(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG51(s,f,__VA_ARGS__)) s f(51,t) -#define STRUCT_PACK_DOARG53(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG52(s,f,__VA_ARGS__)) s f(52,t) -#define STRUCT_PACK_DOARG54(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG53(s,f,__VA_ARGS__)) s f(53,t) -#define STRUCT_PACK_DOARG55(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG54(s,f,__VA_ARGS__)) s f(54,t) -#define STRUCT_PACK_DOARG56(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG55(s,f,__VA_ARGS__)) s f(55,t) -#define STRUCT_PACK_DOARG57(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG56(s,f,__VA_ARGS__)) s f(56,t) -#define STRUCT_PACK_DOARG58(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG57(s,f,__VA_ARGS__)) s f(57,t) -#define STRUCT_PACK_DOARG59(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG58(s,f,__VA_ARGS__)) s f(58,t) -#define STRUCT_PACK_DOARG60(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG59(s,f,__VA_ARGS__)) s f(59,t) -#define STRUCT_PACK_DOARG61(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG60(s,f,__VA_ARGS__)) s f(60,t) -#define STRUCT_PACK_DOARG62(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG61(s,f,__VA_ARGS__)) s f(61,t) -#define STRUCT_PACK_DOARG63(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG62(s,f,__VA_ARGS__)) s f(62,t) -#define STRUCT_PACK_DOARG64(s,f,t,...) STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_DOARG63(s,f,__VA_ARGS__)) s f(63,t) - -#define STRUCT_PACK_MAKE_ARGS0(Type) -#define STRUCT_PACK_MAKE_ARGS1(Type) Type -#define STRUCT_PACK_MAKE_ARGS2(Type) STRUCT_PACK_MAKE_ARGS1(Type), Type -#define STRUCT_PACK_MAKE_ARGS3(Type) STRUCT_PACK_MAKE_ARGS2(Type), Type -#define STRUCT_PACK_MAKE_ARGS4(Type) STRUCT_PACK_MAKE_ARGS3(Type), Type -#define STRUCT_PACK_MAKE_ARGS5(Type) STRUCT_PACK_MAKE_ARGS4(Type), Type -#define STRUCT_PACK_MAKE_ARGS6(Type) STRUCT_PACK_MAKE_ARGS5(Type), Type -#define STRUCT_PACK_MAKE_ARGS7(Type) STRUCT_PACK_MAKE_ARGS6(Type), Type -#define STRUCT_PACK_MAKE_ARGS8(Type) STRUCT_PACK_MAKE_ARGS7(Type), Type -#define STRUCT_PACK_MAKE_ARGS9(Type) STRUCT_PACK_MAKE_ARGS8(Type), Type -#define STRUCT_PACK_MAKE_ARGS10(Type) STRUCT_PACK_MAKE_ARGS9(Type), Type -#define STRUCT_PACK_MAKE_ARGS11(Type) STRUCT_PACK_MAKE_ARGS10(Type), Type -#define STRUCT_PACK_MAKE_ARGS12(Type) STRUCT_PACK_MAKE_ARGS11(Type), Type -#define STRUCT_PACK_MAKE_ARGS13(Type) STRUCT_PACK_MAKE_ARGS12(Type), Type -#define STRUCT_PACK_MAKE_ARGS14(Type) STRUCT_PACK_MAKE_ARGS13(Type), Type -#define STRUCT_PACK_MAKE_ARGS15(Type) STRUCT_PACK_MAKE_ARGS14(Type), Type -#define STRUCT_PACK_MAKE_ARGS16(Type) STRUCT_PACK_MAKE_ARGS15(Type), Type -#define STRUCT_PACK_MAKE_ARGS17(Type) STRUCT_PACK_MAKE_ARGS16(Type), Type -#define STRUCT_PACK_MAKE_ARGS18(Type) STRUCT_PACK_MAKE_ARGS17(Type), Type -#define STRUCT_PACK_MAKE_ARGS19(Type) STRUCT_PACK_MAKE_ARGS18(Type), Type -#define STRUCT_PACK_MAKE_ARGS20(Type) STRUCT_PACK_MAKE_ARGS19(Type), Type -#define STRUCT_PACK_MAKE_ARGS21(Type) STRUCT_PACK_MAKE_ARGS20(Type), Type -#define STRUCT_PACK_MAKE_ARGS22(Type) STRUCT_PACK_MAKE_ARGS21(Type), Type -#define STRUCT_PACK_MAKE_ARGS23(Type) STRUCT_PACK_MAKE_ARGS22(Type), Type -#define STRUCT_PACK_MAKE_ARGS24(Type) STRUCT_PACK_MAKE_ARGS23(Type), Type -#define STRUCT_PACK_MAKE_ARGS25(Type) STRUCT_PACK_MAKE_ARGS24(Type), Type -#define STRUCT_PACK_MAKE_ARGS26(Type) STRUCT_PACK_MAKE_ARGS25(Type), Type -#define STRUCT_PACK_MAKE_ARGS27(Type) STRUCT_PACK_MAKE_ARGS26(Type), Type -#define STRUCT_PACK_MAKE_ARGS28(Type) STRUCT_PACK_MAKE_ARGS27(Type), Type -#define STRUCT_PACK_MAKE_ARGS29(Type) STRUCT_PACK_MAKE_ARGS28(Type), Type -#define STRUCT_PACK_MAKE_ARGS30(Type) STRUCT_PACK_MAKE_ARGS29(Type), Type -#define STRUCT_PACK_MAKE_ARGS31(Type) STRUCT_PACK_MAKE_ARGS30(Type), Type -#define STRUCT_PACK_MAKE_ARGS32(Type) STRUCT_PACK_MAKE_ARGS31(Type), Type -#define STRUCT_PACK_MAKE_ARGS33(Type) STRUCT_PACK_MAKE_ARGS32(Type), Type -#define STRUCT_PACK_MAKE_ARGS34(Type) STRUCT_PACK_MAKE_ARGS33(Type), Type -#define STRUCT_PACK_MAKE_ARGS35(Type) STRUCT_PACK_MAKE_ARGS34(Type), Type -#define STRUCT_PACK_MAKE_ARGS36(Type) STRUCT_PACK_MAKE_ARGS35(Type), Type -#define STRUCT_PACK_MAKE_ARGS37(Type) STRUCT_PACK_MAKE_ARGS36(Type), Type -#define STRUCT_PACK_MAKE_ARGS38(Type) STRUCT_PACK_MAKE_ARGS37(Type), Type -#define STRUCT_PACK_MAKE_ARGS39(Type) STRUCT_PACK_MAKE_ARGS38(Type), Type -#define STRUCT_PACK_MAKE_ARGS40(Type) STRUCT_PACK_MAKE_ARGS39(Type), Type -#define STRUCT_PACK_MAKE_ARGS41(Type) STRUCT_PACK_MAKE_ARGS40(Type), Type -#define STRUCT_PACK_MAKE_ARGS42(Type) STRUCT_PACK_MAKE_ARGS41(Type), Type -#define STRUCT_PACK_MAKE_ARGS43(Type) STRUCT_PACK_MAKE_ARGS42(Type), Type -#define STRUCT_PACK_MAKE_ARGS44(Type) STRUCT_PACK_MAKE_ARGS43(Type), Type -#define STRUCT_PACK_MAKE_ARGS45(Type) STRUCT_PACK_MAKE_ARGS44(Type), Type -#define STRUCT_PACK_MAKE_ARGS46(Type) STRUCT_PACK_MAKE_ARGS45(Type), Type -#define STRUCT_PACK_MAKE_ARGS47(Type) STRUCT_PACK_MAKE_ARGS46(Type), Type -#define STRUCT_PACK_MAKE_ARGS48(Type) STRUCT_PACK_MAKE_ARGS47(Type), Type -#define STRUCT_PACK_MAKE_ARGS49(Type) STRUCT_PACK_MAKE_ARGS48(Type), Type -#define STRUCT_PACK_MAKE_ARGS50(Type) STRUCT_PACK_MAKE_ARGS49(Type), Type -#define STRUCT_PACK_MAKE_ARGS51(Type) STRUCT_PACK_MAKE_ARGS50(Type), Type -#define STRUCT_PACK_MAKE_ARGS52(Type) STRUCT_PACK_MAKE_ARGS51(Type), Type -#define STRUCT_PACK_MAKE_ARGS53(Type) STRUCT_PACK_MAKE_ARGS52(Type), Type -#define STRUCT_PACK_MAKE_ARGS54(Type) STRUCT_PACK_MAKE_ARGS53(Type), Type -#define STRUCT_PACK_MAKE_ARGS55(Type) STRUCT_PACK_MAKE_ARGS54(Type), Type -#define STRUCT_PACK_MAKE_ARGS56(Type) STRUCT_PACK_MAKE_ARGS55(Type), Type -#define STRUCT_PACK_MAKE_ARGS57(Type) STRUCT_PACK_MAKE_ARGS56(Type), Type -#define STRUCT_PACK_MAKE_ARGS58(Type) STRUCT_PACK_MAKE_ARGS57(Type), Type -#define STRUCT_PACK_MAKE_ARGS59(Type) STRUCT_PACK_MAKE_ARGS58(Type), Type -#define STRUCT_PACK_MAKE_ARGS60(Type) STRUCT_PACK_MAKE_ARGS59(Type), Type -#define STRUCT_PACK_MAKE_ARGS61(Type) STRUCT_PACK_MAKE_ARGS60(Type), Type -#define STRUCT_PACK_MAKE_ARGS62(Type) STRUCT_PACK_MAKE_ARGS61(Type), Type -#define STRUCT_PACK_MAKE_ARGS63(Type) STRUCT_PACK_MAKE_ARGS62(Type), Type -#define STRUCT_PACK_MAKE_ARGS64(Type) STRUCT_PACK_MAKE_ARGS63(Type), Type - - -#define STRUCT_PACK_MAKE_ARGS(Type,Count) \ - STRUCT_PACK_CONCAT(STRUCT_PACK_MAKE_ARGS,Count)(Type) - -#define STRUCT_PACK_EXPAND_EACH_(sepatator,fun,...) \ - STRUCT_PACK_MARCO_EXPAND(STRUCT_PACK_CONCAT(STRUCT_PACK_DOARG,STRUCT_PACK_ARG_COUNT(__VA_ARGS__))(sepatator,fun,__VA_ARGS__)) -#define STRUCT_PACK_EXPAND_EACH(sepatator,fun,...) \ - STRUCT_PACK_EXPAND_EACH_(sepatator,fun,__VA_ARGS__) - \ No newline at end of file diff --git a/include/ylt/struct_pack/marco.h b/include/ylt/struct_pack/marco.h deleted file mode 100644 index 546ac6e9e..000000000 --- a/include/ylt/struct_pack/marco.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#if defined __clang__ -#define STRUCT_PACK_INLINE __attribute__((always_inline)) inline -#define CONSTEXPR_INLINE_LAMBDA __attribute__((always_inline)) constexpr -#elif defined _MSC_VER -#define STRUCT_PACK_INLINE __forceinline -#define CONSTEXPR_INLINE_LAMBDA constexpr -#else -#define STRUCT_PACK_INLINE __attribute__((always_inline)) inline -#define CONSTEXPR_INLINE_LAMBDA constexpr __attribute__((always_inline)) -#endif - -#if defined STRUCT_PACK_OPTIMIZE -#define STRUCT_PACK_MAY_INLINE STRUCT_PACK_INLINE -#else -#define STRUCT_PACK_MAY_INLINE inline -#endif - -#if __has_cpp_attribute(likely) && __cplusplus >= 202002L -#define SP_LIKELY(expr) (expr) [[likely]] -#elif __GNUC__ -#define SP_LIKELY(expr) (__builtin_expect(!!(expr), 1)) -#else -#define SP_LIKELY(expr) (expr) -#endif - -#if __has_cpp_attribute(unlikely) && __cplusplus >= 202002L -#define SP_UNLIKELY(expr) (expr) [[unlikely]] -#elif __GNUC__ -#define SP_UNLIKELY(expr) (__builtin_expect(!!(expr), 0)) -#else -#define SP_UNLIKELY(expr) (expr) -#endif - -#if defined(__clang__) -#if __has_feature(cxx_rtti) -#define STRUCT_PACK_RTTI_ENABLED -#endif -#elif defined(__GNUC__) -#if defined(__GXX_RTTI) -#define STRUCT_PACK_RTTI_ENABLED -#endif -#elif defined(_MSC_VER) -#if defined(_CPPRTTI) -#define STRUCT_PACK_RTTI_ENABLED -#endif -#endif - -#if defined __clang__ || __GNUC__ -#define SP_RESTRICT __restrict__ -#elif defined _MSC_VER -#define SP_RESTRICT __restrict -#else -#define SP_RESTRICT -#endif diff --git a/include/ylt/struct_pack/md5_constexpr.hpp b/include/ylt/struct_pack/md5_constexpr.hpp deleted file mode 100644 index bc21e4988..000000000 --- a/include/ylt/struct_pack/md5_constexpr.hpp +++ /dev/null @@ -1,335 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -// Copyright 2019 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#pragma once -#include -#include -#include -#include - -namespace struct_pack { -template -struct string_literal { - constexpr string_literal() = default; - constexpr string_literal(std::basic_string_view str) : ar{} { - for (size_t i = 0; i < Size; ++i) { - ar[i] = str[i]; - } - ar[Size] = '\0'; - } - constexpr string_literal(const CharType (&value)[Size + 1]) : ar{} { - for (size_t i = 0; i <= Size; ++i) { - ar[i] = value[i]; - } - } - - template - constexpr bool operator!=( - const string_literal &other) const { - if constexpr (Size == Size2) { - for (int i = 0; i < Size; ++i) { - if ((*this)[i] != other[i]) - return true; - } - return false; - } - else { - return true; - } - } - - template - constexpr bool operator==( - const string_literal &other) const { - return !(*this != other); - } - - template - string_literal constexpr operator+( - string_literal other) const { - string_literal ret{}; - for (size_t i = 0; i < Size; ++i) { - ret[i] = (*this)[i]; - } - for (size_t i = 0; i < Size2; ++i) { - ret[i + Size] = other[i]; - } - return ret; - } - - constexpr std::size_t size() const { return Size; } - - constexpr bool empty() const { return !Size; } - - constexpr CharType &operator[](std::size_t sz) { return ar[sz]; } - - constexpr const char &operator[](std::size_t sz) const { return ar[sz]; } - - constexpr const CharType *data() const { return &ar[0]; } - - private: - CharType ar[Size + 1]; -}; - -template -string_literal(const CharType (&value)[Size]) - -> string_literal; - -namespace MD5 { -// The implementation here is based on the pseudocode provided by Wikipedia: -// https://en.wikipedia.org/wiki/MD5#Pseudocode -struct MD5CE { - ////////////////////////////////////////////////////////////////////////////// - // DATA STRUCTURES - // The data representation at each round is a 4-tuple of uint32_t. - struct IntermediateData { - uint32_t a; - uint32_t b; - uint32_t c; - uint32_t d; - }; - // The input data for a single round consists of 16 uint32_t (64 bytes). - using RoundData = std::array; - ////////////////////////////////////////////////////////////////////////////// - // CONSTANTS - static constexpr std::array kConstants = { - {0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, - 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, - 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, - 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, - 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, - 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, - 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, - 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, - 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, - 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, - 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391}}; - static constexpr std::array kShifts = { - {7, 12, 17, 22, 5, 9, 14, 20, 4, 11, 16, 23, 6, 10, 15, 21}}; - // The initial intermediate data. - static constexpr IntermediateData kInitialIntermediateData{ - 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476}; - ////////////////////////////////////////////////////////////////////////////// - // PADDED MESSAGE GENERATION / EXTRACTION - // Given the message length, calculates the padded message length. There has - // to be room for the 1-byte end-of-message marker, plus 8 bytes for the - // uint64_t encoded message length, all rounded up to a multiple of 64 bytes. - static constexpr uint32_t GetPaddedMessageLength(const uint32_t n) { - return (((n + 1 + 8) + 63) / 64) * 64; - } - // Extracts the |i|th byte of a uint64_t, where |i == 0| extracts the least - // significant byte. It is expected that 0 <= i < 8. - static constexpr uint8_t ExtractByte(const uint64_t value, const uint32_t i) { - // DCHECK_LT(i, 8u); - return static_cast((value >> (i * 8)) & 0xff); - } - // Extracts the |i|th byte of a message of length |n|. - static constexpr uint8_t GetPaddedMessageByte(const char *data, - const uint32_t n, - const uint32_t m, - const uint32_t i) { - // DCHECK_LT(i, m); - // DCHECK_LT(n, m); - // DCHECK_EQ(m % 64, 0u); - if (i < n) { - // Emit the message itself... - return data[i]; - } - else if (i == n) { - // ...followed by the end of message marker. - return 0x80; - } - else if (i >= m - 8) { - // The last 8 bytes encode the original message length times 8. - return ExtractByte(n * 8, i - (m - 8)); - } - else { - // And everything else is just empyt padding. - return 0; - } - } - // Extracts the uint32_t starting at position |i| from the padded message - // generate by the provided input |data| of length |n|. The bytes are treated - // in little endian order. - static constexpr uint32_t GetPaddedMessageWord(const char *data, - const uint32_t n, - const uint32_t m, - const uint32_t i) { - // DCHECK_EQ(i % 4, 0u); - // DCHECK_LT(i, m); - // DCHECK_LT(n, m); - // DCHECK_EQ(m % 64, 0u); - return static_cast(GetPaddedMessageByte(data, n, m, i)) | - static_cast((GetPaddedMessageByte(data, n, m, i + 1)) - << 8) | - static_cast((GetPaddedMessageByte(data, n, m, i + 2)) - << 16) | - static_cast((GetPaddedMessageByte(data, n, m, i + 3)) - << 24); - } - // Given an input buffer of length |n| bytes, extracts one round worth of data - // starting at offset |i|. - static constexpr RoundData GetRoundData(const char *data, const uint32_t n, - const uint32_t m, const uint32_t i) { - // DCHECK_EQ(i % 64, 0u); - // DCHECK_LT(i, m); - // DCHECK_LT(n, m); - // DCHECK_EQ(m % 64, 0u); - return RoundData{{GetPaddedMessageWord(data, n, m, i), - GetPaddedMessageWord(data, n, m, i + 4), - GetPaddedMessageWord(data, n, m, i + 8), - GetPaddedMessageWord(data, n, m, i + 12), - GetPaddedMessageWord(data, n, m, i + 16), - GetPaddedMessageWord(data, n, m, i + 20), - GetPaddedMessageWord(data, n, m, i + 24), - GetPaddedMessageWord(data, n, m, i + 28), - GetPaddedMessageWord(data, n, m, i + 32), - GetPaddedMessageWord(data, n, m, i + 36), - GetPaddedMessageWord(data, n, m, i + 40), - GetPaddedMessageWord(data, n, m, i + 44), - GetPaddedMessageWord(data, n, m, i + 48), - GetPaddedMessageWord(data, n, m, i + 52), - GetPaddedMessageWord(data, n, m, i + 56), - GetPaddedMessageWord(data, n, m, i + 60)}}; - } - ////////////////////////////////////////////////////////////////////////////// - // HASH IMPLEMENTATION - // Mixes elements |b|, |c| and |d| at round |i| of the calculation. - static constexpr uint32_t CalcF(const uint32_t i, const uint32_t b, - const uint32_t c, const uint32_t d) { - // DCHECK_LT(i, 64u); - if (i < 16) { - return d ^ (b & (c ^ d)); - } - else if (i < 32) { - return c ^ (d & (b ^ c)); - } - else if (i < 48) { - return b ^ c ^ d; - } - else { - return c ^ (b | (~d)); - } - } - static constexpr uint32_t CalcF(const uint32_t i, - const IntermediateData &intermediate) { - return CalcF(i, intermediate.b, intermediate.c, intermediate.d); - } - // Calculates the indexing function at round |i|. - static constexpr uint32_t CalcG(const uint32_t i) { - // DCHECK_LT(i, 64u); - if (i < 16) { - return i; - } - else if (i < 32) { - return (5 * i + 1) % 16; - } - else if (i < 48) { - return (3 * i + 5) % 16; - } - else { - return (7 * i) % 16; - } - } - // Calculates the rotation to be applied at round |i|. - static constexpr uint32_t GetShift(const uint32_t i) { - // DCHECK_LT(i, 64u); - return kShifts[(i / 16) * 4 + (i % 4)]; - } - // Rotates to the left the given |value| by the given |bits|. - static constexpr uint32_t LeftRotate(const uint32_t value, - const uint32_t bits) { - // DCHECK_LT(bits, 32u); - return (value << bits) | (value >> (32 - bits)); - } - // Applies the ith step of mixing. - static constexpr IntermediateData ApplyStep( - const uint32_t i, const RoundData &data, - const IntermediateData &intermediate) { - // DCHECK_LT(i, 64u); - const uint32_t g = CalcG(i); - // DCHECK_LT(g, 16u); - const uint32_t f = - CalcF(i, intermediate) + intermediate.a + kConstants[i] + data[g]; - const uint32_t s = GetShift(i); - return IntermediateData{/* a */ intermediate.d, - /* b */ intermediate.b + LeftRotate(f, s), - /* c */ intermediate.b, - /* d */ intermediate.c}; - } - // Adds two IntermediateData together. - static constexpr IntermediateData Add(const IntermediateData &intermediate1, - const IntermediateData &intermediate2) { - return IntermediateData{ - intermediate1.a + intermediate2.a, intermediate1.b + intermediate2.b, - intermediate1.c + intermediate2.c, intermediate1.d + intermediate2.d}; - } - // Processes an entire message. - static constexpr IntermediateData ProcessMessage(const char *message, - const uint32_t n) { - const uint32_t m = GetPaddedMessageLength(n); - IntermediateData intermediate0 = kInitialIntermediateData; - for (uint32_t offset = 0; offset < m; offset += 64) { - RoundData data = GetRoundData(message, n, m, offset); - IntermediateData intermediate1 = intermediate0; - for (uint32_t i = 0; i < 64; ++i) - intermediate1 = ApplyStep(i, data, intermediate1); - intermediate0 = Add(intermediate0, intermediate1); - } - return intermediate0; - } - ////////////////////////////////////////////////////////////////////////////// - // HELPER FUNCTIONS - static constexpr uint32_t StringLength(const char *string) { - const char *end = string; - while (*end != 0) ++end; - // Double check that the precision losing conversion is safe. - // DCHECK(end >= string); - // DCHECK(static_cast(static_cast(end - - // string)) == - // (end - string)); - return static_cast(end - string); - } - static constexpr uint32_t SwapEndian(uint32_t a) { - return ((a & 0xff) << 24) | (((a >> 8) & 0xff) << 16) | - (((a >> 16) & 0xff) << 8) | ((a >> 24) & 0xff); - } - ////////////////////////////////////////////////////////////////////////////// - // WRAPPER FUNCTIONS - static constexpr uint64_t Hash64(const char *data, uint32_t n) { - IntermediateData intermediate = ProcessMessage(data, n); - return (static_cast(SwapEndian(intermediate.a)) << 32) | - static_cast(SwapEndian(intermediate.b)); - } - static constexpr uint32_t Hash32(const char *data, uint32_t n) { - IntermediateData intermediate = ProcessMessage(data, n); - return SwapEndian(intermediate.a); - } -}; -// https://chromium.googlesource.com/chromium/src/base/+/refs/heads/main/hash/md5_constexpr_internal.h -constexpr uint32_t MD5Hash32Constexpr(const char *string) { - return MD5CE::Hash32(string, MD5CE::StringLength(string)); -} -constexpr uint32_t MD5Hash32Constexpr(const char *string, uint32_t length) { - return MD5CE::Hash32(string, length); -} - -} // namespace MD5 - -} // namespace struct_pack diff --git a/include/ylt/struct_pack/packer.hpp b/include/ylt/struct_pack/packer.hpp deleted file mode 100644 index 1c7fd34bb..000000000 --- a/include/ylt/struct_pack/packer.hpp +++ /dev/null @@ -1,591 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include -#include - -#include "calculate_size.hpp" -#include "endian_wrapper.hpp" -#include "reflection.hpp" -#include "ylt/struct_pack/type_id.hpp" -#include "ylt/struct_pack/util.h" -#include "ylt/struct_pack/varint.hpp" -namespace struct_pack::detail { -template < -#if __cpp_concepts >= 201907L - writer_t writer, -#else - typename writer, -#endif - typename serialize_type, bool force_optimize = false> -class packer { - constexpr inline static serialize_buffer_size useless_info{}; - - public: - packer(writer &writer_, const serialize_buffer_size &info) - : writer_(writer_), info_(info) { -#if __cpp_concepts < 201907L - static_assert(writer_t, - "The writer type must satisfy requirements!"); -#endif - } - packer(writer &writer_) : writer_(writer_), info_(useless_info) { -#if __cpp_concepts < 201907L - static_assert(writer_t, - "The writer type must satisfy requirements!"); -#endif - } - packer(const packer &) = delete; - packer &operator=(const packer &) = delete; - - template - friend struct serialize_one_derived_class_helper; - - template - void serialize_expand_compatible_helper(const T &t, std::index_sequence, - const Args &...args) { - using Type = get_args_type; - (serialize_many[I]>(t, args...), - ...); - } - - template - STRUCT_PACK_INLINE void serialize(const T &t, const Args &...args) { - serialize_metainfo(); - serialize_many(t, args...); - using Type = get_args_type; - if constexpr (serialize_static_config::has_compatible) { - constexpr std::size_t sz = compatible_version_number.size(); - return serialize_expand_compatible_helper( - t, std::make_index_sequence{}, args...); - } - } - - template - static constexpr uint32_t STRUCT_PACK_INLINE calculate_raw_hash() { - if constexpr (sizeof...(Args) == 0) { - return get_types_code>(); - } - else { - return get_types_code< - std::tuple, remove_cvref_t...>>(); - } - } - template - static constexpr uint32_t STRUCT_PACK_INLINE calculate_hash_head() { - constexpr uint32_t raw_types_code = calculate_raw_hash(); - if constexpr (check_has_metainfo()) { - return raw_types_code + 1; - } - else { // default case, only has hash_code - return raw_types_code; - } - } - template - constexpr void STRUCT_PACK_INLINE serialize_metainfo() { - constexpr auto hash_head = calculate_hash_head() | - (is_default_size_type ? 0 : 1); - if constexpr (!check_if_disable_hash_head()) { - write_wrapper(writer_, (char *)&hash_head); - } - if constexpr (hash_head % 2) { // has more metainfo - auto metainfo = info_.metainfo(); - write_wrapper(writer_, (char *)&metainfo); - if constexpr (serialize_static_config::has_compatible) { - std::size_t sz = info_.size(); - switch (metainfo & 0b11) { - case 1: - low_bytes_write_wrapper<2>(writer_, sz); - break; - case 2: - low_bytes_write_wrapper<4>(writer_, sz); - break; - case 3: - if constexpr (sizeof(std::size_t) >= 8) { - low_bytes_write_wrapper<8>(writer_, sz); - } - else { - unreachable(); - } - break; - default: - unreachable(); - } - } - if constexpr (check_if_add_type_literal()) { - constexpr auto type_literal = - struct_pack::get_type_literal(); - write_bytes_array(writer_, type_literal.data(), - type_literal.size() + 1); - } - } - } - - template - constexpr void STRUCT_PACK_INLINE serialize_many(const First &first_item, - const Args &...items) { - serialize_one(first_item); - if constexpr (sizeof...(items) > 0) { - serialize_many(items...); - } - } - constexpr void STRUCT_PACK_INLINE write_padding(std::size_t sz) { - if (sz > 0) { - constexpr char buf = 0; - for (std::size_t i = 0; i < sz; ++i) write_wrapper<1>(writer_, &buf); - } - } - - template - static constexpr void STRUCT_PACK_INLINE - get_fast_varint_width_impl(char (&vec)[sz], unsigned int &i, const Arg &item, - unsigned_t &unsigned_max, signed_t &signed_max) { - if constexpr (varint_t) { - if (get_varint_value(item) != 0) { - vec[i / 8] |= (0b1 << (i % 8)); - if constexpr (std::is_unsigned_v>) { - unsigned_max = - std::max(unsigned_max, get_varint_value(item)); - } - else { - signed_max = std::max(signed_max, - get_varint_value(item) > 0 - ? get_varint_value(item) - : -(get_varint_value(item) + 1)); - } - } - ++i; - } - } - - template - static constexpr int STRUCT_PACK_INLINE - get_fast_varint_width(char (&vec)[sz], const Args &...items) { - typename uint_t()>::type unsigned_max = 0; - typename int_t()>::type signed_max = 0; - unsigned int i = 0; - (get_fast_varint_width_impl(vec, i, items, unsigned_max, - signed_max), - ...); - return get_fast_varint_width_from_max(unsigned_max, - signed_max); - } - - template - constexpr void STRUCT_PACK_INLINE serialize_one_fast_varint(const Arg &item) { - if constexpr (varint_t) { - if (get_varint_value(item)) - low_bytes_write_wrapper<(std::min)(sz, sizeof(Arg))>( - writer_, get_varint_value(item)); - } - } - - template - constexpr void STRUCT_PACK_INLINE - serialize_fast_varint(const Args &...items) { - constexpr auto cnt = calculate_fast_varint_count(); - constexpr auto bitset_size = ((cnt + 2) + 7) / 8; - if constexpr (cnt == 0) { - return; - } - else { - char vec[bitset_size]{}; - auto width = get_fast_varint_width(vec, items...); - vec[cnt / 8] |= (width & 0b1) << (cnt % 8); - vec[(cnt + 1) / 8] |= (!!(width & 0b10)) << ((cnt + 1) % 8); - write_bytes_array(writer_, vec, bitset_size); - switch (width) { - case 0: - (serialize_one_fast_varint(items), ...); - break; - case 1: - (serialize_one_fast_varint(items), ...); - break; - case 2: - (serialize_one_fast_varint(items), ...); - break; - case 3: - if constexpr (has_64bits_varint()) { - (serialize_one_fast_varint(items), ...); - } - else { - unreachable(); - } - break; - default: - unreachable(); - } - } - } - - template - constexpr void inline serialize_one(const T &item) { - using type = remove_cvref_t; - static_assert(!std::is_pointer_v); - constexpr auto id = get_type_id(); - if constexpr (is_trivial_view_v) { - return serialize_one(item.get()); - } - else if constexpr (version == UINT64_MAX) { - if constexpr (id == type_id::compatible_t) { - // do nothing - } - else if constexpr (std::is_same_v) { - // do nothing - } - else if constexpr (id == type_id::user_defined_type) { - sp_serialize_to(writer_, item); - } - else if constexpr (detail::varint_t) { - if constexpr (is_enable_fast_varint_coding(parent_tag)) { - // do nothing - } - else { - detail::serialize_varint(writer_, item); - } - } - else if constexpr (std::is_fundamental_v || std::is_enum_v || - id == type_id::int128_t || id == type_id::uint128_t) { - write_wrapper(writer_, (char *)&item); - } - else if constexpr (id == type_id::bitset_t) { - write_bytes_array(writer_, (char *)&item, sizeof(item)); - } - else if constexpr (unique_ptr) { - bool has_value = (item != nullptr); - write_wrapper(writer_, (char *)&has_value); - if (has_value) { - if constexpr (is_base_class) { - bool is_ok{}; - uint32_t id = item->get_struct_pack_id(); - auto index = search_type_by_md5( - item->get_struct_pack_id(), is_ok); - assert(is_ok); - write_wrapper(writer_, (char *)&id); - template_switch, - std::integral_constant, - std::integral_constant>>(index, this, - item.get()); - } - else { - serialize_one(*item); - } - } - } - else if constexpr (id == type_id::array_t) { - if constexpr (is_trivial_serializable::value && - is_little_endian_copyable) { - write_bytes_array(writer_, (char *)&item, sizeof(type)); - } - else { - for (const auto &i : item) { - serialize_one(i); - } - } - } - else if constexpr (map_container || container) { - auto size = item.size(); - - if constexpr (size_type == 1) { - low_bytes_write_wrapper(writer_, size); - } - else { -#ifdef STRUCT_PACK_OPTIMIZE - constexpr bool struct_pack_optimize = true; -#else - constexpr bool struct_pack_optimize = false; -#endif - if constexpr (force_optimize || struct_pack_optimize) { - if constexpr (size_type == 2) { - low_bytes_write_wrapper(writer_, size); - } - else if constexpr (size_type == 4) { - low_bytes_write_wrapper(writer_, size); - } - else if constexpr (size_type == 8) { - if constexpr (sizeof(std::size_t) >= 8) { - low_bytes_write_wrapper(writer_, size); - } - else { - std::uint64_t sz = size; - low_bytes_write_wrapper(writer_, sz); - } - } - else { - static_assert(!sizeof(item), "illegal size_type."); - } - } - else { - switch ((info_.metainfo() & 0b11000) >> 3) { - case 1: - low_bytes_write_wrapper<2>(writer_, size); - break; - case 2: - low_bytes_write_wrapper<4>(writer_, size); - break; - case 3: - if constexpr (sizeof(std::size_t) >= 8) { - low_bytes_write_wrapper<8>(writer_, size); - } - else { - unreachable(); - } - break; - default: - unreachable(); - } - } - } - if constexpr (trivially_copyable_container && - is_little_endian_copyable) { - using value_type = typename type::value_type; - write_bytes_array(writer_, (char *)item.data(), - item.size() * sizeof(typename type::value_type)); - return; - } - else { - for (const auto &i : item) { - serialize_one(i); - } - } - } - else if constexpr (container_adapter) { - static_assert(!sizeof(type), - "the container adapter type is not supported"); - } - else if constexpr (!pair && tuple && - !is_trivial_tuple) { - std::apply( - [&](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - serialize_many(items...); - }, - item); - } - else if constexpr (optional) { - bool has_value = item.has_value(); - write_wrapper(writer_, (char *)&has_value); - if (has_value) { - serialize_one(*item); - } - } - else if constexpr (is_variant_v) { - static_assert(std::variant_size_v < 256, - "variant's size is too large"); - uint8_t index = item.index(); - write_wrapper(writer_, (char *)&index); - std::visit( - [this](auto &&e) { - this->serialize_one(e); - }, - item); - } - else if constexpr (expected) { - bool has_value = item.has_value(); - write_wrapper(writer_, (char *)&has_value); - if (has_value) { - if constexpr (!std::is_same_v) - serialize_one(item.value()); - } - else { - serialize_one(item.error()); - } - } - else if constexpr (std::is_class_v) { - if constexpr (!pair && !is_trivial_tuple) - if constexpr (!user_defined_refl) - static_assert( - std::is_aggregate_v>, - "struct_pack only support aggregated type, or you should " - "add macro STRUCT_PACK_REFL(Type,field1,field2...)"); - if constexpr (is_trivial_serializable::value && - is_little_endian_copyable) { - write_wrapper(writer_, (char *)&item); - } - else if constexpr ((is_trivial_serializable::value && - !is_little_endian_copyable) || - is_trivial_serializable::value) { - visit_members(item, [this](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - int i = 1; - ((serialize_one(items), - write_padding(align::padding_size[i++])), - ...); - }); - } - else { - constexpr uint64_t tag = get_parent_tag(); - if constexpr (is_enable_fast_varint_coding(tag)) { - visit_members( - item, [this](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - constexpr uint64_t tag = - get_parent_tag(); // to pass msvc with c++17 - serialize_fast_varint(items...); - }); - } - visit_members(item, [this](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - constexpr uint64_t tag = - get_parent_tag(); // to pass msvc with c++17 - serialize_many(items...); - }); - } - } - else { - static_assert(!sizeof(type), "the type is not supported yet"); - } - } - else if constexpr (exist_compatible_member) { - if constexpr (id == type_id::compatible_t) { - if constexpr (version == type::version_number) { - bool has_value = item.has_value(); - write_wrapper(writer_, (char *)&has_value); - if (has_value) { - serialize_one(*item); - } - } - } - else if constexpr (unique_ptr) { - if (item != nullptr) { - if constexpr (is_base_class) { - bool is_ok{}; - auto index = search_type_by_md5( - item->get_struct_pack_id(), is_ok); - assert(is_ok); - template_switch, - std::integral_constant, - std::integral_constant>>(index, this, - item.get()); - } - else { - serialize_one(*item); - } - } - } - else if constexpr (id == type_id::array_t) { - for (const auto &i : item) { - serialize_one(i); - } - } - else if constexpr (map_container || container) { - for (const auto &i : item) { - serialize_one(i); - } - } - else if constexpr (!pair && tuple && - !is_trivial_tuple) { - std::apply( - [&](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - serialize_many(items...); - }, - item); - } - else if constexpr (optional) { - if (item.has_value()) { - serialize_one(*item); - } - } - else if constexpr (is_variant_v) { - std::visit( - [this](const auto &e) { - this->serialize_one(e); - }, - item); - } - else if constexpr (expected) { - if (item.has_value()) { - if constexpr (!std::is_same_v) - serialize_one(item.value()); - } - else { - serialize_one(item.error()); - } - } - else if constexpr (std::is_class_v) { - visit_members(item, [&](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - serialize_many(items...); - }); - } - } - return; - } - - template - friend constexpr serialize_buffer_size get_needed_size(const T &t); - writer &writer_; - const serialize_buffer_size &info_; -}; - -template = 201907L - struct_pack::writer_t Writer, -#else - typename Writer, -#endif - typename... Args> -STRUCT_PACK_MAY_INLINE void serialize_to(Writer &writer, - const serialize_buffer_size &info, - const Args &...args) { -#if __cpp_concepts < 201907L - static_assert(writer_t, "The writer type must satisfy requirements!"); -#endif - static_assert(sizeof...(args) > 0); - detail::packer> o(writer, info); - if constexpr (!check_if_has_container>()) { - o.template serialize(args...); - } - else { - switch ((info.metainfo() & 0b11000) >> 3) { - case 0: - o.template serialize(args...); - break; -#ifdef STRUCT_PACK_OPTIMIZE - case 1: - o.template serialize(args...); - break; - case 2: - o.template serialize(args...); - break; - case 3: - if constexpr (sizeof(std::size_t) >= 8) { - o.template serialize(args...); - } - else { - unreachable(); - } - break; -#else - case 1: - case 2: - case 3: - o.template serialize(args...); - break; -#endif - default: - detail::unreachable(); - break; - }; - } -} -} // namespace struct_pack::detail \ No newline at end of file diff --git a/include/ylt/struct_pack/reflection.hpp b/include/ylt/struct_pack/reflection.hpp deleted file mode 100644 index e20346b6b..000000000 --- a/include/ylt/struct_pack/reflection.hpp +++ /dev/null @@ -1,2320 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if __has_include() -#include -#endif - -#include "derived_helper.hpp" -#include "foreach_macro.h" -#include "marco.h" -#include "util.h" - -#if __cpp_concepts >= 201907L -#include -#endif - -namespace struct_pack { - -enum sp_config : uint64_t { - DEFAULT = 0, - DISABLE_TYPE_INFO = 0b1, - ENABLE_TYPE_INFO = 0b10, - DISABLE_ALL_META_INFO = 0b11, - ENCODING_WITH_VARINT = 0b100, - USE_FAST_VARINT = 0b1000 -}; - -namespace detail { - -template -using get_args_type = remove_cvref_t>, - std::tuple>::type>; - -template -constexpr auto get_types(); - -template typename Op, - typename... Contexts, std::size_t... I> -constexpr void for_each_impl(std::index_sequence, Contexts &...contexts) { - using type = decltype(get_types()); - (Op, I>{}(contexts...), ...); -} - -template typename Op, - typename... Contexts> -constexpr void for_each(Contexts &...contexts) { - using type = decltype(get_types()); - for_each_impl(std::make_index_sequence>(), - contexts...); -} - -template -constexpr std::size_t members_count(); -template -constexpr std::size_t pack_align(); -template -constexpr std::size_t alignment(); -} // namespace detail - -template -constexpr std::size_t members_count = detail::members_count(); -template -constexpr std::size_t pack_alignment_v = 0; -template -constexpr std::size_t alignment_v = 0; - -#if __cpp_concepts >= 201907L - -template -concept writer_t = requires(T t) { - t.write((const char *)nullptr, std::size_t{}); -}; - -template -concept reader_t = requires(T t) { - t.read((char *)nullptr, std::size_t{}); - t.ignore(std::size_t{}); - t.tellg(); -}; - -template -concept view_reader_t = reader_t && requires(T t) { - { t.read_view(std::size_t{}) } -> std::convertible_to; -}; - -#else - -template -struct writer_t_impl : std::false_type {}; - -template -struct writer_t_impl().write( - (const char *)nullptr, std::size_t{}))>> - : std::true_type {}; - -template -constexpr bool writer_t = writer_t_impl::value; - -template -struct reader_t_impl : std::false_type {}; - -template -struct reader_t_impl< - T, std::void_t().read((char *)nullptr, - std::size_t{})), - decltype(std::declval().ignore(std::size_t{})), - decltype(std::declval().tellg())>> : std::true_type {}; - -template -constexpr bool reader_t = reader_t_impl::value; - -template -struct view_reader_t_impl : std::false_type {}; - -template -struct view_reader_t_impl< - T, std::void_t().read_view(std::size_t{}))>> - : std::true_type {}; - -template -constexpr bool view_reader_t = reader_t &&view_reader_t_impl::value; -#endif - -#if __cpp_concepts >= 201907L - -template -concept can_reserve = requires(T t) { - t.reserve(std::size_t{}); -}; - -template -concept can_shrink_to_fit = requires(T t) { - t.shrink_to_fit(); -}; - -#else - -template -struct can_reserve_impl : std::false_type {}; - -template -struct can_reserve_impl< - T, std::void_t().reserve(std::size_t{}))>> - : std::true_type {}; - -template -constexpr bool can_reserve = can_reserve_impl::value; - -template -struct can_shrink_to_fit_impl : std::false_type {}; - -template -struct can_shrink_to_fit_impl< - T, std::void_t().shrink_to_fit())>> - : std::true_type {}; - -template -constexpr bool can_shrink_to_fit = can_shrink_to_fit_impl::value; - -#endif - -template -struct compatible; - -// clang-format off -namespace detail { - -#if __cpp_concepts >= 201907L - -template -concept has_user_defined_id = requires { - typename std::integral_constant; -}; - -template -concept has_user_defined_id_ADL = requires { - typename std::integral_constant; -}; - -#else - -template -struct has_user_defined_id_impl : std::false_type {}; - -template -struct has_user_defined_id_impl< - T, std::void_t>> - : std::true_type {}; - -template -constexpr bool has_user_defined_id = has_user_defined_id_impl::value; - -template -struct constant_checker{}; - -template -struct has_user_defined_id_ADL_impl : std::false_type {}; - -#ifdef _MSC_VER -// FIXME: we can't check if it's compile-time calculated in msvc with C++17 -template -struct has_user_defined_id_ADL_impl< - T, std::void_t> - : std::true_type {}; -#else - -template -struct has_user_defined_id_ADL_impl< - T, std::void_t>> - : std::true_type {}; - -#endif - -template -constexpr bool has_user_defined_id_ADL = has_user_defined_id_ADL_impl::value; - -#endif - - - -#if __cpp_concepts >= 201907L -template -concept is_base_class = requires (T* t) { - std::is_same_vget_struct_pack_id())>; - typename struct_pack::detail::derived_class_set_t; -}; -#else -template -struct is_base_class_impl : std::false_type {}; - -template -struct is_base_class_impl< - T, std::void_t< - std::enable_ifget_struct_pack_id()), uint32_t>>, - typename struct_pack::detail::derived_class_set_t>> - : std::true_type {}; -template -constexpr bool is_base_class=is_base_class_impl::value; - -#endif - -#if __cpp_concepts >= 201907L - template - concept deserialize_view = requires(Type container) { - container.size(); - container.data(); - }; -#else - -template -struct deserialize_view_impl : std::false_type {}; -template -struct deserialize_view_impl< - T, std::void_t().size()),decltype(std::declval().data())>> - : std::true_type {}; - -template -constexpr bool deserialize_view = deserialize_view_impl::value; - -#endif - - struct memory_writer { - char *buffer; - STRUCT_PACK_INLINE void write(const char *data, std::size_t len) { - memcpy(buffer, data, len); - buffer += len; - } - }; - - -#if __cpp_concepts >= 201907L - template - concept container_adapter = requires(Type container) { - typename remove_cvref_t::value_type; - container.size(); - container.pop(); - }; -#else - template - struct container_adapter_impl : std::false_type {}; - - template - struct container_adapter_impl::value_type, - decltype(std::declval().size()), - decltype(std::declval().pop())>> - : std::true_type {}; - - template - constexpr bool container_adapter = container_adapter_impl::value; -#endif - -#if __cpp_concepts >= 201907L - template - concept container = requires(Type container) { - typename remove_cvref_t::value_type; - container.size(); - container.begin(); - container.end(); - }; -#else - template - struct container_impl : std::false_type {}; - - template - struct container_impl::value_type, - decltype(std::declval().size()), - decltype(std::declval().begin()), - decltype(std::declval().end())>> - : std::true_type {}; - - template - constexpr bool container = container_impl::value; -#endif - - template - constexpr bool is_char_t = std::is_same_v || - std::is_same_v || std::is_same_v || - std::is_same_v || std::is_same_v || - std::is_same_v -#ifdef __cpp_lib_char8_t - || std::is_same_v -#endif -; - - -#if __cpp_concepts >= 201907L - template - concept string = container && requires(Type container) { - requires is_char_t::value_type>; - container.length(); - container.data(); - }; -#else - template - struct string_impl : std::false_type {}; - - template - struct string_impl::value_type>>, - decltype(std::declval().length()), - decltype(std::declval().data())>> - : std::true_type {}; - - template - constexpr bool string = string_impl::value && container; -#endif - -#if __cpp_concepts >= 201907L - template - concept string_view = string && !requires(Type container) { - container.resize(std::size_t{}); - }; -#else - template - struct string_view_impl : std::true_type {}; - - template - struct string_view_impl().resize(std::size_t{}))>> - : std::false_type {}; - - template - constexpr bool string_view = string && string_view_impl::value; -#endif - -#if __cpp_concepts >= 201907L - template - concept span = container && requires(Type t) { - Type{(typename Type::value_type*)nullptr ,std::size_t{} }; - t.subspan(std::size_t{},std::size_t{}); - }; -#else - template - struct span_impl : std::false_type {}; - - template - struct span_impl().subspan(std::size_t{},std::size_t{}))>> - : std::true_type {}; - - template - constexpr bool span = container && span_impl::value; -#endif - - -#if __cpp_concepts >= 201907L - template - concept dynamic_span = span && Type::extent == SIZE_MAX; -#else - template - struct dynamic_span_impl : std::false_type {}; - - template - struct dynamic_span_impl>> - : std::true_type {}; - - template - constexpr bool dynamic_span = span && dynamic_span_impl::value; -#endif - template - constexpr bool static_span = span && !dynamic_span; - - -#if __cpp_lib_span >= 202002L && __cpp_concepts>=201907L - - template - concept continuous_container = - string || (container && requires(Type container) { - std::span{container}; - }); - -#else - - template - constexpr inline bool is_std_basic_string_v = false; - - template - constexpr inline bool is_std_basic_string_v> = - true; - - template - constexpr inline bool is_std_vector_v = false; - - template - constexpr inline bool is_std_vector_v> = true; - - template - constexpr bool continuous_container = - string || (container && (is_std_vector_v || is_std_basic_string_v)); -#endif - -#if __cpp_concepts >= 201907L - template - concept map_container = container && requires(Type container) { - typename remove_cvref_t::mapped_type; - }; -#else -template - struct map_container_impl : std::false_type {}; - - template - struct map_container_impl::mapped_type>> - : std::true_type {}; - - template - constexpr bool map_container = container && map_container_impl::value; -#endif - -#if __cpp_concepts >= 201907L - template - concept set_container = container && requires { - typename remove_cvref_t::key_type; - }; -#else - template - struct set_container_impl : std::false_type {}; - - template - struct set_container_impl::key_type>> - : std::true_type {}; - - template - constexpr bool set_container = container && set_container_impl::value; -#endif - -#if __cpp_concepts >= 201907L - template - concept bitset = requires (Type t){ - t.flip(); - t.set(); - t.reset(); - t.count(); - } && (Type{}.size()+7)/8 == sizeof(Type); -#else - template - struct bitset_impl : std::false_type {}; - - - template - struct bitset_impl().flip()), - decltype(std::declval().set()), - decltype(std::declval().reset()), - decltype(std::declval().count()), - decltype(std::declval().size())>> - : std::true_type {}; - - template - constexpr bool bitset_size_checker() { - if constexpr (bitset_impl::value) { - return (T{}.size()+7)/8==sizeof(T); - } - else { - return false; - } - } - - template - constexpr bool bitset = bitset_impl::value && bitset_size_checker(); -#endif - -#if __cpp_concepts >= 201907L - template - concept tuple = requires(Type tuple) { - std::get<0>(tuple); - sizeof(std::tuple_size>); - }; -#else -template - struct tuple_impl : std::false_type {}; - - template - struct tuple_impl(std::declval())), - decltype(sizeof(std::tuple_size>::value))>> - : std::true_type {}; - - template - constexpr bool tuple = tuple_impl::value; -#endif - -#if __cpp_concepts >= 201907L - template - concept user_defined_refl = std::is_same_v())),Type&>; -#else - template - struct user_defined_refl_impl : std::false_type {}; - - template - struct user_defined_refl_impl())),T&>>>> - : std::true_type {}; - - template - constexpr bool user_defined_refl = user_defined_refl_impl::value; -#endif - -#if __cpp_concepts >= 201907L - template - concept user_defined_config_by_ADL = std::is_same_v())),struct_pack::sp_config>; -#else - template - struct user_defined_config_by_ADL_impl : std::false_type {}; - - template - struct user_defined_config_by_ADL_impl())),struct_pack::sp_config>>>> - : std::true_type {}; - - template - constexpr bool user_defined_config_by_ADL = user_defined_config_by_ADL_impl::value; -#endif - -#if __cpp_concepts >= 201907L - template - concept user_defined_config = requires { - Type::struct_pack_config; - }; -#else - template - struct user_defined_config_impl : std::false_type {}; - - template - struct user_defined_config_impl> - : std::true_type {}; - - template - constexpr bool user_defined_config = user_defined_config_impl::value; -#endif - -struct memory_reader; - -#if __cpp_concepts >= 201907L - template - concept user_defined_serialization = requires (Type& t) { - sp_serialize_to(std::declval(),(const Type&)t); - {sp_deserialize_to(std::declval(),t)} -> std::same_as; - {sp_get_needed_size((const Type&)t)}->std::same_as; - }; - template - concept user_defined_type_name = requires { - { sp_set_type_name((Type*)nullptr) } -> std::same_as; - }; -#else - - template - struct user_defined_serialization_impl : std::false_type {}; - - template - struct user_defined_serialization_impl(),std::declval())), - std::enable_if(),std::declval())), struct_pack::err_code>, - std::enable_if())), std::string_view>>>>> - : std::true_type {}; - - template - constexpr bool user_defined_serialization = user_defined_serialization_impl::value; - - template - struct user_defined_type_name_impl : std::false_type {}; - - template - struct user_defined_type_name_impl>>> - : std::true_type {}; - - template - constexpr bool user_defined_type_name = user_defined_type_name_impl::value; -#endif - -#if __cpp_concepts >= 201907L - template - concept tuple_size = requires(Type tuple) { - std::tuple_size>::value; - }; -#else - template - struct tuple_size_impl : std::false_type {}; - - template - struct tuple_size_impl>::value)>> - : std::true_type {}; - - template - constexpr bool tuple_size = tuple_size_impl::value; -#endif - -#if __cpp_concepts >= 201907L - template - concept array = requires(Type arr) { - arr.size(); - std::tuple_size>{}; - }; -#else - template - struct array_impl : std::false_type {}; - - template - struct array_impl().size()), - decltype(std::tuple_size>{})>> - : std::true_type {}; - - template - constexpr bool array = array_impl::value; -#endif - - - template - constexpr bool c_array = - std::is_array_v && std::extent_v> > 0; - -#if __cpp_concepts >= 201907L - template - concept pair = requires(Type p) { - typename remove_cvref_t::first_type; - typename remove_cvref_t::second_type; - p.first; - p.second; - }; -#else - template - struct pair_impl : std::false_type {}; - - template - struct pair_impl::first_type, - typename remove_cvref_t::second_type, - decltype(std::declval().first), - decltype(std::declval().second)>> - : std::true_type {}; - - template - constexpr bool pair = pair_impl::value; -#endif - -#if __cpp_concepts >= 201907L - template - concept expected = requires(Type e) { - typename remove_cvref_t::value_type; - typename remove_cvref_t::error_type; - typename remove_cvref_t::unexpected_type; - e.has_value(); - e.error(); - requires std::is_same_v::value_type> || - requires(Type e) { - e.value(); - }; - }; -#else - template - struct expected_impl : std::false_type {}; - - template - struct expected_impl::value_type, - typename remove_cvref_t::error_type, - typename remove_cvref_t::unexpected_type, - decltype(std::declval().has_value()), - decltype(std::declval().error())>> - : std::true_type {}; - //TODO: check e.value() - template - constexpr bool expected = expected_impl::value; -#endif - -#if __cpp_concepts >= 201907L - template - concept unique_ptr = requires(Type ptr) { - ptr.operator*(); - typename remove_cvref_t::element_type; - } - &&!requires(Type ptr, Type ptr2) { ptr = ptr2; }; -#else - template - struct unique_ptr_impl : std::false_type {}; - - template - struct unique_ptr_impl::element_type, - decltype(std::declval().operator*())>> - : std::true_type {}; - - template - constexpr bool unique_ptr = unique_ptr_impl::value; -#endif - - -#if __cpp_concepts >= 201907L - template - concept optional = !expected && requires(Type optional) { - optional.value(); - optional.has_value(); - optional.operator*(); - typename remove_cvref_t::value_type; - }; -#else - template - struct optional_impl : std::false_type {}; - - template - struct optional_impl().value()), - decltype(std::declval().has_value()), - decltype(std::declval().operator*()), - typename remove_cvref_t::value_type>> - : std::true_type {}; - - template - constexpr bool optional = !expected && optional_impl::value; -#endif - - - - - - template - constexpr inline bool is_compatible_v = false; - - template - constexpr inline bool is_compatible_v> = true; - - template - constexpr inline bool is_variant_v = false; - - template - constexpr inline bool is_variant_v> = true; - - template - constexpr inline bool is_trivial_tuple = false; - - template - class varint; - - template - class sint; - - template - constexpr bool varintable_t = - std::is_same_v> || std::is_same_v> || - std::is_same_v> || std::is_same_v>; - template - constexpr bool sintable_t = - std::is_same_v> || std::is_same_v>; - - template - constexpr bool varint_t = varintable_t || sintable_t || ((parent_tag&struct_pack::ENCODING_WITH_VARINT) && (std::is_same_v || std::is_same_v || std::is_same_v || std::is_same_v)); - - template - constexpr inline bool is_trivial_view_v = false; - - template - constexpr uint64_t get_parent_tag(); - - template - struct is_trivial_serializable { - private: - template - static constexpr bool class_visit_helper(std::index_sequence) { - return (is_trivial_serializable, - ignore_compatible_field,parent_tag_>::value && - ...); - } - static constexpr bool solve() { - if constexpr (user_defined_serialization) { - return false; - } - else if constexpr (std::is_same_v) { - return true; - } - else if constexpr (std::is_abstract_v) { - return false; - } - else if constexpr (varint_t) { - return false; - } - else if constexpr (is_compatible_v || is_trivial_view_v) { - return ignore_compatible_field; - } - else if constexpr (std::is_enum_v || std::is_fundamental_v || bitset -#if (__GNUC__ || __clang__) && defined(STRUCT_PACK_ENABLE_INT128) - || std::is_same_v<__int128,T> || std::is_same_v -#endif - ) { - return true; - } - else if constexpr (array) { - return is_trivial_serializable::value; - } - else if constexpr (c_array) { - return is_trivial_serializable::type, - ignore_compatible_field>::value; - } - else if constexpr (!pair && tuple && !is_trivial_tuple) { - return false; - } - else if constexpr (user_defined_refl) { - return false; - } - else if constexpr (container || optional || is_variant_v || - unique_ptr || expected || container_adapter) { - return false; - } - else if constexpr (pair) { - return is_trivial_serializable::value && - is_trivial_serializable::value; - } - else if constexpr (is_trivial_tuple) { - return class_visit_helper(std::make_index_sequence>{}); - } - else if constexpr (std::is_class_v) { - constexpr auto tag = get_parent_tag(); - using U = decltype(get_types()); - return class_visit_helper(std::make_index_sequence>{}); - } - else - return false; - } - - public: - static inline constexpr bool value = is_trivial_serializable::solve(); - }; - -} -template ::value>> -struct trivial_view; -namespace detail { - -#if __cpp_concepts < 201907L - -template -struct trivially_copyable_container_impl : std::false_type {}; - -template -struct trivially_copyable_container_impl::value>>> - : std::true_type {}; - -template -constexpr bool trivially_copyable_container = - continuous_container && trivially_copyable_container_impl::value; - -#else - -template -constexpr bool trivially_copyable_container = - continuous_container && - requires(Type container) { - requires is_trivial_serializable::value; - }; - -#endif - - template - constexpr inline bool is_trivial_view_v> = true; - - struct UniversalVectorType { - template - operator std::vector(); - }; - - struct UniversalType { - template - operator T(); - }; - - struct UniversalIntegralType { - template >> - operator T(); - }; - - struct UniversalNullptrType { - operator std::nullptr_t(); - }; - - struct UniversalOptionalType { - template >> - operator U(); - }; - - struct UniversalCompatibleType { - template >> - operator U(); - }; - - template - struct is_constructable_impl : std::false_type {}; - template - struct is_constructable_impl, Args...> - : std::true_type {}; - - template - constexpr bool is_constructable=is_constructable_impl::value; - - template - constexpr std::size_t members_count_impl() { - if constexpr (is_constructable) { - return members_count_impl(); - } - else if constexpr (is_constructable) { - return members_count_impl(); - } - else if constexpr (is_constructable) { - return members_count_impl(); - } - else if constexpr (is_constructable) { - return members_count_impl(); - } - else if constexpr (is_constructable) { - return members_count_impl(); - } - else if constexpr (is_constructable) { - return members_count_impl(); - } - else { - return sizeof...(Args); - } - } - - template - constexpr std::size_t members_count() { - using type = remove_cvref_t; - if constexpr (user_defined_refl) { - return decltype(STRUCT_PACK_FIELD_COUNT(std::declval()))::value; - } - else if constexpr (tuple_size) { - return std::tuple_size::value; - } - else { - return members_count_impl(); - } - } - - constexpr static auto MaxVisitMembers = 64; - - template - constexpr decltype(auto) STRUCT_PACK_INLINE visit_members_by_user_defined_refl(Object &&object, - Visitor &&visitor); - - template - constexpr decltype(auto) STRUCT_PACK_INLINE visit_members_by_structure_binding(Object &&object, - Visitor &&visitor); - - template - constexpr decltype(auto) STRUCT_PACK_INLINE visit_members(Object &&object, - Visitor &&visitor) { - using type = remove_cvref_t; - if constexpr (user_defined_refl) { - return visit_members_by_user_defined_refl(object,visitor); - } - else { - return visit_members_by_structure_binding(object,visitor); - } - } - - template - constexpr decltype(auto) STRUCT_PACK_INLINE visit_members_by_user_defined_refl(Object &&object, - Visitor &&visitor) { - using type = remove_cvref_t; - constexpr auto Count = decltype(STRUCT_PACK_FIELD_COUNT(object))::value; - - static_assert(Count <= MaxVisitMembers, "exceed max visit members"); - if constexpr (Count >= 0) { - if constexpr (Count==1) { return visitor(STRUCT_PACK_GET_0(object)); - } - else if constexpr (Count==2) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object)); - } - else if constexpr (Count==3) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object)); - } - else if constexpr (Count==4) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object)); - } - else if constexpr (Count==5) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object)); - } - else if constexpr (Count==6) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object)); - } - else if constexpr (Count==7) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object)); - } - else if constexpr (Count==8) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object)); - } - else if constexpr (Count==9) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object)); - } - else if constexpr (Count==10) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object)); - } - else if constexpr (Count==11) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object)); - } - else if constexpr (Count==12) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object)); - } - else if constexpr (Count==13) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object)); - } - else if constexpr (Count==14) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object)); - } - else if constexpr (Count==15) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object)); - } - else if constexpr (Count==16) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object)); - } - else if constexpr (Count==17) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object)); - } - else if constexpr (Count==18) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object)); - } - else if constexpr (Count==19) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object)); - } - else if constexpr (Count==20) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object)); - } - else if constexpr (Count==21) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object)); - } - else if constexpr (Count==22) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object)); - } - else if constexpr (Count==23) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object)); - } - else if constexpr (Count==24) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object)); - } - else if constexpr (Count==25) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object)); - } - else if constexpr (Count==26) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object)); - } - else if constexpr (Count==27) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object)); - } - else if constexpr (Count==28) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object)); - } - else if constexpr (Count==29) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object)); - } - else if constexpr (Count==30) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object)); - } - else if constexpr (Count==31) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object)); - } - else if constexpr (Count==32) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object)); - } - else if constexpr (Count==33) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object)); - } - else if constexpr (Count==34) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object)); - } - else if constexpr (Count==35) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object)); - } - else if constexpr (Count==36) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object)); - } - else if constexpr (Count==37) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object)); - } - else if constexpr (Count==38) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object)); - } - else if constexpr (Count==39) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object)); - } - else if constexpr (Count==40) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object)); - } - else if constexpr (Count==41) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object)); - } - else if constexpr (Count==42) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object)); - } - else if constexpr (Count==43) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object)); - } - else if constexpr (Count==44) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object)); - } - else if constexpr (Count==45) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object)); - } - else if constexpr (Count==46) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object)); - } - else if constexpr (Count==47) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object)); - } - else if constexpr (Count==48) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object)); - } - else if constexpr (Count==49) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object)); - } - else if constexpr (Count==50) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object)); - } - else if constexpr (Count==51) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object)); - } - else if constexpr (Count==52) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object)); - } - else if constexpr (Count==53) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object)); - } - else if constexpr (Count==54) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object)); - } - else if constexpr (Count==55) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object)); - } - else if constexpr (Count==56) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object)); - } - else if constexpr (Count==57) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object)); - } - else if constexpr (Count==58) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object),STRUCT_PACK_GET_57(object)); - } - else if constexpr (Count==59) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object),STRUCT_PACK_GET_57(object),STRUCT_PACK_GET_58(object)); - } - else if constexpr (Count==60) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object),STRUCT_PACK_GET_57(object),STRUCT_PACK_GET_58(object),STRUCT_PACK_GET_59(object)); - } - else if constexpr (Count==61) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object),STRUCT_PACK_GET_57(object),STRUCT_PACK_GET_58(object),STRUCT_PACK_GET_59(object),STRUCT_PACK_GET_60(object)); - } - else if constexpr (Count==62) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object),STRUCT_PACK_GET_57(object),STRUCT_PACK_GET_58(object),STRUCT_PACK_GET_59(object),STRUCT_PACK_GET_60(object),STRUCT_PACK_GET_61(object)); - } - else if constexpr (Count==63) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object),STRUCT_PACK_GET_57(object),STRUCT_PACK_GET_58(object),STRUCT_PACK_GET_59(object),STRUCT_PACK_GET_60(object),STRUCT_PACK_GET_61(object),STRUCT_PACK_GET_62(object)); - } - else if constexpr (Count==64) { return visitor(STRUCT_PACK_GET_0(object),STRUCT_PACK_GET_1(object),STRUCT_PACK_GET_2(object),STRUCT_PACK_GET_3(object),STRUCT_PACK_GET_4(object),STRUCT_PACK_GET_5(object),STRUCT_PACK_GET_6(object),STRUCT_PACK_GET_7(object),STRUCT_PACK_GET_8(object),STRUCT_PACK_GET_9(object),STRUCT_PACK_GET_10(object),STRUCT_PACK_GET_11(object),STRUCT_PACK_GET_12(object),STRUCT_PACK_GET_13(object),STRUCT_PACK_GET_14(object),STRUCT_PACK_GET_15(object),STRUCT_PACK_GET_16(object),STRUCT_PACK_GET_17(object),STRUCT_PACK_GET_18(object),STRUCT_PACK_GET_19(object),STRUCT_PACK_GET_20(object),STRUCT_PACK_GET_21(object),STRUCT_PACK_GET_22(object),STRUCT_PACK_GET_23(object),STRUCT_PACK_GET_24(object),STRUCT_PACK_GET_25(object),STRUCT_PACK_GET_26(object),STRUCT_PACK_GET_27(object),STRUCT_PACK_GET_28(object),STRUCT_PACK_GET_29(object),STRUCT_PACK_GET_30(object),STRUCT_PACK_GET_31(object),STRUCT_PACK_GET_32(object),STRUCT_PACK_GET_33(object),STRUCT_PACK_GET_34(object),STRUCT_PACK_GET_35(object),STRUCT_PACK_GET_36(object),STRUCT_PACK_GET_37(object),STRUCT_PACK_GET_38(object),STRUCT_PACK_GET_39(object),STRUCT_PACK_GET_40(object),STRUCT_PACK_GET_41(object),STRUCT_PACK_GET_42(object),STRUCT_PACK_GET_43(object),STRUCT_PACK_GET_44(object),STRUCT_PACK_GET_45(object),STRUCT_PACK_GET_46(object),STRUCT_PACK_GET_47(object),STRUCT_PACK_GET_48(object),STRUCT_PACK_GET_49(object),STRUCT_PACK_GET_50(object),STRUCT_PACK_GET_51(object),STRUCT_PACK_GET_52(object),STRUCT_PACK_GET_53(object),STRUCT_PACK_GET_54(object),STRUCT_PACK_GET_55(object),STRUCT_PACK_GET_56(object),STRUCT_PACK_GET_57(object),STRUCT_PACK_GET_58(object),STRUCT_PACK_GET_59(object),STRUCT_PACK_GET_60(object),STRUCT_PACK_GET_61(object),STRUCT_PACK_GET_62(object),STRUCT_PACK_GET_63(object)); - } - } - else { - static_assert(!sizeof(type), "empty struct/class is not allowed!"); - } - } - - template - constexpr decltype(auto) STRUCT_PACK_INLINE visit_members_by_structure_binding(Object &&object, - Visitor &&visitor) { - using type = remove_cvref_t; - constexpr auto Count = struct_pack::members_count; - if constexpr (Count == 0 && std::is_class_v && - !std::is_same_v) { - static_assert(!sizeof(type), "1. If the struct is empty, which is not allowed in struct_pack type system.\n" - "2. If the strut is not empty, it means struct_pack can't calculate your struct members' count. You can use macro STRUCT_PACK_REFL(Typename, field1, field2...)."); - } - static_assert(Count <= MaxVisitMembers, "exceed max visit members"); - // If you see any structured binding error in the follow line, it - // means struct_pack can't calculate your struct's members count - // correctly. - // The best way is use macro STRUCT_PACK_REFL(Typename, field1, field2...) - // See the src/struct_pack/example/non_aggregated_type.cpp for more details. - // - // You can also to mark it manually. - // For example, there is a struct named Hello, - // and it has 3 members. - // - // You can mark it as: - // - // template <> - // constexpr size_t struct_pack::members_count = 3; - - if constexpr (Count == 0) { - return visitor(); - } - else if constexpr (Count == 1) { - auto &&[a1] = object; - return visitor(a1); - } - else if constexpr (Count == 2) { - auto &&[a1, a2] = object; - return visitor(a1, a2); - } - else if constexpr (Count == 3) { - auto &&[a1, a2, a3] = object; - return visitor(a1, a2, a3); - } - else if constexpr (Count == 4) { - auto &&[a1, a2, a3, a4] = object; - return visitor(a1, a2, a3, a4); - } - else if constexpr (Count == 5) { - auto &&[a1, a2, a3, a4, a5] = object; - return visitor(a1, a2, a3, a4, a5); - } - else if constexpr (Count == 6) { - auto &&[a1, a2, a3, a4, a5, a6] = object; - return visitor(a1, a2, a3, a4, a5, a6); - } - else if constexpr (Count == 7) { - auto &&[a1, a2, a3, a4, a5, a6, a7] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7); - } - else if constexpr (Count == 8) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8); - } - else if constexpr (Count == 9) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9); - } - else if constexpr (Count == 10) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); - } - else if constexpr (Count == 11) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); - } - else if constexpr (Count == 12) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); - } - else if constexpr (Count == 13) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); - } - else if constexpr (Count == 14) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14] = - object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14); - } - else if constexpr (Count == 15) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, - a15] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15); - } - else if constexpr (Count == 16) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16); - } - else if constexpr (Count == 17) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17); - } - else if constexpr (Count == 18) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18); - } - else if constexpr (Count == 19) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19); - } - else if constexpr (Count == 20) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20); - } - else if constexpr (Count == 21) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21); - } - else if constexpr (Count == 22) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22); - } - else if constexpr (Count == 23) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23); - } - else if constexpr (Count == 24) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24); - } - else if constexpr (Count == 25) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, - a25); - } - else if constexpr (Count == 26) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26); - } - else if constexpr (Count == 27) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27] = - object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27); - } - else if constexpr (Count == 28) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28] = - object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28); - } - else if constexpr (Count == 29) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29); - } - else if constexpr (Count == 30) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30); - } - else if constexpr (Count == 31) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31); - } - else if constexpr (Count == 32) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32); - } - else if constexpr (Count == 33) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33); - } - else if constexpr (Count == 34) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34); - } - else if constexpr (Count == 35) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35); - } - else if constexpr (Count == 36) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36); - } - else if constexpr (Count == 37) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, - a37); - } - else if constexpr (Count == 38) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38); - } - else if constexpr (Count == 39) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39); - } - else if constexpr (Count == 40) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40] = - object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40); - } - else if constexpr (Count == 41) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41] = - object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41); - } - else if constexpr (Count == 42) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42); - } - else if constexpr (Count == 43) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43); - } - else if constexpr (Count == 44) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44); - } - else if constexpr (Count == 45) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45); - } - else if constexpr (Count == 46) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46); - } - else if constexpr (Count == 47) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47); - } - else if constexpr (Count == 48) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48); - } - else if constexpr (Count == 49) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, - a49); - } - else if constexpr (Count == 50) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50); - } - else if constexpr (Count == 51) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50, a51] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50, a51); - } - else if constexpr (Count == 52) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50, a51, a52); - } - else if constexpr (Count == 53) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53] = - object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50, a51, a52, a53); - } - else if constexpr (Count == 54) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54] = - object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50, a51, a52, a53, a54); - } - else if constexpr (Count == 55) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, - a55] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50, a51, a52, a53, a54, a55); - } - else if constexpr (Count == 56) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, - a55, a56] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50, a51, a52, a53, a54, a55, a56); - } - else if constexpr (Count == 57) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, - a55, a56, a57] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50, a51, a52, a53, a54, a55, a56, a57); - } - else if constexpr (Count == 58) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, - a55, a56, a57, a58] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50, a51, a52, a53, a54, a55, a56, a57, a58); - } - else if constexpr (Count == 59) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, - a55, a56, a57, a58, a59] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50, a51, a52, a53, a54, a55, a56, a57, a58, a59); - } - else if constexpr (Count == 60) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, - a55, a56, a57, a58, a59, a60] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60); - } - else if constexpr (Count == 61) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, - a55, a56, a57, a58, a59, a60, a61] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, - a61); - } - else if constexpr (Count == 62) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, - a55, a56, a57, a58, a59, a60, a61, a62] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, a61, - a62); - } - else if constexpr (Count == 63) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, - a55, a56, a57, a58, a59, a60, a61, a62, a63] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, a61, - a62, a63); - } - else if constexpr (Count == 64) { - auto &&[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, - a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, a26, a27, a28, - a29, a30, a31, a32, a33, a34, a35, a36, a37, a38, a39, a40, a41, - a42, a43, a44, a45, a46, a47, a48, a49, a50, a51, a52, a53, a54, - a55, a56, a57, a58, a59, a60, a61, a62, a63, a64] = object; - return visitor(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, - a14, a15, a16, a17, a18, a19, a20, a21, a22, a23, a24, a25, - a26, a27, a28, a29, a30, a31, a32, a33, a34, a35, a36, a37, - a38, a39, a40, a41, a42, a43, a44, a45, a46, a47, a48, a49, - a50, a51, a52, a53, a54, a55, a56, a57, a58, a59, a60, a61, - a62, a63, a64); - } - } -// clang-format off -template -constexpr decltype(auto) STRUCT_PACK_INLINE template_switch(std::size_t index, - Args &&...args) { - switch (index) { - case 0: - return Func::template run<0>(std::forward(args)...); - case 1: - return Func::template run<1>(std::forward(args)...); - case 2: - return Func::template run<2>(std::forward(args)...); - case 3: - return Func::template run<3>(std::forward(args)...); - case 4: - return Func::template run<4>(std::forward(args)...); - case 5: - return Func::template run<5>(std::forward(args)...); - case 6: - return Func::template run<6>(std::forward(args)...); - case 7: - return Func::template run<7>(std::forward(args)...); - case 8: - return Func::template run<8>(std::forward(args)...); - case 9: - return Func::template run<9>(std::forward(args)...); - case 10: - return Func::template run<10>(std::forward(args)...); - case 11: - return Func::template run<11>(std::forward(args)...); - case 12: - return Func::template run<12>(std::forward(args)...); - case 13: - return Func::template run<13>(std::forward(args)...); - case 14: - return Func::template run<14>(std::forward(args)...); - case 15: - return Func::template run<15>(std::forward(args)...); - case 16: - return Func::template run<16>(std::forward(args)...); - case 17: - return Func::template run<17>(std::forward(args)...); - case 18: - return Func::template run<18>(std::forward(args)...); - case 19: - return Func::template run<19>(std::forward(args)...); - case 20: - return Func::template run<20>(std::forward(args)...); - case 21: - return Func::template run<21>(std::forward(args)...); - case 22: - return Func::template run<22>(std::forward(args)...); - case 23: - return Func::template run<23>(std::forward(args)...); - case 24: - return Func::template run<24>(std::forward(args)...); - case 25: - return Func::template run<25>(std::forward(args)...); - case 26: - return Func::template run<26>(std::forward(args)...); - case 27: - return Func::template run<27>(std::forward(args)...); - case 28: - return Func::template run<28>(std::forward(args)...); - case 29: - return Func::template run<29>(std::forward(args)...); - case 30: - return Func::template run<30>(std::forward(args)...); - case 31: - return Func::template run<31>(std::forward(args)...); - case 32: - return Func::template run<32>(std::forward(args)...); - case 33: - return Func::template run<33>(std::forward(args)...); - case 34: - return Func::template run<34>(std::forward(args)...); - case 35: - return Func::template run<35>(std::forward(args)...); - case 36: - return Func::template run<36>(std::forward(args)...); - case 37: - return Func::template run<37>(std::forward(args)...); - case 38: - return Func::template run<38>(std::forward(args)...); - case 39: - return Func::template run<39>(std::forward(args)...); - case 40: - return Func::template run<40>(std::forward(args)...); - case 41: - return Func::template run<41>(std::forward(args)...); - case 42: - return Func::template run<42>(std::forward(args)...); - case 43: - return Func::template run<43>(std::forward(args)...); - case 44: - return Func::template run<44>(std::forward(args)...); - case 45: - return Func::template run<45>(std::forward(args)...); - case 46: - return Func::template run<46>(std::forward(args)...); - case 47: - return Func::template run<47>(std::forward(args)...); - case 48: - return Func::template run<48>(std::forward(args)...); - case 49: - return Func::template run<49>(std::forward(args)...); - case 50: - return Func::template run<50>(std::forward(args)...); - case 51: - return Func::template run<51>(std::forward(args)...); - case 52: - return Func::template run<52>(std::forward(args)...); - case 53: - return Func::template run<53>(std::forward(args)...); - case 54: - return Func::template run<54>(std::forward(args)...); - case 55: - return Func::template run<55>(std::forward(args)...); - case 56: - return Func::template run<56>(std::forward(args)...); - case 57: - return Func::template run<57>(std::forward(args)...); - case 58: - return Func::template run<58>(std::forward(args)...); - case 59: - return Func::template run<59>(std::forward(args)...); - case 60: - return Func::template run<60>(std::forward(args)...); - case 61: - return Func::template run<61>(std::forward(args)...); - case 62: - return Func::template run<62>(std::forward(args)...); - case 63: - return Func::template run<63>(std::forward(args)...); - case 64: - return Func::template run<64>(std::forward(args)...); - case 65: - return Func::template run<65>(std::forward(args)...); - case 66: - return Func::template run<66>(std::forward(args)...); - case 67: - return Func::template run<67>(std::forward(args)...); - case 68: - return Func::template run<68>(std::forward(args)...); - case 69: - return Func::template run<69>(std::forward(args)...); - case 70: - return Func::template run<70>(std::forward(args)...); - case 71: - return Func::template run<71>(std::forward(args)...); - case 72: - return Func::template run<72>(std::forward(args)...); - case 73: - return Func::template run<73>(std::forward(args)...); - case 74: - return Func::template run<74>(std::forward(args)...); - case 75: - return Func::template run<75>(std::forward(args)...); - case 76: - return Func::template run<76>(std::forward(args)...); - case 77: - return Func::template run<77>(std::forward(args)...); - case 78: - return Func::template run<78>(std::forward(args)...); - case 79: - return Func::template run<79>(std::forward(args)...); - case 80: - return Func::template run<80>(std::forward(args)...); - case 81: - return Func::template run<81>(std::forward(args)...); - case 82: - return Func::template run<82>(std::forward(args)...); - case 83: - return Func::template run<83>(std::forward(args)...); - case 84: - return Func::template run<84>(std::forward(args)...); - case 85: - return Func::template run<85>(std::forward(args)...); - case 86: - return Func::template run<86>(std::forward(args)...); - case 87: - return Func::template run<87>(std::forward(args)...); - case 88: - return Func::template run<88>(std::forward(args)...); - case 89: - return Func::template run<89>(std::forward(args)...); - case 90: - return Func::template run<90>(std::forward(args)...); - case 91: - return Func::template run<91>(std::forward(args)...); - case 92: - return Func::template run<92>(std::forward(args)...); - case 93: - return Func::template run<93>(std::forward(args)...); - case 94: - return Func::template run<94>(std::forward(args)...); - case 95: - return Func::template run<95>(std::forward(args)...); - case 96: - return Func::template run<96>(std::forward(args)...); - case 97: - return Func::template run<97>(std::forward(args)...); - case 98: - return Func::template run<98>(std::forward(args)...); - case 99: - return Func::template run<99>(std::forward(args)...); - case 100: - return Func::template run<100>(std::forward(args)...); - case 101: - return Func::template run<101>(std::forward(args)...); - case 102: - return Func::template run<102>(std::forward(args)...); - case 103: - return Func::template run<103>(std::forward(args)...); - case 104: - return Func::template run<104>(std::forward(args)...); - case 105: - return Func::template run<105>(std::forward(args)...); - case 106: - return Func::template run<106>(std::forward(args)...); - case 107: - return Func::template run<107>(std::forward(args)...); - case 108: - return Func::template run<108>(std::forward(args)...); - case 109: - return Func::template run<109>(std::forward(args)...); - case 110: - return Func::template run<110>(std::forward(args)...); - case 111: - return Func::template run<111>(std::forward(args)...); - case 112: - return Func::template run<112>(std::forward(args)...); - case 113: - return Func::template run<113>(std::forward(args)...); - case 114: - return Func::template run<114>(std::forward(args)...); - case 115: - return Func::template run<115>(std::forward(args)...); - case 116: - return Func::template run<116>(std::forward(args)...); - case 117: - return Func::template run<117>(std::forward(args)...); - case 118: - return Func::template run<118>(std::forward(args)...); - case 119: - return Func::template run<119>(std::forward(args)...); - case 120: - return Func::template run<120>(std::forward(args)...); - case 121: - return Func::template run<121>(std::forward(args)...); - case 122: - return Func::template run<122>(std::forward(args)...); - case 123: - return Func::template run<123>(std::forward(args)...); - case 124: - return Func::template run<124>(std::forward(args)...); - case 125: - return Func::template run<125>(std::forward(args)...); - case 126: - return Func::template run<126>(std::forward(args)...); - case 127: - return Func::template run<127>(std::forward(args)...); - case 128: - return Func::template run<128>(std::forward(args)...); - case 129: - return Func::template run<129>(std::forward(args)...); - case 130: - return Func::template run<130>(std::forward(args)...); - case 131: - return Func::template run<131>(std::forward(args)...); - case 132: - return Func::template run<132>(std::forward(args)...); - case 133: - return Func::template run<133>(std::forward(args)...); - case 134: - return Func::template run<134>(std::forward(args)...); - case 135: - return Func::template run<135>(std::forward(args)...); - case 136: - return Func::template run<136>(std::forward(args)...); - case 137: - return Func::template run<137>(std::forward(args)...); - case 138: - return Func::template run<138>(std::forward(args)...); - case 139: - return Func::template run<139>(std::forward(args)...); - case 140: - return Func::template run<140>(std::forward(args)...); - case 141: - return Func::template run<141>(std::forward(args)...); - case 142: - return Func::template run<142>(std::forward(args)...); - case 143: - return Func::template run<143>(std::forward(args)...); - case 144: - return Func::template run<144>(std::forward(args)...); - case 145: - return Func::template run<145>(std::forward(args)...); - case 146: - return Func::template run<146>(std::forward(args)...); - case 147: - return Func::template run<147>(std::forward(args)...); - case 148: - return Func::template run<148>(std::forward(args)...); - case 149: - return Func::template run<149>(std::forward(args)...); - case 150: - return Func::template run<150>(std::forward(args)...); - case 151: - return Func::template run<151>(std::forward(args)...); - case 152: - return Func::template run<152>(std::forward(args)...); - case 153: - return Func::template run<153>(std::forward(args)...); - case 154: - return Func::template run<154>(std::forward(args)...); - case 155: - return Func::template run<155>(std::forward(args)...); - case 156: - return Func::template run<156>(std::forward(args)...); - case 157: - return Func::template run<157>(std::forward(args)...); - case 158: - return Func::template run<158>(std::forward(args)...); - case 159: - return Func::template run<159>(std::forward(args)...); - case 160: - return Func::template run<160>(std::forward(args)...); - case 161: - return Func::template run<161>(std::forward(args)...); - case 162: - return Func::template run<162>(std::forward(args)...); - case 163: - return Func::template run<163>(std::forward(args)...); - case 164: - return Func::template run<164>(std::forward(args)...); - case 165: - return Func::template run<165>(std::forward(args)...); - case 166: - return Func::template run<166>(std::forward(args)...); - case 167: - return Func::template run<167>(std::forward(args)...); - case 168: - return Func::template run<168>(std::forward(args)...); - case 169: - return Func::template run<169>(std::forward(args)...); - case 170: - return Func::template run<170>(std::forward(args)...); - case 171: - return Func::template run<171>(std::forward(args)...); - case 172: - return Func::template run<172>(std::forward(args)...); - case 173: - return Func::template run<173>(std::forward(args)...); - case 174: - return Func::template run<174>(std::forward(args)...); - case 175: - return Func::template run<175>(std::forward(args)...); - case 176: - return Func::template run<176>(std::forward(args)...); - case 177: - return Func::template run<177>(std::forward(args)...); - case 178: - return Func::template run<178>(std::forward(args)...); - case 179: - return Func::template run<179>(std::forward(args)...); - case 180: - return Func::template run<180>(std::forward(args)...); - case 181: - return Func::template run<181>(std::forward(args)...); - case 182: - return Func::template run<182>(std::forward(args)...); - case 183: - return Func::template run<183>(std::forward(args)...); - case 184: - return Func::template run<184>(std::forward(args)...); - case 185: - return Func::template run<185>(std::forward(args)...); - case 186: - return Func::template run<186>(std::forward(args)...); - case 187: - return Func::template run<187>(std::forward(args)...); - case 188: - return Func::template run<188>(std::forward(args)...); - case 189: - return Func::template run<189>(std::forward(args)...); - case 190: - return Func::template run<190>(std::forward(args)...); - case 191: - return Func::template run<191>(std::forward(args)...); - case 192: - return Func::template run<192>(std::forward(args)...); - case 193: - return Func::template run<193>(std::forward(args)...); - case 194: - return Func::template run<194>(std::forward(args)...); - case 195: - return Func::template run<195>(std::forward(args)...); - case 196: - return Func::template run<196>(std::forward(args)...); - case 197: - return Func::template run<197>(std::forward(args)...); - case 198: - return Func::template run<198>(std::forward(args)...); - case 199: - return Func::template run<199>(std::forward(args)...); - case 200: - return Func::template run<200>(std::forward(args)...); - case 201: - return Func::template run<201>(std::forward(args)...); - case 202: - return Func::template run<202>(std::forward(args)...); - case 203: - return Func::template run<203>(std::forward(args)...); - case 204: - return Func::template run<204>(std::forward(args)...); - case 205: - return Func::template run<205>(std::forward(args)...); - case 206: - return Func::template run<206>(std::forward(args)...); - case 207: - return Func::template run<207>(std::forward(args)...); - case 208: - return Func::template run<208>(std::forward(args)...); - case 209: - return Func::template run<209>(std::forward(args)...); - case 210: - return Func::template run<210>(std::forward(args)...); - case 211: - return Func::template run<211>(std::forward(args)...); - case 212: - return Func::template run<212>(std::forward(args)...); - case 213: - return Func::template run<213>(std::forward(args)...); - case 214: - return Func::template run<214>(std::forward(args)...); - case 215: - return Func::template run<215>(std::forward(args)...); - case 216: - return Func::template run<216>(std::forward(args)...); - case 217: - return Func::template run<217>(std::forward(args)...); - case 218: - return Func::template run<218>(std::forward(args)...); - case 219: - return Func::template run<219>(std::forward(args)...); - case 220: - return Func::template run<220>(std::forward(args)...); - case 221: - return Func::template run<221>(std::forward(args)...); - case 222: - return Func::template run<222>(std::forward(args)...); - case 223: - return Func::template run<223>(std::forward(args)...); - case 224: - return Func::template run<224>(std::forward(args)...); - case 225: - return Func::template run<225>(std::forward(args)...); - case 226: - return Func::template run<226>(std::forward(args)...); - case 227: - return Func::template run<227>(std::forward(args)...); - case 228: - return Func::template run<228>(std::forward(args)...); - case 229: - return Func::template run<229>(std::forward(args)...); - case 230: - return Func::template run<230>(std::forward(args)...); - case 231: - return Func::template run<231>(std::forward(args)...); - case 232: - return Func::template run<232>(std::forward(args)...); - case 233: - return Func::template run<233>(std::forward(args)...); - case 234: - return Func::template run<234>(std::forward(args)...); - case 235: - return Func::template run<235>(std::forward(args)...); - case 236: - return Func::template run<236>(std::forward(args)...); - case 237: - return Func::template run<237>(std::forward(args)...); - case 238: - return Func::template run<238>(std::forward(args)...); - case 239: - return Func::template run<239>(std::forward(args)...); - case 240: - return Func::template run<240>(std::forward(args)...); - case 241: - return Func::template run<241>(std::forward(args)...); - case 242: - return Func::template run<242>(std::forward(args)...); - case 243: - return Func::template run<243>(std::forward(args)...); - case 244: - return Func::template run<244>(std::forward(args)...); - case 245: - return Func::template run<245>(std::forward(args)...); - case 246: - return Func::template run<246>(std::forward(args)...); - case 247: - return Func::template run<247>(std::forward(args)...); - case 248: - return Func::template run<248>(std::forward(args)...); - case 249: - return Func::template run<249>(std::forward(args)...); - case 250: - return Func::template run<250>(std::forward(args)...); - case 251: - return Func::template run<251>(std::forward(args)...); - case 252: - return Func::template run<252>(std::forward(args)...); - case 253: - return Func::template run<253>(std::forward(args)...); - case 254: - return Func::template run<254>(std::forward(args)...); - case 255: - return Func::template run<255>(std::forward(args)...); - default: - unreachable(); - // index shouldn't bigger than 256 - } -} // namespace detail -} // namespace detail -#if __cpp_concepts >= 201907L - -template -concept checkable_reader_t = reader_t && requires(T t) { - t.check(std::size_t{}); -}; - -#else - -template -struct checkable_reader_t_impl : std::false_type {}; - -template -struct checkable_reader_t_impl< - T, std::void_t().check(std::size_t{}))>> - : std::true_type {}; - -template -constexpr bool checkable_reader_t = reader_t &&checkable_reader_t_impl::value; -#endif -} // namespace struct_pack - -// clang-format off - - -#define STRUCT_PACK_RETURN_ELEMENT(Idx, X) \ -if constexpr (Idx == I) {\ - return c.X;\ -}\ - -#define STRUCT_PACK_GET_INDEX(Idx, Type) \ -inline auto& STRUCT_PACK_GET_##Idx(Type& c) {\ - return STRUCT_PACK_GET()-1-Idx>(c);\ -}\ - -#define STRUCT_PACK_GET_INDEX_CONST(Idx, Type) \ -inline const auto& STRUCT_PACK_GET_##Idx(const Type& c) {\ - return STRUCT_PACK_GET()-1-Idx>(c);\ -}\ - -#define STRUCT_PACK_REFL(Type,...) \ -inline Type& STRUCT_PACK_REFL_FLAG(Type& t) {return t;} \ -template \ -constexpr std::size_t STRUCT_PACK_FIELD_COUNT_IMPL(); \ -template<> \ -constexpr std::size_t STRUCT_PACK_FIELD_COUNT_IMPL() {return STRUCT_PACK_ARG_COUNT(__VA_ARGS__);} \ -inline decltype(auto) STRUCT_PACK_FIELD_COUNT(const Type &){ \ - return std::integral_constant{}; \ -} \ -template auto& STRUCT_PACK_GET(Type& c) { \ - STRUCT_PACK_EXPAND_EACH(,STRUCT_PACK_RETURN_ELEMENT,__VA_ARGS__) \ - else { \ - static_assert(I < STRUCT_PACK_FIELD_COUNT_IMPL()); \ - } \ -} \ -template const auto& STRUCT_PACK_GET(const Type& c) { \ - STRUCT_PACK_EXPAND_EACH(,STRUCT_PACK_RETURN_ELEMENT,__VA_ARGS__) \ - else { \ - static_assert(I < STRUCT_PACK_FIELD_COUNT_IMPL()); \ - } \ -} \ -STRUCT_PACK_EXPAND_EACH(,STRUCT_PACK_GET_INDEX,STRUCT_PACK_MAKE_ARGS(Type,STRUCT_PACK_ARG_COUNT(__VA_ARGS__))) \ -STRUCT_PACK_EXPAND_EACH(,STRUCT_PACK_GET_INDEX_CONST,STRUCT_PACK_MAKE_ARGS(Type,STRUCT_PACK_ARG_COUNT(__VA_ARGS__))) \ - -#define STRUCT_PACK_FRIEND_DECL(Type) \ -template \ -friend auto& STRUCT_PACK_GET(Type& c); \ -template \ -friend const auto& STRUCT_PACK_GET(const Type& c); diff --git a/include/ylt/struct_pack/size_info.hpp b/include/ylt/struct_pack/size_info.hpp deleted file mode 100644 index e9884e38e..000000000 --- a/include/ylt/struct_pack/size_info.hpp +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -namespace struct_pack::detail { -struct size_info { - std::size_t total; - std::size_t size_cnt; - std::size_t max_size; - constexpr size_info &operator+=(const size_info &other) { - this->total += other.total; - this->size_cnt += other.size_cnt; - this->max_size = (std::max)(this->max_size, other.max_size); - return *this; - } - constexpr size_info operator+(const size_info &other) { - return {this->total + other.total, this->size_cnt + other.size_cnt, - (std::max)(this->max_size, other.max_size)}; - } -}; -} // namespace struct_pack::detail \ No newline at end of file diff --git a/include/ylt/struct_pack/trivial_view.hpp b/include/ylt/struct_pack/trivial_view.hpp deleted file mode 100644 index 35ff46d4c..000000000 --- a/include/ylt/struct_pack/trivial_view.hpp +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once - -#include - -#include "reflection.hpp" - -namespace struct_pack { -/*! - * \ingroup struct_pack - * \struct trivial_view - * \tparam T trivial_view指向的类型 - * \brief - * trivial_view is a view for trivial struct. It's equals T in type system. - * It can decrease memory copy in proto initialization/deserialization - * - * For example: - * - * ```cpp - * struct Data { - * int x[10000],y[10000],z[10000]; - * }; - * - * struct Proto { - * std::string name; - * Data data; - * }; - * void serialzie(std::string_view name, Data& data) { - * Proto proto={.name = name, .data = data}; - * // heavy cost in initialization. - * auto buffer = struct_pack::serialize(proto); - * auto result = struct_pack::deserialize(data); - * // memory copy in deserialization. - * assert(result->name == name && result->data == data); - * } - * ``` - * - * The solution: use view type: - * ```cpp - * struct ProtoView { - * std::string_view name; - * struct_pack::trivial_view data; - * }; - * void serialzie(std::string_view name, Data& data) { - * ProtoView proto={.name = name, .data = data}; - * // zero-copy initialization. - * auto buffer = struct_pack::serialize(proto); - * auto result = struct_pack::deserialize(data); - * // zero-copy deserialization. - * assert(result->name == name && result->data.get() == data); - * } - * ``` - * trivial_view has same layout as T. So it's legal to serialize T then - * deserialize to trivial_view - * ```cpp - * void serialzie(Proto& proto) { - * auto buffer = struct_pack::serialize(proto); - * auto result = struct_pack::deserialize(data); - * // zero-copy deserialization. - * assert(result->name == name && result->data.get() == data); - * } - * ``` - * - */ -template -struct trivial_view { - private: - const T* ref; - - public: - trivial_view(const T* t) : ref(t){}; - trivial_view(const T& t) : ref(&t){}; - trivial_view(const trivial_view&) = default; - trivial_view() : ref(nullptr){}; - trivial_view& operator=(const trivial_view&) = default; - - using value_type = T; - - void set(const T& obj) { ref = &obj; } - const T& get() const { - assert(ref != nullptr); - return *ref; - } - const T* operator->() const { - assert(ref != nullptr); - return ref; - } -}; -} // namespace struct_pack diff --git a/include/ylt/struct_pack/tuple.hpp b/include/ylt/struct_pack/tuple.hpp deleted file mode 100644 index 714240516..000000000 --- a/include/ylt/struct_pack/tuple.hpp +++ /dev/null @@ -1,629 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -// https://github.com/codeinred/tuplet/blob/main/include/tuplet/tuple.hpp -// commit id: ce4ab635c4f70b63ef9d19728bc8d76d71ae8685 -// Use of this source code is governed by a Boost Software License that can be -// found in the LICENSE file. - -#ifndef TUPLET_TUPLET_HPP_IMPLEMENTATION -#define TUPLET_TUPLET_HPP_IMPLEMENTATION - -#include -#include -#include -#include -#include - -#if (__has_cpp_attribute(no_unique_address)) -#define TUPLET_NO_UNIQUE_ADDRESS [[no_unique_address]] -#elif (__has_cpp_attribute(msvc::no_unique_address)) || \ - ((defined _MSC_VER) && (!defined __clang__)) -// Note __has_cpp_attribute(msvc::no_unique_address) itself doesn't work as -// of 19.30.30709, even though the attribute itself is supported. See -// https://github.com/llvm/llvm-project/issues/49358#issuecomment-981041089 -#define TUPLET_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] -#else -// no_unique_address is not available. -#define TUPLET_NO_UNIQUE_ADDRESS -#endif - -// tuplet concepts and traits -namespace tuplet { -template -using identity_t = T; - -// Obtains T::type -template -using type_t = typename T::type; - -template -using tag = std::integral_constant; - -template -constexpr tag tag_v{}; - -template -using tag_range = std::make_index_sequence; - -template -concept same_as = std::is_same_v && std::is_same_v; - -template -concept other_than = !std::is_same_v, U>; - -template -using base_list_t = typename std::decay_t::base_list; -template -using element_list_t = typename std::decay_t::element_list; - -template -concept base_list_tuple = requires() { - typename std::decay_t::base_list; -}; - -template -concept stateless = std::is_empty_v>; - -template -concept indexable = stateless || requires(T t) { - t[tag<0>()]; -}; - -template -constexpr decltype(auto) get(Tup&& tup); - -template -concept other_than_tuple = - !std::is_same_v, U> && (requires(U u) { get(); }); - -template -concept assignable_to = requires(U u, T t) { - t = u; -}; - -template -concept ordered = requires(T const& t) { - {t <=> t}; -}; -template -concept equality_comparable = requires(T const& t) { - { t == t } -> same_as; -}; -} // namespace tuplet - -// tuplet::type_list implementation -// tuplet::type_map implementation -// tuplet::tuple_elem implementation -// tuplet::deduce_elems -namespace tuplet { -template -struct tuple; - -template -struct type_list {}; - -template -constexpr auto operator+(type_list, type_list) { - return type_list{}; -} - -template -struct type_map : Bases... { - using base_list = type_list; - using Bases::operator[]...; - using Bases::decl_elem...; - auto operator<=>(type_map const&) const = default; - bool operator==(type_map const&) const = default; -}; - -template -struct tuple_elem { - // Like declval, but with the element - static T decl_elem(tag); - using type = T; - - TUPLET_NO_UNIQUE_ADDRESS T value; - - constexpr decltype(auto) operator[](tag) & { return (value); } - constexpr decltype(auto) operator[](tag) const& { return (value); } - constexpr decltype(auto) operator[](tag) && { - return (std::move(*this).value); - } - auto operator<=>(tuple_elem const&) const = default; - bool operator==(tuple_elem const&) const = default; - // Implements comparison for tuples containing reference types - constexpr auto operator<=>(tuple_elem const& other) const noexcept(noexcept( - value <=> other.value)) requires(std::is_reference_v&& ordered) { - return value <=> other.value; - } - constexpr bool operator==(tuple_elem const& other) const - noexcept(noexcept(value == other.value)) requires( - std::is_reference_v&& equality_comparable) { - return value == other.value; - } -}; -template -using unwrap_ref_decay_t = typename std::unwrap_ref_decay::type; -} // namespace tuplet - -// tuplet::detail::get_tuple_base implementation -// tuplet::detail::apply_impl -// tuplet::detail::size_t_from_digits -namespace tuplet::detail { -template -struct get_tuple_base; - -template -struct get_tuple_base, T...> { - using type = type_map...>; -}; - -template -constexpr decltype(auto) apply_impl(F&& f, T&& t, type_list) { - return static_cast(f)(static_cast(t).identity_t::value...); -} -template -constexpr size_t size_t_from_digits() { - static_assert((('0' <= D && D <= '9') && ...), "Must be integral literal"); - size_t num = 0; - return ((num = num * 10 + (D - '0')), ..., num); -} -template -using first_t = First; - -template -constexpr auto repeat_type(type_list) { - return type_list...>{}; -} -template -constexpr auto get_outer_bases(type_list) { - return (repeat_type(base_list_t>{}) + ...); -} -template -constexpr auto get_inner_bases(type_list) { - return (base_list_t>{} + ...); -} - -// This takes a forwarding tuple as a parameter. The forwarding tuple only -// contains references, so it should just be taken by value. -template -constexpr auto cat_impl(T tup, type_list, type_list) - -> tuple...> { - return {static_cast&&>(tup.identity_t::value) - .identity_t::value...}; -} -} // namespace tuplet::detail - -// tuplet::tuple implementation -namespace tuplet { -template -using tuple_base_t = - typename detail::get_tuple_base, T...>::type; - -template -struct tuple : tuple_base_t { - constexpr static size_t N = sizeof...(T); - using super = tuple_base_t; - using super::operator[]; - using base_list = typename super::base_list; - using element_list = type_list; - using super::decl_elem; - - template U> // Preserves default assignments - constexpr auto& operator=(U&& tup) { - using tuple2 = std::decay_t; - if constexpr (base_list_tuple) { - eq_impl(static_cast(tup), base_list(), typename tuple2::base_list()); - } - else { - eq_impl(static_cast(tup), tag_range()); - } - return *this; - } - - template ... U> - constexpr auto& assign(U&&... values) { - assign_impl(base_list(), static_cast(values)...); - return *this; - } - - auto operator<=>(tuple const&) const = default; - bool operator==(tuple const&) const = default; - - // Applies a function to every element of the tuple. The order is the - // declaration order, so first the function will be applied to element 0, - // then element 1, then element 2, and so on, where element N is identified - // by get - template - constexpr void for_each(F&& func) & { - for_each_impl(base_list(), static_cast(func)); - } - template - constexpr void for_each(F&& func) const& { - for_each_impl(base_list(), static_cast(func)); - } - template - constexpr void for_each(F&& func) && { - static_cast(*this).for_each_impl(base_list(), - static_cast(func)); - } - - // Applies a function to each element successively, until one returns a - // truthy value. Returns true if any application returned a truthy value, - // and false otherwise - template - constexpr bool any(F&& func) & { - return any_impl(base_list(), static_cast(func)); - } - template - constexpr bool any(F&& func) const& { - return any_impl(base_list(), static_cast(func)); - } - template - constexpr bool any(F&& func) && { - return static_cast(*this).any_impl(base_list(), - static_cast(func)); - } - - // Applies a function to each element successively, until one returns a - // falsy value. Returns true if every application returned a truthy value, - // and false otherwise - template - constexpr bool all(F&& func) & { - return all_impl(base_list(), static_cast(func)); - } - template - constexpr bool all(F&& func) const& { - return all_impl(base_list(), static_cast(func)); - } - template - constexpr bool all(F&& func) && { - return static_cast(*this).all_impl(base_list(), - static_cast(func)); - } - - // Map a function over every element in the tuple, using the values to - // construct a new tuple - template - constexpr auto map(F&& func) & { - return map_impl(base_list(), static_cast(func)); - } - template - constexpr auto map(F&& func) const& { - return map_impl(base_list(), static_cast(func)); - } - template - constexpr auto map(F&& func) && { - return static_cast(*this).map_impl(base_list(), - static_cast(func)); - } - - private: - template - constexpr void eq_impl(U&& u, type_list, type_list) { - // See: - // https://developercommunity.visualstudio.com/t/fold-expressions-unreliable-in-171-with-c20/1676476 - (void(B1::value = static_cast(u).B2::value), ...); - } - template - constexpr void eq_impl(U&& u, std::index_sequence) { - (void(tuple_elem::value = get(static_cast(u))), ...); - } - template - constexpr void assign_impl(type_list, U&&... u) { - (void(B::value = static_cast(u)), ...); - } - - template - constexpr void for_each_impl(type_list, F&& func) & { - (void(func(B::value)), ...); - } - template - constexpr void for_each_impl(type_list, F&& func) const& { - (void(func(B::value)), ...); - } - template - constexpr void for_each_impl(type_list, F&& func) && { - (void(func(static_cast(B::value))), ...); - } - - template - constexpr bool any_impl(type_list, F&& func) & { - return (bool(func(B::value)) || ...); - } - template - constexpr bool any_impl(type_list, F&& func) const& { - return (bool(func(B::value)) || ...); - } - template - constexpr bool any_impl(type_list, F&& func) && { - return (bool(func(static_cast(B::value))) || ...); - } - - template - constexpr bool all_impl(type_list, F&& func) & { - return (bool(func(B::value)) && ...); - } - template - constexpr bool all_impl(type_list, F&& func) const& { - return (bool(func(B::value)) && ...); - } - template - constexpr bool all_impl(type_list, F&& func) && { - return (bool(func(static_cast(B::value))) && ...); - } - - template - constexpr auto map_impl( - type_list, - F&& func) & -> tuple...> { - return {func(B::value)...}; - } - template - constexpr auto map_impl(type_list, F&& func) - const& -> tuple...> { - return {func(B::value)...}; - } - template - constexpr auto map_impl(type_list, F&& func) && -> tuple< - unwrap_ref_decay_t(B::value)))>...> { - return {func(static_cast(B::value))...}; - } -}; -template <> -struct tuple<> : tuple_base_t<> { - constexpr static size_t N = 0; - using super = tuple_base_t<>; - using base_list = type_list<>; - using element_list = type_list<>; - - template U> // Preserves default assignments - requires stateless // Check that U is similarly stateless - constexpr auto& operator=(U&&) noexcept { return *this; } - - constexpr auto& assign() noexcept { return *this; } - auto operator<=>(tuple const&) const = default; - bool operator==(tuple const&) const = default; - - // Applies a function to every element of the tuple. The order is the - // declaration order, so first the function will be applied to element 0, - // then element 1, then element 2, and so on, where element N is identified - // by get - // - // (Does nothing when invoked on empty tuple) - template - constexpr void for_each(F&&) const noexcept {} - - // Applies a function to each element successively, until one returns a - // truthy value. Returns true if any application returned a truthy value, - // and false otherwise - // - // (Returns false for empty tuple) - template - constexpr bool any(F&&) const noexcept { - return false; - } - - // Applies a function to each element successively, until one returns a - // falsy value. Returns true if every application returned a truthy value, - // and false otherwise - // - // (Returns true for empty tuple) - template - constexpr bool all(F&&) const noexcept { - return true; - } - - // Map a function over every element in the tuple, using the values to - // construct a new tuple - // - // (Returns empty tuple when invoked on empty tuple) - template - constexpr auto map(F&&) const noexcept { - return tuple{}; - } -}; -template -tuple(Ts...) -> tuple...>; -} // namespace tuplet - -// tuplet::pair implementation -namespace tuplet { -template -struct pair { - constexpr static size_t N = 2; - TUPLET_NO_UNIQUE_ADDRESS First first; - TUPLET_NO_UNIQUE_ADDRESS Second second; - - constexpr decltype(auto) operator[](tag<0>) & { return (first); } - constexpr decltype(auto) operator[](tag<0>) const& { return (first); } - constexpr decltype(auto) operator[](tag<0>) && { - return (std::move(*this).first); - } - constexpr decltype(auto) operator[](tag<1>) & { return (second); } - constexpr decltype(auto) operator[](tag<1>) const& { return (second); } - constexpr decltype(auto) operator[](tag<1>) && { - return (std::move(*this).second); - } - - template Type> // Preserves default assignments - constexpr auto& operator=(Type&& tup) { - auto&& [a, b] = static_cast(tup); - first = static_cast(a); - second = static_cast(b); - return *this; - } - - template F2, assignable_to S2> - constexpr auto& assign(F2&& f, S2&& s) { - first = static_cast(f); - second = static_cast(s); - return *this; - } - auto operator<=>(pair const&) const = default; - bool operator==(pair const&) const = default; -}; -template -pair(A, B) -> pair, unwrap_ref_decay_t>; -} // namespace tuplet - -// tuplet::convert implementation -namespace tuplet { -// Converts from one tuple type to any other tuple or U -template -struct convert { - using base_list = typename std::decay_t::base_list; - Tuple tuple; - template - constexpr operator U() && { - return convert_impl(base_list{}); - } - - private: - template - constexpr U convert_impl(type_list) { - return U{static_cast(tuple).identity_t::value...}; - } -}; -template -convert(Tuple&) -> convert; -template -convert(Tuple const&) -> convert; -template -convert(Tuple&&) -> convert; -} // namespace tuplet - -// tuplet::get implementation -// tuplet::tie implementation -// tuplet::apply implementation -namespace tuplet { -template -constexpr decltype(auto) get(Tup&& tup) { - return static_cast(tup)[tag()]; -} - -template -constexpr tuple tie(T&... t) { - return {t...}; -} - -template -constexpr decltype(auto) apply(F&& func, Tup&& tup) { - return detail::apply_impl(static_cast(func), static_cast(tup), - typename std::decay_t::base_list()); -} -template -constexpr decltype(auto) apply(F&& func, tuplet::pair& pair) { - return static_cast(func)(pair.first, pair.second); -} -template -constexpr decltype(auto) apply(F&& func, tuplet::pair const& pair) { - return static_cast(func)(pair.first, pair.second); -} -template -constexpr decltype(auto) apply(F&& func, tuplet::pair&& pair) { - return static_cast(func)(std::move(pair).first, std::move(pair).second); -} -} // namespace tuplet - -// tuplet::tuple_cat implementation -// tuplet::make_tuple implementation -// tuplet::forward_as_tuple implementation -namespace tuplet { -template -constexpr auto tuple_cat(T&&... ts) { - if constexpr (sizeof...(T) == 0) { - return tuple<>(); - } - else { -/** - * It appears that Clang produces better assembly when - * TUPLET_CAT_BY_FORWARDING_TUPLE == 0, while GCC produces better assembly when - * TUPLET_CAT_BY_FORWARDING_TUPLE == 1. MSVC always produces terrible assembly - * in either case. This will set TUPLET_CAT_BY_FORWARDING_TUPLE to the correct - * value (0 for clang, 1 for everyone else) - * - * See: https://github.com/codeinred/tuplet/discussions/14 - */ -#if !defined(TUPLET_CAT_BY_FORWARDING_TUPLE) -#if defined(__clang__) -#define TUPLET_CAT_BY_FORWARDING_TUPLE 0 -#else -#define TUPLET_CAT_BY_FORWARDING_TUPLE 1 -#endif -#endif -#if TUPLET_CAT_BY_FORWARDING_TUPLE - using big_tuple = tuple; -#else - using big_tuple = tuple...>; -#endif - using outer_bases = base_list_t; - constexpr auto outer = detail::get_outer_bases(outer_bases{}); - constexpr auto inner = detail::get_inner_bases(outer_bases{}); - return detail::cat_impl(big_tuple{static_cast(ts)...}, outer, inner); - } -} - -template -constexpr auto make_tuple(Ts&&... args) { - return tuple...>{static_cast(args)...}; -} - -template -constexpr auto forward_as_tuple(T&&... a) noexcept { - return tuple{static_cast(a)...}; -} -} // namespace tuplet - -// tuplet literals -namespace tuplet::literals { -template -constexpr auto operator""_tag() noexcept - -> tag()> { - return {}; -} -} // namespace tuplet::literals - -// std::tuple_size specialization -// std::tuple_element specialization -namespace std { -template -struct tuple_size> - : std::integral_constant {}; - -template -struct tuple_element> { - using type = decltype(tuplet::tuple::decl_elem(tuplet::tag())); -}; -template -struct tuple_size> : std::integral_constant {}; - -template -struct tuple_element> { - static_assert(I < 2, "tuplet::pair only has 2 elements"); - using type = std::conditional_t; -}; -} // namespace std - -namespace tuplet { -template -constexpr size_t tuple_size_v = std::tuple_size::value; - -template -using tuple_element_t = typename std::tuple_element::type; -} // namespace tuplet -#endif diff --git a/include/ylt/struct_pack/type_calculate.hpp b/include/ylt/struct_pack/type_calculate.hpp deleted file mode 100644 index b53a0d22c..000000000 --- a/include/ylt/struct_pack/type_calculate.hpp +++ /dev/null @@ -1,915 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include "alignment.hpp" -#include "marco.h" -#include "md5_constexpr.hpp" -#include "reflection.hpp" -#include "type_id.hpp" -namespace struct_pack { -template -STRUCT_PACK_INLINE constexpr decltype(auto) get_type_literal(); -namespace detail { -template -constexpr decltype(auto) get_size_literal() { - static_assert(sizeof(size_t) <= 8); - if constexpr (size < 1ull * 127) { - return string_literal{{static_cast(size + 129)}}; - } - else if constexpr (size < 1ull * 127 * 127) { - return string_literal{{static_cast(size % 127 + 1), - static_cast(size / 127 + 129)}}; - } - else if constexpr (size < 1ull * 127 * 127 * 127) { - return string_literal{ - {static_cast(size % 127 + 1), - static_cast(size / 127 % 127 + 1), - static_cast(size / (127 * 127) + 129)}}; - } - else if constexpr (size < 1ull * 127 * 127 * 127 * 127) { - return string_literal{ - {static_cast(size % 127 + 1), - static_cast(size / 127 % 127 + 1), - static_cast(size / (127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127) + 129)}}; - } - else if constexpr (size < 1ull * 127 * 127 * 127 * 127 * 127) { - return string_literal{ - {static_cast(size % 127 + 1), - static_cast(size / 127 % 127 + 1), - static_cast(size / (127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127 * 127) + 129)}}; - } - else if constexpr (size < 1ull * 127 * 127 * 127 * 127 * 127 * 127) { - return string_literal{ - {static_cast(size % 127 + 1), - static_cast(size / 127 % 127 + 1), - static_cast(size / (127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127 * 127 * 127) + 129)}}; - } - else if constexpr (size < 1ull * 127 * 127 * 127 * 127 * 127 * 127 * 127) { - return string_literal{ - {static_cast(size % 127 + 1), - static_cast(size / 127 % 127 + 1), - static_cast(size / (127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127 * 127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127 * 127 * 127 * 127) + 129)}}; - } - else if constexpr (size < - 1ull * 127 * 127 * 127 * 127 * 127 * 127 * 127 * 127) { - return string_literal{{ - static_cast(size % 127 + 1), - static_cast(size / 127 % 127 + 1), - static_cast(size / (127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127 * 127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127 * 127 * 127 * 127) % 127 + 1), - static_cast(size / (127 * 127 * 127 * 127 * 127 * 127 * 127) + - 129), - }}; - } - else { - static_assert( - size >= 1ull * 127 * 127 * 127 * 127 * 127 * 127 * 127 * 127 * 127, - "The size is too large."); - } -} - -template -constexpr std::size_t check_circle_impl(std::index_sequence) { - using types_tuple = std::tuple; - return (std::max)( - {(std::is_same_v, Arg> ? I + 1 - : 0)...}); -} - -template -constexpr std::size_t check_circle() { - if constexpr (sizeof...(ParentArgs) != 0) { - return check_circle_impl( - std::make_index_sequence()); - } - else { - return 0; - } -} - -template -struct get_array_element { - using type = typename T::value_type; -}; - -template -struct get_array_element { - using type = T; -}; - -template -std::size_t constexpr get_array_size() { - if constexpr (array || c_array) { - return sizeof(T) / sizeof(typename get_array_element::type); - } - else if constexpr (bitset) { - return T{}.size(); - } - else { - return T::extent; - } -} - -template -constexpr decltype(auto) get_type_end_flag() { - if constexpr (has_user_defined_id) { - return string_literal{ - {static_cast(type_id::type_end_flag_with_id)}} + - get_size_literal(); - } - else if constexpr (has_user_defined_id_ADL) { - return string_literal{ - {static_cast(type_id::type_end_flag_with_id)}} + - get_size_literal(); - } - else { - return string_literal{{static_cast(type_id::type_end_flag)}}; - } -} - -template -constexpr uint64_t get_parent_tag_impl() { - if constexpr (user_defined_config_by_ADL) { - return static_cast(set_sp_config((Arg *)nullptr)); - } - else if constexpr (user_defined_config) { - return static_cast(Arg::struct_pack_config); - } - else { - return 0; - } -} - -template -constexpr uint64_t get_parent_tag() { - if constexpr (sizeof...(Args) == 0) { - return 0; - } - else { - return get_parent_tag_impl(); - } -} - -template -constexpr decltype(auto) get_type_literal(std::index_sequence); - -template -constexpr decltype(auto) get_variant_literal(std::index_sequence); - -template -constexpr decltype(auto) get_type_literal() { - if constexpr (is_trivial_view_v) { - return get_type_literal(); - } - else if constexpr (user_defined_serialization) { - constexpr auto begin = string_literal{ - {static_cast(type_id::user_defined_type)}}; - constexpr auto end = - string_literal{{static_cast(type_id::type_end_flag)}}; - if constexpr (user_defined_type_name) { - constexpr auto type_name = sp_set_type_name((Arg *)nullptr); - string_literal ret{type_name}; - return begin + ret + end; - } - else { - constexpr auto type_name = type_string(); - string_literal ret{type_name}; - return begin + ret + end; - } - } - else { - constexpr std::size_t has_cycle = check_circle(); - if constexpr (has_cycle != 0) { - static_assert(has_cycle >= 2); - return string_literal{ - {static_cast(type_id::circle_flag)}} + - get_size_literal(); - } - else { - constexpr auto parent_tag = get_parent_tag(); - constexpr auto id = get_type_id(); - constexpr auto begin = string_literal{{static_cast(id)}}; - if constexpr (id == type_id::struct_t) { - using Args = decltype(get_types()); - constexpr auto end = get_type_end_flag(); - constexpr auto body = get_type_literal( - std::make_index_sequence>()); - if constexpr (is_trivial_serializable::value) { - static_assert( - align::pack_alignment_v <= align::alignment_v, - "If you add #pragma_pack to a struct, please specify the " - "struct_pack::pack_alignment_v."); - return begin + body + - get_size_literal>() + - get_size_literal>() + end; - } - else { - return begin + body + end; - } - } - else if constexpr (id == type_id::variant_t) { - constexpr auto sz = std::variant_size_v; - static_assert(sz > 0, "empty param of std::variant is not allowed!"); - static_assert(sz < 256, "too many alternative type in variant!"); - constexpr auto body = get_variant_literal( - std::make_index_sequence>()); - constexpr auto end = string_literal{ - {static_cast(type_id::type_end_flag)}}; - return begin + body + end; - } - else if constexpr (id == type_id::array_t) { - constexpr auto sz = get_array_size(); - static_assert(sz > 0, "The array's size must greater than zero!"); - return begin + - get_type_literal< - remove_cvref_t()[0])>, Arg, - ParentArgs...>() + - get_size_literal(); - } - else if constexpr (id == type_id::bitset_t) { - constexpr auto sz = get_array_size(); - static_assert(sz > 0, "The array's size must greater than zero!"); - return begin + get_size_literal(); - } - else if constexpr (unique_ptr) { - return begin + - get_type_literal, Arg, - ParentArgs...>(); - } - else if constexpr (id == type_id::container_t || - id == type_id::optional_t || id == type_id::string_t) { - return begin + - get_type_literal, Arg, - ParentArgs...>(); - } - else if constexpr (id == type_id::set_container_t) { - return begin + get_type_literal, - Arg, ParentArgs...>(); - } - else if constexpr (id == type_id::map_container_t) { - return begin + - get_type_literal, Arg, - ParentArgs...>() + - get_type_literal, Arg, - ParentArgs...>(); - } - else if constexpr (id == type_id::expected_t) { - return begin + - get_type_literal, Arg, - ParentArgs...>() + - get_type_literal, Arg, - ParentArgs...>(); - } - else if constexpr (id != type_id::compatible_t) { - return begin; - } - else { - return string_literal{}; - } - } - } -} - -template -constexpr decltype(auto) get_type_literal(std::index_sequence) { - return ((get_type_literal>, - ParentArgs...>()) + - ...); -} - -template -constexpr decltype(auto) get_variant_literal(std::index_sequence) { - return ((get_type_literal>, - Args, ParentArgs...>()) + - ...); -} - -template -constexpr decltype(auto) get_types_literal_impl() { - if constexpr (std::is_same_v) - return (get_type_literal() + ...); - else - return (get_type_literal() + ...); -} - -template -constexpr decltype(auto) get_types_literal() { - if constexpr (is_trivial_view_v) { - return get_types_literal(); - } - else if constexpr (user_defined_serialization) { - constexpr auto begin = string_literal{ - {static_cast(type_id::user_defined_type)}}; - constexpr auto end = - string_literal{{static_cast(type_id::type_end_flag)}}; - if constexpr (user_defined_type_name) { - constexpr auto type_name = sp_set_type_name((T *)nullptr); - string_literal ret{type_name}; - return begin + ret + end; - } - else { - constexpr auto type_name = type_string(); - string_literal ret{type_name}; - return begin + ret + end; - } - } - else { - constexpr auto root_id = get_type_id>(); - if constexpr (root_id == type_id::struct_t) { - constexpr auto end = get_type_end_flag>(); - constexpr auto begin = - string_literal{{static_cast(root_id)}}; - constexpr auto body = get_types_literal_impl(); - if constexpr (is_trivial_serializable::value) { - static_assert(align::pack_alignment_v <= align::alignment_v, - "If you add #pragma_pack to a struct, please specify the " - "struct_pack::pack_alignment_v."); - return begin + body + get_size_literal>() + - get_size_literal>() + end; - } - else { - return begin + body + end; - } - } - else { - return get_types_literal_impl(); - } - } -} - -template -constexpr decltype(auto) get_types_literal(std::index_sequence) { - return get_types_literal>...>(); -} - -template -constexpr bool check_if_compatible_element_exist_impl_helper(); - -template -constexpr bool check_if_compatible_element_exist_impl( - std::index_sequence) { - return (check_if_compatible_element_exist_impl_helper< - version, remove_cvref_t>, - ParentArgs...>() || - ...); -} - -template -constexpr bool check_if_compatible_element_exist_impl_variant( - std::index_sequence) { - return (check_if_compatible_element_exist_impl_helper< - version, remove_cvref_t>, - ParentArgs...>() || - ...); -} - -template -constexpr bool check_if_compatible_element_exist_impl_helper() { - using T = remove_cvref_t; - constexpr auto id = get_type_id(); - if constexpr (is_trivial_view_v) { - return check_if_compatible_element_exist_impl_helper< - version, typename Arg::value_type, ParentArgs...>(); - } - else if constexpr (check_circle() != 0) { - return false; - } - else if constexpr (id == type_id::compatible_t) { - if constexpr (version != UINT64_MAX) - return T::version_number == version; - else - return true; - } - else { - if constexpr (id == type_id::struct_t) { - using subArgs = decltype(get_types()); - return check_if_compatible_element_exist_impl( - std::make_index_sequence>()); - } - else if constexpr (id == type_id::optional_t) { - if constexpr (unique_ptr) { - if constexpr (is_base_class) { - return check_if_compatible_element_exist_impl< - version, derived_class_set_t, T, - ParentArgs...>(); - } - else { - return check_if_compatible_element_exist_impl_helper< - version, typename T::element_type, T, ParentArgs...>(); - } - } - else { - return check_if_compatible_element_exist_impl_helper< - version, typename T::value_type, T, ParentArgs...>(); - } - } - else if constexpr (id == type_id::array_t) { - return check_if_compatible_element_exist_impl_helper< - version, remove_cvref_t::type>, T, - ParentArgs...>(); - } - else if constexpr (id == type_id::map_container_t) { - return check_if_compatible_element_exist_impl_helper< - version, typename T::key_type, T, ParentArgs...>() || - check_if_compatible_element_exist_impl_helper< - version, typename T::mapped_type, T, ParentArgs...>(); - } - else if constexpr (id == type_id::set_container_t || - id == type_id::container_t) { - return check_if_compatible_element_exist_impl_helper< - version, typename T::value_type, T, ParentArgs...>(); - } - else if constexpr (id == type_id::expected_t) { - return check_if_compatible_element_exist_impl_helper< - version, typename T::value_type, T, ParentArgs...>() || - check_if_compatible_element_exist_impl_helper< - version, typename T::error_type, T, ParentArgs...>(); - } - else if constexpr (id == type_id::variant_t) { - return check_if_compatible_element_exist_impl_variant( - std::make_index_sequence>{}); - } - else { - return false; - } - } -} - -template -constexpr uint32_t get_types_code_impl() { - constexpr auto str = get_types_literal...>(); - return MD5::MD5Hash32Constexpr(str.data(), str.size()) & 0xFFFFFFFE; -} - -template -constexpr uint32_t get_types_code(std::index_sequence) { - return get_types_code_impl...>(); -} - -template -constexpr uint32_t get_types_code() { - using tuple_t = decltype(get_types()); - return detail::get_types_code( - std::make_index_sequence>{}); -} - -template -constexpr std::size_t calculate_compatible_version_size(); - -template -constexpr void get_compatible_version_numbers(Buffer &buffer, std::size_t &sz); - -template -constexpr auto STRUCT_PACK_INLINE get_sorted_compatible_version_numbers() { - std::array()> buffer{}; - std::size_t sz = 0; - get_compatible_version_numbers(buffer, sz); - compile_time_sort(buffer); - return buffer; -} - -template -constexpr auto STRUCT_PACK_INLINE -get_sorted_and_uniqued_compatible_version_numbers() { - constexpr auto buffer = get_sorted_compatible_version_numbers(); - std::array uniqued_buffer{}; - compile_time_unique(buffer, uniqued_buffer); - return uniqued_buffer; -} - -template -constexpr auto compatible_version_number = - get_sorted_and_uniqued_compatible_version_numbers(); - -template -constexpr bool check_if_compatible_element_exist() { - using U = remove_cvref_t; - return detail::check_if_compatible_element_exist_impl( - std::make_index_sequence>{}); -} - -template -constexpr bool exist_compatible_member = - check_if_compatible_element_exist()), version>(); -// clang-format off -template -constexpr bool unexist_compatible_member = ! -exist_compatible_member()), version>; -// clang-format on - -template -constexpr std::size_t calculate_compatible_version_size( - std::index_sequence) { - return (calculate_compatible_version_size< - remove_cvref_t>, ParentArgs...>() + - ...); -} - -template -constexpr std::size_t calculate_variant_compatible_version_size( - std::index_sequence) { - return ( - calculate_compatible_version_size< - remove_cvref_t>, ParentArgs...>() + - ...); -} - -template -constexpr std::size_t calculate_compatible_version_size() { - using T = remove_cvref_t; - constexpr auto id = get_type_id(); - std::size_t sz = 0; - if constexpr (is_trivial_view_v) { - return 0; - } - if constexpr (check_circle()) - sz = 0; - else if constexpr (id == type_id::compatible_t) { - sz = 1; - } - else { - if constexpr (id == type_id::struct_t) { - using subArgs = decltype(get_types()); - return calculate_compatible_version_size( - std::make_index_sequence>()); - } - else if constexpr (id == type_id::optional_t) { - if constexpr (unique_ptr) { - if constexpr (is_base_class) { - sz = calculate_compatible_version_size< - derived_class_set_t, T, - ParentArgs...>(); - } - else { - sz = calculate_compatible_version_size(); - } - } - else { - sz = calculate_compatible_version_size(); - } - } - else if constexpr (id == type_id::array_t) { - return calculate_compatible_version_size< - remove_cvref_t::type>, T, - ParentArgs...>(); - } - else if constexpr (id == type_id::map_container_t) { - return calculate_compatible_version_size() + - calculate_compatible_version_size(); - } - else if constexpr (id == type_id::set_container_t || - id == type_id::container_t) { - return calculate_compatible_version_size(); - } - else if constexpr (id == type_id::expected_t) { - return calculate_compatible_version_size() + - calculate_compatible_version_size(); - } - else if constexpr (id == type_id::variant_t) { - return calculate_variant_compatible_version_size( - std::make_index_sequence>{}); - } - } - return sz; -} - -template -constexpr void get_compatible_version_numbers(Buffer &buffer, std::size_t &sz, - std::index_sequence) { - return ( - get_compatible_version_numbers< - Buffer, remove_cvref_t>, ParentArgs...>( - buffer, sz), - ...); -} - -template -constexpr void get_variant_compatible_version_numbers( - Buffer &buffer, std::size_t &sz, std::index_sequence) { - return (get_compatible_version_numbers< - Buffer, remove_cvref_t>, - ParentArgs...>(buffer, sz), - ...); -} - -template -constexpr void get_compatible_version_numbers(Buffer &buffer, std::size_t &sz) { - using T = remove_cvref_t; - constexpr auto id = get_type_id(); - if constexpr (is_trivial_view_v) { - return; - } - else if constexpr (check_circle()) { - return; - } - else if constexpr (id == type_id::compatible_t) { - buffer[sz++] = T::version_number; - return; - } - else { - if constexpr (id == type_id::struct_t) { - using subArgs = decltype(get_types()); - get_compatible_version_numbers( - buffer, sz, std::make_index_sequence>()); - } - else if constexpr (id == type_id::optional_t) { - if constexpr (unique_ptr) { - if constexpr (is_base_class) { - sz = get_compatible_version_numbers< - Buffer, derived_class_set_t, T, - ParentArgs...>(buffer, sz); - } - else { - get_compatible_version_numbers(buffer, sz); - } - } - else { - get_compatible_version_numbers(buffer, sz); - } - } - else if constexpr (id == type_id::array_t) { - get_compatible_version_numbers< - Buffer, remove_cvref_t::type>, T, - ParentArgs...>(buffer, sz); - } - else if constexpr (id == type_id::map_container_t) { - get_compatible_version_numbers(buffer, sz); - get_compatible_version_numbers(buffer, sz); - } - else if constexpr (id == type_id::set_container_t || - id == type_id::container_t) { - get_compatible_version_numbers(buffer, sz); - } - else if constexpr (id == type_id::expected_t) { - get_compatible_version_numbers(buffer, sz); - get_compatible_version_numbers(buffer, sz); - } - else if constexpr (id == type_id::variant_t) { - get_variant_compatible_version_numbers( - buffer, sz, std::make_index_sequence>{}); - } - } -} - -template -struct serialize_static_config { - static constexpr bool has_compatible = exist_compatible_member; -#ifdef NDEBUG - static constexpr bool has_type_literal = false; -#else - static constexpr bool has_type_literal = true; -#endif -}; -} // namespace detail - -namespace detail { - -template -constexpr bool check_if_add_type_literal() { - constexpr auto config = conf & 0b11; - if constexpr (config == sp_config::DEFAULT) { - if constexpr (struct_pack::detail::user_defined_config_by_ADL) { - constexpr auto config = set_sp_config((T *)nullptr) & 0b11; - if constexpr (config == sp_config::DEFAULT) { - return serialize_static_config::has_type_literal; - } - else { - return config == sp_config::ENABLE_TYPE_INFO; - } - } - else if constexpr (struct_pack::detail::user_defined_config) { - constexpr auto config = T::struct_pack_config & 0b11; - if constexpr (config == sp_config::DEFAULT) { - return serialize_static_config::has_type_literal; - } - else { - return config == sp_config::ENABLE_TYPE_INFO; - } - } - else { - return serialize_static_config::has_type_literal; - } - } - else { - return config == sp_config::ENABLE_TYPE_INFO; - } -} - -template -constexpr bool check_if_has_container(); - -template -constexpr bool check_if_has_container_helper(std::index_sequence idx) { - return ((check_if_has_container>, - ParentArgs...>()) || - ...); -} - -template -constexpr bool check_if_has_container_variant_helper( - std::index_sequence idx) { - return ((check_if_has_container< - remove_cvref_t>, Arg, - ParentArgs...>()) || - ...); -} - -template -constexpr bool check_if_has_container() { - if constexpr (is_trivial_view_v) { - return check_if_has_container(); - } - else { - constexpr std::size_t has_cycle = check_circle(); - if constexpr (has_cycle != 0) { - return false; - } - else { - constexpr auto id = get_type_id(); - if constexpr (id == type_id::struct_t) { - using Args = decltype(get_types()); - return check_if_has_container_helper( - std::make_index_sequence>()); - } - else if constexpr (id == type_id::variant_t) { - constexpr auto sz = std::variant_size_v; - static_assert(sz > 0, "empty param of std::variant is not allowed!"); - static_assert(sz < 256, "too many alternative type in variant!"); - return check_if_has_container_variant_helper( - std::make_index_sequence>()); - } - else if constexpr (id == type_id::array_t) { - return check_if_has_container< - remove_cvref_t()[0])>, Arg, - ParentArgs...>(); - } - else if constexpr (id == type_id::bitset_t) { - return false; - } - else if constexpr (unique_ptr) { - if constexpr (is_base_class) { - // We can't make sure if derived class has container or not - return true; - } - else { - return check_if_has_container< - remove_cvref_t, Arg, ParentArgs...>(); - } - } - else if constexpr (id == type_id::container_t || - id == type_id::string_t || - id == type_id::set_container_t || - id == type_id::map_container_t) { - return true; - } - else if constexpr (id == type_id::optional_t || - id == type_id::compatible_t) { - return check_if_has_container, - Arg, ParentArgs...>(); - } - else if constexpr (id == type_id::expected_t) { - return check_if_has_container, - Arg, ParentArgs...>() || - check_if_has_container, - Arg, ParentArgs...>(); - } - else { - return false; - } - } - } -} - -template -constexpr bool check_if_disable_hash_head_impl() { - constexpr auto config = conf & 0b11; - if constexpr (config != sp_config::DISABLE_ALL_META_INFO) { - if constexpr (struct_pack::detail::user_defined_config_by_ADL) { - constexpr auto config = set_sp_config((T *)nullptr) & 0b11; - if constexpr (config == sp_config::DISABLE_ALL_META_INFO) { - return true; - } - } - else if constexpr (struct_pack::detail::user_defined_config) { - constexpr auto config = T::struct_pack_config & 0b11; - if constexpr (config == sp_config::DISABLE_ALL_META_INFO) { - return true; - } - } - return false; - } - return true; -} - -template -constexpr bool check_if_disable_hash_head() { - if constexpr (check_if_disable_hash_head_impl()) { - static_assert( - !check_if_compatible_element_exist())>(), - "It's not allow add compatible member when you disable hash head"); - return true; - } - else { - return false; - } -} - -template -constexpr bool check_has_metainfo() { - return serialize_static_config::has_compatible || - (!check_if_disable_hash_head() && - check_if_add_type_literal()) || - ((check_if_disable_hash_head() && - check_if_has_container())); -} - -template -constexpr auto get_types() { - using T = remove_cvref_t; - if constexpr (user_defined_serialization) { - return declval>(); - } - else if constexpr (std::is_fundamental_v || std::is_enum_v || - varint_t || string || container || optional || - unique_ptr || is_variant_v || expected || - array || c_array || - std::is_same_v || bitset -#if (__GNUC__ || __clang__) && defined(STRUCT_PACK_ENABLE_INT128) - || std::is_same_v<__int128, T> || - std::is_same_v -#endif - ) { - return declval>(); - } - else if constexpr (tuple) { - return declval(); - } - else if constexpr (is_trivial_tuple) { - return declval(); - } - else if constexpr (pair) { - return declval< - std::tuple>(); - } - else if constexpr (std::is_class_v) { - // clang-format off - return visit_members( - declval(), [](auto &&... args) constexpr { - return declval...>>(); - }); - // clang-format on - } - else { - static_assert(!sizeof(T), "the type is not supported!"); - } -} - -} // namespace detail -} // namespace struct_pack \ No newline at end of file diff --git a/include/ylt/struct_pack/type_id.hpp b/include/ylt/struct_pack/type_id.hpp deleted file mode 100644 index 4e815a8aa..000000000 --- a/include/ylt/struct_pack/type_id.hpp +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include -#include -#include - -#include "varint.hpp" -namespace struct_pack::detail { -enum class type_id { - // compatible template type - compatible_t = 0, - // fundamental integral type - int32_t = 1, - uint32_t, - int64_t, - uint64_t, - int8_t, - uint8_t, - int16_t, - uint16_t, - int128_t, // Tips: We only support 128-bit integer on gcc clang - uint128_t, - bool_t, - char_8_t, - char_16_t, - char_32_t, - w_char_t, // Note: this type is not portable!Enable it with marco - // STRUCT_PACK_ENABLE_UNPORTABLE_TYPE - // fundamental float type - float16_t, // TODO: wait for C++23 standard float type - float32_t, - float64_t, - float128_t, - vint32_t, // variable size int - vint64_t, // variable size int - vuint32_t, // variable size unsigned int - vuint64_t, // variable size unsigned int - fast_vint32_t, // variable size int with fast encoding - fast_vint64_t, // variable size int with fast encoding - fast_vuint32_t, // variable size unsigned int with fast encoding - fast_vuint64_t, // variable size unsigned int with fast encoding - // template type - string_t = 128, - array_t, - map_container_t, - set_container_t, - container_t, - optional_t, - variant_t, - expected_t, - bitset_t, - polymorphic_unique_ptr_t, - // flag for user-defined type - user_defined_type = 249, - // monostate, or void - monostate_t = 250, - // circle_flag - circle_flag = 251, - // end helper with user defined type ID - type_end_flag_with_id = 252, - // class type - struct_t = 253, - // end helper - type_end_flag = 255, -}; - -template -constexpr type_id get_varint_type() { - if constexpr (is_enable_fast_varint_coding(parent_tag)) { - if constexpr (std::is_same_v || - std::is_same_v) { - return type_id::fast_vint32_t; - } - else if constexpr (std::is_same_v || - std::is_same_v) { - return type_id::fast_vint64_t; - } - else if constexpr (std::is_same_v || - std::is_same_v) { - return type_id::fast_vuint32_t; - } - else if constexpr (std::is_same_v || - std::is_same_v) { - return type_id::fast_vuint64_t; - } - else { - static_assert(!sizeof(T), "unsupported varint type!"); - } - } - else { - if constexpr (std::is_same_v || - std::is_same_v) { - return type_id::vint32_t; - } - else if constexpr (std::is_same_v || - std::is_same_v) { - return type_id::vint64_t; - } - else if constexpr (std::is_same_v || - std::is_same_v) { - return type_id::vuint32_t; - } - else if constexpr (std::is_same_v || - std::is_same_v) { - return type_id::vuint64_t; - } - else { - static_assert(!sizeof(T), "unsupported varint type!"); - } - } -} - -template -constexpr type_id get_integral_type() { - if constexpr (std::is_same_v) { - return type_id::int32_t; - } - else if constexpr (std::is_same_v) { - return type_id::uint32_t; - } - else if constexpr (std::is_same_v || - (sizeof(long long) == 8 && std::is_same_v)) { - return type_id::int64_t; - } - else if constexpr (std::is_same_v || - (sizeof(unsigned long long) == 8 && - std::is_same_v)) { - return type_id::uint64_t; - } - else if constexpr (std::is_same_v || - std::is_same_v) { - return type_id::int8_t; - } - else if constexpr (std::is_same_v || - std::is_same_v) { - return type_id::uint8_t; - } - else if constexpr (std::is_same_v) { - return type_id::int16_t; - } - else if constexpr (std::is_same_v) { - return type_id::uint16_t; - } - // In struct_pack, the char will be saved as unsigned! - else if constexpr (std::is_same_v -#ifdef __cpp_lib_char8_t - || std::is_same_v -#endif - ) { - return type_id::char_8_t; - } -#ifdef STRUCT_PACK_ENABLE_UNPORTABLE_TYPE - else if constexpr (std::is_same_v) { - return type_id::w_char_t; - } -#endif - // char16_t's size maybe bigger than 16 bits, which is not supported. - else if constexpr (std::is_same_v) { - static_assert(sizeof(char16_t) == 2, - "sizeof(char16_t)!=2, which is not supported."); - return type_id::char_16_t; - } - // char32_t's size maybe bigger than 32bits, which is not supported. - else if constexpr (std::is_same_v && sizeof(char32_t) == 4) { - static_assert(sizeof(char32_t) == 4, - "sizeof(char32_t)!=4, which is not supported."); - return type_id::char_32_t; - } - else if constexpr (std::is_same_v && sizeof(bool)) { - static_assert(sizeof(bool) == 1, - "sizeof(bool)!=1, which is not supported."); - return type_id::bool_t; - } -#if (__GNUC__ || __clang__) && defined(STRUCT_PACK_ENABLE_INT128) - //-std=gnu++20 - else if constexpr (std::is_same_v<__int128, T>) { - return type_id::int128_t; - } - else if constexpr (std::is_same_v) { - return type_id::uint128_t; - } -#endif - else if constexpr (std::is_same_v) { - if constexpr (sizeof(long) == sizeof(int32_t)) { - return type_id::int32_t; - } - else if constexpr (sizeof(long) == sizeof(int64_t)) { - return type_id::int64_t; - } - else { - static_assert(!sizeof(T), "unsupport size of long type"); - } - } - else if constexpr (std::is_same_v) { - if constexpr (sizeof(unsigned long) == sizeof(uint32_t)) { - return type_id::uint32_t; - } - else if constexpr (sizeof(unsigned long) == sizeof(uint64_t)) { - return type_id::uint64_t; - } - else { - static_assert(!sizeof(T), "unsupport size of long type"); - } - } - else { - /* - * Due to different data model, - * the following types are not allowed on macOS - * but work on Linux - * For example, - * on macOS, `typedef unsigned long long uint64_t;` - * on Linux, `typedef unsigned long int uint64_t;` - * - * - long - * - long int - * - signed long - * - signed long int - * - unsigned long - * - unsigned long int - * - * We add this static_assert to give more information about not supported - * type. - */ - static_assert( - !std::is_same_v, - "Tips: Add macro STRUCT_PACK_ENABLE_UNPORTABLE_TYPE to support " - "wchar_t"); - static_assert(!sizeof(T), "not supported type"); - // This branch will always compiled error. - } -} - -template -constexpr type_id get_floating_point_type() { - if constexpr (std::is_same_v) { - if constexpr (!std::numeric_limits::is_iec559 || - sizeof(float) != 4) { - static_assert( - !sizeof(T), - "The float type in this machine is not standard IEEE 754 32bits " - "float point!"); - } - return type_id::float32_t; - } - else if constexpr (std::is_same_v) { - if constexpr (!std::numeric_limits::is_iec559 || - sizeof(double) != 8) { - static_assert( - !sizeof(T), - "The double type in this machine is not standard IEEE 754 64bits " - "float point!"); - } - return type_id::float64_t; - } - else if constexpr (std::is_same_v) { - if constexpr (sizeof(long double) != 16 || - std::numeric_limits::is_iec559) { - static_assert(!sizeof(T), - "The long double type in this machine is not standard IEEE " - "754 128bits " - "float point!"); - } - return type_id::float128_t; - } - else { - static_assert(!sizeof(T), "not supported type"); - } -} - -template -constexpr type_id get_type_id() { - static_assert(CHAR_BIT == 8); - // compatible member, which should be ignored in MD5 calculated. - if constexpr (user_defined_serialization) { - return type_id::user_defined_type; - } - else if constexpr (optional && is_compatible_v) { - return type_id::compatible_t; - } - else if constexpr (detail::varint_t) { - return get_varint_type(); - } - else if constexpr (std::is_enum_v) { - return get_integral_type>(); - } - else if constexpr (std::is_integral_v -#if (__GNUC__ || __clang__) && defined(STRUCT_PACK_ENABLE_INT128) - || std::is_same_v<__int128, T> || - std::is_same_v -#endif - ) { - return get_integral_type(); - } - else if constexpr (std::is_floating_point_v) { - return get_floating_point_type(); - } - else if constexpr (std::is_same_v || - std::is_same_v || std::is_abstract_v) { - return type_id::monostate_t; - } -#ifdef STRUCT_PACK_ENABLE_UNPORTABLE_TYPE - else if constexpr (bitset) { - return type_id::bitset_t; - } -#endif - else if constexpr (string) { - return type_id::string_t; - } - else if constexpr (array || c_array || static_span) { - return type_id::array_t; - } - else if constexpr (map_container) { - return type_id::map_container_t; - } - else if constexpr (set_container) { - return type_id::set_container_t; - } - else if constexpr (container) { - return type_id::container_t; - } - else if constexpr (optional) { - return type_id::optional_t; - } - else if constexpr (unique_ptr) { - if constexpr (is_base_class) { - return type_id::polymorphic_unique_ptr_t; - } - else { - return type_id::optional_t; - } - } - else if constexpr (is_variant_v) { - static_assert( - std::variant_size_v > 1 || - (std::variant_size_v == 1 && - !std::is_same_v, std::monostate>), - "The variant should contain's at least one type!"); - static_assert(std::variant_size_v < 256, "The variant is too complex!"); - return type_id::variant_t; - } - else if constexpr (expected) { - return type_id::expected_t; - } - else if constexpr (is_trivial_tuple || pair || std::is_class_v) { - return type_id::struct_t; - } - else { - static_assert(!sizeof(T), "not supported type"); - } -} -} // namespace struct_pack::detail \ No newline at end of file diff --git a/include/ylt/struct_pack/type_trait.hpp b/include/ylt/struct_pack/type_trait.hpp deleted file mode 100644 index 20946f712..000000000 --- a/include/ylt/struct_pack/type_trait.hpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include "reflection.hpp" -#include "type_calculate.hpp" - -#if __cplusplus >= 202002L -#include "tuple.hpp" -#endif - -namespace struct_pack::detail { -template -constexpr bool struct_pack_byte = - std::is_same_v || std::is_same_v || - std::is_same_v || std::is_same_v; - -template -#if __cpp_concepts < 201907L -constexpr bool -#else -concept -#endif - - struct_pack_buffer = trivially_copyable_container && - struct_pack_byte; - -#if __cplusplus >= 202002L -template -constexpr inline bool is_trivial_tuple> = true; -#endif - -template -struct MD5_reader_wrapper; - -template -constexpr bool is_MD5_reader_wrapper = false; - -template -constexpr bool is_MD5_reader_wrapper> = true; - -} // namespace struct_pack::detail \ No newline at end of file diff --git a/include/ylt/struct_pack/unpacker.hpp b/include/ylt/struct_pack/unpacker.hpp deleted file mode 100644 index 6319f6b03..000000000 --- a/include/ylt/struct_pack/unpacker.hpp +++ /dev/null @@ -1,1474 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "alignment.hpp" -#include "calculate_size.hpp" -#include "derived_helper.hpp" -#include "endian_wrapper.hpp" -#include "error_code.hpp" -#include "reflection.hpp" -#include "type_calculate.hpp" -#include "type_id.hpp" -#include "type_trait.hpp" -#include "varint.hpp" - -#define STRUCT_PACK_MAX_UNCONFIRM_PREREAD_SIZE 1 * 1024 * 1024 // 1MB - -namespace struct_pack { - -namespace detail { - -struct memory_reader { - const char *now; - const char *end; - constexpr memory_reader(const char *beg, const char *end) noexcept - : now(beg), end(end) {} - bool read(char *target, size_t len) { - if SP_UNLIKELY (end - now < len) { - return false; - } - memcpy(target, now, len); - now += len; - return true; - } - bool check(size_t len) { return end - now >= len; } - const char *read_view(size_t len) { - if SP_UNLIKELY (end - now < len) { - return nullptr; - } - auto ret = now; - now += len; - return ret; - } - bool ignore(size_t len) { - if SP_UNLIKELY (end - now < len) { - return false; - } - now += len; - return true; - } - std::size_t tellg() { return (std::size_t)now; } -}; - -#if __cpp_concepts >= 201907L -template -#else -template -#endif -class unpacker { - public: - unpacker() = delete; - unpacker(const unpacker &) = delete; - unpacker &operator=(const unpacker &) = delete; - - STRUCT_PACK_INLINE unpacker(Reader &reader) : reader_(reader) { -#if __cpp_concepts < 201907L - static_assert(reader_t, - "The writer type must satisfy requirements!"); -#endif - } - - template - friend STRUCT_PACK_INLINE struct_pack::err_code read(Reader &reader, T &t); - - template - STRUCT_PACK_MAY_INLINE struct_pack::err_code deserialize(T &t, - Args &...args) { - using Type = get_args_type; - constexpr bool has_compatible = - check_if_compatible_element_exist())>(); - if constexpr (has_compatible) { - data_len_ = reader_.tellg(); - } - auto &&[err_code, buffer_len] = deserialize_metainfo(); - if SP_UNLIKELY (err_code) { - return err_code; - } - if constexpr (has_compatible) { - data_len_ += buffer_len; - } - switch (size_type_) { - case 0: - err_code = deserialize_many<1, UINT64_MAX, true>(t, args...); - break; -#ifdef STRUCT_PACK_OPTIMIZE - case 1: - err_code = deserialize_many<2, UINT64_MAX, true>(t, args...); - break; - case 2: - err_code = deserialize_many<4, UINT64_MAX, true>(t, args...); - break; - case 3: - if constexpr (sizeof(std::size_t) >= 8) { - err_code = deserialize_many<8, UINT64_MAX, true>(t, args...); - } - else { - return struct_pack::errc::invalid_width_of_container_length; - } - break; -#else - - case 3: - if constexpr (sizeof(std::size_t) < 8) { - return struct_pack::errc::invalid_width_of_container_length; - } - case 2: - case 1: - err_code = deserialize_many<2, UINT64_MAX, true>(t, args...); - break; -#endif - default: - unreachable(); - } - if constexpr (has_compatible) { - if SP_UNLIKELY (err_code) { - return err_code; - } - constexpr std::size_t sz = compatible_version_number.size(); - err_code = deserialize_compatibles( - t, std::make_index_sequence{}, args...); - } - return err_code; - } - - template - STRUCT_PACK_MAY_INLINE struct_pack::err_code deserialize_with_len( - std::size_t &len, T &t, Args &...args) { - using Type = get_args_type; - constexpr bool has_compatible = - check_if_compatible_element_exist())>(); - if constexpr (has_compatible) { - data_len_ = reader_.tellg(); - } - auto &&[err_code, buffer_len] = deserialize_metainfo(); - len = buffer_len; - if SP_UNLIKELY (err_code) { - return err_code; - } - if constexpr (has_compatible) { - data_len_ += buffer_len; - } - switch (size_type_) { - case 0: - err_code = deserialize_many<1, UINT64_MAX, true>(t, args...); - break; -#ifdef STRUCT_PACK_OPTIMIZE - case 1: - err_code = deserialize_many<2, UINT64_MAX, true>(t, args...); - break; - case 2: - err_code = deserialize_many<4, UINT64_MAX, true>(t, args...); - break; - case 3: - if constexpr (sizeof(std::size_t) >= 8) { - err_code = deserialize_many<8, UINT64_MAX, true>(t, args...); - } - else { - return struct_pack::errc::invalid_width_of_container_length; - } - break; -#else - case 3: - if constexpr (sizeof(std::size_t) < 8) { - return struct_pack::errc::invalid_width_of_container_length; - } - case 2: - case 1: - err_code = deserialize_many<2, UINT64_MAX, true>(t, args...); - break; -#endif - default: - unreachable(); - } - if constexpr (has_compatible) { - if SP_UNLIKELY (err_code) { - return err_code; - } - constexpr std::size_t sz = compatible_version_number.size(); - err_code = deserialize_compatibles( - t, std::make_index_sequence{}, args...); - } - return err_code; - } - - template - STRUCT_PACK_MAY_INLINE struct_pack::err_code get_field( - std::tuple_element_t())> &field) { - using T = remove_cvref_t; - using Type = get_args_type; - - constexpr bool has_compatible = - check_if_compatible_element_exist())>(); - if constexpr (has_compatible) { - data_len_ = reader_.tellg(); - } - - auto &&[err_code, buffer_len] = deserialize_metainfo(); - if SP_UNLIKELY (err_code) { - return err_code; - } - if constexpr (has_compatible) { - data_len_ += buffer_len; - } - switch (size_type_) { - case 0: - err_code = get_field_impl<1, UINT64_MAX, U, I>(field); - break; -#ifdef STRUCT_PACK_OPTIMIZE - case 1: - err_code = get_field_impl<2, UINT64_MAX, U, I>(field); - break; - case 2: - err_code = get_field_impl<4, UINT64_MAX, U, I>(field); - break; - case 3: - if constexpr (sizeof(std::size_t) >= 8) { - err_code = get_field_impl<8, UINT64_MAX, U, I>(field); - } - else { - return struct_pack::errc::invalid_width_of_container_length; - } - break; -#else - case 3: - if constexpr (sizeof(std::size_t) < 8) { - return struct_pack::errc::invalid_width_of_container_length; - } - case 2: - case 1: - err_code = get_field_impl<2, UINT64_MAX, U, I>(field); - break; -#endif - default: - unreachable(); - } - if constexpr (has_compatible) { - if SP_UNLIKELY (err_code) { - return err_code; - } - constexpr std::size_t sz = compatible_version_number.size(); - err_code = deserialize_compatible_fields( - field, std::make_index_sequence{}); - } - return err_code; - } - - template - STRUCT_PACK_INLINE struct_pack::err_code deserialize_compatibles( - T &t, std::index_sequence, Args &...args) { - using Type = get_args_type; - struct_pack::err_code err_code; - switch (size_type_) { - case 0: - ([&] { - err_code = - deserialize_many<1, compatible_version_number[I], true>( - t, args...); - return err_code == errc::ok; - }() && - ...); - break; -#ifdef STRUCT_PACK_OPTIMIZE - case 1: - ([&] { - err_code = - deserialize_many<2, compatible_version_number[I], true>( - t, args...); - return err_code == errc::ok; - }() && - ...); - break; - case 2: - ([&] { - err_code = - deserialize_many<4, compatible_version_number[I], true>( - t, args...); - return err_code == errc::ok; - }() && - ...); - break; - case 3: - if constexpr (sizeof(std::size_t) >= 8) { - ([&] { - err_code = - deserialize_many<8, compatible_version_number[I], true>( - t, args...); - return err_code == errc::ok; - }() && - ...); - } - else { - return struct_pack::errc::invalid_width_of_container_length; - } - - break; -#else - case 3: - if constexpr (sizeof(std::size_t) < 8) { - return struct_pack::errc::invalid_width_of_container_length; - } - case 2: - case 1: - ([&] { - err_code = - deserialize_many<2, compatible_version_number[I], true>( - t, args...); - return err_code == errc::ok; - }() && - ...); - break; -#endif - default: - unreachable(); - } - if (size_type_ == - UCHAR_MAX) { // reuse size_type_ as a tag that the buffer miss some - // compatible field, whic is legal. - err_code = {}; - } - return err_code; - } - - template - STRUCT_PACK_INLINE struct_pack::err_code deserialize_compatible_fields( - std::tuple_element_t())> &field, - std::index_sequence) { - using T = remove_cvref_t; - using Type = get_args_type; - struct_pack::err_code err_code; - switch (size_type_) { - case 0: - ([&] { - err_code = - get_field_impl<1, compatible_version_number[Is], U, I>( - field); - return err_code == errc::ok; - }() && - ...); - break; -#ifdef STRUCT_PACK_OPTIMIZE - case 1: - ([&] { - err_code = - get_field_impl<2, compatible_version_number[Is], U, I>( - field); - return err_code == errc::ok; - }() && - ...); - break; - case 2: - ([&] { - err_code = - get_field_impl<4, compatible_version_number[Is], U, I>( - field); - return err_code == errc::ok; - }() && - ...); - break; - case 3: - if constexpr (sizeof(std::size_t) >= 8) { - ([&] { - err_code = - get_field_impl<8, compatible_version_number[Is], U, I>( - field); - return err_code == errc::ok; - }() && - ...); - } - else { - return errc::invalid_width_of_container_length; - } - break; -#else - case 3: - if constexpr (sizeof(std::size_t) < 8) { - return errc::invalid_width_of_container_length; - } - case 2: - case 1: - ([&] { - err_code = - get_field_impl<2, compatible_version_number[Is], U, I>( - field); - return err_code == errc::ok; - }() && - ...); - break; -#endif - default: - unreachable(); - } - if (size_type_ == - UCHAR_MAX) { // reuse size_type_ as a tag that the buffer miss some - // compatible field, which is legal. - err_code = {}; - } - return err_code; - } - - template - STRUCT_PACK_INLINE struct_pack::err_code get_field_impl( - std::tuple_element_t())> &field) { - using T = remove_cvref_t; - - T t; - struct_pack::err_code err_code; - if constexpr (tuple) { - err_code = std::apply( - [&](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - static_assert(I < sizeof...(items), "out of range"); - return for_each(field, items...); - }, - t); - } - else if constexpr (std::is_class_v) { - if constexpr (!user_defined_refl) - static_assert(std::is_aggregate_v>, - "struct_pack only support aggregated type, or you should " - "add macro STRUCT_PACK_REFL(Type,field1,field2...)"); - err_code = visit_members(t, [&](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - static_assert(I < sizeof...(items), "out of range"); - return for_each(field, items...); - }); - } - else { - static_assert(!sizeof(T), "illegal type"); - } - return err_code; - } - - template - struct variant_construct_helper { - template - static STRUCT_PACK_INLINE constexpr void run(unpack &unpacker, - variant_t &v) { - if constexpr (index >= std::variant_size_v) { - unreachable(); - return; - } - else { - v = variant_t{std::in_place_index_t{}}; - unpacker.template deserialize_one(std::get(v)); - } - } - }; - - STRUCT_PACK_INLINE std::pair - deserialize_compatible(unsigned compatible_sz_len) { - constexpr std::size_t sz[] = {0, 2, 4, 8}; - auto len_sz = sz[compatible_sz_len]; - std::size_t data_len = 0; - bool result; - switch (compatible_sz_len) { - case 1: - if SP_LIKELY (low_bytes_read_wrapper<2>(reader_, data_len)) { - return {errc{}, data_len}; - } - break; - case 2: - if SP_LIKELY (low_bytes_read_wrapper<4>(reader_, data_len)) { - return {errc{}, data_len}; - } - break; - case 3: - if constexpr (sizeof(std::size_t) >= 8) { - if SP_LIKELY (low_bytes_read_wrapper<8>(reader_, data_len)) { - return {errc{}, data_len}; - } - } - else { - return {errc::invalid_width_of_container_length, 0}; - } - break; - default: - unreachable(); - } - return {errc::no_buffer_space, 0}; - } - - template - STRUCT_PACK_INLINE struct_pack::err_code deserialize_type_literal() { - constexpr auto literal = struct_pack::get_type_literal(); - if constexpr (view_reader_t) { - const char *buffer = reader_.read_view(literal.size() + 1); - if SP_UNLIKELY (!buffer) { - return errc::no_buffer_space; - } - if SP_UNLIKELY (memcmp(buffer, literal.data(), literal.size() + 1)) { - return errc::hash_conflict; - } - } - else { - char buffer[literal.size() + 1]; - if SP_UNLIKELY (!read_bytes_array(reader_, buffer, literal.size() + 1)) { - return errc::no_buffer_space; - } - if SP_UNLIKELY (memcmp(buffer, literal.data(), literal.size() + 1)) { - return errc::hash_conflict; - } - } - - return errc{}; - } - - template - STRUCT_PACK_INLINE std::pair - deserialize_metainfo() { - uint32_t current_types_code; - if constexpr (check_if_disable_hash_head()) { - if constexpr (is_MD5_reader_wrapper) { - static_assert(!sizeof(T), - "it's illegal if you want to deserialize a derived class " - "without md5"); - } - else if constexpr (check_if_has_container()) { - unsigned char metainfo; - if SP_UNLIKELY (!read_wrapper( - reader_, (char *)&metainfo)) { - return {struct_pack::errc::no_buffer_space, 0}; - } - size_type_ = (metainfo & 0b11000) >> 3; - return {}; - } - else { - size_type_ = 0; - return {}; - } - } - else { - if constexpr (is_MD5_reader_wrapper) { - reader_.read_head((char *)¤t_types_code); - if SP_LIKELY (current_types_code % 2 == 0) // unexist metainfo - { - size_type_ = 0; - return {}; - } - } - else { - if SP_UNLIKELY (!read_wrapper( - reader_, (char *)¤t_types_code)) { - return {struct_pack::errc::no_buffer_space, 0}; - } - constexpr uint32_t types_code = get_types_code(); - if SP_UNLIKELY ((current_types_code / 2) != (types_code / 2)) { - return {struct_pack::errc::invalid_buffer, 0}; - } - if SP_LIKELY (current_types_code % 2 == 0) // unexist metainfo - { - size_type_ = 0; - return {}; - } - } - unsigned char metainfo; - if SP_UNLIKELY (!read_wrapper(reader_, - (char *)&metainfo)) { - return {struct_pack::errc::no_buffer_space, 0}; - } - std::pair ret; - auto compatible_sz_len = metainfo & 0b11; - if (compatible_sz_len) { - ret = deserialize_compatible(compatible_sz_len); - if SP_UNLIKELY (ret.first) { - return ret; - } - } - auto has_type_literal = metainfo & 0b100; - if (has_type_literal) { - auto ec = deserialize_type_literal(); - if SP_UNLIKELY (ec) { - return {ec, 0}; - } - } - size_type_ = (metainfo & 0b11000) >> 3; - return ret; - } - } - - template - constexpr struct_pack::err_code STRUCT_PACK_INLINE deserialize_many() { - return {}; - } - template - constexpr struct_pack::err_code STRUCT_PACK_INLINE - deserialize_many(First &&first_item, Args &&...items) { - auto code = - deserialize_one(first_item); - if SP_UNLIKELY (code) { - return code; - } - if constexpr (sizeof...(items) > 0) { - return deserialize_many( - items...); - } - else { - return code; - } - } - - constexpr struct_pack::err_code STRUCT_PACK_INLINE - ignore_padding(std::size_t sz) { - if (sz > 0) { - return reader_.ignore(sz) ? errc{} : errc::no_buffer_space; - } - else { - return errc{}; - } - } - - template - constexpr struct_pack::err_code STRUCT_PACK_INLINE - deserialize_one_fast_varint(char (&vec)[bitset_width], unsigned int &i, - Arg &item) { - if constexpr (varint_t) { - constexpr auto real_width = (std::min)(width, sizeof(Arg)); - auto index = i++; - if (!(vec[index / 8] & (0b1 << (index % 8)))) - return {}; - if constexpr (!no_skip) { - return reader_.ignore(real_width) ? errc{} : errc::no_buffer_space; - } - else { - bool ec{}; - if constexpr (std::is_unsigned_v>) { - get_varint_value(item) = 0; - bool ec = low_bytes_read_wrapper(reader_, - get_varint_value(item)); - if SP_UNLIKELY (!ec) { - return errc::no_buffer_space; - } - } - else { - typename int_t::type target; - ec = read_wrapper(reader_, (char *)&target); - if SP_UNLIKELY (!ec) { - return errc::no_buffer_space; - } - item = target; - } - return {}; - } - } - else { - return {}; - } - } - template - constexpr struct_pack::err_code STRUCT_PACK_INLINE - deserialize_fast_varint_helper(char (&vec)[bitset_width], unsigned int &i, - Arg &item, Args &...items) { - auto ec = - deserialize_one_fast_varint(vec, i, item); - if constexpr (sizeof...(items) > 0) { - if SP_UNLIKELY (ec) { - return ec; - } - else { - return deserialize_fast_varint_helper( - vec, i, items...); - } - } - else { - return ec; - } - } - - template - constexpr struct_pack::err_code STRUCT_PACK_INLINE - deserialize_fast_varint(Args &...items) { - constexpr auto cnt = calculate_fast_varint_count(); - constexpr auto bitset_size = ((cnt + 2) + 7) / 8; - if constexpr (cnt == 0) { - static_assert(cnt != 0, "ilegal branch"); - return {}; - } - else { - char vec[bitset_size]; - if (auto ec = read_bytes_array(reader_, vec, bitset_size); !ec) { - return errc::no_buffer_space; - } - int width = !!(vec[cnt / 8] & (0b1 << (cnt % 8))) + - !!(vec[(cnt + 1) / 8] & (0b1 << ((cnt + 1) % 8))) * 2; - unsigned int i = 0; - struct_pack::err_code ec{}; - switch (width) { - case 0: - ec = deserialize_fast_varint_helper(vec, i, - items...); - break; - case 1: - ec = deserialize_fast_varint_helper(vec, i, - items...); - break; - case 2: - ec = deserialize_fast_varint_helper(vec, i, - items...); - break; - case 3: - if constexpr (has_64bits_varint()) { - ec = deserialize_fast_varint_helper( - vec, i, items...); - } - else { - return struct_pack::errc::invalid_buffer; - } - break; - default: - unreachable(); - } - return ec; - } - } - - template - constexpr struct_pack::err_code inline deserialize_one(T &item) { - struct_pack::err_code code{}; - using type = remove_cvref_t; - static_assert(!std::is_pointer_v); - constexpr auto id = get_type_id(); - if constexpr (is_trivial_view_v) { - static_assert(view_reader_t, - "The Reader isn't a view_reader, can't deserialize " - "a trivial_view"); - static_assert( - is_little_endian_copyable, - "get a trivial view with byte width > 1 in big-endian system is " - "not allowed."); - const char *view = reader_.read_view(sizeof(typename T::value_type)); - if SP_LIKELY (view != nullptr) { - item = *reinterpret_cast(view); - code = errc::ok; - } - else { - code = errc::no_buffer_space; - } - } - else if constexpr (version == UINT64_MAX) { - if constexpr (id == type_id::compatible_t) { - // do nothing - } - else if constexpr (std::is_same_v) { - // do nothing - } - else if constexpr (id == type_id::user_defined_type) { - if constexpr (NotSkip) { - code = sp_deserialize_to(reader_, item); - } - else { - code = sp_deserialize_to_with_skip(reader_, item); - } - } - else if constexpr (detail::varint_t) { - if constexpr (is_enable_fast_varint_coding(parent_tag)) { - // do nothing, we have deserialized it in parent. - } - else { - code = detail::deserialize_varint(reader_, item); - } - } - else if constexpr (std::is_fundamental_v || std::is_enum_v || - id == type_id::int128_t || id == type_id::uint128_t) { - if constexpr (NotSkip) { - if SP_UNLIKELY (!read_wrapper(reader_, (char *)&item)) { - return struct_pack::errc::no_buffer_space; - } - } - else { - return reader_.ignore(sizeof(type)) ? errc{} : errc::no_buffer_space; - } - } - else if constexpr (id == type_id::bitset_t) { - if constexpr (NotSkip) { - if SP_UNLIKELY (!read_bytes_array(reader_, (char *)&item, - sizeof(type))) { - return struct_pack::errc::no_buffer_space; - } - } - else { - return reader_.ignore(sizeof(type)) ? errc{} : errc::no_buffer_space; - } - } - else if constexpr (unique_ptr) { - bool has_value{}; - if SP_UNLIKELY (!read_wrapper(reader_, - (char *)&has_value)) { - return struct_pack::errc::no_buffer_space; - } - if (!has_value) { - return {}; - } - if constexpr (is_base_class) { - uint32_t id{}; - read_wrapper(reader_, (char *)&id); - bool ok{}; - auto index = search_type_by_md5(id, ok); - if SP_UNLIKELY (!ok) { - return errc::invalid_buffer; - } - else { - return template_switch, - std::integral_constant, - std::integral_constant, - std::integral_constant>>(index, this, - item); - } - } - else { - item = std::make_unique(); - deserialize_one(*item); - } - } - else if constexpr (id == type_id::array_t) { - if constexpr (is_trivial_serializable::value && - is_little_endian_copyable) { - if constexpr (NotSkip) { - if SP_UNLIKELY (!read_bytes_array(reader_, (char *)&item, - sizeof(item))) { - return struct_pack::errc::no_buffer_space; - } - } - else { - return reader_.ignore(sizeof(type)) ? errc{} - : errc::no_buffer_space; - } - } - else { - for (auto &i : item) { - code = deserialize_one(i); - if SP_UNLIKELY (code) { - return code; - } - } - } - } - else if constexpr (container) { - std::size_t size = 0; - bool result{}; - if constexpr (size_type == 1) { - if SP_UNLIKELY (!low_bytes_read_wrapper(reader_, size)) { - return struct_pack::errc::no_buffer_space; - } - } - else { -#ifdef STRUCT_PACK_OPTIMIZE - constexpr bool struct_pack_optimize = true; -#else - constexpr bool struct_pack_optimize = false; -#endif - if constexpr (force_optimize || struct_pack_optimize) { - if constexpr (size_type == 2) { - if SP_UNLIKELY (!low_bytes_read_wrapper(reader_, - size)) { - return struct_pack::errc::no_buffer_space; - } - } - else if constexpr (size_type == 4) { - if SP_UNLIKELY (!low_bytes_read_wrapper(reader_, - size)) { - return struct_pack::errc::no_buffer_space; - } - } - else if constexpr (size_type == 8) { - if constexpr (sizeof(std::size_t) >= 8) { - if SP_UNLIKELY (!low_bytes_read_wrapper(reader_, - size)) { - return struct_pack::errc::no_buffer_space; - } - } - else { - std::uint64_t sz; - if SP_UNLIKELY (!low_bytes_read_wrapper(reader_, - sz)) { - return struct_pack::errc::no_buffer_space; - } - if SP_UNLIKELY (sz > UINT32_MAX) { - return struct_pack::errc::invalid_width_of_container_length; - } - size = sz; - } - } - else { - static_assert(!sizeof(T), "illegal size_type"); - } - } - else { - switch (size_type_) { - case 1: - if SP_UNLIKELY (!low_bytes_read_wrapper<2>(reader_, size)) { - return struct_pack::errc::no_buffer_space; - } - break; - case 2: - if SP_UNLIKELY (!low_bytes_read_wrapper<4>(reader_, size)) { - return struct_pack::errc::no_buffer_space; - } - break; - case 3: - if constexpr (sizeof(std::size_t) >= 8) { - if SP_UNLIKELY (!low_bytes_read_wrapper<8>(reader_, size)) { - return struct_pack::errc::no_buffer_space; - } - } - else { - unreachable(); - } - break; - default: - unreachable(); - } - } - } - if (size == 0) { - return {}; - } - if constexpr (map_container) { - std::pair - value{}; - if constexpr (is_trivial_serializable::value && - !NotSkip) { - if constexpr (sizeof(value) > 1) { - if SP_UNLIKELY (size > SIZE_MAX / sizeof(value)) { - return errc::no_buffer_space; - } - } - return reader_.ignore(size * sizeof(value)) ? errc{} - : errc::no_buffer_space; - } - else { - item.clear(); - for (uint64_t i = 0; i < size; ++i) { - code = deserialize_one(value); - if SP_UNLIKELY (code) { - return code; - } - if constexpr (NotSkip) { - item.emplace(std::move(value)); - // TODO: mapped_type can deserialize without be moved - } - } - } - } - else if constexpr (set_container) { - typename type::value_type value{}; - if constexpr (is_trivial_serializable::value && - !NotSkip) { - if constexpr (sizeof(value) > 1) { - if SP_UNLIKELY (size > SIZE_MAX / sizeof(value)) { - return errc::no_buffer_space; - } - } - return reader_.ignore(size * sizeof(value)) ? errc{} - : errc::no_buffer_space; - } - else { - item.clear(); - for (uint64_t i = 0; i < size; ++i) { - code = deserialize_one(value); - if SP_UNLIKELY (code) { - return code; - } - if constexpr (NotSkip) { - item.emplace(std::move(value)); - // TODO: mapped_type can deserialize without be moved - } - } - } - } - else { - using value_type = typename type::value_type; - constexpr std::size_t block_lim_cnt = - STRUCT_PACK_MAX_UNCONFIRM_PREREAD_SIZE / sizeof(value_type); - if constexpr (trivially_copyable_container) { - if constexpr (sizeof(value_type) > 1) { - if SP_UNLIKELY (size > SIZE_MAX / sizeof(value_type)) { - return errc::no_buffer_space; - } - } - std::size_t mem_sz = size * sizeof(value_type); - if constexpr (NotSkip) { - if constexpr (string_view || dynamic_span) { - static_assert( - view_reader_t, - "The Reader isn't a view_reader, can't deserialize " - "a string_view/span"); - const char *view = reader_.read_view(mem_sz); - if SP_UNLIKELY (view == nullptr) { - return struct_pack::errc::no_buffer_space; - } - item = {(value_type *)(view), (std::size_t)size}; - } - else { - if constexpr (checkable_reader_t) { - if SP_UNLIKELY (!reader_.check(mem_sz)) { - return struct_pack::errc::no_buffer_space; - } - resize(item, size); - if constexpr (is_little_endian_copyable) { - auto ec = - read_bytes_array(reader_, (char *)item.data(), mem_sz); - assert(ec == true); - } - else { - for (auto &i : item) { - code = deserialize_one(i); - if SP_UNLIKELY (code) { - return code; - } - } - } - } - else { - for (size_t i = 0, len = block_lim_cnt; i < size; - i += block_lim_cnt) { - if (i + block_lim_cnt >= size) { - len = size - i; - } - resize(item, i + len); - if constexpr (is_little_endian_copyable) { - if SP_UNLIKELY (!read_bytes_array( - reader_, (char *)(item.data() + i), - len * sizeof(value_type))) { - item.resize(i); - if constexpr (can_shrink_to_fit) { - item.shrink_to_fit(); - } - return struct_pack::errc::no_buffer_space; - } - } - else { - for (size_t j = i; j < i + len; ++j) { - code = deserialize_one( - item[j]); - if SP_UNLIKELY (code) { - return code; - } - } - } - } - } - } - } - else { - return reader_.ignore(mem_sz) ? errc{} : errc::no_buffer_space; - } - } - else { - if constexpr (dynamic_span) { - static_assert(!dynamic_span, - "It's illegal to deserialize a span which T " - "is a non-trival-serializable type."); - } - else if constexpr (NotSkip) { - item.clear(); - if constexpr (can_reserve) { - item.reserve((std::min)(size, block_lim_cnt)); - } - for (size_t i = 0; i < size; ++i) { - item.emplace_back(); - code = - deserialize_one(item.back()); - if SP_UNLIKELY (code) { - if constexpr (can_reserve) { - if constexpr (can_shrink_to_fit) { - item.shrink_to_fit(); // release reserve memory - } - } - return code; - } - } - } - else { - value_type useless; - for (size_t i = 0; i < size; ++i) { - code = deserialize_one(useless); - if SP_UNLIKELY (code) { - return code; - } - } - } - } - } - } - else if constexpr (container_adapter) { - static_assert(!sizeof(type), - "the container adapter type is not supported"); - } - else if constexpr (!pair && tuple && - !is_trivial_tuple) { - std::apply( - [&](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - code = deserialize_many(items...); - }, - item); - } - else if constexpr (optional || expected) { - bool has_value{}; - if SP_UNLIKELY (!read_wrapper(reader_, - (char *)&has_value)) { - return struct_pack::errc::no_buffer_space; - } - if SP_UNLIKELY (!has_value) { - if constexpr (expected) { - item = typename type::unexpected_type{typename type::error_type{}}; - deserialize_one(item.error()); - } - else { - return {}; - } - } - else { - if constexpr (expected) { - if constexpr (!std::is_same_v) - deserialize_one(item.value()); - } - else { - item = type{std::in_place_t{}}; - deserialize_one(*item); - } - } - } - else if constexpr (is_variant_v) { - uint8_t index{}; - if SP_UNLIKELY (!read_wrapper(reader_, (char *)&index)) { - return struct_pack::errc::no_buffer_space; - } - if SP_UNLIKELY (index >= std::variant_size_v) { - return struct_pack::errc::invalid_buffer; - } - else { - template_switch, - std::integral_constant, - std::integral_constant>>(index, *this, item); - } - } - else if constexpr (std::is_class_v) { - if constexpr (!pair && !is_trivial_tuple) - if constexpr (!user_defined_refl) - static_assert( - std::is_aggregate_v>, - "struct_pack only support aggregated type, or you should " - "add macro STRUCT_PACK_REFL(Type,field1,field2...)"); - if constexpr (is_trivial_serializable::value && - is_little_endian_copyable) { - if constexpr (NotSkip) { - if SP_UNLIKELY (!read_wrapper(reader_, - (char *)&item)) { - return struct_pack::errc::no_buffer_space; - } - } - else { - return reader_.ignore(sizeof(type)) ? errc{} - : errc::no_buffer_space; - } - } - else if constexpr ((is_trivial_serializable::value && - !is_little_endian_copyable) || - is_trivial_serializable::value) { - visit_members(item, [&](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - int i = 1; - auto f = [&](auto &&item) -> bool { - code = deserialize_one(item); - if SP_LIKELY (!code) { - code = ignore_padding(align::padding_size[i++]); - } - return !code; - }; - [[maybe_unused]] bool op = (f(items) && ...); - }); - } - else { - constexpr uint64_t tag = get_parent_tag(); - if constexpr (is_enable_fast_varint_coding(tag)) { - code = visit_members( - item, [this](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - constexpr uint64_t tag = - get_parent_tag(); // to pass msvc with c++17 - return deserialize_fast_varint(items...); - }); - if SP_UNLIKELY (code) { - return code; - } - } - code = visit_members( - item, [this](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - constexpr uint64_t tag = - get_parent_tag(); // to pass msvc with c++17 - return deserialize_many( - items...); - }); - } - } - else { - static_assert(!sizeof(type), "the type is not supported yet"); - } - } - else if constexpr (exist_compatible_member) { - if constexpr (id == type_id::compatible_t) { - if constexpr (version == type::version_number) { - auto pos = reader_.tellg(); - if ((std::size_t)pos >= data_len_) { - if (std::is_unsigned_v || pos >= 0) { - size_type_ = UCHAR_MAX; // Just notice that this is not a real - // error, this is a flag for exit. - } - return struct_pack::errc::no_buffer_space; - } - bool has_value{}; - if SP_UNLIKELY (!read_wrapper(reader_, - (char *)&has_value)) { - return struct_pack::errc::no_buffer_space; - } - if (!has_value) { - return code; - } - else { - item = type{std::in_place_t{}}; - deserialize_one(*item); - } - } - } - else if constexpr (unique_ptr) { - if (item == nullptr) { - return {}; - } - if constexpr (is_base_class) { - uint32_t id = item->get_struct_pack_id(); - bool ok{}; - auto index = search_type_by_md5(id, ok); - assert(ok); - return template_switch, - std::integral_constant, - std::integral_constant, - std::integral_constant>>(index, this, - item); - } - else { - deserialize_one(*item); - } - } - else if constexpr (id == type_id::array_t) { - for (auto &i : item) { - code = deserialize_one(i); - if SP_UNLIKELY (code) { - return code; - } - } - } - else if constexpr (container) { - if constexpr (id == type_id::set_container_t) { - // TODO: support it. - static_assert(!sizeof(type), - "we don't support compatible field in set now."); - } - else if constexpr (id == type_id::map_container_t) { - static_assert( - !exist_compatible_member, - "we don't support compatible field in map's key_type now."); - if constexpr (NotSkip) { - for (auto &e : item) { - code = deserialize_one(e.second); - if SP_UNLIKELY (code) { - return code; - } - } - } - else { - // TODO: support it. - static_assert( - !sizeof(type), - "we don't support skip compatible field in container now."); - } - // how to deserialize it quickly? - } - else { - if constexpr (NotSkip) { - for (auto &i : item) { - code = deserialize_one(i); - if SP_UNLIKELY (code) { - return code; - } - } - } - else { - // TODO: support it. - static_assert( - !sizeof(type), - "we don't support skip compatible field in container now."); - } - } - } - else if constexpr (!pair && tuple && - !is_trivial_tuple) { - std::apply( - [&](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - code = deserialize_many(items...); - }, - item); - } - else if constexpr (optional || expected) { - bool has_value = item.has_value(); - if (!has_value) { - if constexpr (expected) { - deserialize_one(item.error()); - } - } - else { - if constexpr (expected) { - if constexpr (!std::is_same_v) - deserialize_one(item.value()); - } - else { - deserialize_one(item.value()); - } - } - } - else if constexpr (is_variant_v) { - std::visit( - [this](auto &item) { - deserialize_one(item); - }, - item); - } - else if constexpr (std::is_class_v) { - visit_members(item, [&](auto &&...items) CONSTEXPR_INLINE_LAMBDA { - code = deserialize_many(items...); - }); - } - } - return code; - } - - // partial deserialize_to - template - STRUCT_PACK_INLINE constexpr bool set_value(struct_pack::err_code &err_code, - FieldType &field, T &&t) { - if constexpr (FieldIndex == I) { - static_assert( - std::is_same_v, remove_cvref_t>); - err_code = deserialize_one(field); - return /*don't skip=*/true; - } - else { - err_code = deserialize_one(t); - return /*skip=*/false; - } - } - - template - decltype(auto) get_nth(Ts &&...ts) { - return std::get(std::forward_as_tuple(ts...)); - } - - template - STRUCT_PACK_INLINE constexpr void for_each_helper(struct_pack::err_code &code, - FieldType &field, - std::index_sequence, - Args &&...items) { - [[maybe_unused]] auto result = - (!set_value(code, field, - get_nth(items...)) && - ...); - } - - template - STRUCT_PACK_INLINE constexpr struct_pack::err_code for_each(FieldType &field, - Args &&...items) { - struct_pack::err_code code{}; - for_each_helper( - code, field, std::make_index_sequence(), items...); - return code; - } - - public: - std::size_t data_len_; - - private: - Reader &reader_; - unsigned char size_type_; -}; - -template -struct MD5_reader_wrapper : public Reader { - MD5_reader_wrapper(Reader &&reader) : Reader(std::move(reader)) { - is_failed = - !read_wrapper(*(Reader *)this, (char *)&head_chars); - } - bool read_head(char *target) { - if SP_UNLIKELY (is_failed) { - return false; - } - memcpy(target, &head_chars, sizeof(head_chars)); - return true; - } - Reader &&release_reader() { return std::move(*(Reader *)this); } - bool is_failed; - uint32_t get_md5() { return head_chars & 0xFFFFFFFE; } - - private: - std::uint32_t head_chars; - std::size_t read_pos; -}; - -template -[[nodiscard]] STRUCT_PACK_INLINE struct_pack::err_code -deserialize_derived_class(std::unique_ptr &base, Reader &reader) { - MD5_reader_wrapper wrapper{std::move(reader)}; - if (wrapper.is_failed) { - return struct_pack::errc::no_buffer_space; - } - unpacker> unpack{wrapper}; - constexpr auto &MD5s = MD5_set>::value; - MD5_pair md5_pair{wrapper.get_md5(), 0}; - auto result = std::lower_bound(MD5s.begin(), MD5s.end(), md5_pair); - if (result == MD5s.end() || result->md5 != md5_pair.md5) { - return struct_pack::errc::invalid_buffer; - } - auto ret = template_switch< - deserialize_derived_class_helper>>( - result->index, base, unpack); - reader = std::move(wrapper.release_reader()); - return ret; -} -} // namespace detail - -} // namespace struct_pack - -#undef STRUCT_PACK_MAX_UNCONFIRM_PREREAD_SIZE \ No newline at end of file diff --git a/include/ylt/struct_pack/user_helper.hpp b/include/ylt/struct_pack/user_helper.hpp deleted file mode 100644 index 25f6cd29c..000000000 --- a/include/ylt/struct_pack/user_helper.hpp +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once -#include -#include - -#include "ylt/struct_pack/calculate_size.hpp" -#include "ylt/struct_pack/packer.hpp" -#include "ylt/struct_pack/reflection.hpp" -#include "ylt/struct_pack/unpacker.hpp" -namespace struct_pack { -template -STRUCT_PACK_INLINE void write(Writer& writer, const T& t) { - struct_pack::detail::packer packer{writer}; - packer.template serialize_one(t); -}; -template -STRUCT_PACK_INLINE void write(Writer& writer, const T* t, std::size_t len) { - if constexpr (detail::is_trivial_serializable::value && - detail::is_little_endian_copyable) { - write_bytes_array(writer, (char*)t, sizeof(T) * len); - } - else { - struct_pack::detail::packer packer{writer}; - for (std::size_t i = 0; i < len; ++i) { - packer.template serialize_one(t[i]); - } - } -}; -template -STRUCT_PACK_INLINE struct_pack::err_code read(Reader& reader, T& t) { - struct_pack::detail::unpacker unpacker{ - reader}; - return unpacker.template deserialize_one(t); -}; -template -STRUCT_PACK_INLINE struct_pack::err_code read(Reader& reader, T* t, - std::size_t len) { - if constexpr (detail::is_trivial_serializable::value && - detail::is_little_endian_copyable) { - if constexpr (!ifSkip) { - if SP_UNLIKELY (!read_bytes_array(reader, (char*)t, sizeof(T) * len)) { - return struct_pack::errc::no_buffer_space; - } - } - else { - return reader.ignore(sizeof(T) * len) ? errc{} : errc::no_buffer_space; - } - } - else { - struct_pack::detail::unpacker unpacker{ - reader}; - for (std::size_t i = 0; i < len; ++i) { - auto code = - unpacker.template deserialize_one( - t[i]); - if SP_UNLIKELY (code) { - return code; - } - } - } - return {}; -}; -template -STRUCT_PACK_INLINE constexpr std::size_t get_write_size(const T& t) { - auto sz = struct_pack::detail::calculate_one_size(t); - return sz.size_cnt * size_width + sz.total; -}; -template -STRUCT_PACK_INLINE constexpr std::size_t get_write_size(const T* t, - std::size_t len) { - if constexpr (detail::is_trivial_serializable::value) { - return sizeof(T) * len; - } - else { - detail::size_info sz{}; - for (std::size_t i = 0; i < len; ++i) { - sz += struct_pack::detail::calculate_one_size(t[i]); - } - return sz.size_cnt * size_width + sz.total; - } -}; -}; // namespace struct_pack \ No newline at end of file diff --git a/include/ylt/struct_pack/util.h b/include/ylt/struct_pack/util.h deleted file mode 100644 index ec9218c4c..000000000 --- a/include/ylt/struct_pack/util.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include -#include -#include -#include - -#include "marco.h" - -namespace struct_pack::detail { - -template -constexpr std::string_view get_raw_name() { -#ifdef _MSC_VER - return __FUNCSIG__; -#else - return __PRETTY_FUNCTION__; -#endif -} - -template -constexpr std::string_view get_raw_name() { -#ifdef _MSC_VER - return __FUNCSIG__; -#else - return __PRETTY_FUNCTION__; -#endif -} - -template -inline constexpr std::string_view type_string() { - constexpr std::string_view sample = get_raw_name(); - constexpr size_t pos = sample.find("int"); - constexpr std::string_view str = get_raw_name(); - constexpr auto next1 = str.rfind(sample[pos + 3]); -#if defined(_MSC_VER) - constexpr std::size_t npos = str.find_first_of(" ", pos); - if (npos != std::string_view::npos) - return str.substr(npos + 1, next1 - npos - 1); - else - return str.substr(pos, next1 - pos); -#else - return str.substr(pos, next1 - pos); -#endif -} - -#if __cpp_concepts >= 201907L -constexpr bool is_string_reserve_shrink = requires { std::string{}.reserve(); }; -#else -constexpr bool is_string_reserve_shrink = true; -#endif - -template -using remove_cvref_t = std::remove_cv_t>; - -[[noreturn]] inline void unreachable() { - // Uses compiler specific extensions if possible. - // Even if no extension is used, undefined behavior is still raised by - // an empty function body and the noreturn attribute. -#ifdef __GNUC__ // GCC, Clang, ICC - __builtin_unreachable(); -#elif defined(_MSC_VER) // msvc - __assume(false); -#endif -} - -template -[[noreturn]] constexpr T declval() { - unreachable(); -} - -template -constexpr void STRUCT_PACK_INLINE compile_time_sort(std::array &array) { - // FIXME: use faster compile-time sort - for (std::size_t i = 0; i < array.size(); ++i) { - for (std::size_t j = i + 1; j < array.size(); ++j) { - if (array[i] > array[j]) { - auto tmp = array[i]; - array[i] = array[j]; - array[j] = tmp; - } - } - } - return; -} - -template -constexpr std::size_t STRUCT_PACK_INLINE -calculate_uniqued_size(const std::array &input) { - std::size_t unique_cnt = sz; - for (std::size_t i = 1; i < input.size(); ++i) { - if (input[i] == input[i - 1]) { - --unique_cnt; - } - } - return unique_cnt; -} - -template -constexpr void STRUCT_PACK_INLINE compile_time_unique( - const std::array &input, std::array &output) { - std::size_t j = 0; - static_assert(sz1 != 0, "not allow empty input!"); - output[0] = input[0]; - for (std::size_t i = 1; i < input.size(); ++i) { - if (input[i] != input[i - 1]) { - output[++j] = input[i]; - } - } -} - -#ifndef __clang__ -#define struct_pack_has_feature(X) false -#else -#define struct_pack_has_feature __has_feature -#endif - -#if __cpp_lib_string_resize_and_overwrite >= 202110L -template -inline void resize(std::basic_string &str, std::size_t sz) { - str.resize_and_overwrite(sz, [sz](ch *, std::size_t) { - return sz; - }); -} -#elif (defined(_MSC_VER) && _MSC_VER <= 1920) -// old msvc don't support visit private, discard it. - -#else - -template -class string_thief { - public: - friend void string_set_length_hacker(std::string &self, std::size_t sz) { -#if defined(_MSVC_STL_VERSION) - (self.*func_ptr)._Myval2._Mysize = sz; -#else -#if defined(_LIBCPP_VERSION) - (self.*func_ptr)(sz); -#else -#if (_GLIBCXX_USE_CXX11_ABI == 0) && defined(__GLIBCXX__) - (self.*func_ptr)()->_M_set_length_and_sharable(sz); -#else -#if defined(__GLIBCXX__) - (self.*func_ptr)(sz); -#endif -#endif -#endif -#endif - } -}; - -#if defined(__GLIBCXX__) // libstdc++ -#if (_GLIBCXX_USE_CXX11_ABI == 0) -template class string_thief; -#else -template class string_thief; -#endif -#elif defined(_LIBCPP_VERSION) -template class string_thief; -#elif defined(_MSVC_STL_VERSION) -template class string_thief; -#endif - -void string_set_length_hacker(std::string &, std::size_t); - -template -inline void resize(std::basic_string &raw_str, std::size_t sz) { - std::string &str = *reinterpret_cast(&raw_str); -#if defined(_GLIBCXX_USE_CXX11_ABI) - constexpr bool is_use_cxx11_abi = _GLIBCXX_USE_CXX11_ABI; -#else - constexpr bool is_use_cxx11_abi = true; -#endif - if constexpr (std::is_same_v == false && - is_use_cxx11_abi == false) { - raw_str.resize(sz); - } - else { -#if defined(__SANITIZE_ADDRESS__) || \ - struct_pack_has_feature(address_sanitizer) || \ - (!defined(NDEBUG) && defined(_MSVC_STL_VERSION)) - raw_str.resize(sz); -#elif defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) || \ - defined(_MSVC_STL_VERSION) - if constexpr (is_string_reserve_shrink) { - if (sz > raw_str.capacity()) { - str.reserve(sz * sizeof(ch)); - } - } - else { - str.reserve(sz * sizeof(ch)); - } - string_set_length_hacker(str, sz); - for (auto i = sz; i < sz + sizeof(ch); ++i) str[i] = '\0'; -#else - raw_str.resize(sz); -#endif - } -} - -#endif - -#if (defined(_MSC_VER) && _MSC_VER <= 1920) -#else -void vector_set_length_hacker(std::vector &self, std::size_t sz); - -template -class vector_thief { - public: - friend void vector_set_length_hacker(std::vector &self, - std::size_t sz) { -#if defined(_MSVC_STL_VERSION) - (self.*func_ptr)._Myval2._Mylast = self.data() + sz; -#else -#if defined(_LIBCPP_VERSION) -#if _LIBCPP_VERSION < 14000 - ((*(std::__vector_base> *)(&self)).*func_ptr) = - self.data() + sz; -#else - (self.*func_ptr) = self.data() + sz; -#endif -#else -#if defined(__GLIBCXX__) - ((*(std::_Vector_base> *)(&self)).*func_ptr) - ._M_finish = self.data() + sz; -#endif -#endif -#endif - } -}; - -#if defined(__GLIBCXX__) // libstdc++ -template class vector_thief::_M_impl), - &std::vector::_M_impl>; -#elif defined(_LIBCPP_VERSION) -template class vector_thief::__end_), - &std::vector::__end_>; -#elif defined(_MSVC_STL_VERSION) -template class vector_thief::_Mypair), - &std::vector::_Mypair>; -#endif - -template -inline void resize(std::vector &raw_vec, std::size_t sz) { -#if defined(__SANITIZE_ADDRESS__) || struct_pack_has_feature(address_sanitizer) - raw_vec.resize(sz); -#elif defined(__GLIBCXX__) || \ - (defined(_LIBCPP_VERSION) && defined(_LIBCPP_HAS_NO_ASAN)) || \ - defined(_MSVC_STL_VERSION) - std::vector &vec = *reinterpret_cast *>(&raw_vec); - vec.reserve(sz * sizeof(ch)); - vector_set_length_hacker(vec, sz * sizeof(ch)); -#else - raw_vec.resize(sz); -#endif -} -#endif - -#undef struct_pack_has_feature - -template -inline void resize(T &str, std::size_t sz) { - str.resize(sz); -} - -} // namespace struct_pack::detail \ No newline at end of file diff --git a/include/ylt/struct_pack/varint.hpp b/include/ylt/struct_pack/varint.hpp deleted file mode 100644 index 2a6346e78..000000000 --- a/include/ylt/struct_pack/varint.hpp +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include -#include - -#include "endian_wrapper.hpp" -#include "reflection.hpp" -namespace struct_pack { - -namespace detail { - -constexpr inline bool is_enable_fast_varint_coding(uint64_t tag) { - return tag & struct_pack::USE_FAST_VARINT; -} - -template -struct int_t; - -template <> -struct int_t<1> { - using type = int8_t; -}; - -template <> -struct int_t<2> { - using type = int16_t; -}; - -template <> -struct int_t<4> { - using type = int32_t; -}; - -template <> -struct int_t<8> { - using type = int64_t; -}; - -template -struct uint_t; - -template <> -struct uint_t<1> { - using type = uint8_t; -}; - -template <> -struct uint_t<2> { - using type = uint16_t; -}; - -template <> -struct uint_t<4> { - using type = uint32_t; -}; - -template <> -struct uint_t<8> { - using type = uint64_t; -}; - -template -class varint { - public: - using value_type = T; - varint() noexcept = default; - varint(T t) noexcept : val(t) {} - [[nodiscard]] operator T() const noexcept { return val; } - auto& operator=(T t) noexcept { - val = t; - return *this; - } - [[nodiscard]] auto operator<(const varint& o) const noexcept { - return val < o.val; - } - [[nodiscard]] auto operator<=(const varint& o) const noexcept { - return val <= o.val; - } - [[nodiscard]] auto operator>(const varint& o) const noexcept { - return val > o.val; - } - [[nodiscard]] auto operator>=(const varint& o) const noexcept { - return val >= o.val; - } - [[nodiscard]] auto operator!=(const varint& o) const noexcept { - return val != o.val; - } - [[nodiscard]] bool operator==(const varint& t) const noexcept { - return val == t.val; - } - [[nodiscard]] bool operator==(T t) const noexcept { return val == t; } - [[nodiscard]] auto operator&(uint8_t mask) const noexcept { - T new_val = val & mask; - return varint(new_val); - } - template >> - [[nodiscard]] auto operator<<(U shift) const noexcept { - T new_val = val << shift; - return varint(new_val); - } - template - [[nodiscard]] auto operator|=(U shift) noexcept { - if constexpr (std::is_same_v>) { - val |= shift.val; - } - else { - val |= shift; - } - return *this; - } - friend std::ostream& operator<<(std::ostream& os, const varint& varint) { - os << varint.val; - return os; - } - - const T& get() const noexcept { return val; } - T& get() noexcept { return val; } - - private: - T val; -}; - -template -class sint { - public: - using value_type = T; - sint() noexcept = default; - sint(T t) noexcept : val(t) {} - [[nodiscard]] operator T() const noexcept { return val; } - auto& operator=(T t) noexcept { - val = t; - return *this; - } - [[nodiscard]] auto operator<(const sint& o) const noexcept { - return val < o.val; - } - [[nodiscard]] auto operator<=(const sint& o) const noexcept { - return val <= o.val; - } - [[nodiscard]] auto operator>(const sint& o) const noexcept { - return val > o.val; - } - [[nodiscard]] auto operator>=(const sint& o) const noexcept { - return val >= o.val; - } - [[nodiscard]] auto operator!=(const sint& o) const noexcept { - return val != o.val; - } - [[nodiscard]] bool operator==(T t) const noexcept { return val == t; } - [[nodiscard]] bool operator==(const sint& t) const noexcept { - return val == t.val; - } - [[nodiscard]] auto operator&(uint8_t mask) const noexcept { - T new_val = val & mask; - return sint(new_val); - } - template >> - auto operator<<(U shift) const noexcept { - T new_val = val << shift; - return sint(new_val); - } - const T& get() const noexcept { return val; } - T& get() noexcept { return val; } - friend std::ostream& operator<<(std::ostream& os, const sint& t) { - os << t.val; - return os; - } - - private: - T val; -}; - -template -[[nodiscard]] STRUCT_PACK_INLINE T decode_zigzag(U u) { - return static_cast((u >> 1U)) ^ static_cast(-static_cast(u & 1U)); -} - -template -[[nodiscard]] STRUCT_PACK_INLINE U encode_zigzag(T t) { - return (static_cast(t) << 1U) ^ - static_cast(-static_cast(static_cast(t) >> Shift)); -} -template -[[nodiscard]] STRUCT_PACK_INLINE auto encode_zigzag(T t) { - if constexpr (std::is_same_v) { - return encode_zigzag(t); - } - else if constexpr (std::is_same_v) { - return encode_zigzag(t); - } - else { - static_assert(!sizeof(T), "error zigzag type"); - } -} - -template -[[nodiscard]] STRUCT_PACK_INLINE constexpr int calculate_varint_size(T t) { - if constexpr (!varint_t) { - int ret = 0; - if constexpr (std::is_unsigned_v) { - do { - ret++; - t >>= 7; - } while (t != 0); - } - else { - uint64_t temp = t; - do { - ret++; - temp >>= 7; - } while (temp != 0); - } - return ret; - } - else if constexpr (varintable_t) { - return calculate_varint_size(t.get()); - } - else if constexpr (sintable_t) { - return calculate_varint_size(encode_zigzag(t.get())); - } - else { - static_assert(!sizeof(T), "error type"); - } -} - -template < -#if __cpp_concepts >= 201907L - writer_t writer, -#else - typename writer, -#endif - typename T> -STRUCT_PACK_INLINE void serialize_varint(writer& writer_, const T& t) { -#if __cpp_concepts < 201907L - static_assert(writer_t, "The writer type must satisfy requirements!"); -#endif - uint64_t v; - if constexpr (sintable_t) { - v = encode_zigzag(get_varint_value(t)); - } - else { - v = t; - } - while (v >= 0x80) { - uint8_t temp = v | 0x80u; - write_wrapper(writer_, (char*)&temp); - v >>= 7; - } - if constexpr (is_system_little_endian) { - write_wrapper(writer_, (char*)&v); - } - else { - uint8_t tmp = v; - write_wrapper(writer_, (char*)&tmp); - } -} -#if __cpp_concepts >= 201907L -template -#else -template -#endif -[[nodiscard]] STRUCT_PACK_INLINE struct_pack::err_code deserialize_varint_impl( - Reader& reader, uint64_t& v) { -#if __cpp_concepts < 201907L - static_assert(reader_t, "The writer type must satisfy requirements!"); -#endif - uint8_t now; - constexpr const int8_t max_varint_length = sizeof(uint64_t) * 8 / 7 + 1; - for (int8_t i = 0; i < max_varint_length; ++i) { - if SP_UNLIKELY (!reader.read((char*)&now, sizeof(char))) { - return struct_pack::errc::no_buffer_space; - } - v |= (1ull * (now & 0x7fu)) << (i * 7); - if ((now & 0x80U) == 0) { - return {}; - } - } - return struct_pack::errc::invalid_buffer; -} -template = 201907L - reader_t Reader, -#else - typename Reader, -#endif - typename T> -[[nodiscard]] STRUCT_PACK_INLINE struct_pack::err_code deserialize_varint( - Reader& reader, T& t) { -#if __cpp_concepts < 201907L - static_assert(reader_t, "The writer type must satisfy requirements!"); -#endif - uint64_t v = 0; - auto ec = deserialize_varint_impl(reader, v); - if constexpr (NotSkip) { - if SP_LIKELY (!ec) { - if constexpr (sintable_t) { - t = decode_zigzag(v); - } - else if constexpr (std::is_enum_v) { - t = static_cast(v); - } - else { - t = v; - } - } - } - return ec; - // Variable-width integers, or varints, - // are at the core of the wire format. - // They allow encoding unsigned 64-bit integers using anywhere - // between one and ten bytes, with small values using fewer bytes. - // return decode_varint_v1(f); -} - -template -const auto& get_varint_value(const T& v) { - if constexpr (varint_t) { - return v.get(); - } - else { - return v; - } -} - -template -auto& get_varint_value(T& v) { - if constexpr (varint_t) { - return v.get(); - } - else { - return v; - } -} - -} // namespace detail -using var_int32_t = detail::sint; -using var_int64_t = detail::sint; -using var_uint32_t = detail::varint; -using var_uint64_t = detail::varint; -} // namespace struct_pack diff --git a/include/ylt/struct_pb.hpp b/include/ylt/struct_pb.hpp deleted file mode 100644 index a57ea241d..000000000 --- a/include/ylt/struct_pb.hpp +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include -#include -#if defined __clang__ -#define STRUCT_PB_INLINE __attribute__((always_inline)) inline -#elif defined _MSC_VER -#define STRUCT_PB_INLINE __forceinline -#else -#define STRUCT_PB_INLINE __attribute__((always_inline)) inline -#endif -#define STRUCT_PB_NODISCARD [[nodiscard]] -namespace struct_pb { - -struct UnknownFields { - STRUCT_PB_NODISCARD std::size_t total_size() const { - std::size_t total = 0; - for (const auto& f : fields) { - total += f.len; - } - return total; - } - void serialize_to(char* data, std::size_t& pos, std::size_t size) const { - for (const auto& f : fields) { - assert(pos + f.len <= size); - std::memcpy(data + pos, f.data, f.len); - pos += f.len; - } - } - void add_field(const char* data, std::size_t start, std::size_t end) { - fields.push_back(Field{data + start, end - start}); - } - struct Field { - const char* data; - std::size_t len; - }; - std::vector fields; -}; -/* - * Low-Level API for struct_pb user - * the following internal API will be generated by struct_pb protoc plugin - */ -namespace internal { -template -STRUCT_PB_NODISCARD std::size_t get_needed_size( - const T& t, const UnknownFields& unknown_fields = {}); -template -void serialize_to(char* data, std::size_t size, const T& t, - const UnknownFields& unknown_fields = {}); -template -STRUCT_PB_NODISCARD bool deserialize_to(T& t, const char* data, - std::size_t size, - UnknownFields& unknown_fields); -template -STRUCT_PB_NODISCARD bool deserialize_to(T& t, const char* data, - std::size_t size); -} // namespace internal - -/* - * High-Level API for struct_pb user - * If you need more fine-grained operations, encapsulate the internal API - * yourself. - */ -template , typename T> -STRUCT_PB_NODISCARD Buffer serialize(const T& t, - const UnknownFields& unknown_fields = {}) { - Buffer buffer; - auto size = struct_pb::internal::get_needed_size(t, unknown_fields); - buffer.resize(size); - struct_pb::internal::serialize_to(buffer.data(), buffer.size(), t, - unknown_fields); - return buffer; -} -template -STRUCT_PB_NODISCARD STRUCT_PB_INLINE bool deserialize_to( - T& t, UnknownFields& unknown_fields, const Buffer& buffer) { - return struct_pb::internal::deserialize_to(t, buffer.data(), buffer.size(), - unknown_fields); -} -template -STRUCT_PB_NODISCARD STRUCT_PB_INLINE bool deserialize_to(T& t, - const Buffer& buffer) { - return struct_pb::internal::deserialize_to(t, buffer.data(), buffer.size()); -} - -} // namespace struct_pb diff --git a/include/ylt/struct_pb/struct_pb_impl.hpp b/include/ylt/struct_pb/struct_pb_impl.hpp deleted file mode 100644 index 12a2a76c2..000000000 --- a/include/ylt/struct_pb/struct_pb_impl.hpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include -#include -#include -#include - -#include "ylt/struct_pb.hpp" - -namespace struct_pb { - -namespace internal { -STRUCT_PB_NODISCARD STRUCT_PB_INLINE uint32_t encode_zigzag(int32_t v) { - return (static_cast(v) << 1U) ^ - static_cast( - -static_cast(static_cast(v) >> 31U)); -} -STRUCT_PB_NODISCARD STRUCT_PB_INLINE uint64_t encode_zigzag(int64_t v) { - return (static_cast(v) << 1U) ^ - static_cast( - -static_cast(static_cast(v) >> 63U)); -} - -STRUCT_PB_NODISCARD STRUCT_PB_INLINE int64_t decode_zigzag(uint64_t u) { - return static_cast((u >> 1U)) ^ - static_cast(-static_cast(u & 1U)); -} -STRUCT_PB_NODISCARD STRUCT_PB_INLINE int64_t decode_zigzag(uint32_t u) { - return static_cast((u >> 1U)) ^ - static_cast(-static_cast(u & 1U)); -} - -STRUCT_PB_NODISCARD STRUCT_PB_INLINE std::size_t calculate_varint_size( - uint64_t v) { - std::size_t ret = 0; - do { - ret++; - v >>= 7; - } while (v != 0); - return ret; -} - -[[nodiscard]] STRUCT_PB_INLINE bool decode_varint(const char* data, - std::size_t& pos_, - std::size_t size_, - uint64_t& v) { - // fix test failed on arm due to different char definition - const signed char* data_ = reinterpret_cast(data); - // from https://github.com/facebook/folly/blob/main/folly/Varint.h - if (pos_ < size_ && (static_cast(data_[pos_]) & 0x80U) == 0) { - v = static_cast(data_[pos_]); - pos_++; - return true; - } - constexpr const int8_t max_varint_length = sizeof(uint64_t) * 8 / 7 + 1; - uint64_t val = 0; - if (size_ - pos_ >= max_varint_length) [[likely]] { - do { - // clang-format off - int64_t b = data_[pos_++]; - val = ((uint64_t(b) & 0x7fU) ); if (b >= 0) { break; } - b = data_[pos_++]; val |= ((uint64_t(b) & 0x7fU) << 7U); if (b >= 0) { break; } - b = data_[pos_++]; val |= ((uint64_t(b) & 0x7fU) << 14U); if (b >= 0) { break; } - b = data_[pos_++]; val |= ((uint64_t(b) & 0x7fU) << 21U); if (b >= 0) { break; } - b = data_[pos_++]; val |= ((uint64_t(b) & 0x7fU) << 28U); if (b >= 0) { break; } - b = data_[pos_++]; val |= ((uint64_t(b) & 0x7fU) << 35U); if (b >= 0) { break; } - b = data_[pos_++]; val |= ((uint64_t(b) & 0x7fU) << 42U); if (b >= 0) { break; } - b = data_[pos_++]; val |= ((uint64_t(b) & 0x7fU) << 49U); if (b >= 0) { break; } - b = data_[pos_++]; val |= ((uint64_t(b) & 0x7fU) << 56U); if (b >= 0) { break; } - b = data_[pos_++]; val |= ((uint64_t(b) & 0x01U) << 63U); if (b >= 0) { break; } - // clang-format on - return false; - } while (false); - } - else { - unsigned int shift = 0; - while (pos_ != size_ && int64_t(data_[pos_]) < 0) { - val |= (uint64_t(data_[pos_++]) & 0x7fU) << shift; - shift += 7; - } - if (pos_ == size_) { - return false; - } - val |= uint64_t(data_[pos_++]) << shift; - } - v = val; - return true; -} -STRUCT_PB_INLINE void serialize_varint(char* const data, std::size_t& pos, - std::size_t size, uint64_t v) { - while (v >= 0x80) { - assert(pos < size); - data[pos++] = static_cast(v | 0x80); - v >>= 7; - } - data[pos++] = static_cast(v); -} -STRUCT_PB_NODISCARD STRUCT_PB_INLINE bool deserialize_varint(const char* data, - std::size_t& pos, - std::size_t size, - uint64_t& v) { - return decode_varint(data, pos, size, v); -} -STRUCT_PB_NODISCARD STRUCT_PB_INLINE bool read_tag(const char* data, - std::size_t& pos, - std::size_t size, - uint64_t& tag) { - return deserialize_varint(data, pos, size, tag); -} -inline bool deserialize_unknown(const char* data, std::size_t& pos, - std::size_t size, uint32_t tag, - UnknownFields& unknown_fields) { - uint32_t field_number = tag >> 3; - if (field_number == 0) { - return false; - } - auto offset = internal::calculate_varint_size(tag); - auto start = pos - offset; - uint32_t wire_type = tag & 0b0000'0111; - switch (wire_type) { - case 0: { - uint64_t t; - auto ok = internal::deserialize_varint(data, pos, size, t); - if (!ok) [[unlikely]] { - return false; - } - unknown_fields.add_field(data, start, pos); - break; - } - case 1: { - static_assert(sizeof(double) == 8); - if (pos + 8 > size) [[unlikely]] { - return false; - } - pos += 8; - unknown_fields.add_field(data, start, pos); - break; - } - case 2: { - uint64_t sz; - auto ok = internal::deserialize_varint(data, pos, size, sz); - if (!ok) [[unlikely]] { - return false; - } - if (pos + sz > size) [[unlikely]] { - return false; - } - pos += sz; - unknown_fields.add_field(data, start, pos); - break; - } - case 5: { - static_assert(sizeof(float) == 4); - if (pos + 4 > size) [[unlikely]] { - return false; - } - pos += 4; - unknown_fields.add_field(data, start, pos); - break; - } - default: { - assert(false && "error path"); - } - } - return true; -} -} // namespace internal - -} // namespace struct_pb \ No newline at end of file diff --git a/include/ylt/struct_xml/xml_reader.h b/include/ylt/struct_xml/xml_reader.h deleted file mode 100644 index ca43b396e..000000000 --- a/include/ylt/struct_xml/xml_reader.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include -#include - -namespace struct_xml = iguana; diff --git a/include/ylt/struct_xml/xml_writer.h b/include/ylt/struct_xml/xml_writer.h deleted file mode 100644 index 6784317c9..000000000 --- a/include/ylt/struct_xml/xml_writer.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include - -namespace struct_xml = iguana; diff --git a/include/ylt/struct_yaml/yaml_reader.h b/include/ylt/struct_yaml/yaml_reader.h deleted file mode 100644 index 68c58493a..000000000 --- a/include/ylt/struct_yaml/yaml_reader.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include - -namespace struct_yaml = iguana; diff --git a/include/ylt/struct_yaml/yaml_writer.h b/include/ylt/struct_yaml/yaml_writer.h deleted file mode 100644 index 6d4032cc1..000000000 --- a/include/ylt/struct_yaml/yaml_writer.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2023, Alibaba Group Holding Limited; - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#pragma once -#include - -namespace struct_yaml = iguana; diff --git a/include/ylt/thirdparty/asio.hpp b/include/ylt/thirdparty/asio.hpp deleted file mode 100644 index 8c78e5723..000000000 --- a/include/ylt/thirdparty/asio.hpp +++ /dev/null @@ -1,208 +0,0 @@ -// -// asio.hpp -// ~~~~~~~~ -// -// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software 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/append.hpp" -#include "asio/as_tuple.hpp" -#include "asio/associated_allocator.hpp" -#include "asio/associated_executor.hpp" -#include "asio/associated_cancellation_slot.hpp" -#include "asio/associator.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_file.hpp" -#include "asio/basic_io_object.hpp" -#include "asio/basic_random_access_file.hpp" -#include "asio/basic_raw_socket.hpp" -#include "asio/basic_readable_pipe.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_file.hpp" -#include "asio/basic_stream_socket.hpp" -#include "asio/basic_streambuf.hpp" -#include "asio/basic_waitable_timer.hpp" -#include "asio/basic_writable_pipe.hpp" -#include "asio/bind_allocator.hpp" -#include "asio/bind_cancellation_slot.hpp" -#include "asio/bind_executor.hpp" -#include "asio/buffer.hpp" -#include "asio/buffer_registration.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/cancellation_signal.hpp" -#include "asio/cancellation_state.hpp" -#include "asio/cancellation_type.hpp" -#include "asio/co_spawn.hpp" -#include "asio/completion_condition.hpp" -#include "asio/compose.hpp" -#include "asio/connect.hpp" -#include "asio/connect_pipe.hpp" -#include "asio/coroutine.hpp" -#include "asio/deadline_timer.hpp" -#include "asio/defer.hpp" -#include "asio/deferred.hpp" -#include "asio/detached.hpp" -#include "asio/dispatch.hpp" -#include "asio/error.hpp" -#include "asio/error_code.hpp" -#include "asio/execution.hpp" -#include "asio/execution/allocator.hpp" -#include "asio/execution/any_executor.hpp" -#include "asio/execution/blocking.hpp" -#include "asio/execution/blocking_adaptation.hpp" -#include "asio/execution/bulk_execute.hpp" -#include "asio/execution/bulk_guarantee.hpp" -#include "asio/execution/connect.hpp" -#include "asio/execution/context.hpp" -#include "asio/execution/context_as.hpp" -#include "asio/execution/execute.hpp" -#include "asio/execution/executor.hpp" -#include "asio/execution/invocable_archetype.hpp" -#include "asio/execution/mapping.hpp" -#include "asio/execution/occupancy.hpp" -#include "asio/execution/operation_state.hpp" -#include "asio/execution/outstanding_work.hpp" -#include "asio/execution/prefer_only.hpp" -#include "asio/execution/receiver.hpp" -#include "asio/execution/receiver_invocation_error.hpp" -#include "asio/execution/relationship.hpp" -#include "asio/execution/schedule.hpp" -#include "asio/execution/scheduler.hpp" -#include "asio/execution/sender.hpp" -#include "asio/execution/set_done.hpp" -#include "asio/execution/set_error.hpp" -#include "asio/execution/set_value.hpp" -#include "asio/execution/start.hpp" -#include "asio/execution_context.hpp" -#include "asio/executor.hpp" -#include "asio/executor_work_guard.hpp" -#include "asio/file_base.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_applicable_property.hpp" -#include "asio/is_contiguous_iterator.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/multiple_exceptions.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/prefer.hpp" -#include "asio/prepend.hpp" -#include "asio/query.hpp" -#include "asio/random_access_file.hpp" -#include "asio/read.hpp" -#include "asio/read_at.hpp" -#include "asio/read_until.hpp" -#include "asio/readable_pipe.hpp" -#include "asio/recycling_allocator.hpp" -#include "asio/redirect_error.hpp" -#include "asio/registered_buffer.hpp" -#include "asio/require.hpp" -#include "asio/require_concept.hpp" -#include "asio/serial_port.hpp" -#include "asio/serial_port_base.hpp" -#include "asio/signal_set.hpp" -#include "asio/socket_base.hpp" -#include "asio/static_thread_pool.hpp" -#include "asio/steady_timer.hpp" -#include "asio/strand.hpp" -#include "asio/stream_file.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/writable_pipe.hpp" -#include "asio/write.hpp" -#include "asio/write_at.hpp" - -#endif // ASIO_HPP diff --git a/include/ylt/thirdparty/asio/any_io_executor.hpp b/include/ylt/thirdparty/asio/any_io_executor.hpp deleted file mode 100644 index 36c54277b..000000000 --- a/include/ylt/thirdparty/asio/any_io_executor.hpp +++ /dev/null @@ -1,303 +0,0 @@ -// -// any_io_executor.hpp -// ~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef ASIO_ANY_IO_EXECUTOR_HPP -#define ASIO_ANY_IO_EXECUTOR_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_USE_TS_EXECUTOR_AS_DEFAULT) -# include "asio/executor.hpp" -#else // defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT) -# include "asio/execution.hpp" -# include "asio/execution_context.hpp" -#endif // defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT) - -#include "asio/detail/push_options.hpp" - -namespace asio { - -#if defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT) - -typedef executor any_io_executor; - -#else // defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT) - -/// Polymorphic executor type for use with I/O objects. -/** - * The @c any_io_executor type is a polymorphic executor that supports the set - * of properties required by I/O objects. It is defined as the - * execution::any_executor class template parameterised as follows: - * @code execution::any_executor< - * execution::context_as_t, - * execution::blocking_t::never_t, - * execution::prefer_only, - * execution::prefer_only, - * execution::prefer_only, - * execution::prefer_only, - * execution::prefer_only - * > @endcode - */ -class any_io_executor : -#if defined(GENERATING_DOCUMENTATION) - public execution::any_executor<...> -#else // defined(GENERATING_DOCUMENTATION) - public execution::any_executor< - execution::context_as_t, - execution::blocking_t::never_t, - execution::prefer_only, - execution::prefer_only, - execution::prefer_only, - execution::prefer_only, - execution::prefer_only - > -#endif // defined(GENERATING_DOCUMENTATION) -{ -public: -#if !defined(GENERATING_DOCUMENTATION) - typedef execution::any_executor< - execution::context_as_t, - execution::blocking_t::never_t, - execution::prefer_only, - execution::prefer_only, - execution::prefer_only, - execution::prefer_only, - execution::prefer_only - > base_type; - - typedef void supportable_properties_type( - execution::context_as_t, - execution::blocking_t::never_t, - execution::prefer_only, - execution::prefer_only, - execution::prefer_only, - execution::prefer_only, - execution::prefer_only - ); -#endif // !defined(GENERATING_DOCUMENTATION) - - /// Default constructor. - ASIO_DECL any_io_executor() ASIO_NOEXCEPT; - - /// Construct in an empty state. Equivalent effects to default constructor. - ASIO_DECL any_io_executor(nullptr_t) ASIO_NOEXCEPT; - - /// Copy constructor. - ASIO_DECL any_io_executor(const any_io_executor& e) ASIO_NOEXCEPT; - -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move constructor. - ASIO_DECL any_io_executor(any_io_executor&& e) ASIO_NOEXCEPT; -#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Construct to point to the same target as another any_executor. -#if defined(GENERATING_DOCUMENTATION) - template - any_io_executor(execution::any_executor e); -#else // defined(GENERATING_DOCUMENTATION) - template - any_io_executor(OtherAnyExecutor e, - typename constraint< - conditional< - !is_same::value - && is_base_of::value, - typename execution::detail::supportable_properties< - 0, supportable_properties_type>::template - is_valid_target, - false_type - >::type::value - >::type = 0) - : base_type(ASIO_MOVE_CAST(OtherAnyExecutor)(e)) - { - } -#endif // defined(GENERATING_DOCUMENTATION) - - /// Construct a polymorphic wrapper for the specified executor. -#if defined(GENERATING_DOCUMENTATION) - template - any_io_executor(Executor e); -#else // defined(GENERATING_DOCUMENTATION) - template - any_io_executor(Executor e, - typename constraint< - conditional< - !is_same::value - && !is_base_of::value, - execution::detail::is_valid_target_executor< - Executor, supportable_properties_type>, - false_type - >::type::value - >::type = 0) - : base_type(ASIO_MOVE_CAST(Executor)(e)) - { - } -#endif // defined(GENERATING_DOCUMENTATION) - - /// Assignment operator. - ASIO_DECL any_io_executor& operator=( - const any_io_executor& e) ASIO_NOEXCEPT; - -#if defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - /// Move assignment operator. - ASIO_DECL any_io_executor& operator=( - any_io_executor&& e) ASIO_NOEXCEPT; -#endif // defined(ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) - - /// Assignment operator that sets the polymorphic wrapper to the empty state. - ASIO_DECL any_io_executor& operator=(nullptr_t); - - /// Destructor. - ASIO_DECL ~any_io_executor(); - - /// Swap targets with another polymorphic wrapper. - ASIO_DECL void swap(any_io_executor& other) ASIO_NOEXCEPT; - - /// Obtain a polymorphic wrapper with the specified property. - /** - * Do not call this function directly. It is intended for use with the - * asio::require and asio::prefer customisation points. - * - * For example: - * @code any_io_executor ex = ...; - * auto ex2 = asio::require(ex, execution::blocking.possibly); @endcode - */ - template - any_io_executor require(const Property& p, - typename constraint< - traits::require_member::is_valid - >::type = 0) const - { - return static_cast(*this).require(p); - } - - /// Obtain a polymorphic wrapper with the specified property. - /** - * Do not call this function directly. It is intended for use with the - * asio::prefer customisation point. - * - * For example: - * @code any_io_executor ex = ...; - * auto ex2 = asio::prefer(ex, execution::blocking.possibly); @endcode - */ - template - any_io_executor prefer(const Property& p, - typename constraint< - traits::prefer_member::is_valid - >::type = 0) const - { - return static_cast(*this).prefer(p); - } -}; - -#if !defined(GENERATING_DOCUMENTATION) - -template <> -ASIO_DECL any_io_executor any_io_executor::require( - const execution::blocking_t::never_t&, int) const; - -template <> -ASIO_DECL any_io_executor any_io_executor::prefer( - const execution::blocking_t::possibly_t&, int) const; - -template <> -ASIO_DECL any_io_executor any_io_executor::prefer( - const execution::outstanding_work_t::tracked_t&, int) const; - -template <> -ASIO_DECL any_io_executor any_io_executor::prefer( - const execution::outstanding_work_t::untracked_t&, int) const; - -template <> -ASIO_DECL any_io_executor any_io_executor::prefer( - const execution::relationship_t::fork_t&, int) const; - -template <> -ASIO_DECL any_io_executor any_io_executor::prefer( - const execution::relationship_t::continuation_t&, int) const; - -namespace traits { - -#if !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) - -template <> -struct equality_comparable -{ - static const bool is_valid = true; - static const bool is_noexcept = true; -}; - -#endif // !defined(ASIO_HAS_DEDUCED_EQUALITY_COMPARABLE_TRAIT) - -#if !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) - -template -struct execute_member -{ - static const bool is_valid = true; - static const bool is_noexcept = false; - typedef void result_type; -}; - -#endif // !defined(ASIO_HAS_DEDUCED_EXECUTE_MEMBER_TRAIT) - -#if !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) - -template -struct query_member : - query_member -{ -}; - -#endif // !defined(ASIO_HAS_DEDUCED_QUERY_MEMBER_TRAIT) - -#if !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT) - -template -struct require_member : - require_member -{ - typedef any_io_executor result_type; -}; - -#endif // !defined(ASIO_HAS_DEDUCED_REQUIRE_MEMBER_TRAIT) - -#if !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT) - -template -struct prefer_member : - prefer_member -{ - typedef any_io_executor result_type; -}; - -#endif // !defined(ASIO_HAS_DEDUCED_PREFER_MEMBER_TRAIT) - -} // namespace traits - -#endif // !defined(GENERATING_DOCUMENTATION) - -#endif // defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT) - -} // namespace asio - -#include "asio/detail/pop_options.hpp" - -#if defined(ASIO_HEADER_ONLY) \ - && !defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT) -# include "asio/impl/any_io_executor.ipp" -#endif // defined(ASIO_HEADER_ONLY) - // && !defined(ASIO_USE_TS_EXECUTOR_AS_DEFAULT) - -#endif // ASIO_ANY_IO_EXECUTOR_HPP diff --git a/include/ylt/thirdparty/asio/append.hpp b/include/ylt/thirdparty/asio/append.hpp deleted file mode 100644 index 227de90ff..000000000 --- a/include/ylt/thirdparty/asio/append.hpp +++ /dev/null @@ -1,78 +0,0 @@ -// -// append.hpp -// ~~~~~~~~~~ -// -// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef ASIO_APPEND_HPP -#define ASIO_APPEND_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_TUPLE) \ - && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \ - || defined(GENERATING_DOCUMENTATION) - -#include -#include "asio/detail/type_traits.hpp" - -#include "asio/detail/push_options.hpp" - -namespace asio { - -/// Completion token type used to specify that the completion handler -/// arguments should be passed additional values after the results of the -/// operation. -template -class append_t -{ -public: - /// Constructor. - template - ASIO_CONSTEXPR explicit append_t( - ASIO_MOVE_ARG(T) completion_token, - ASIO_MOVE_ARG(V)... values) - : token_(ASIO_MOVE_CAST(T)(completion_token)), - values_(ASIO_MOVE_CAST(V)(values)...) - { - } - -//private: - CompletionToken token_; - std::tuple values_; -}; - -/// Completion token type used to specify that the completion handler -/// arguments should be passed additional values after the results of the -/// operation. -template -ASIO_NODISCARD inline ASIO_CONSTEXPR append_t< - typename decay::type, typename decay::type...> -append(ASIO_MOVE_ARG(CompletionToken) completion_token, - ASIO_MOVE_ARG(Values)... values) -{ - return append_t< - typename decay::type, typename decay::type...>( - ASIO_MOVE_CAST(CompletionToken)(completion_token), - ASIO_MOVE_CAST(Values)(values)...); -} - -} // namespace asio - -#include "asio/detail/pop_options.hpp" - -#include "asio/impl/append.hpp" - -#endif // (defined(ASIO_HAS_STD_TUPLE) - // && defined(ASIO_HAS_VARIADIC_TEMPLATES)) - // || defined(GENERATING_DOCUMENTATION) - -#endif // ASIO_APPEND_HPP diff --git a/include/ylt/thirdparty/asio/as_tuple.hpp b/include/ylt/thirdparty/asio/as_tuple.hpp deleted file mode 100644 index 0629033b8..000000000 --- a/include/ylt/thirdparty/asio/as_tuple.hpp +++ /dev/null @@ -1,139 +0,0 @@ -// -// as_tuple.hpp -// ~~~~~~~~~~~~ -// -// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef ASIO_AS_TUPLE_HPP -#define ASIO_AS_TUPLE_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_TUPLE) \ - && defined(ASIO_HAS_VARIADIC_TEMPLATES)) \ - || defined(GENERATING_DOCUMENTATION) - -#include "asio/detail/type_traits.hpp" - -#include "asio/detail/push_options.hpp" - -namespace asio { - -/// A @ref completion_token adapter used to specify that the completion handler -/// arguments should be combined into a single tuple argument. -/** - * The as_tuple_t class is used to indicate that any arguments to the - * completion handler should be combined and passed as a single tuple argument. - * The arguments are first moved into a @c std::tuple and that tuple is then - * passed to the completion handler. - */ -template -class as_tuple_t -{ -public: - /// Tag type used to prevent the "default" constructor from being used for - /// conversions. - struct default_constructor_tag {}; - - /// Default constructor. - /** - * This constructor is only valid if the underlying completion token is - * default constructible and move constructible. The underlying completion - * token is itself defaulted as an argument to allow it to capture a source - * location. - */ - ASIO_CONSTEXPR as_tuple_t( - default_constructor_tag = default_constructor_tag(), - CompletionToken token = CompletionToken()) - : token_(ASIO_MOVE_CAST(CompletionToken)(token)) - { - } - - /// Constructor. - template - ASIO_CONSTEXPR explicit as_tuple_t( - ASIO_MOVE_ARG(T) completion_token) - : token_(ASIO_MOVE_CAST(T)(completion_token)) - { - } - - /// Adapts an executor to add the @c as_tuple_t completion token as the - /// default. - template - struct executor_with_default : InnerExecutor - { - /// Specify @c as_tuple_t as the default completion token type. - typedef as_tuple_t default_completion_token_type; - - /// Construct the adapted executor from the inner executor type. - template - executor_with_default(const InnerExecutor1& ex, - typename constraint< - conditional< - !is_same::value, - is_convertible, - false_type - >::type::value - >::type = 0) ASIO_NOEXCEPT - : InnerExecutor(ex) - { - } - }; - - /// Type alias to adapt an I/O object to use @c as_tuple_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 as_tuple_t as its - /// default completion token type. - template - static typename decay::type::template rebind_executor< - executor_with_default::type::executor_type> - >::other - as_default_on(ASIO_MOVE_ARG(T) object) - { - return typename decay::type::template rebind_executor< - executor_with_default::type::executor_type> - >::other(ASIO_MOVE_CAST(T)(object)); - } - -//private: - CompletionToken token_; -}; - -/// Adapt a @ref completion_token to specify that the completion handler -/// arguments should be combined into a single tuple argument. -template -ASIO_NODISCARD inline -ASIO_CONSTEXPR as_tuple_t::type> -as_tuple(ASIO_MOVE_ARG(CompletionToken) completion_token) -{ - return as_tuple_t::type>( - ASIO_MOVE_CAST(CompletionToken)(completion_token)); -} - -} // namespace asio - -#include "asio/detail/pop_options.hpp" - -#include "asio/impl/as_tuple.hpp" - -#endif // (defined(ASIO_HAS_STD_TUPLE) - // && defined(ASIO_HAS_VARIADIC_TEMPLATES)) - // || defined(GENERATING_DOCUMENTATION) - -#endif // ASIO_AS_TUPLE_HPP diff --git a/include/ylt/thirdparty/asio/associated_allocator.hpp b/include/ylt/thirdparty/asio/associated_allocator.hpp deleted file mode 100644 index e391004b8..000000000 --- a/include/ylt/thirdparty/asio/associated_allocator.hpp +++ /dev/null @@ -1,177 +0,0 @@ -// -// associated_allocator.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software 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/associator.hpp" -#include "asio/detail/functional.hpp" -#include "asio/detail/type_traits.hpp" - -#include "asio/detail/push_options.hpp" - -namespace asio { - -template -struct associated_allocator; - -namespace detail { - -template -struct has_allocator_type : false_type -{ -}; - -template -struct has_allocator_type::type> - : true_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(); - } -}; - -template -struct associated_allocator_impl::value - >::type, - typename void_type< - typename associator::type - >::type> : associator -{ -}; - -} // 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 -ASIO_NODISCARD 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 -ASIO_NODISCARD 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) - -#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) \ - || defined(GENERATING_DOCUMENTATION) - -/// Specialisation of associated_allocator for @c std::reference_wrapper. -template -struct associated_allocator, Allocator> -{ - /// Forwards @c type to the associator specialisation for the unwrapped type - /// @c T. - typedef typename associated_allocator::type type; - - /// Forwards the request to get the allocator to the associator specialisation - /// for the unwrapped type @c T. - static type get(reference_wrapper t, - const Allocator& a = Allocator()) ASIO_NOEXCEPT - { - return associated_allocator::get(t.get(), a); - } -}; - -#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER) - // || defined(GENERATING_DOCUMENTATION) - -} // namespace asio - -#include "asio/detail/pop_options.hpp" - -#endif // ASIO_ASSOCIATED_ALLOCATOR_HPP diff --git a/include/ylt/thirdparty/asio/associated_cancellation_slot.hpp b/include/ylt/thirdparty/asio/associated_cancellation_slot.hpp deleted file mode 100644 index 8fb21b6b7..000000000 --- a/include/ylt/thirdparty/asio/associated_cancellation_slot.hpp +++ /dev/null @@ -1,178 +0,0 @@ -// -// associated_cancellation_slot.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software 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_CANCELLATION_SLOT_HPP -#define ASIO_ASSOCIATED_CANCELLATION_SLOT_HPP - -#if defined(_MSC_VER) && (_MSC_VER >= 1200) -# pragma once -#endif // defined(_MSC_VER) && (_MSC_VER >= 1200) - -#include "asio/detail/config.hpp" -#include "asio/associator.hpp" -#include "asio/cancellation_signal.hpp" -#include "asio/detail/type_traits.hpp" - -#include "asio/detail/push_options.hpp" - -namespace asio { - -template -struct associated_cancellation_slot; - -namespace detail { - -template -struct has_cancellation_slot_type : false_type -{ -}; - -template -struct has_cancellation_slot_type::type> - : true_type -{ -}; - -template -struct associated_cancellation_slot_impl -{ - typedef void asio_associated_cancellation_slot_is_unspecialised; - - typedef S type; - - static type get(const T&, const S& s = S()) ASIO_NOEXCEPT - { - return s; - } -}; - -template -struct associated_cancellation_slot_impl::type> -{ - typedef typename T::cancellation_slot_type type; - - static type get(const T& t, const S& = S()) ASIO_NOEXCEPT - { - return t.get_cancellation_slot(); - } -}; - -template -struct associated_cancellation_slot_impl::value - >::type, - typename void_type< - typename associator::type - >::type> : associator -{ -}; - -} // namespace detail - -/// Traits type used to obtain the cancellation_slot 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 - * CancellationSlot shall be a type meeting the CancellationSlot requirements. - * - * Specialisations shall meet the following requirements, where @c t is a const - * reference to an object of type @c T, and @c s is an object of type @c - * CancellationSlot. - * - * @li Provide a nested typedef @c type that identifies a type meeting the - * CancellationSlot 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,s) and with return type @c type. - */ -template -struct associated_cancellation_slot -#if !defined(GENERATING_DOCUMENTATION) - : detail::associated_cancellation_slot_impl -#endif // !defined(GENERATING_DOCUMENTATION) -{ -#if defined(GENERATING_DOCUMENTATION) - /// If @c T has a nested type @c cancellation_slot_type, - /// T::cancellation_slot_type. Otherwise - /// @c CancellationSlot. - typedef see_below type; - - /// If @c T has a nested type @c cancellation_slot_type, returns - /// t.get_cancellation_slot(). Otherwise returns @c s. - static type get(const T& t, - const CancellationSlot& s = CancellationSlot()) ASIO_NOEXCEPT; -#endif // defined(GENERATING_DOCUMENTATION) -}; - -/// Helper function to obtain an object's associated cancellation_slot. -/** - * @returns associated_cancellation_slot::get(t) - */ -template -ASIO_NODISCARD inline typename associated_cancellation_slot::type -get_associated_cancellation_slot(const T& t) ASIO_NOEXCEPT -{ - return associated_cancellation_slot::get(t); -} - -/// Helper function to obtain an object's associated cancellation_slot. -/** - * @returns associated_cancellation_slot::get(t, st) - */ -template -ASIO_NODISCARD inline -typename associated_cancellation_slot::type -get_associated_cancellation_slot(const T& t, - const CancellationSlot& st) ASIO_NOEXCEPT -{ - return associated_cancellation_slot::get(t, st); -} - -#if defined(ASIO_HAS_ALIAS_TEMPLATES) - -template -using associated_cancellation_slot_t = - typename associated_cancellation_slot::type; - -#endif // defined(ASIO_HAS_ALIAS_TEMPLATES) - -namespace detail { - -template -struct associated_cancellation_slot_forwarding_base -{ -}; - -template -struct associated_cancellation_slot_forwarding_base::asio_associated_cancellation_slot_is_unspecialised, - void - >::value - >::type> -{ - typedef void asio_associated_cancellation_slot_is_unspecialised; -}; - -} // namespace detail -} // namespace asio - -#include "asio/detail/pop_options.hpp" - -#endif // ASIO_ASSOCIATED_CANCELLATION_SLOT_HPP diff --git a/include/ylt/thirdparty/asio/associated_executor.hpp b/include/ylt/thirdparty/asio/associated_executor.hpp deleted file mode 100644 index 3439bc563..000000000 --- a/include/ylt/thirdparty/asio/associated_executor.hpp +++ /dev/null @@ -1,222 +0,0 @@ -// -// associated_executor.hpp -// ~~~~~~~~~~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software 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/associator.hpp" -#include "asio/detail/functional.hpp" -#include "asio/detail/type_traits.hpp" -#include "asio/execution/executor.hpp" -#include "asio/is_executor.hpp" -#include "asio/system_executor.hpp" - -#include "asio/detail/push_options.hpp" - -namespace asio { - -template -struct associated_executor; - -namespace detail { - -template -struct has_executor_type : false_type -{ -}; - -template -struct has_executor_type::type> - : true_type -{ -}; - -template -struct associated_executor_impl -{ - typedef void asio_associated_executor_is_unspecialised; - - typedef E type; - - static type get(const T&, const E& 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& = E()) ASIO_NOEXCEPT - { - return t.get_executor(); - } -}; - -template -struct associated_executor_impl::value - >::type, - typename void_type< - typename associator::type - >::type> : associator -{ -}; - -} // 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 !defined(GENERATING_DOCUMENTATION) - : detail::associated_executor_impl -#endif // !defined(GENERATING_DOCUMENTATION) -{ -#if defined(GENERATING_DOCUMENTATION) - /// If @c T has a nested type @c executor_type, T::executor_type. - /// Otherwise @c Executor. - typedef see_below type; - - /// 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; -#endif // defined(GENERATING_DOCUMENTATION) -}; - -/// Helper function to obtain an object's associated executor. -/** - * @returns associated_executor::get(t) - */ -template -ASIO_NODISCARD 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 -ASIO_NODISCARD inline typename associated_executor::type -get_associated_executor(const T& t, const Executor& ex, - typename constraint< - is_executor::value || execution::is_executor::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 -ASIO_NODISCARD inline typename associated_executor::type -get_associated_executor(const T& t, ExecutionContext& ctx, - typename constraint::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 detail { - -template -struct associated_executor_forwarding_base -{ -}; - -template -struct associated_executor_forwarding_base::asio_associated_executor_is_unspecialised, - void - >::value - >::type> -{ - typedef void asio_associated_executor_is_unspecialised; -}; - -} // namespace detail - -#if defined(ASIO_HAS_STD_REFERENCE_WRAPPER) \ - || defined(GENERATING_DOCUMENTATION) - -/// Specialisation of associated_executor for @c std::reference_wrapper. -template -struct associated_executor, Executor> -#if !defined(GENERATING_DOCUMENTATION) - : detail::associated_executor_forwarding_base -#endif // !defined(GENERATING_DOCUMENTATION) -{ - /// Forwards @c type to the associator specialisation for the unwrapped type - /// @c T. - typedef typename associated_executor::type type; - - /// Forwards the request to get the executor to the associator specialisation - /// for the unwrapped type @c T. - static type get(reference_wrapper t, - const Executor& ex = Executor()) ASIO_NOEXCEPT - { - return associated_executor::get(t.get(), ex); - } -}; - -#endif // defined(ASIO_HAS_STD_REFERENCE_WRAPPER) - // || defined(GENERATING_DOCUMENTATION) - -} // namespace asio - -#include "asio/detail/pop_options.hpp" - -#endif // ASIO_ASSOCIATED_EXECUTOR_HPP diff --git a/include/ylt/thirdparty/asio/associator.hpp b/include/ylt/thirdparty/asio/associator.hpp deleted file mode 100644 index 1452de6a2..000000000 --- a/include/ylt/thirdparty/asio/associator.hpp +++ /dev/null @@ -1,35 +0,0 @@ -// -// associator.hpp -// ~~~~~~~~~~~~~~ -// -// Copyright (c) 2003-2022 Christopher M. Kohlhoff (chris at kohlhoff dot com) -// -// Distributed under the Boost Software License, Version 1.0. (See accompanying -// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) -// - -#ifndef ASIO_ASSOCIATOR_HPP -#define ASIO_ASSOCIATOR_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 { - -/// Used to generically specialise associators for a type. -template