couchbase 3.0.0-universal-darwin-19 → 3.0.1-universal-darwin-19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/ext/CMakeLists.txt +86 -169
- data/ext/build_version.hxx.in +3 -2
- data/ext/cmake/Backtrace.cmake +35 -0
- data/ext/cmake/BuildTracing.cmake +6 -0
- data/ext/cmake/Cache.cmake +29 -0
- data/ext/cmake/CompilerWarnings.cmake +78 -0
- data/ext/cmake/PreventInSourceBuilds.cmake +18 -0
- data/ext/cmake/Sanitizers.cmake +66 -0
- data/ext/cmake/StandardProjectSettings.cmake +40 -0
- data/ext/cmake/StaticAnalyzers.cmake +37 -0
- data/ext/cmake/Testing.cmake +52 -0
- data/ext/cmake/ThirdPartyDependencies.cmake +20 -0
- data/ext/cmake/VersionInfo.cmake +37 -0
- data/ext/couchbase/bucket.hxx +37 -12
- data/ext/couchbase/capabilities.hxx +117 -0
- data/ext/couchbase/cbcrypto/cbcrypto.cc +15 -15
- data/ext/couchbase/cluster.hxx +34 -2
- data/ext/couchbase/cluster_options.hxx +1 -0
- data/ext/couchbase/configuration.hxx +228 -52
- data/ext/couchbase/couchbase.cxx +914 -35
- data/ext/couchbase/diagnostics.hxx +251 -0
- data/ext/couchbase/document_id.hxx +3 -1
- data/ext/couchbase/errors.hxx +10 -1
- data/ext/couchbase/io/http_command.hxx +11 -7
- data/ext/couchbase/io/http_context.hxx +37 -0
- data/ext/couchbase/io/http_message.hxx +9 -0
- data/ext/couchbase/io/http_parser.hxx +2 -0
- data/ext/couchbase/io/http_session.hxx +100 -14
- data/ext/couchbase/io/http_session_manager.hxx +65 -5
- data/ext/couchbase/io/mcbp_command.hxx +16 -7
- data/ext/couchbase/io/mcbp_session.hxx +193 -51
- data/ext/couchbase/io/query_cache.hxx +61 -0
- data/ext/couchbase/io/retry_context.hxx +1 -2
- data/ext/couchbase/io/retry_orchestrator.hxx +16 -0
- data/ext/couchbase/io/retry_strategy.hxx +1 -1
- data/ext/couchbase/io/streams.hxx +61 -10
- data/ext/couchbase/operations.hxx +13 -0
- data/ext/couchbase/operations/analytics_dataset_create.hxx +1 -1
- data/ext/couchbase/operations/analytics_dataset_drop.hxx +1 -1
- data/ext/couchbase/operations/analytics_dataset_get_all.hxx +1 -1
- data/ext/couchbase/operations/analytics_dataverse_create.hxx +1 -1
- data/ext/couchbase/operations/analytics_dataverse_drop.hxx +1 -1
- data/ext/couchbase/operations/analytics_get_pending_mutations.hxx +1 -1
- data/ext/couchbase/operations/analytics_index_create.hxx +1 -1
- data/ext/couchbase/operations/analytics_index_drop.hxx +1 -1
- data/ext/couchbase/operations/analytics_index_get_all.hxx +1 -1
- data/ext/couchbase/operations/analytics_link_connect.hxx +1 -1
- data/ext/couchbase/operations/analytics_link_disconnect.hxx +1 -1
- data/ext/couchbase/operations/bucket_create.hxx +11 -5
- data/ext/couchbase/operations/bucket_drop.hxx +1 -1
- data/ext/couchbase/operations/bucket_flush.hxx +1 -1
- data/ext/couchbase/operations/bucket_get.hxx +1 -1
- data/ext/couchbase/operations/bucket_get_all.hxx +1 -1
- data/ext/couchbase/operations/bucket_settings.hxx +43 -4
- data/ext/couchbase/operations/bucket_update.hxx +11 -5
- data/ext/couchbase/operations/cluster_developer_preview_enable.hxx +1 -1
- data/ext/couchbase/operations/collection_create.hxx +3 -1
- data/ext/couchbase/operations/collection_drop.hxx +1 -1
- data/ext/couchbase/operations/collections_manifest_get.hxx +70 -0
- data/ext/couchbase/operations/document_analytics.hxx +6 -1
- data/ext/couchbase/operations/document_get_projected.hxx +1 -1
- data/ext/couchbase/operations/document_query.hxx +85 -8
- data/ext/couchbase/operations/document_search.hxx +14 -4
- data/ext/couchbase/operations/document_view.hxx +1 -1
- data/ext/couchbase/operations/group_drop.hxx +71 -0
- data/ext/couchbase/operations/group_get.hxx +75 -0
- data/ext/couchbase/operations/group_get_all.hxx +70 -0
- data/ext/couchbase/operations/group_upsert.hxx +118 -0
- data/ext/couchbase/operations/query_index_build_deferred.hxx +1 -1
- data/ext/couchbase/operations/query_index_create.hxx +1 -1
- data/ext/couchbase/operations/query_index_drop.hxx +1 -1
- data/ext/couchbase/operations/query_index_get_all.hxx +3 -2
- data/ext/couchbase/operations/rbac.hxx +276 -0
- data/ext/couchbase/operations/role_get_all.hxx +70 -0
- data/ext/couchbase/operations/scope_create.hxx +6 -2
- data/ext/couchbase/operations/scope_drop.hxx +1 -1
- data/ext/couchbase/operations/scope_get_all.hxx +1 -1
- data/ext/couchbase/operations/search_get_stats.hxx +59 -0
- data/ext/couchbase/operations/search_index_analyze_document.hxx +1 -1
- data/ext/couchbase/operations/search_index_control_ingest.hxx +1 -1
- data/ext/couchbase/operations/search_index_control_plan_freeze.hxx +1 -1
- data/ext/couchbase/operations/search_index_control_query.hxx +1 -1
- data/ext/couchbase/operations/search_index_drop.hxx +1 -1
- data/ext/couchbase/operations/search_index_get.hxx +1 -1
- data/ext/couchbase/operations/search_index_get_all.hxx +1 -1
- data/ext/couchbase/operations/search_index_get_documents_count.hxx +24 -16
- data/ext/couchbase/operations/search_index_get_stats.hxx +81 -0
- data/ext/couchbase/operations/search_index_upsert.hxx +1 -1
- data/ext/couchbase/operations/user_drop.hxx +72 -0
- data/ext/couchbase/operations/user_get.hxx +76 -0
- data/ext/couchbase/operations/user_get_all.hxx +71 -0
- data/ext/couchbase/operations/user_upsert.hxx +125 -0
- data/ext/couchbase/operations/view_index_drop.hxx +1 -1
- data/ext/couchbase/operations/view_index_get.hxx +1 -1
- data/ext/couchbase/operations/view_index_get_all.hxx +1 -1
- data/ext/couchbase/operations/view_index_upsert.hxx +1 -1
- data/ext/couchbase/origin.hxx +4 -4
- data/ext/couchbase/platform/terminate_handler.cc +5 -4
- data/ext/couchbase/protocol/client_opcode.hxx +38 -38
- data/ext/couchbase/protocol/client_response.hxx +2 -2
- data/ext/couchbase/protocol/cmd_cluster_map_change_notification.hxx +6 -3
- data/ext/couchbase/protocol/cmd_get_cluster_config.hxx +3 -1
- data/ext/couchbase/protocol/magic.hxx +6 -6
- data/ext/couchbase/protocol/server_opcode.hxx +2 -2
- data/ext/couchbase/protocol/status.hxx +57 -57
- data/ext/couchbase/service_type.hxx +1 -1
- data/ext/couchbase/utils/connection_string.hxx +12 -3
- data/ext/couchbase/version.hxx +1 -1
- data/ext/extconf.rb +21 -9
- data/ext/test/test_helper.hxx +141 -0
- data/ext/test/test_helper_native.hxx +59 -0
- data/ext/test/test_helper_ruby.hxx +72 -0
- data/ext/test/test_native_diagnostics.cxx +385 -0
- data/ext/test/test_native_trivial_crud.cxx +83 -0
- data/ext/test/test_ruby_trivial_crud.cxx +35 -0
- data/ext/test/test_ruby_trivial_query.cxx +34 -0
- data/ext/third_party/asio/asio/include/asio.hpp +35 -0
- data/ext/third_party/asio/asio/include/asio/any_io_executor.hpp +71 -0
- data/ext/third_party/asio/asio/include/asio/associated_allocator.hpp +1 -7
- data/ext/third_party/asio/asio/include/asio/associated_executor.hpp +36 -19
- data/ext/third_party/asio/asio/include/asio/async_result.hpp +1 -8
- data/ext/third_party/asio/asio/include/asio/awaitable.hpp +14 -4
- data/ext/third_party/asio/asio/include/asio/basic_datagram_socket.hpp +12 -7
- data/ext/third_party/asio/asio/include/asio/basic_deadline_timer.hpp +4 -4
- data/ext/third_party/asio/asio/include/asio/basic_raw_socket.hpp +11 -7
- data/ext/third_party/asio/asio/include/asio/basic_seq_packet_socket.hpp +9 -4
- data/ext/third_party/asio/asio/include/asio/basic_serial_port.hpp +6 -6
- data/ext/third_party/asio/asio/include/asio/basic_signal_set.hpp +4 -4
- data/ext/third_party/asio/asio/include/asio/basic_socket.hpp +5 -5
- data/ext/third_party/asio/asio/include/asio/basic_socket_acceptor.hpp +13 -7
- data/ext/third_party/asio/asio/include/asio/basic_stream_socket.hpp +7 -3
- data/ext/third_party/asio/asio/include/asio/basic_waitable_timer.hpp +52 -4
- data/ext/third_party/asio/asio/include/asio/bind_executor.hpp +10 -15
- data/ext/third_party/asio/asio/include/asio/buffer.hpp +6 -4
- data/ext/third_party/asio/asio/include/asio/co_spawn.hpp +380 -9
- data/ext/third_party/asio/asio/include/asio/defer.hpp +4 -1
- data/ext/third_party/asio/asio/include/asio/detached.hpp +50 -0
- data/ext/third_party/asio/asio/include/asio/detail/atomic_count.hpp +19 -0
- data/ext/third_party/asio/asio/include/asio/detail/bind_handler.hpp +144 -26
- data/ext/third_party/asio/asio/include/asio/detail/blocking_executor_op.hpp +107 -0
- data/ext/third_party/asio/asio/include/asio/detail/buffer_sequence_adapter.hpp +106 -0
- data/ext/third_party/asio/asio/include/asio/detail/bulk_executor_op.hpp +88 -0
- data/ext/third_party/asio/asio/include/asio/detail/completion_handler.hpp +10 -5
- data/ext/third_party/asio/asio/include/asio/detail/conditionally_enabled_event.hpp +8 -0
- data/ext/third_party/asio/asio/include/asio/detail/config.hpp +360 -37
- data/ext/third_party/asio/asio/include/asio/detail/deadline_timer_service.hpp +17 -2
- data/ext/third_party/asio/asio/include/asio/detail/descriptor_ops.hpp +24 -6
- data/ext/third_party/asio/asio/include/asio/detail/descriptor_read_op.hpp +32 -14
- data/ext/third_party/asio/asio/include/asio/detail/descriptor_write_op.hpp +32 -14
- data/ext/third_party/asio/asio/include/asio/detail/executor_function.hpp +133 -34
- data/ext/third_party/asio/asio/include/asio/detail/handler_alloc_helpers.hpp +42 -0
- data/ext/third_party/asio/asio/include/asio/detail/handler_invoke_helpers.hpp +23 -0
- data/ext/third_party/asio/asio/include/asio/detail/handler_tracking.hpp +26 -0
- data/ext/third_party/asio/asio/include/asio/detail/handler_work.hpp +370 -45
- data/ext/third_party/asio/asio/include/asio/detail/impl/descriptor_ops.ipp +208 -74
- data/ext/third_party/asio/asio/include/asio/detail/impl/handler_tracking.ipp +39 -1
- data/ext/third_party/asio/asio/include/asio/detail/impl/reactive_serial_port_service.ipp +12 -15
- data/ext/third_party/asio/asio/include/asio/detail/impl/scheduler.ipp +37 -0
- data/ext/third_party/asio/asio/include/asio/detail/impl/signal_set_service.ipp +2 -1
- data/ext/third_party/asio/asio/include/asio/detail/impl/socket_ops.ipp +661 -274
- data/ext/third_party/asio/asio/include/asio/detail/impl/strand_executor_service.hpp +210 -4
- data/ext/third_party/asio/asio/include/asio/detail/impl/strand_service.hpp +8 -9
- data/ext/third_party/asio/asio/include/asio/detail/impl/strand_service.ipp +5 -4
- data/ext/third_party/asio/asio/include/asio/detail/impl/win_iocp_io_context.ipp +15 -6
- data/ext/third_party/asio/asio/include/asio/detail/io_object_impl.hpp +32 -50
- data/ext/third_party/asio/asio/include/asio/detail/memory.hpp +3 -0
- data/ext/third_party/asio/asio/include/asio/detail/null_event.hpp +6 -0
- data/ext/third_party/asio/asio/include/asio/detail/pop_options.hpp +1 -1
- data/ext/third_party/asio/asio/include/asio/detail/posix_event.hpp +13 -0
- data/ext/third_party/asio/asio/include/asio/detail/push_options.hpp +1 -1
- data/ext/third_party/asio/asio/include/asio/detail/reactive_descriptor_service.hpp +38 -13
- data/ext/third_party/asio/asio/include/asio/detail/reactive_null_buffers_op.hpp +12 -6
- data/ext/third_party/asio/asio/include/asio/detail/reactive_serial_port_service.hpp +2 -3
- data/ext/third_party/asio/asio/include/asio/detail/reactive_socket_accept_op.hpp +36 -24
- data/ext/third_party/asio/asio/include/asio/detail/reactive_socket_connect_op.hpp +17 -10
- data/ext/third_party/asio/asio/include/asio/detail/reactive_socket_recv_op.hpp +38 -16
- data/ext/third_party/asio/asio/include/asio/detail/reactive_socket_recvfrom_op.hpp +36 -14
- data/ext/third_party/asio/asio/include/asio/detail/reactive_socket_recvmsg_op.hpp +21 -11
- data/ext/third_party/asio/asio/include/asio/detail/reactive_socket_send_op.hpp +43 -17
- data/ext/third_party/asio/asio/include/asio/detail/reactive_socket_sendto_op.hpp +39 -17
- data/ext/third_party/asio/asio/include/asio/detail/reactive_socket_service.hpp +44 -21
- data/ext/third_party/asio/asio/include/asio/detail/reactive_socket_service_base.hpp +41 -18
- data/ext/third_party/asio/asio/include/asio/detail/reactive_wait_op.hpp +12 -6
- data/ext/third_party/asio/asio/include/asio/detail/reactor_op.hpp +3 -1
- data/ext/third_party/asio/asio/include/asio/detail/resolve_endpoint_op.hpp +10 -8
- data/ext/third_party/asio/asio/include/asio/detail/resolve_query_op.hpp +11 -9
- data/ext/third_party/asio/asio/include/asio/detail/scheduler.hpp +8 -0
- data/ext/third_party/asio/asio/include/asio/detail/signal_handler.hpp +7 -5
- data/ext/third_party/asio/asio/include/asio/detail/socket_ops.hpp +46 -0
- data/ext/third_party/asio/asio/include/asio/detail/source_location.hpp +45 -0
- data/ext/third_party/asio/asio/include/asio/detail/std_event.hpp +12 -0
- data/ext/third_party/asio/asio/include/asio/detail/strand_executor_service.hpp +25 -1
- data/ext/third_party/asio/asio/include/asio/detail/strand_service.hpp +4 -1
- data/ext/third_party/asio/asio/include/asio/detail/thread_info_base.hpp +58 -0
- data/ext/third_party/asio/asio/include/asio/detail/type_traits.hpp +59 -0
- data/ext/third_party/asio/asio/include/asio/detail/variadic_templates.hpp +144 -1
- data/ext/third_party/asio/asio/include/asio/detail/wait_handler.hpp +9 -6
- data/ext/third_party/asio/asio/include/asio/detail/win_event.hpp +13 -0
- data/ext/third_party/asio/asio/include/asio/detail/win_iocp_handle_read_op.hpp +9 -5
- data/ext/third_party/asio/asio/include/asio/detail/win_iocp_handle_write_op.hpp +9 -5
- data/ext/third_party/asio/asio/include/asio/detail/win_iocp_io_context.hpp +5 -1
- data/ext/third_party/asio/asio/include/asio/detail/win_iocp_null_buffers_op.hpp +10 -6
- data/ext/third_party/asio/asio/include/asio/detail/win_iocp_overlapped_op.hpp +9 -5
- data/ext/third_party/asio/asio/include/asio/detail/win_iocp_overlapped_ptr.hpp +18 -6
- data/ext/third_party/asio/asio/include/asio/detail/win_iocp_socket_accept_op.hpp +15 -11
- data/ext/third_party/asio/asio/include/asio/detail/win_iocp_socket_connect_op.hpp +10 -5
- data/ext/third_party/asio/asio/include/asio/detail/win_iocp_socket_recv_op.hpp +8 -4
- data/ext/third_party/asio/asio/include/asio/detail/win_iocp_socket_recvfrom_op.hpp +8 -4
- data/ext/third_party/asio/asio/include/asio/detail/win_iocp_socket_recvmsg_op.hpp +8 -4
- data/ext/third_party/asio/asio/include/asio/detail/win_iocp_socket_send_op.hpp +8 -4
- data/ext/third_party/asio/asio/include/asio/detail/win_iocp_wait_op.hpp +10 -5
- data/ext/third_party/asio/asio/include/asio/detail/winrt_resolve_op.hpp +8 -4
- data/ext/third_party/asio/asio/include/asio/detail/winrt_socket_connect_op.hpp +8 -4
- data/ext/third_party/asio/asio/include/asio/detail/winrt_socket_recv_op.hpp +8 -4
- data/ext/third_party/asio/asio/include/asio/detail/winrt_socket_send_op.hpp +8 -4
- data/ext/third_party/asio/asio/include/asio/detail/work_dispatcher.hpp +81 -6
- data/ext/third_party/asio/asio/include/asio/detail/wrapped_handler.hpp +45 -9
- data/ext/third_party/asio/asio/include/asio/dispatch.hpp +4 -1
- data/ext/third_party/asio/asio/include/asio/execution.hpp +48 -0
- data/ext/third_party/asio/asio/include/asio/execution/allocator.hpp +249 -0
- data/ext/third_party/asio/asio/include/asio/execution/any_executor.hpp +2264 -0
- data/ext/third_party/asio/asio/include/asio/execution/bad_executor.hpp +47 -0
- data/ext/third_party/asio/asio/include/asio/execution/blocking.hpp +1351 -0
- data/ext/third_party/asio/asio/include/asio/execution/blocking_adaptation.hpp +1064 -0
- data/ext/third_party/asio/asio/include/asio/execution/bulk_execute.hpp +390 -0
- data/ext/third_party/asio/asio/include/asio/execution/bulk_guarantee.hpp +1018 -0
- data/ext/third_party/asio/asio/include/asio/execution/connect.hpp +486 -0
- data/ext/third_party/asio/asio/include/asio/execution/context.hpp +185 -0
- data/ext/third_party/asio/asio/include/asio/execution/context_as.hpp +201 -0
- data/ext/third_party/asio/asio/include/asio/execution/detail/as_invocable.hpp +152 -0
- data/ext/third_party/asio/asio/include/asio/execution/detail/as_operation.hpp +105 -0
- data/ext/third_party/asio/asio/include/asio/execution/detail/as_receiver.hpp +128 -0
- data/ext/third_party/asio/asio/include/asio/execution/detail/bulk_sender.hpp +261 -0
- data/ext/third_party/asio/asio/include/asio/execution/detail/submit_receiver.hpp +233 -0
- data/ext/third_party/asio/asio/include/asio/execution/detail/void_receiver.hpp +90 -0
- data/ext/third_party/asio/asio/include/asio/execution/execute.hpp +264 -0
- data/ext/third_party/asio/asio/include/asio/execution/executor.hpp +238 -0
- data/ext/third_party/asio/asio/include/asio/execution/impl/bad_executor.ipp +40 -0
- data/ext/third_party/asio/asio/include/asio/execution/impl/receiver_invocation_error.ipp +36 -0
- data/ext/third_party/asio/asio/include/asio/execution/invocable_archetype.hpp +71 -0
- data/ext/third_party/asio/asio/include/asio/execution/mapping.hpp +917 -0
- data/ext/third_party/asio/asio/include/asio/execution/occupancy.hpp +178 -0
- data/ext/third_party/asio/asio/include/asio/execution/operation_state.hpp +94 -0
- data/ext/third_party/asio/asio/include/asio/execution/outstanding_work.hpp +721 -0
- data/ext/third_party/asio/asio/include/asio/execution/prefer_only.hpp +327 -0
- data/ext/third_party/asio/asio/include/asio/execution/receiver.hpp +280 -0
- data/ext/third_party/asio/asio/include/asio/execution/receiver_invocation_error.hpp +48 -0
- data/ext/third_party/asio/asio/include/asio/execution/relationship.hpp +720 -0
- data/ext/third_party/asio/asio/include/asio/execution/schedule.hpp +290 -0
- data/ext/third_party/asio/asio/include/asio/execution/scheduler.hpp +86 -0
- data/ext/third_party/asio/asio/include/asio/execution/sender.hpp +311 -0
- data/ext/third_party/asio/asio/include/asio/execution/set_done.hpp +253 -0
- data/ext/third_party/asio/asio/include/asio/execution/set_error.hpp +253 -0
- data/ext/third_party/asio/asio/include/asio/execution/set_value.hpp +486 -0
- data/ext/third_party/asio/asio/include/asio/execution/start.hpp +250 -0
- data/ext/third_party/asio/asio/include/asio/execution/submit.hpp +450 -0
- data/ext/third_party/asio/asio/include/asio/executor.hpp +7 -1
- data/ext/third_party/asio/asio/include/asio/executor_work_guard.hpp +126 -9
- data/ext/third_party/asio/asio/include/asio/handler_alloc_hook.hpp +28 -5
- data/ext/third_party/asio/asio/include/asio/handler_invoke_hook.hpp +29 -3
- data/ext/third_party/asio/asio/include/asio/impl/awaitable.hpp +14 -0
- data/ext/third_party/asio/asio/include/asio/impl/buffered_read_stream.hpp +44 -8
- data/ext/third_party/asio/asio/include/asio/impl/buffered_write_stream.hpp +44 -8
- data/ext/third_party/asio/asio/include/asio/impl/co_spawn.hpp +145 -7
- data/ext/third_party/asio/asio/include/asio/impl/compose.hpp +124 -22
- data/ext/third_party/asio/asio/include/asio/impl/connect.hpp +52 -8
- data/ext/third_party/asio/asio/include/asio/impl/defer.hpp +147 -12
- data/ext/third_party/asio/asio/include/asio/impl/dispatch.hpp +142 -12
- data/ext/third_party/asio/asio/include/asio/impl/executor.hpp +15 -101
- data/ext/third_party/asio/asio/include/asio/impl/executor.ipp +5 -0
- data/ext/third_party/asio/asio/include/asio/impl/handler_alloc_hook.ipp +13 -4
- data/ext/third_party/asio/asio/include/asio/impl/io_context.hpp +144 -57
- data/ext/third_party/asio/asio/include/asio/impl/multiple_exceptions.ipp +49 -0
- data/ext/third_party/asio/asio/include/asio/impl/post.hpp +147 -12
- data/ext/third_party/asio/asio/include/asio/impl/read.hpp +85 -18
- data/ext/third_party/asio/asio/include/asio/impl/read_at.hpp +59 -14
- data/ext/third_party/asio/asio/include/asio/impl/read_until.hpp +241 -56
- data/ext/third_party/asio/asio/include/asio/impl/redirect_error.hpp +22 -4
- data/ext/third_party/asio/asio/include/asio/impl/spawn.hpp +58 -22
- data/ext/third_party/asio/asio/include/asio/impl/src.hpp +3 -0
- data/ext/third_party/asio/asio/include/asio/impl/system_context.ipp +16 -4
- data/ext/third_party/asio/asio/include/asio/impl/system_executor.hpp +113 -12
- data/ext/third_party/asio/asio/include/asio/impl/thread_pool.hpp +260 -37
- data/ext/third_party/asio/asio/include/asio/impl/thread_pool.ipp +61 -7
- data/ext/third_party/asio/asio/include/asio/impl/use_awaitable.hpp +5 -2
- data/ext/third_party/asio/asio/include/asio/impl/use_future.hpp +147 -6
- data/ext/third_party/asio/asio/include/asio/impl/write.hpp +75 -14
- data/ext/third_party/asio/asio/include/asio/impl/write_at.hpp +53 -11
- data/ext/third_party/asio/asio/include/asio/io_context.hpp +706 -48
- data/ext/third_party/asio/asio/include/asio/io_context_strand.hpp +3 -1
- data/ext/third_party/asio/asio/include/asio/ip/basic_resolver.hpp +4 -4
- data/ext/third_party/asio/asio/include/asio/is_applicable_property.hpp +61 -0
- data/ext/third_party/asio/asio/include/asio/multiple_exceptions.hpp +58 -0
- data/ext/third_party/asio/asio/include/asio/posix/basic_descriptor.hpp +4 -4
- data/ext/third_party/asio/asio/include/asio/posix/basic_stream_descriptor.hpp +5 -5
- data/ext/third_party/asio/asio/include/asio/post.hpp +4 -1
- data/ext/third_party/asio/asio/include/asio/prefer.hpp +656 -0
- data/ext/third_party/asio/asio/include/asio/query.hpp +296 -0
- data/ext/third_party/asio/asio/include/asio/read_until.hpp +6 -6
- data/ext/third_party/asio/asio/include/asio/require.hpp +524 -0
- data/ext/third_party/asio/asio/include/asio/require_concept.hpp +310 -0
- data/ext/third_party/asio/asio/include/asio/spawn.hpp +12 -4
- data/ext/third_party/asio/asio/include/asio/ssl/detail/buffered_handshake_op.hpp +5 -0
- data/ext/third_party/asio/asio/include/asio/ssl/detail/engine.hpp +5 -0
- data/ext/third_party/asio/asio/include/asio/ssl/detail/handshake_op.hpp +5 -0
- data/ext/third_party/asio/asio/include/asio/ssl/detail/impl/engine.ipp +16 -3
- data/ext/third_party/asio/asio/include/asio/ssl/detail/io.hpp +38 -4
- data/ext/third_party/asio/asio/include/asio/ssl/detail/read_op.hpp +5 -0
- data/ext/third_party/asio/asio/include/asio/ssl/detail/shutdown_op.hpp +5 -0
- data/ext/third_party/asio/asio/include/asio/ssl/detail/stream_core.hpp +36 -2
- data/ext/third_party/asio/asio/include/asio/ssl/detail/write_op.hpp +10 -1
- data/ext/third_party/asio/asio/include/asio/ssl/stream.hpp +15 -0
- data/ext/third_party/asio/asio/include/asio/static_thread_pool.hpp +31 -0
- data/ext/third_party/asio/asio/include/asio/strand.hpp +232 -9
- data/ext/third_party/asio/asio/include/asio/system_context.hpp +12 -3
- data/ext/third_party/asio/asio/include/asio/system_executor.hpp +557 -24
- data/ext/third_party/asio/asio/include/asio/thread_pool.hpp +913 -37
- data/ext/third_party/asio/asio/include/asio/traits/bulk_execute_free.hpp +114 -0
- data/ext/third_party/asio/asio/include/asio/traits/bulk_execute_member.hpp +114 -0
- data/ext/third_party/asio/asio/include/asio/traits/connect_free.hpp +112 -0
- data/ext/third_party/asio/asio/include/asio/traits/connect_member.hpp +112 -0
- data/ext/third_party/asio/asio/include/asio/traits/equality_comparable.hpp +100 -0
- data/ext/third_party/asio/asio/include/asio/traits/execute_free.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/execute_member.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/prefer_free.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/prefer_member.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/query_free.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/query_member.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/query_static_constexpr_member.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/require_concept_free.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/require_concept_member.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/require_free.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/require_member.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/schedule_free.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/schedule_member.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/set_done_free.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/set_done_member.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/set_error_free.hpp +112 -0
- data/ext/third_party/asio/asio/include/asio/traits/set_error_member.hpp +112 -0
- data/ext/third_party/asio/asio/include/asio/traits/set_value_free.hpp +234 -0
- data/ext/third_party/asio/asio/include/asio/traits/set_value_member.hpp +234 -0
- data/ext/third_party/asio/asio/include/asio/traits/start_free.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/start_member.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/static_query.hpp +108 -0
- data/ext/third_party/asio/asio/include/asio/traits/static_require.hpp +123 -0
- data/ext/third_party/asio/asio/include/asio/traits/static_require_concept.hpp +123 -0
- data/ext/third_party/asio/asio/include/asio/traits/submit_free.hpp +112 -0
- data/ext/third_party/asio/asio/include/asio/traits/submit_member.hpp +112 -0
- data/ext/third_party/asio/asio/include/asio/ts/executor.hpp +1 -0
- data/ext/third_party/asio/asio/include/asio/ts/netfwd.hpp +67 -8
- data/ext/third_party/asio/asio/include/asio/use_awaitable.hpp +63 -4
- data/ext/third_party/asio/asio/include/asio/version.hpp +1 -1
- data/ext/third_party/asio/asio/include/asio/windows/basic_object_handle.hpp +4 -4
- data/ext/third_party/asio/asio/include/asio/windows/basic_overlapped_handle.hpp +2 -2
- data/ext/third_party/asio/asio/include/asio/windows/basic_random_access_handle.hpp +5 -5
- data/ext/third_party/asio/asio/include/asio/windows/basic_stream_handle.hpp +5 -5
- data/ext/third_party/asio/asio/include/asio/windows/overlapped_ptr.hpp +4 -2
- data/ext/third_party/gsl/CMakeLists.txt +13 -5
- data/ext/third_party/gsl/include/gsl/gsl_assert +1 -1
- data/ext/third_party/gsl/include/gsl/gsl_byte +3 -3
- data/ext/third_party/gsl/include/gsl/gsl_narrow +52 -0
- data/ext/third_party/gsl/include/gsl/gsl_util +8 -50
- data/ext/third_party/gsl/include/gsl/multi_span +0 -10
- data/ext/third_party/gsl/include/gsl/pointers +14 -28
- data/ext/third_party/gsl/include/gsl/span +98 -46
- data/ext/third_party/gsl/include/gsl/string_span +37 -47
- data/ext/third_party/http_parser/http_parser.c +17 -10
- data/ext/third_party/http_parser/http_parser.h +4 -2
- data/ext/third_party/json/include/tao/json/basic_value.hpp +3 -2
- data/ext/third_party/json/include/tao/json/binary.hpp +4 -4
- data/ext/third_party/json/include/tao/json/binary_view.hpp +2 -2
- data/ext/third_party/json/include/tao/json/binding.hpp +2 -2
- data/ext/third_party/json/include/tao/json/binding/factory.hpp +8 -7
- data/ext/third_party/json/include/tao/json/binding/internal/array.hpp +2 -1
- data/ext/third_party/json/include/tao/json/binding/internal/object.hpp +6 -5
- data/ext/third_party/json/include/tao/json/binding/versions.hpp +3 -1
- data/ext/third_party/json/include/tao/json/cbor.hpp +1 -0
- data/ext/third_party/json/include/tao/json/cbor/consume_file.hpp +7 -7
- data/ext/third_party/json/include/tao/json/cbor/events/from_binary.hpp +43 -0
- data/ext/third_party/json/include/tao/json/cbor/events/from_file.hpp +4 -4
- data/ext/third_party/json/include/tao/json/cbor/events/from_string.hpp +3 -3
- data/ext/third_party/json/include/tao/json/cbor/from_binary.hpp +32 -0
- data/ext/third_party/json/include/tao/json/cbor/from_file.hpp +5 -5
- data/ext/third_party/json/include/tao/json/cbor/internal/grammar.hpp +2 -1
- data/ext/third_party/json/include/tao/json/consume_file.hpp +7 -7
- data/ext/third_party/json/include/tao/json/contrib/internal/indirect_traits.hpp +13 -6
- data/ext/third_party/json/include/tao/json/contrib/position.hpp +15 -15
- data/ext/third_party/json/include/tao/json/contrib/reference.hpp +5 -7
- data/ext/third_party/json/include/tao/json/contrib/schema.hpp +58 -35
- data/ext/third_party/json/include/tao/json/contrib/shared_ptr_traits.hpp +12 -4
- data/ext/third_party/json/include/tao/json/contrib/unique_ptr_traits.hpp +12 -4
- data/ext/third_party/json/include/tao/json/contrib/unordered_map_traits.hpp +1 -1
- data/ext/third_party/json/include/tao/json/contrib/unordered_set_traits.hpp +2 -2
- data/ext/third_party/json/include/tao/json/events/compare.hpp +2 -12
- data/ext/third_party/json/include/tao/json/events/from_file.hpp +4 -4
- data/ext/third_party/json/include/tao/json/events/from_string.hpp +2 -2
- data/ext/third_party/json/include/tao/json/events/invalid_string_to_binary.hpp +1 -1
- data/ext/third_party/json/include/tao/json/events/key_camel_case_to_snake_case.hpp +3 -3
- data/ext/third_party/json/include/tao/json/events/key_snake_case_to_camel_case.hpp +1 -1
- data/ext/third_party/json/include/tao/json/events/tee.hpp +2 -2
- data/ext/third_party/json/include/tao/json/events/to_pretty_stream.hpp +1 -1
- data/ext/third_party/json/include/tao/json/events/to_stream.hpp +1 -1
- data/ext/third_party/json/include/tao/json/events/transformer.hpp +3 -3
- data/ext/third_party/json/include/tao/json/events/validate_event_order.hpp +3 -3
- data/ext/third_party/json/include/tao/json/events/virtual_ref.hpp +6 -0
- data/ext/third_party/json/include/tao/json/external/pegtl.hpp +4 -13
- data/ext/third_party/json/include/tao/json/external/pegtl/argv_input.hpp +3 -5
- data/ext/third_party/json/include/tao/json/external/pegtl/ascii.hpp +5 -18
- data/ext/third_party/json/include/tao/json/external/pegtl/buffer_input.hpp +3 -3
- data/ext/third_party/json/include/tao/json/external/pegtl/change_action.hpp +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/change_action_and_state.hpp +6 -6
- data/ext/third_party/json/include/tao/json/external/pegtl/change_action_and_states.hpp +5 -5
- data/ext/third_party/json/include/tao/json/external/pegtl/change_control.hpp +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/change_state.hpp +6 -6
- data/ext/third_party/json/include/tao/json/external/pegtl/change_states.hpp +5 -5
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/alphabet.hpp +52 -52
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/analyze.hpp +176 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/analyze_traits.hpp +275 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/control_action.hpp +77 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/coverage.hpp +151 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/forward.hpp +16 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/http.hpp +37 -18
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/icu/internal.hpp +20 -22
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/icu/utf16.hpp +6 -10
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/icu/utf32.hpp +6 -10
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/icu/utf8.hpp +2 -4
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/if_then.hpp +11 -10
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/integer.hpp +116 -131
- data/ext/third_party/json/include/tao/json/external/pegtl/{internal → contrib/internal}/endian.hpp +4 -4
- data/ext/third_party/json/include/tao/json/external/pegtl/{internal → contrib/internal}/endian_gcc.hpp +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/{internal → contrib/internal}/endian_win.hpp +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/{internal → contrib/internal}/peek_mask_uint.hpp +9 -9
- data/ext/third_party/json/include/tao/json/external/pegtl/{internal → contrib/internal}/peek_mask_uint8.hpp +9 -10
- data/ext/third_party/json/include/tao/json/external/pegtl/{internal → contrib/internal}/peek_uint.hpp +9 -9
- data/ext/third_party/json/include/tao/json/external/pegtl/{internal → contrib/internal}/peek_uint8.hpp +9 -10
- data/ext/third_party/json/include/tao/json/external/pegtl/{internal → contrib/internal}/peek_utf16.hpp +10 -10
- data/ext/third_party/json/include/tao/json/external/pegtl/{internal → contrib/internal}/peek_utf32.hpp +9 -9
- data/ext/third_party/json/include/tao/json/external/pegtl/{internal → contrib/internal}/read_uint.hpp +3 -3
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/internal/set_stack_guard.hpp +52 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/parse_tree.hpp +80 -201
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/parse_tree_to_dot.hpp +11 -10
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/print.hpp +75 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/print_coverage.hpp +53 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/raw_string.hpp +45 -36
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/remove_first_state.hpp +33 -50
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/remove_last_states.hpp +117 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/rep_one_min_max.hpp +43 -11
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/rep_string.hpp +1 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/shuffle_states.hpp +193 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/state_control.hpp +118 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/trace.hpp +227 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/{uint16.hpp → contrib/uint16.hpp} +5 -5
- data/ext/third_party/json/include/tao/json/external/pegtl/{uint32.hpp → contrib/uint32.hpp} +5 -5
- data/ext/third_party/json/include/tao/json/external/pegtl/{uint64.hpp → contrib/uint64.hpp} +5 -5
- data/ext/third_party/json/include/tao/json/external/pegtl/{uint8.hpp → contrib/uint8.hpp} +5 -5
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/unescape.hpp +14 -14
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/uri.hpp +1 -1
- data/ext/third_party/json/include/tao/json/external/pegtl/{utf16.hpp → contrib/utf16.hpp} +5 -5
- data/ext/third_party/json/include/tao/json/external/pegtl/{utf32.hpp → contrib/utf32.hpp} +5 -5
- data/ext/third_party/json/include/tao/json/external/pegtl/cstream_input.hpp +2 -3
- data/ext/third_party/json/include/tao/json/external/pegtl/{internal/demangle.hpp → demangle.hpp} +12 -14
- data/ext/third_party/json/include/tao/json/external/pegtl/disable_action.hpp +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/discard_input.hpp +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/discard_input_on_failure.hpp +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/discard_input_on_success.hpp +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/enable_action.hpp +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/file_input.hpp +1 -1
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/action.hpp +19 -9
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/action_input.hpp +7 -8
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/any.hpp +14 -14
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/apply.hpp +9 -9
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/apply0.hpp +8 -7
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/apply_single.hpp +4 -4
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/at.hpp +17 -15
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/bof.hpp +7 -6
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/bol.hpp +8 -8
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/bump.hpp +4 -4
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/bump_help.hpp +3 -3
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/bytes.hpp +17 -10
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/control.hpp +19 -9
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/cr_crlf_eol.hpp +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/cr_eol.hpp +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/crlf_eol.hpp +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/cstream_reader.hpp +1 -1
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/{always_false.hpp → dependent_false.hpp} +3 -8
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/disable.hpp +19 -9
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/discard.hpp +7 -6
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/enable.hpp +19 -9
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/{skip_control.hpp → enable_control.hpp} +5 -5
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/eof.hpp +7 -6
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/eol.hpp +8 -7
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/eolf.hpp +8 -7
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/failure.hpp +32 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/file_mapper_posix.hpp +61 -10
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/file_mapper_win32.hpp +27 -33
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/file_reader.hpp +29 -26
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/has_apply.hpp +3 -7
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/has_apply0.hpp +3 -7
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/has_match.hpp +4 -20
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/has_unwind.hpp +21 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/if_apply.hpp +8 -7
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/if_must.hpp +8 -9
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/if_must_else.hpp +2 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/if_then_else.hpp +7 -7
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/istream_reader.hpp +1 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/istring.hpp +11 -11
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/iterator.hpp +7 -10
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/lf_crlf_eol.hpp +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/lf_eol.hpp +2 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/list_tail.hpp +4 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/list_tail_pad.hpp +1 -1
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/marker.hpp +3 -5
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/minus.hpp +21 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/missing_apply.hpp +5 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/missing_apply0.hpp +5 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/must.hpp +16 -24
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/not_at.hpp +17 -15
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/one.hpp +23 -12
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/opt.hpp +16 -16
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/path_to_string.hpp +26 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/peek_char.hpp +5 -5
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/peek_utf8.hpp +12 -13
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/plus.hpp +18 -11
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/raise.hpp +8 -17
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/range.hpp +22 -17
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/ranges.hpp +28 -18
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/rematch.hpp +12 -9
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/rep.hpp +26 -25
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/rep_min_max.hpp +23 -21
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/rep_opt.hpp +24 -9
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/require.hpp +10 -10
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/rules.hpp +4 -4
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/seq.hpp +18 -33
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/sor.hpp +24 -17
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/star.hpp +13 -8
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/state.hpp +21 -11
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/string.hpp +11 -11
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/success.hpp +32 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/try_catch_type.hpp +16 -16
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/until.hpp +18 -14
- data/ext/third_party/json/include/tao/json/external/pegtl/istream_input.hpp +2 -3
- data/ext/third_party/json/include/tao/json/external/pegtl/match.hpp +125 -29
- data/ext/third_party/json/include/tao/json/external/pegtl/memory_input.hpp +32 -48
- data/ext/third_party/json/include/tao/json/external/pegtl/mmap_input.hpp +16 -16
- data/ext/third_party/json/include/tao/json/external/pegtl/must_if.hpp +64 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/normal.hpp +25 -25
- data/ext/third_party/json/include/tao/json/external/pegtl/nothing.hpp +1 -2
- data/ext/third_party/json/include/tao/json/external/pegtl/parse.hpp +6 -8
- data/ext/third_party/json/include/tao/json/external/pegtl/parse_error.hpp +80 -35
- data/ext/third_party/json/include/tao/json/external/pegtl/position.hpp +18 -10
- data/ext/third_party/json/include/tao/json/external/pegtl/read_input.hpp +18 -38
- data/ext/third_party/json/include/tao/json/external/pegtl/rules.hpp +6 -5
- data/ext/third_party/json/include/tao/json/external/pegtl/string_input.hpp +3 -5
- data/ext/third_party/json/include/tao/json/external/pegtl/type_list.hpp +46 -0
- data/ext/third_party/json/include/tao/json/external/pegtl/visit.hpp +66 -0
- data/ext/third_party/json/include/tao/json/from_file.hpp +5 -5
- data/ext/third_party/json/include/tao/json/internal/action.hpp +3 -3
- data/ext/third_party/json/include/tao/json/internal/dependent_false.hpp +14 -0
- data/ext/third_party/json/include/tao/json/internal/errors.hpp +17 -17
- data/ext/third_party/json/include/tao/json/internal/format.hpp +0 -2
- data/ext/third_party/json/include/tao/json/internal/grammar.hpp +17 -17
- data/ext/third_party/json/include/tao/json/internal/pair.hpp +1 -1
- data/ext/third_party/json/include/tao/json/internal/sha256.hpp +8 -8
- data/ext/third_party/json/include/tao/json/internal/single.hpp +1 -1
- data/ext/third_party/json/include/tao/json/internal/type_traits.hpp +12 -29
- data/ext/third_party/json/include/tao/json/jaxn/consume_file.hpp +7 -7
- data/ext/third_party/json/include/tao/json/jaxn/events/from_file.hpp +4 -4
- data/ext/third_party/json/include/tao/json/jaxn/events/from_string.hpp +2 -2
- data/ext/third_party/json/include/tao/json/jaxn/from_file.hpp +5 -5
- data/ext/third_party/json/include/tao/json/jaxn/internal/action.hpp +6 -6
- data/ext/third_party/json/include/tao/json/jaxn/internal/bunescape_action.hpp +2 -2
- data/ext/third_party/json/include/tao/json/jaxn/internal/errors.hpp +43 -43
- data/ext/third_party/json/include/tao/json/jaxn/internal/grammar.hpp +36 -36
- data/ext/third_party/json/include/tao/json/jaxn/internal/integer.hpp +10 -11
- data/ext/third_party/json/include/tao/json/jaxn/is_identifier.hpp +2 -2
- data/ext/third_party/json/include/tao/json/jaxn/parts_parser.hpp +1 -3
- data/ext/third_party/json/include/tao/json/message_extension.hpp +2 -2
- data/ext/third_party/json/include/tao/json/msgpack.hpp +1 -0
- data/ext/third_party/json/include/tao/json/msgpack/consume_file.hpp +7 -7
- data/ext/third_party/json/include/tao/json/msgpack/events/from_binary.hpp +43 -0
- data/ext/third_party/json/include/tao/json/msgpack/events/from_file.hpp +4 -4
- data/ext/third_party/json/include/tao/json/msgpack/events/from_string.hpp +4 -4
- data/ext/third_party/json/include/tao/json/msgpack/events/to_stream.hpp +4 -4
- data/ext/third_party/json/include/tao/json/msgpack/from_binary.hpp +32 -0
- data/ext/third_party/json/include/tao/json/msgpack/from_file.hpp +5 -5
- data/ext/third_party/json/include/tao/json/msgpack/internal/grammar.hpp +2 -1
- data/ext/third_party/json/include/tao/json/operators.hpp +0 -4
- data/ext/third_party/json/include/tao/json/parts_parser.hpp +3 -7
- data/ext/third_party/json/include/tao/json/self_contained.hpp +6 -18
- data/ext/third_party/json/include/tao/json/span.hpp +94 -166
- data/ext/third_party/json/include/tao/json/ubjson.hpp +1 -0
- data/ext/third_party/json/include/tao/json/ubjson/consume_file.hpp +7 -7
- data/ext/third_party/json/include/tao/json/ubjson/events/from_binary.hpp +43 -0
- data/ext/third_party/json/include/tao/json/ubjson/events/from_file.hpp +4 -4
- data/ext/third_party/json/include/tao/json/ubjson/events/from_string.hpp +3 -3
- data/ext/third_party/json/include/tao/json/ubjson/from_binary.hpp +32 -0
- data/ext/third_party/json/include/tao/json/ubjson/from_file.hpp +5 -5
- data/ext/third_party/json/include/tao/json/ubjson/internal/grammar.hpp +5 -3
- data/ext/third_party/json/include/tao/json/utf8.hpp +1 -1
- data/ext/third_party/snappy/snappy.cc +6 -2
- data/ext/third_party/spdlog/CMakeLists.txt +24 -57
- data/ext/third_party/spdlog/cmake/version.rc.in +1 -1
- data/ext/third_party/spdlog/include/spdlog/async.h +3 -3
- data/ext/third_party/spdlog/include/spdlog/cfg/argv.h +3 -4
- data/ext/third_party/spdlog/include/spdlog/cfg/env.h +6 -4
- data/ext/third_party/spdlog/include/spdlog/cfg/helpers-inl.h +22 -6
- data/ext/third_party/spdlog/include/spdlog/cfg/helpers.h +3 -2
- data/ext/third_party/spdlog/include/spdlog/common.h +1 -2
- data/ext/third_party/spdlog/include/spdlog/details/fmt_helper.h +9 -1
- data/ext/third_party/spdlog/include/spdlog/details/os.h +1 -1
- data/ext/third_party/spdlog/include/spdlog/details/registry-inl.h +21 -7
- data/ext/third_party/spdlog/include/spdlog/details/registry.h +6 -3
- data/ext/third_party/spdlog/include/spdlog/details/synchronous_factory.h +1 -1
- data/ext/third_party/spdlog/include/spdlog/details/tcp_client-windows.h +1 -1
- data/ext/third_party/spdlog/include/spdlog/details/tcp_client.h +8 -7
- data/ext/third_party/spdlog/include/spdlog/fmt/bin_to_hex.h +2 -2
- data/ext/third_party/spdlog/include/spdlog/fmt/bundled/chrono.h +66 -62
- data/ext/third_party/spdlog/include/spdlog/fmt/bundled/color.h +35 -37
- data/ext/third_party/spdlog/include/spdlog/fmt/bundled/compile.h +173 -103
- data/ext/third_party/spdlog/include/spdlog/fmt/bundled/core.h +538 -445
- data/ext/third_party/spdlog/include/spdlog/fmt/bundled/format-inl.h +114 -64
- data/ext/third_party/spdlog/include/spdlog/fmt/bundled/format.h +1152 -1071
- data/ext/third_party/spdlog/include/spdlog/fmt/bundled/locale.h +16 -16
- data/ext/third_party/spdlog/include/spdlog/fmt/bundled/os.h +450 -0
- data/ext/third_party/spdlog/include/spdlog/fmt/bundled/ostream.h +37 -13
- data/ext/third_party/spdlog/include/spdlog/fmt/bundled/posix.h +1 -1
- data/ext/third_party/spdlog/include/spdlog/fmt/bundled/printf.h +93 -63
- data/ext/third_party/spdlog/include/spdlog/fmt/bundled/ranges.h +35 -36
- data/ext/third_party/spdlog/include/spdlog/fmt/chrono.h +20 -0
- data/ext/third_party/spdlog/include/spdlog/fmt/fmt.h +2 -0
- data/ext/third_party/spdlog/include/spdlog/logger-inl.h +5 -1
- data/ext/third_party/spdlog/include/spdlog/logger.h +50 -76
- data/ext/third_party/spdlog/include/spdlog/pattern_formatter-inl.h +23 -8
- data/ext/third_party/spdlog/include/spdlog/pattern_formatter.h +3 -3
- data/ext/third_party/spdlog/include/spdlog/sinks/daily_file_sink.h +1 -1
- data/ext/third_party/spdlog/include/spdlog/sinks/msvc_sink.h +5 -5
- data/ext/third_party/spdlog/include/spdlog/sinks/ringbuffer_sink.h +6 -4
- data/ext/third_party/spdlog/include/spdlog/sinks/stdout_sinks-inl.h +32 -3
- data/ext/third_party/spdlog/include/spdlog/sinks/stdout_sinks.h +7 -0
- data/ext/third_party/spdlog/include/spdlog/sinks/wincolor_sink-inl.h +4 -14
- data/ext/third_party/spdlog/include/spdlog/spdlog-inl.h +11 -1
- data/ext/third_party/spdlog/include/spdlog/spdlog.h +23 -68
- data/ext/third_party/spdlog/include/spdlog/stopwatch.h +61 -0
- data/ext/third_party/spdlog/include/spdlog/version.h +2 -2
- data/ext/third_party/spdlog/src/fmt.cpp +21 -147
- data/lib/couchbase/cluster.rb +111 -1
- data/lib/couchbase/collection_options.rb +18 -1
- data/lib/couchbase/errors.rb +3 -0
- data/lib/couchbase/libcouchbase.bundle +0 -0
- data/lib/couchbase/management/bucket_manager.rb +36 -3
- data/lib/couchbase/management/search_index_manager.rb +42 -1
- data/lib/couchbase/management/user_manager.rb +155 -48
- data/lib/couchbase/query_options.rb +7 -0
- data/lib/couchbase/scope.rb +1 -0
- data/lib/couchbase/search_options.rb +69 -1
- data/lib/couchbase/version.rb +1 -1
- metadata +171 -267
- data/.rubocop.yml +0 -227
- data/.rubocop_todo.yml +0 -47
- data/.yardopts +0 -1
- data/CONTRIBUTING.md +0 -110
- data/Gemfile +0 -37
- data/Rakefile +0 -51
- data/couchbase.gemspec +0 -79
- data/examples/analytics.rb +0 -236
- data/examples/auth.rb +0 -33
- data/examples/crud.rb +0 -34
- data/examples/managing_analytics_indexes.rb +0 -86
- data/examples/managing_buckets.rb +0 -61
- data/examples/managing_collections.rb +0 -71
- data/examples/managing_query_indexes.rb +0 -83
- data/examples/managing_search_indexes.rb +0 -77
- data/examples/managing_view_indexes.rb +0 -68
- data/examples/query.rb +0 -32
- data/examples/query_with_consistency.rb +0 -86
- data/examples/search.rb +0 -202
- data/examples/search_with_consistency.rb +0 -97
- data/examples/subdocument.rb +0 -63
- data/examples/view.rb +0 -59
- data/ext/.clang-format +0 -15
- data/ext/.clang-tidy +0 -22
- data/ext/.cmake-format.yaml +0 -8
- data/ext/.gitignore +0 -2
- data/ext/.idea/.name +0 -1
- data/ext/.idea/dictionaries/couchbase_terms.xml +0 -14
- data/ext/.idea/ext.iml +0 -2
- data/ext/.idea/misc.xml +0 -16
- data/ext/.idea/modules.xml +0 -8
- data/ext/.idea/vcs.xml +0 -12
- data/ext/test/main.cxx +0 -184
- data/ext/third_party/asio/.appveyor.yml +0 -107
- data/ext/third_party/asio/.cirrus.yml +0 -16
- data/ext/third_party/asio/.gitignore +0 -3
- data/ext/third_party/asio/.travis.yml +0 -323
- data/ext/third_party/asio/asio/.gitignore +0 -23
- data/ext/third_party/asio/asio/COPYING +0 -4
- data/ext/third_party/asio/asio/INSTALL +0 -5
- data/ext/third_party/asio/asio/LICENSE_1_0.txt +0 -23
- data/ext/third_party/asio/asio/Makefile.am +0 -19
- data/ext/third_party/asio/asio/README +0 -4
- data/ext/third_party/asio/asio/asio.manifest +0 -4865
- data/ext/third_party/asio/asio/autogen.sh +0 -55
- data/ext/third_party/asio/asio/boost_asio.manifest +0 -5193
- data/ext/third_party/asio/asio/boostify.pl +0 -603
- data/ext/third_party/asio/asio/configure.ac +0 -182
- data/ext/third_party/asio/asio/include/.gitignore +0 -2
- data/ext/third_party/asio/asio/include/Makefile.am +0 -484
- data/ext/third_party/asio/asio/include/asio/detail/io_object_executor.hpp +0 -167
- data/ext/third_party/asio/asio/include/asio/impl/src.cpp +0 -25
- data/ext/third_party/asio/asio/release.pl +0 -440
- data/ext/third_party/asio/asio/src/.gitignore +0 -11
- data/ext/third_party/asio/asio/src/Makefile.am +0 -23
- data/ext/third_party/asio/asio/src/Makefile.mgw +0 -204
- data/ext/third_party/asio/asio/src/Makefile.msc +0 -497
- data/ext/third_party/asio/asio/src/asio.cpp +0 -11
- data/ext/third_party/asio/asio/src/asio_ssl.cpp +0 -11
- data/ext/third_party/asio/asio/src/doc/.gitignore +0 -5
- data/ext/third_party/asio/asio/src/doc/Jamfile.v2 +0 -62
- data/ext/third_party/asio/asio/src/doc/asio.png +0 -0
- data/ext/third_party/asio/asio/src/doc/asio.qbk +0 -127
- data/ext/third_party/asio/asio/src/doc/asioref.sty +0 -90
- data/ext/third_party/asio/asio/src/doc/asioref.xsl +0 -94
- data/ext/third_party/asio/asio/src/doc/boost_bind_dox.txt +0 -5
- data/ext/third_party/asio/asio/src/doc/doxy2qbk.pl +0 -22
- data/ext/third_party/asio/asio/src/doc/examples.qbk +0 -564
- data/ext/third_party/asio/asio/src/doc/history.qbk +0 -1794
- data/ext/third_party/asio/asio/src/doc/index.xml +0 -13
- data/ext/third_party/asio/asio/src/doc/makepdf.pl +0 -26
- data/ext/third_party/asio/asio/src/doc/net_ts.qbk +0 -479
- data/ext/third_party/asio/asio/src/doc/noncopyable_dox.txt +0 -3
- data/ext/third_party/asio/asio/src/doc/overview.qbk +0 -103
- data/ext/third_party/asio/asio/src/doc/overview/allocation.qbk +0 -89
- data/ext/third_party/asio/asio/src/doc/overview/async.qbk +0 -185
- data/ext/third_party/asio/asio/src/doc/overview/async_op1.dot +0 -78
- data/ext/third_party/asio/asio/src/doc/overview/async_op1.png +0 -0
- data/ext/third_party/asio/asio/src/doc/overview/async_op2.dot +0 -78
- data/ext/third_party/asio/asio/src/doc/overview/async_op2.png +0 -0
- data/ext/third_party/asio/asio/src/doc/overview/basics.qbk +0 -106
- data/ext/third_party/asio/asio/src/doc/overview/bsd_sockets.qbk +0 -270
- data/ext/third_party/asio/asio/src/doc/overview/buffers.qbk +0 -163
- data/ext/third_party/asio/asio/src/doc/overview/concurrency_hint.qbk +0 -88
- data/ext/third_party/asio/asio/src/doc/overview/coroutine.qbk +0 -51
- data/ext/third_party/asio/asio/src/doc/overview/coroutines_ts.qbk +0 -97
- data/ext/third_party/asio/asio/src/doc/overview/cpp2011.qbk +0 -271
- data/ext/third_party/asio/asio/src/doc/overview/handler_tracking.qbk +0 -220
- data/ext/third_party/asio/asio/src/doc/overview/implementation.qbk +0 -305
- data/ext/third_party/asio/asio/src/doc/overview/iostreams.qbk +0 -72
- data/ext/third_party/asio/asio/src/doc/overview/line_based.qbk +0 -118
- data/ext/third_party/asio/asio/src/doc/overview/other_protocols.qbk +0 -94
- data/ext/third_party/asio/asio/src/doc/overview/posix.qbk +0 -152
- data/ext/third_party/asio/asio/src/doc/overview/proactor.dot +0 -100
- data/ext/third_party/asio/asio/src/doc/overview/proactor.png +0 -0
- data/ext/third_party/asio/asio/src/doc/overview/protocols.qbk +0 -149
- data/ext/third_party/asio/asio/src/doc/overview/rationale.qbk +0 -54
- data/ext/third_party/asio/asio/src/doc/overview/reactor.qbk +0 -44
- data/ext/third_party/asio/asio/src/doc/overview/serial_ports.qbk +0 -45
- data/ext/third_party/asio/asio/src/doc/overview/signals.qbk +0 -44
- data/ext/third_party/asio/asio/src/doc/overview/spawn.qbk +0 -102
- data/ext/third_party/asio/asio/src/doc/overview/ssl.qbk +0 -124
- data/ext/third_party/asio/asio/src/doc/overview/strands.qbk +0 -114
- data/ext/third_party/asio/asio/src/doc/overview/streams.qbk +0 -62
- data/ext/third_party/asio/asio/src/doc/overview/sync_op.dot +0 -67
- data/ext/third_party/asio/asio/src/doc/overview/sync_op.png +0 -0
- data/ext/third_party/asio/asio/src/doc/overview/threads.qbk +0 -67
- data/ext/third_party/asio/asio/src/doc/overview/timers.qbk +0 -52
- data/ext/third_party/asio/asio/src/doc/overview/windows.qbk +0 -126
- data/ext/third_party/asio/asio/src/doc/project-root.jam +0 -1
- data/ext/third_party/asio/asio/src/doc/quickref.xml +0 -561
- data/ext/third_party/asio/asio/src/doc/reference.dox +0 -264
- data/ext/third_party/asio/asio/src/doc/reference.qbk +0 -125973
- data/ext/third_party/asio/asio/src/doc/reference.xsl +0 -1831
- data/ext/third_party/asio/asio/src/doc/release_checklist.htm +0 -68
- data/ext/third_party/asio/asio/src/doc/requirements/AcceptHandler.qbk +0 -72
- data/ext/third_party/asio/asio/src/doc/requirements/AcceptableProtocol.qbk +0 -25
- data/ext/third_party/asio/asio/src/doc/requirements/AsyncRandomAccessReadDevice.qbk +0 -56
- data/ext/third_party/asio/asio/src/doc/requirements/AsyncRandomAccessWriteDevice.qbk +0 -57
- data/ext/third_party/asio/asio/src/doc/requirements/AsyncReadStream.qbk +0 -50
- data/ext/third_party/asio/asio/src/doc/requirements/AsyncWriteStream.qbk +0 -48
- data/ext/third_party/asio/asio/src/doc/requirements/BufferedHandshakeHandler.qbk +0 -55
- data/ext/third_party/asio/asio/src/doc/requirements/CompletionCondition.qbk +0 -42
- data/ext/third_party/asio/asio/src/doc/requirements/CompletionHandler.qbk +0 -63
- data/ext/third_party/asio/asio/src/doc/requirements/ConnectCondition.qbk +0 -34
- data/ext/third_party/asio/asio/src/doc/requirements/ConnectHandler.qbk +0 -72
- data/ext/third_party/asio/asio/src/doc/requirements/ConstBufferSequence.qbk +0 -53
- data/ext/third_party/asio/asio/src/doc/requirements/DynamicBuffer.qbk +0 -16
- data/ext/third_party/asio/asio/src/doc/requirements/DynamicBuffer_v1.qbk +0 -93
- data/ext/third_party/asio/asio/src/doc/requirements/DynamicBuffer_v2.qbk +0 -94
- data/ext/third_party/asio/asio/src/doc/requirements/Endpoint.qbk +0 -97
- data/ext/third_party/asio/asio/src/doc/requirements/EndpointSequence.qbk +0 -30
- data/ext/third_party/asio/asio/src/doc/requirements/ExecutionContext.qbk +0 -36
- data/ext/third_party/asio/asio/src/doc/requirements/Executor.qbk +0 -141
- data/ext/third_party/asio/asio/src/doc/requirements/GettableSerialPortOption.qbk +0 -33
- data/ext/third_party/asio/asio/src/doc/requirements/GettableSocketOption.qbk +0 -67
- data/ext/third_party/asio/asio/src/doc/requirements/Handler.qbk +0 -64
- data/ext/third_party/asio/asio/src/doc/requirements/HandshakeHandler.qbk +0 -72
- data/ext/third_party/asio/asio/src/doc/requirements/InternetProtocol.qbk +0 -47
- data/ext/third_party/asio/asio/src/doc/requirements/IoControlCommand.qbk +0 -34
- data/ext/third_party/asio/asio/src/doc/requirements/IoObjectService.qbk +0 -62
- data/ext/third_party/asio/asio/src/doc/requirements/IteratorConnectHandler.qbk +0 -81
- data/ext/third_party/asio/asio/src/doc/requirements/LegacyCompletionHandler.qbk +0 -65
- data/ext/third_party/asio/asio/src/doc/requirements/MoveAcceptHandler.qbk +0 -61
- data/ext/third_party/asio/asio/src/doc/requirements/MutableBufferSequence.qbk +0 -54
- data/ext/third_party/asio/asio/src/doc/requirements/ProtoAllocator.qbk +0 -19
- data/ext/third_party/asio/asio/src/doc/requirements/Protocol.qbk +0 -56
- data/ext/third_party/asio/asio/src/doc/requirements/RangeConnectHandler.qbk +0 -82
- data/ext/third_party/asio/asio/src/doc/requirements/ReadHandler.qbk +0 -79
- data/ext/third_party/asio/asio/src/doc/requirements/ResolveHandler.qbk +0 -82
- data/ext/third_party/asio/asio/src/doc/requirements/Service.qbk +0 -40
- data/ext/third_party/asio/asio/src/doc/requirements/SettableSerialPortOption.qbk +0 -33
- data/ext/third_party/asio/asio/src/doc/requirements/SettableSocketOption.qbk +0 -54
- data/ext/third_party/asio/asio/src/doc/requirements/ShutdownHandler.qbk +0 -72
- data/ext/third_party/asio/asio/src/doc/requirements/SignalHandler.qbk +0 -79
- data/ext/third_party/asio/asio/src/doc/requirements/SyncRandomAccessReadDevice.qbk +0 -49
- data/ext/third_party/asio/asio/src/doc/requirements/SyncRandomAccessWriteDevice.qbk +0 -49
- data/ext/third_party/asio/asio/src/doc/requirements/SyncReadStream.qbk +0 -41
- data/ext/third_party/asio/asio/src/doc/requirements/SyncWriteStream.qbk +0 -39
- data/ext/third_party/asio/asio/src/doc/requirements/TimeTraits.qbk +0 -72
- data/ext/third_party/asio/asio/src/doc/requirements/WaitHandler.qbk +0 -72
- data/ext/third_party/asio/asio/src/doc/requirements/WaitTraits.qbk +0 -52
- data/ext/third_party/asio/asio/src/doc/requirements/WriteHandler.qbk +0 -79
- data/ext/third_party/asio/asio/src/doc/requirements/asynchronous_operations.qbk +0 -300
- data/ext/third_party/asio/asio/src/doc/requirements/asynchronous_socket_operations.qbk +0 -39
- data/ext/third_party/asio/asio/src/doc/requirements/read_write_operations.qbk +0 -34
- data/ext/third_party/asio/asio/src/doc/requirements/synchronous_socket_operations.qbk +0 -37
- data/ext/third_party/asio/asio/src/doc/std_exception_dox.txt +0 -7
- data/ext/third_party/asio/asio/src/doc/tutorial.dox +0 -226
- data/ext/third_party/asio/asio/src/doc/tutorial.qbk +0 -2387
- data/ext/third_party/asio/asio/src/doc/tutorial.xsl +0 -437
- data/ext/third_party/asio/asio/src/doc/using.qbk +0 -309
- data/ext/third_party/asio/asio/tsify.pl +0 -574
- data/ext/third_party/gsl/.clang-format +0 -34
- data/ext/third_party/gsl/.github/workflows/main.yml +0 -94
- data/ext/third_party/gsl/.gitignore +0 -16
- data/ext/third_party/gsl/.travis.yml +0 -551
- data/ext/third_party/gsl/CMakeSettings.json +0 -18
- data/ext/third_party/gsl/CONTRIBUTING.md +0 -29
- data/ext/third_party/gsl/GSL.natvis +0 -98
- data/ext/third_party/gsl/README.md +0 -124
- data/ext/third_party/gsl/appveyor.yml +0 -128
- data/ext/third_party/http_parser/.gitignore +0 -30
- data/ext/third_party/http_parser/.mailmap +0 -8
- data/ext/third_party/http_parser/.travis.yml +0 -13
- data/ext/third_party/http_parser/AUTHORS +0 -68
- data/ext/third_party/http_parser/Makefile +0 -160
- data/ext/third_party/http_parser/README.md +0 -246
- data/ext/third_party/http_parser/bench.c +0 -128
- data/ext/third_party/http_parser/http_parser.gyp +0 -111
- data/ext/third_party/http_parser/test.c +0 -4600
- data/ext/third_party/json/.appveyor.yml +0 -44
- data/ext/third_party/json/.clang-format +0 -84
- data/ext/third_party/json/.conan/build.py +0 -80
- data/ext/third_party/json/.conan/test_package/CMakeLists.txt +0 -12
- data/ext/third_party/json/.conan/test_package/conanfile.py +0 -24
- data/ext/third_party/json/.conan/test_package/test_package.cpp +0 -16
- data/ext/third_party/json/.gitignore +0 -3
- data/ext/third_party/json/.travis.yml +0 -173
- data/ext/third_party/json/Makefile +0 -77
- data/ext/third_party/json/README.md +0 -149
- data/ext/third_party/json/conanfile.py +0 -28
- data/ext/third_party/json/include/tao/json/external/pegtl/analysis/analyze_cycles.hpp +0 -127
- data/ext/third_party/json/include/tao/json/external/pegtl/analysis/counted.hpp +0 -23
- data/ext/third_party/json/include/tao/json/external/pegtl/analysis/generic.hpp +0 -31
- data/ext/third_party/json/include/tao/json/external/pegtl/analysis/grammar_info.hpp +0 -32
- data/ext/third_party/json/include/tao/json/external/pegtl/analysis/insert_guard.hpp +0 -51
- data/ext/third_party/json/include/tao/json/external/pegtl/analysis/insert_rules.hpp +0 -25
- data/ext/third_party/json/include/tao/json/external/pegtl/analysis/rule_info.hpp +0 -29
- data/ext/third_party/json/include/tao/json/external/pegtl/analysis/rule_type.hpp +0 -21
- data/ext/third_party/json/include/tao/json/external/pegtl/analyze.hpp +0 -21
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/counter.hpp +0 -54
- data/ext/third_party/json/include/tao/json/external/pegtl/contrib/tracer.hpp +0 -158
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/alnum.hpp +0 -18
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/alpha.hpp +0 -18
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/dusel_mode.hpp +0 -23
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/duseltronik.hpp +0 -187
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/file_opener.hpp +0 -72
- data/ext/third_party/json/include/tao/json/external/pegtl/internal/trivial.hpp +0 -32
- data/ext/third_party/snappy/.appveyor.yml +0 -36
- data/ext/third_party/snappy/.gitignore +0 -8
- data/ext/third_party/snappy/.travis.yml +0 -98
- data/ext/third_party/snappy/AUTHORS +0 -1
- data/ext/third_party/snappy/CONTRIBUTING.md +0 -26
- data/ext/third_party/snappy/NEWS +0 -188
- data/ext/third_party/snappy/README.md +0 -148
- data/ext/third_party/snappy/docs/README.md +0 -72
- data/ext/third_party/snappy/format_description.txt +0 -110
- data/ext/third_party/snappy/framing_format.txt +0 -135
- data/ext/third_party/snappy/snappy-test.cc +0 -613
- data/ext/third_party/snappy/snappy-test.h +0 -526
- data/ext/third_party/snappy/snappy_compress_fuzzer.cc +0 -60
- data/ext/third_party/snappy/snappy_uncompress_fuzzer.cc +0 -58
- data/ext/third_party/snappy/snappy_unittest.cc +0 -1512
- data/ext/third_party/spdlog/.clang-format +0 -108
- data/ext/third_party/spdlog/.clang-tidy +0 -54
- data/ext/third_party/spdlog/.gitattributes +0 -1
- data/ext/third_party/spdlog/.gitignore +0 -83
- data/ext/third_party/spdlog/.travis.yml +0 -112
- data/ext/third_party/spdlog/INSTALL +0 -24
- data/ext/third_party/spdlog/README.md +0 -423
- data/ext/third_party/spdlog/appveyor.yml +0 -51
- data/ext/third_party/spdlog/include/spdlog/cfg/log_levels.h +0 -47
@@ -15,6 +15,7 @@
|
|
15
15
|
#include <cstdarg>
|
16
16
|
#include <cstring> // for std::memmove
|
17
17
|
#include <cwchar>
|
18
|
+
#include <exception>
|
18
19
|
|
19
20
|
#include "format.h"
|
20
21
|
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
|
@@ -22,8 +23,16 @@
|
|
22
23
|
#endif
|
23
24
|
|
24
25
|
#ifdef _WIN32
|
26
|
+
# if !defined(NOMINMAX) && !defined(WIN32_LEAN_AND_MEAN)
|
27
|
+
# define NOMINMAX
|
28
|
+
# define WIN32_LEAN_AND_MEAN
|
29
|
+
# include <windows.h>
|
30
|
+
# undef WIN32_LEAN_AND_MEAN
|
31
|
+
# undef NOMINMAX
|
32
|
+
# else
|
33
|
+
# include <windows.h>
|
34
|
+
# endif
|
25
35
|
# include <io.h>
|
26
|
-
# include <windows.h>
|
27
36
|
#endif
|
28
37
|
|
29
38
|
#ifdef _MSC_VER
|
@@ -33,15 +42,19 @@
|
|
33
42
|
|
34
43
|
// Dummy implementations of strerror_r and strerror_s called if corresponding
|
35
44
|
// system functions are not available.
|
36
|
-
inline fmt::
|
37
|
-
inline fmt::
|
45
|
+
inline fmt::detail::null<> strerror_r(int, char*, ...) { return {}; }
|
46
|
+
inline fmt::detail::null<> strerror_s(char*, size_t, ...) { return {}; }
|
38
47
|
|
39
48
|
FMT_BEGIN_NAMESPACE
|
40
|
-
namespace
|
49
|
+
namespace detail {
|
41
50
|
|
42
51
|
FMT_FUNC void assert_fail(const char* file, int line, const char* message) {
|
43
|
-
|
44
|
-
|
52
|
+
// Use unchecked std::fprintf to avoid triggering another assertion when
|
53
|
+
// writing to stderr fails
|
54
|
+
std::fprintf(stderr, "%s:%d: assertion failed: %s", file, line, message);
|
55
|
+
// Chosen instead of std::abort to satisfy Clang in CUDA mode during device
|
56
|
+
// code pass.
|
57
|
+
std::terminate();
|
45
58
|
}
|
46
59
|
|
47
60
|
#ifndef _MSC_VER
|
@@ -67,14 +80,14 @@ inline int fmt_snprintf(char* buffer, size_t size, const char* format, ...) {
|
|
67
80
|
// other - failure
|
68
81
|
// Buffer should be at least of size 1.
|
69
82
|
FMT_FUNC int safe_strerror(int error_code, char*& buffer,
|
70
|
-
|
83
|
+
size_t buffer_size) FMT_NOEXCEPT {
|
71
84
|
FMT_ASSERT(buffer != nullptr && buffer_size != 0, "invalid buffer");
|
72
85
|
|
73
86
|
class dispatcher {
|
74
87
|
private:
|
75
88
|
int error_code_;
|
76
89
|
char*& buffer_;
|
77
|
-
|
90
|
+
size_t buffer_size_;
|
78
91
|
|
79
92
|
// A noop assignment operator to avoid bogus warnings.
|
80
93
|
void operator=(const dispatcher&) {}
|
@@ -97,7 +110,7 @@ FMT_FUNC int safe_strerror(int error_code, char*& buffer,
|
|
97
110
|
|
98
111
|
// Handle the case when strerror_r is not available.
|
99
112
|
FMT_MAYBE_UNUSED
|
100
|
-
int handle(
|
113
|
+
int handle(detail::null<>) {
|
101
114
|
return fallback(strerror_s(buffer_, buffer_size_, error_code_));
|
102
115
|
}
|
103
116
|
|
@@ -111,7 +124,7 @@ FMT_FUNC int safe_strerror(int error_code, char*& buffer,
|
|
111
124
|
|
112
125
|
#if !FMT_MSC_VER
|
113
126
|
// Fallback to strerror if strerror_r and strerror_s are not available.
|
114
|
-
int fallback(
|
127
|
+
int fallback(detail::null<>) {
|
115
128
|
errno = 0;
|
116
129
|
buffer_ = strerror(error_code_);
|
117
130
|
return errno;
|
@@ -119,7 +132,7 @@ FMT_FUNC int safe_strerror(int error_code, char*& buffer,
|
|
119
132
|
#endif
|
120
133
|
|
121
134
|
public:
|
122
|
-
dispatcher(int err_code, char*& buf,
|
135
|
+
dispatcher(int err_code, char*& buf, size_t buf_size)
|
123
136
|
: error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
|
124
137
|
|
125
138
|
int run() { return handle(strerror_r(error_code_, buffer_, buffer_size_)); }
|
@@ -127,7 +140,7 @@ FMT_FUNC int safe_strerror(int error_code, char*& buffer,
|
|
127
140
|
return dispatcher(error_code, buffer, buffer_size).run();
|
128
141
|
}
|
129
142
|
|
130
|
-
FMT_FUNC void format_error_code(
|
143
|
+
FMT_FUNC void format_error_code(detail::buffer<char>& out, int error_code,
|
131
144
|
string_view message) FMT_NOEXCEPT {
|
132
145
|
// Report error code making sure that the output fits into
|
133
146
|
// inline_buffer_size to avoid dynamic memory allocation and potential
|
@@ -136,20 +149,17 @@ FMT_FUNC void format_error_code(internal::buffer<char>& out, int error_code,
|
|
136
149
|
static const char SEP[] = ": ";
|
137
150
|
static const char ERROR_STR[] = "error ";
|
138
151
|
// Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
|
139
|
-
|
152
|
+
size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
|
140
153
|
auto abs_value = static_cast<uint32_or_64_or_128_t<int>>(error_code);
|
141
|
-
if (
|
154
|
+
if (detail::is_negative(error_code)) {
|
142
155
|
abs_value = 0 - abs_value;
|
143
156
|
++error_code_size;
|
144
157
|
}
|
145
|
-
error_code_size +=
|
146
|
-
|
147
|
-
if (message.size() <= inline_buffer_size - error_code_size)
|
148
|
-
|
149
|
-
|
150
|
-
}
|
151
|
-
w.write(ERROR_STR);
|
152
|
-
w.write(error_code);
|
158
|
+
error_code_size += detail::to_unsigned(detail::count_digits(abs_value));
|
159
|
+
auto it = std::back_inserter(out);
|
160
|
+
if (message.size() <= inline_buffer_size - error_code_size)
|
161
|
+
format_to(it, "{}{}", message, SEP);
|
162
|
+
format_to(it, "{}{}", ERROR_STR, error_code);
|
153
163
|
assert(out.size() <= inline_buffer_size);
|
154
164
|
}
|
155
165
|
|
@@ -168,10 +178,10 @@ FMT_FUNC void fwrite_fully(const void* ptr, size_t size, size_t count,
|
|
168
178
|
size_t written = std::fwrite(ptr, size, count, stream);
|
169
179
|
if (written < count) FMT_THROW(system_error(errno, "cannot write to file"));
|
170
180
|
}
|
171
|
-
} // namespace
|
181
|
+
} // namespace detail
|
172
182
|
|
173
183
|
#if !defined(FMT_STATIC_THOUSANDS_SEPARATOR)
|
174
|
-
namespace
|
184
|
+
namespace detail {
|
175
185
|
|
176
186
|
template <typename Locale>
|
177
187
|
locale_ref::locale_ref(const Locale& loc) : locale_(&loc) {
|
@@ -194,18 +204,16 @@ template <typename Char> FMT_FUNC Char decimal_point_impl(locale_ref loc) {
|
|
194
204
|
return std::use_facet<std::numpunct<Char>>(loc.get<std::locale>())
|
195
205
|
.decimal_point();
|
196
206
|
}
|
197
|
-
} // namespace
|
207
|
+
} // namespace detail
|
198
208
|
#else
|
199
209
|
template <typename Char>
|
200
|
-
FMT_FUNC std::string
|
210
|
+
FMT_FUNC std::string detail::grouping_impl(locale_ref) {
|
201
211
|
return "\03";
|
202
212
|
}
|
203
|
-
template <typename Char>
|
204
|
-
FMT_FUNC Char internal::thousands_sep_impl(locale_ref) {
|
213
|
+
template <typename Char> FMT_FUNC Char detail::thousands_sep_impl(locale_ref) {
|
205
214
|
return FMT_STATIC_THOUSANDS_SEPARATOR;
|
206
215
|
}
|
207
|
-
template <typename Char>
|
208
|
-
FMT_FUNC Char internal::decimal_point_impl(locale_ref) {
|
216
|
+
template <typename Char> FMT_FUNC Char detail::decimal_point_impl(locale_ref) {
|
209
217
|
return '.';
|
210
218
|
}
|
211
219
|
#endif
|
@@ -222,9 +230,9 @@ FMT_FUNC void system_error::init(int err_code, string_view format_str,
|
|
222
230
|
base = std::runtime_error(to_string(buffer));
|
223
231
|
}
|
224
232
|
|
225
|
-
namespace
|
233
|
+
namespace detail {
|
226
234
|
|
227
|
-
template <> FMT_FUNC int count_digits<4>(
|
235
|
+
template <> FMT_FUNC int count_digits<4>(detail::fallback_uintptr n) {
|
228
236
|
// fallback_uintptr is always stored in little endian.
|
229
237
|
int i = static_cast<int>(sizeof(void*)) - 1;
|
230
238
|
while (i > 0 && n.value[i] == 0) --i;
|
@@ -233,12 +241,27 @@ template <> FMT_FUNC int count_digits<4>(internal::fallback_uintptr n) {
|
|
233
241
|
}
|
234
242
|
|
235
243
|
template <typename T>
|
236
|
-
const
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
244
|
+
const typename basic_data<T>::digit_pair basic_data<T>::digits[] = {
|
245
|
+
{'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'},
|
246
|
+
{'0', '5'}, {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'},
|
247
|
+
{'1', '0'}, {'1', '1'}, {'1', '2'}, {'1', '3'}, {'1', '4'},
|
248
|
+
{'1', '5'}, {'1', '6'}, {'1', '7'}, {'1', '8'}, {'1', '9'},
|
249
|
+
{'2', '0'}, {'2', '1'}, {'2', '2'}, {'2', '3'}, {'2', '4'},
|
250
|
+
{'2', '5'}, {'2', '6'}, {'2', '7'}, {'2', '8'}, {'2', '9'},
|
251
|
+
{'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'},
|
252
|
+
{'3', '5'}, {'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'},
|
253
|
+
{'4', '0'}, {'4', '1'}, {'4', '2'}, {'4', '3'}, {'4', '4'},
|
254
|
+
{'4', '5'}, {'4', '6'}, {'4', '7'}, {'4', '8'}, {'4', '9'},
|
255
|
+
{'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'}, {'5', '4'},
|
256
|
+
{'5', '5'}, {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'},
|
257
|
+
{'6', '0'}, {'6', '1'}, {'6', '2'}, {'6', '3'}, {'6', '4'},
|
258
|
+
{'6', '5'}, {'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'},
|
259
|
+
{'7', '0'}, {'7', '1'}, {'7', '2'}, {'7', '3'}, {'7', '4'},
|
260
|
+
{'7', '5'}, {'7', '6'}, {'7', '7'}, {'7', '8'}, {'7', '9'},
|
261
|
+
{'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'}, {'8', '4'},
|
262
|
+
{'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'},
|
263
|
+
{'9', '0'}, {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'},
|
264
|
+
{'9', '5'}, {'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'}};
|
242
265
|
|
243
266
|
template <typename T>
|
244
267
|
const char basic_data<T>::hex_digits[] = "0123456789abcdef";
|
@@ -317,6 +340,10 @@ const char basic_data<T>::background_color[] = "\x1b[48;2;";
|
|
317
340
|
template <typename T> const char basic_data<T>::reset_color[] = "\x1b[0m";
|
318
341
|
template <typename T> const wchar_t basic_data<T>::wreset_color[] = L"\x1b[0m";
|
319
342
|
template <typename T> const char basic_data<T>::signs[] = {0, '-', '+', ' '};
|
343
|
+
template <typename T>
|
344
|
+
const char basic_data<T>::left_padding_shifts[] = {31, 31, 0, 1, 0};
|
345
|
+
template <typename T>
|
346
|
+
const char basic_data<T>::right_padding_shifts[] = {0, 31, 0, 1, 0};
|
320
347
|
|
321
348
|
template <typename T> struct bits {
|
322
349
|
static FMT_CONSTEXPR_DECL const int value =
|
@@ -576,9 +603,10 @@ class bigint {
|
|
576
603
|
void operator=(const bigint&) = delete;
|
577
604
|
|
578
605
|
void assign(const bigint& other) {
|
579
|
-
|
606
|
+
auto size = other.bigits_.size();
|
607
|
+
bigits_.resize(size);
|
580
608
|
auto data = other.bigits_.data();
|
581
|
-
std::copy(data, data +
|
609
|
+
std::copy(data, data + size, make_checked(bigits_.data(), size));
|
582
610
|
exp_ = other.exp_;
|
583
611
|
}
|
584
612
|
|
@@ -594,7 +622,7 @@ class bigint {
|
|
594
622
|
|
595
623
|
int num_bigits() const { return static_cast<int>(bigits_.size()) + exp_; }
|
596
624
|
|
597
|
-
bigint& operator<<=(int shift) {
|
625
|
+
FMT_NOINLINE bigint& operator<<=(int shift) {
|
598
626
|
assert(shift >= 0);
|
599
627
|
exp_ += shift / bigit_bits;
|
600
628
|
shift %= bigit_bits;
|
@@ -1125,7 +1153,7 @@ int snprintf_float(T value, int precision, float_specs specs,
|
|
1125
1153
|
precision = (precision >= 0 ? precision : 6) - 1;
|
1126
1154
|
|
1127
1155
|
// Build the format string.
|
1128
|
-
enum { max_format_size = 7 }; //
|
1156
|
+
enum { max_format_size = 7 }; // The longest format is "%#.*Le".
|
1129
1157
|
char format[max_format_size];
|
1130
1158
|
char* format_ptr = format;
|
1131
1159
|
*format_ptr++ = '%';
|
@@ -1145,13 +1173,13 @@ int snprintf_float(T value, int precision, float_specs specs,
|
|
1145
1173
|
for (;;) {
|
1146
1174
|
auto begin = buf.data() + offset;
|
1147
1175
|
auto capacity = buf.capacity() - offset;
|
1148
|
-
#ifdef
|
1176
|
+
#ifdef FMT_FUZZ
|
1149
1177
|
if (precision > 100000)
|
1150
1178
|
throw std::runtime_error(
|
1151
1179
|
"fuzz mode - avoid large allocation inside snprintf");
|
1152
1180
|
#endif
|
1153
1181
|
// Suppress the warning about a nonliteral format string.
|
1154
|
-
// Cannot use auto
|
1182
|
+
// Cannot use auto because of a bug in MinGW (#1532).
|
1155
1183
|
int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF;
|
1156
1184
|
int result = precision >= 0
|
1157
1185
|
? snprintf_ptr(begin, capacity, format, precision, value)
|
@@ -1268,14 +1296,14 @@ FMT_FUNC const char* utf8_decode(const char* buf, uint32_t* c, int* e) {
|
|
1268
1296
|
|
1269
1297
|
return next;
|
1270
1298
|
}
|
1271
|
-
} // namespace
|
1299
|
+
} // namespace detail
|
1272
1300
|
|
1273
|
-
template <> struct formatter<
|
1301
|
+
template <> struct formatter<detail::bigint> {
|
1274
1302
|
format_parse_context::iterator parse(format_parse_context& ctx) {
|
1275
1303
|
return ctx.begin();
|
1276
1304
|
}
|
1277
1305
|
|
1278
|
-
format_context::iterator format(const
|
1306
|
+
format_context::iterator format(const detail::bigint& n,
|
1279
1307
|
format_context& ctx) {
|
1280
1308
|
auto out = ctx.out();
|
1281
1309
|
bool first = true;
|
@@ -1289,12 +1317,12 @@ template <> struct formatter<internal::bigint> {
|
|
1289
1317
|
out = format_to(out, "{:08x}", value);
|
1290
1318
|
}
|
1291
1319
|
if (n.exp_ > 0)
|
1292
|
-
out = format_to(out, "p{}", n.exp_ *
|
1320
|
+
out = format_to(out, "p{}", n.exp_ * detail::bigint::bigit_bits);
|
1293
1321
|
return out;
|
1294
1322
|
}
|
1295
1323
|
};
|
1296
1324
|
|
1297
|
-
FMT_FUNC
|
1325
|
+
FMT_FUNC detail::utf8_to_utf16::utf8_to_utf16(string_view s) {
|
1298
1326
|
auto transcode = [this](const char* p) {
|
1299
1327
|
auto cp = uint32_t();
|
1300
1328
|
auto error = 0;
|
@@ -1325,7 +1353,7 @@ FMT_FUNC internal::utf8_to_utf16::utf8_to_utf16(string_view s) {
|
|
1325
1353
|
buffer_.push_back(0);
|
1326
1354
|
}
|
1327
1355
|
|
1328
|
-
FMT_FUNC void format_system_error(
|
1356
|
+
FMT_FUNC void format_system_error(detail::buffer<char>& out, int error_code,
|
1329
1357
|
string_view message) FMT_NOEXCEPT {
|
1330
1358
|
FMT_TRY {
|
1331
1359
|
memory_buffer buf;
|
@@ -1333,12 +1361,9 @@ FMT_FUNC void format_system_error(internal::buffer<char>& out, int error_code,
|
|
1333
1361
|
for (;;) {
|
1334
1362
|
char* system_message = &buf[0];
|
1335
1363
|
int result =
|
1336
|
-
|
1364
|
+
detail::safe_strerror(error_code, system_message, buf.size());
|
1337
1365
|
if (result == 0) {
|
1338
|
-
|
1339
|
-
w.write(message);
|
1340
|
-
w.write(": ");
|
1341
|
-
w.write(system_message);
|
1366
|
+
format_to(std::back_inserter(out), "{}: {}", message, system_message);
|
1342
1367
|
return;
|
1343
1368
|
}
|
1344
1369
|
if (result != ERANGE)
|
@@ -1350,7 +1375,7 @@ FMT_FUNC void format_system_error(internal::buffer<char>& out, int error_code,
|
|
1350
1375
|
format_error_code(out, error_code, message);
|
1351
1376
|
}
|
1352
1377
|
|
1353
|
-
FMT_FUNC void
|
1378
|
+
FMT_FUNC void detail::error_handler::on_error(const char* message) {
|
1354
1379
|
FMT_THROW(format_error(message));
|
1355
1380
|
}
|
1356
1381
|
|
@@ -1359,14 +1384,39 @@ FMT_FUNC void report_system_error(int error_code,
|
|
1359
1384
|
report_error(format_system_error, error_code, message);
|
1360
1385
|
}
|
1361
1386
|
|
1387
|
+
struct stringifier {
|
1388
|
+
template <typename T> FMT_INLINE std::string operator()(T value) const {
|
1389
|
+
return to_string(value);
|
1390
|
+
}
|
1391
|
+
std::string operator()(basic_format_arg<format_context>::handle h) const {
|
1392
|
+
memory_buffer buf;
|
1393
|
+
detail::buffer<char>& base = buf;
|
1394
|
+
format_parse_context parse_ctx({});
|
1395
|
+
format_context format_ctx(std::back_inserter(base), {}, {});
|
1396
|
+
h.format(parse_ctx, format_ctx);
|
1397
|
+
return to_string(buf);
|
1398
|
+
}
|
1399
|
+
};
|
1400
|
+
|
1401
|
+
FMT_FUNC std::string detail::vformat(string_view format_str, format_args args) {
|
1402
|
+
if (format_str.size() == 2 && equal2(format_str.data(), "{}")) {
|
1403
|
+
auto arg = args.get(0);
|
1404
|
+
if (!arg) error_handler().on_error("argument not found");
|
1405
|
+
return visit_format_arg(stringifier(), arg);
|
1406
|
+
}
|
1407
|
+
memory_buffer buffer;
|
1408
|
+
detail::vformat_to(buffer, format_str, args);
|
1409
|
+
return to_string(buffer);
|
1410
|
+
}
|
1411
|
+
|
1362
1412
|
FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) {
|
1363
1413
|
memory_buffer buffer;
|
1364
|
-
|
1365
|
-
|
1414
|
+
detail::vformat_to(buffer, format_str,
|
1415
|
+
basic_format_args<buffer_context<char>>(args));
|
1366
1416
|
#ifdef _WIN32
|
1367
1417
|
auto fd = _fileno(f);
|
1368
1418
|
if (_isatty(fd)) {
|
1369
|
-
|
1419
|
+
detail::utf8_to_utf16 u16(string_view(buffer.data(), buffer.size()));
|
1370
1420
|
auto written = DWORD();
|
1371
1421
|
if (!WriteConsoleW(reinterpret_cast<HANDLE>(_get_osfhandle(fd)),
|
1372
1422
|
u16.c_str(), static_cast<DWORD>(u16.size()), &written,
|
@@ -1376,16 +1426,16 @@ FMT_FUNC void vprint(std::FILE* f, string_view format_str, format_args args) {
|
|
1376
1426
|
return;
|
1377
1427
|
}
|
1378
1428
|
#endif
|
1379
|
-
|
1429
|
+
detail::fwrite_fully(buffer.data(), 1, buffer.size(), f);
|
1380
1430
|
}
|
1381
1431
|
|
1382
1432
|
#ifdef _WIN32
|
1383
1433
|
// Print assuming legacy (non-Unicode) encoding.
|
1384
|
-
FMT_FUNC void
|
1385
|
-
|
1434
|
+
FMT_FUNC void detail::vprint_mojibake(std::FILE* f, string_view format_str,
|
1435
|
+
format_args args) {
|
1386
1436
|
memory_buffer buffer;
|
1387
|
-
|
1388
|
-
|
1437
|
+
detail::vformat_to(buffer, format_str,
|
1438
|
+
basic_format_args<buffer_context<char>>(args));
|
1389
1439
|
fwrite_fully(buffer.data(), 1, buffer.size(), f);
|
1390
1440
|
}
|
1391
1441
|
#endif
|
@@ -43,10 +43,6 @@
|
|
43
43
|
|
44
44
|
#include "core.h"
|
45
45
|
|
46
|
-
#ifdef FMT_DEPRECATED_INCLUDE_OS
|
47
|
-
# include "os.h"
|
48
|
-
#endif
|
49
|
-
|
50
46
|
#ifdef __INTEL_COMPILER
|
51
47
|
# define FMT_ICC_VERSION __INTEL_COMPILER
|
52
48
|
#elif defined(__ICL)
|
@@ -76,7 +72,8 @@
|
|
76
72
|
#if __cplusplus == 201103L || __cplusplus == 201402L
|
77
73
|
# if defined(__clang__)
|
78
74
|
# define FMT_FALLTHROUGH [[clang::fallthrough]]
|
79
|
-
# elif FMT_GCC_VERSION >= 700 && !defined(__PGI)
|
75
|
+
# elif FMT_GCC_VERSION >= 700 && !defined(__PGI) && \
|
76
|
+
(!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520)
|
80
77
|
# define FMT_FALLTHROUGH [[gnu::fallthrough]]
|
81
78
|
# else
|
82
79
|
# define FMT_FALLTHROUGH
|
@@ -88,20 +85,28 @@
|
|
88
85
|
# define FMT_FALLTHROUGH
|
89
86
|
#endif
|
90
87
|
|
88
|
+
#ifndef FMT_MAYBE_UNUSED
|
89
|
+
# if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused)
|
90
|
+
# define FMT_MAYBE_UNUSED [[maybe_unused]]
|
91
|
+
# else
|
92
|
+
# define FMT_MAYBE_UNUSED
|
93
|
+
# endif
|
94
|
+
#endif
|
95
|
+
|
91
96
|
#ifndef FMT_THROW
|
92
97
|
# if FMT_EXCEPTIONS
|
93
98
|
# if FMT_MSC_VER || FMT_NVCC
|
94
99
|
FMT_BEGIN_NAMESPACE
|
95
|
-
namespace
|
100
|
+
namespace detail {
|
96
101
|
template <typename Exception> inline void do_throw(const Exception& x) {
|
97
102
|
// Silence unreachable code warnings in MSVC and NVCC because these
|
98
103
|
// are nearly impossible to fix in a generic code.
|
99
104
|
volatile bool b = true;
|
100
105
|
if (b) throw x;
|
101
106
|
}
|
102
|
-
} // namespace
|
107
|
+
} // namespace detail
|
103
108
|
FMT_END_NAMESPACE
|
104
|
-
# define FMT_THROW(x)
|
109
|
+
# define FMT_THROW(x) detail::do_throw(x)
|
105
110
|
# else
|
106
111
|
# define FMT_THROW(x) throw x
|
107
112
|
# endif
|
@@ -123,11 +128,10 @@ FMT_END_NAMESPACE
|
|
123
128
|
#endif
|
124
129
|
|
125
130
|
#ifndef FMT_USE_USER_DEFINED_LITERALS
|
126
|
-
//
|
127
|
-
# if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 ||
|
128
|
-
FMT_MSC_VER >= 1900) &&
|
129
|
-
(!(
|
130
|
-
FMT_CUDA_VERSION >= 700)
|
131
|
+
// EDG based compilers (Intel, NVIDIA, Elbrus, etc), GCC and MSVC support UDLs.
|
132
|
+
# if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \
|
133
|
+
FMT_MSC_VER >= 1900) && \
|
134
|
+
(!defined(__EDG_VERSION__) || __EDG_VERSION__ >= /* UDL feature */ 480)
|
131
135
|
# define FMT_USE_USER_DEFINED_LITERALS 1
|
132
136
|
# else
|
133
137
|
# define FMT_USE_USER_DEFINED_LITERALS 0
|
@@ -135,12 +139,11 @@ FMT_END_NAMESPACE
|
|
135
139
|
#endif
|
136
140
|
|
137
141
|
#ifndef FMT_USE_UDL_TEMPLATE
|
138
|
-
// EDG
|
142
|
+
// EDG frontend based compilers (icc, nvcc, etc) and GCC < 6.4 do not properly
|
139
143
|
// support UDL templates and GCC >= 9 warns about them.
|
140
|
-
# if FMT_USE_USER_DEFINED_LITERALS &&
|
141
|
-
|
142
|
-
((FMT_GCC_VERSION >= 604 &&
|
143
|
-
__cplusplus >= 201402L) || \
|
144
|
+
# if FMT_USE_USER_DEFINED_LITERALS && \
|
145
|
+
(!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 501) && \
|
146
|
+
((FMT_GCC_VERSION >= 604 && __cplusplus >= 201402L) || \
|
144
147
|
FMT_CLANG_VERSION >= 304)
|
145
148
|
# define FMT_USE_UDL_TEMPLATE 1
|
146
149
|
# else
|
@@ -176,7 +179,7 @@ FMT_END_NAMESPACE
|
|
176
179
|
# include <intrin.h> // _BitScanReverse, _BitScanReverse64
|
177
180
|
|
178
181
|
FMT_BEGIN_NAMESPACE
|
179
|
-
namespace
|
182
|
+
namespace detail {
|
180
183
|
// Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning.
|
181
184
|
# ifndef __clang__
|
182
185
|
# pragma intrinsic(_BitScanReverse)
|
@@ -189,10 +192,10 @@ inline uint32_t clz(uint32_t x) {
|
|
189
192
|
// Static analysis complains about using uninitialized data
|
190
193
|
// "r", but the only way that can happen is if "x" is 0,
|
191
194
|
// which the callers guarantee to not happen.
|
192
|
-
|
195
|
+
FMT_SUPPRESS_MSC_WARNING(6102)
|
193
196
|
return 31 - r;
|
194
197
|
}
|
195
|
-
# define FMT_BUILTIN_CLZ(n)
|
198
|
+
# define FMT_BUILTIN_CLZ(n) detail::clz(n)
|
196
199
|
|
197
200
|
# if defined(_WIN64) && !defined(__clang__)
|
198
201
|
# pragma intrinsic(_BitScanReverse64)
|
@@ -214,26 +217,21 @@ inline uint32_t clzll(uint64_t x) {
|
|
214
217
|
// Static analysis complains about using uninitialized data
|
215
218
|
// "r", but the only way that can happen is if "x" is 0,
|
216
219
|
// which the callers guarantee to not happen.
|
217
|
-
|
220
|
+
FMT_SUPPRESS_MSC_WARNING(6102)
|
218
221
|
return 63 - r;
|
219
222
|
}
|
220
|
-
# define FMT_BUILTIN_CLZLL(n)
|
221
|
-
} // namespace
|
223
|
+
# define FMT_BUILTIN_CLZLL(n) detail::clzll(n)
|
224
|
+
} // namespace detail
|
222
225
|
FMT_END_NAMESPACE
|
223
226
|
#endif
|
224
227
|
|
225
228
|
// Enable the deprecated numeric alignment.
|
226
|
-
#ifndef
|
227
|
-
# define
|
228
|
-
#endif
|
229
|
-
|
230
|
-
// Enable the deprecated percent specifier.
|
231
|
-
#ifndef FMT_DEPRECATED_PERCENT
|
232
|
-
# define FMT_DEPRECATED_PERCENT 0
|
229
|
+
#ifndef FMT_DEPRECATED_NUMERIC_ALIGN
|
230
|
+
# define FMT_DEPRECATED_NUMERIC_ALIGN 0
|
233
231
|
#endif
|
234
232
|
|
235
233
|
FMT_BEGIN_NAMESPACE
|
236
|
-
namespace
|
234
|
+
namespace detail {
|
237
235
|
|
238
236
|
// An equivalent of `*reinterpret_cast<Dest*>(&source)` that doesn't have
|
239
237
|
// undefined behavior (e.g. due to type aliasing).
|
@@ -285,14 +283,31 @@ template <typename T> constexpr T max_value() {
|
|
285
283
|
template <typename T> constexpr int num_bits() {
|
286
284
|
return std::numeric_limits<T>::digits;
|
287
285
|
}
|
286
|
+
// std::numeric_limits<T>::digits may return 0 for 128-bit ints.
|
287
|
+
template <> constexpr int num_bits<int128_t>() { return 128; }
|
288
|
+
template <> constexpr int num_bits<uint128_t>() { return 128; }
|
288
289
|
template <> constexpr int num_bits<fallback_uintptr>() {
|
289
290
|
return static_cast<int>(sizeof(void*) *
|
290
291
|
std::numeric_limits<unsigned char>::digits);
|
291
292
|
}
|
292
293
|
|
294
|
+
FMT_INLINE void assume(bool condition) {
|
295
|
+
(void)condition;
|
296
|
+
#if FMT_HAS_BUILTIN(__builtin_assume)
|
297
|
+
__builtin_assume(condition);
|
298
|
+
#endif
|
299
|
+
}
|
300
|
+
|
301
|
+
// A workaround for gcc 4.8 to make void_t work in a SFINAE context.
|
302
|
+
template <typename... Ts> struct void_t_impl { using type = void; };
|
303
|
+
|
304
|
+
template <typename... Ts>
|
305
|
+
using void_t = typename detail::void_t_impl<Ts...>::type;
|
306
|
+
|
293
307
|
// An approximation of iterator_t for pre-C++20 systems.
|
294
308
|
template <typename T>
|
295
309
|
using iterator_t = decltype(std::begin(std::declval<T&>()));
|
310
|
+
template <typename T> using sentinel_t = decltype(std::end(std::declval<T&>()));
|
296
311
|
|
297
312
|
// Detect the iterator category of *any* given type in a SFINAE-friendly way.
|
298
313
|
// Unfortunately, older implementations of std::iterator_traits are not safe
|
@@ -339,25 +354,39 @@ inline typename Container::value_type* get_data(Container& c) {
|
|
339
354
|
#if defined(_SECURE_SCL) && _SECURE_SCL
|
340
355
|
// Make a checked iterator to avoid MSVC warnings.
|
341
356
|
template <typename T> using checked_ptr = stdext::checked_array_iterator<T*>;
|
342
|
-
template <typename T> checked_ptr<T> make_checked(T* p,
|
357
|
+
template <typename T> checked_ptr<T> make_checked(T* p, size_t size) {
|
343
358
|
return {p, size};
|
344
359
|
}
|
345
360
|
#else
|
346
361
|
template <typename T> using checked_ptr = T*;
|
347
|
-
template <typename T> inline T* make_checked(T* p,
|
362
|
+
template <typename T> inline T* make_checked(T* p, size_t) { return p; }
|
348
363
|
#endif
|
349
364
|
|
350
365
|
template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
|
351
|
-
|
352
|
-
|
366
|
+
#if FMT_CLANG_VERSION
|
367
|
+
__attribute__((no_sanitize("undefined")))
|
368
|
+
#endif
|
369
|
+
inline checked_ptr<typename Container::value_type>
|
370
|
+
reserve(std::back_insert_iterator<Container> it, size_t n) {
|
353
371
|
Container& c = get_container(it);
|
354
|
-
|
372
|
+
size_t size = c.size();
|
355
373
|
c.resize(size + n);
|
356
374
|
return make_checked(get_data(c) + size, n);
|
357
375
|
}
|
358
376
|
|
377
|
+
template <typename Iterator> inline Iterator& reserve(Iterator& it, size_t) {
|
378
|
+
return it;
|
379
|
+
}
|
380
|
+
|
381
|
+
template <typename Container, FMT_ENABLE_IF(is_contiguous<Container>::value)>
|
382
|
+
inline std::back_insert_iterator<Container> base_iterator(
|
383
|
+
std::back_insert_iterator<Container>& it,
|
384
|
+
checked_ptr<typename Container::value_type>) {
|
385
|
+
return it;
|
386
|
+
}
|
387
|
+
|
359
388
|
template <typename Iterator>
|
360
|
-
inline Iterator
|
389
|
+
inline Iterator base_iterator(Iterator, Iterator it) {
|
361
390
|
return it;
|
362
391
|
}
|
363
392
|
|
@@ -365,7 +394,7 @@ inline Iterator& reserve(Iterator& it, std::size_t) {
|
|
365
394
|
// discards them.
|
366
395
|
class counting_iterator {
|
367
396
|
private:
|
368
|
-
|
397
|
+
size_t count_;
|
369
398
|
|
370
399
|
public:
|
371
400
|
using iterator_category = std::output_iterator_tag;
|
@@ -380,7 +409,7 @@ class counting_iterator {
|
|
380
409
|
|
381
410
|
counting_iterator() : count_(0) {}
|
382
411
|
|
383
|
-
|
412
|
+
size_t count() const { return count_; }
|
384
413
|
|
385
414
|
counting_iterator& operator++() {
|
386
415
|
++count_;
|
@@ -399,10 +428,10 @@ class counting_iterator {
|
|
399
428
|
template <typename OutputIt> class truncating_iterator_base {
|
400
429
|
protected:
|
401
430
|
OutputIt out_;
|
402
|
-
|
403
|
-
|
431
|
+
size_t limit_;
|
432
|
+
size_t count_;
|
404
433
|
|
405
|
-
truncating_iterator_base(OutputIt out,
|
434
|
+
truncating_iterator_base(OutputIt out, size_t limit)
|
406
435
|
: out_(out), limit_(limit), count_(0) {}
|
407
436
|
|
408
437
|
public:
|
@@ -415,7 +444,7 @@ template <typename OutputIt> class truncating_iterator_base {
|
|
415
444
|
truncating_iterator_base; // Mark iterator as checked.
|
416
445
|
|
417
446
|
OutputIt base() const { return out_; }
|
418
|
-
|
447
|
+
size_t count() const { return count_; }
|
419
448
|
};
|
420
449
|
|
421
450
|
// An output iterator that truncates the output and counts the number of objects
|
@@ -433,7 +462,7 @@ class truncating_iterator<OutputIt, std::false_type>
|
|
433
462
|
public:
|
434
463
|
using value_type = typename truncating_iterator_base<OutputIt>::value_type;
|
435
464
|
|
436
|
-
truncating_iterator(OutputIt out,
|
465
|
+
truncating_iterator(OutputIt out, size_t limit)
|
437
466
|
: truncating_iterator_base<OutputIt>(out, limit) {}
|
438
467
|
|
439
468
|
truncating_iterator& operator++() {
|
@@ -456,7 +485,7 @@ template <typename OutputIt>
|
|
456
485
|
class truncating_iterator<OutputIt, std::true_type>
|
457
486
|
: public truncating_iterator_base<OutputIt> {
|
458
487
|
public:
|
459
|
-
truncating_iterator(OutputIt out,
|
488
|
+
truncating_iterator(OutputIt out, size_t limit)
|
460
489
|
: truncating_iterator_base<OutputIt>(out, limit) {}
|
461
490
|
|
462
491
|
template <typename T> truncating_iterator& operator=(T val) {
|
@@ -469,22 +498,6 @@ class truncating_iterator<OutputIt, std::true_type>
|
|
469
498
|
truncating_iterator& operator*() { return *this; }
|
470
499
|
};
|
471
500
|
|
472
|
-
// A range with the specified output iterator and value type.
|
473
|
-
template <typename OutputIt, typename T = typename OutputIt::value_type>
|
474
|
-
class output_range {
|
475
|
-
private:
|
476
|
-
OutputIt it_;
|
477
|
-
|
478
|
-
public:
|
479
|
-
using value_type = T;
|
480
|
-
using iterator = OutputIt;
|
481
|
-
struct sentinel {};
|
482
|
-
|
483
|
-
explicit output_range(OutputIt it) : it_(it) {}
|
484
|
-
OutputIt begin() const { return it_; }
|
485
|
-
sentinel end() const { return {}; } // Sentinel is not used yet.
|
486
|
-
};
|
487
|
-
|
488
501
|
template <typename Char>
|
489
502
|
inline size_t count_code_points(basic_string_view<Char> s) {
|
490
503
|
return s.size();
|
@@ -523,8 +536,6 @@ inline size_t code_point_index(basic_string_view<char8_type> s, size_t n) {
|
|
523
536
|
return s.size();
|
524
537
|
}
|
525
538
|
|
526
|
-
inline char8_type to_char8_t(char c) { return static_cast<char8_type>(c); }
|
527
|
-
|
528
539
|
template <typename InputIt, typename OutChar>
|
529
540
|
using needs_conversion = bool_constant<
|
530
541
|
std::is_same<typename std::iterator_traits<InputIt>::value_type,
|
@@ -540,7 +551,8 @@ OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) {
|
|
540
551
|
template <typename OutChar, typename InputIt, typename OutputIt,
|
541
552
|
FMT_ENABLE_IF(needs_conversion<InputIt, OutChar>::value)>
|
542
553
|
OutputIt copy_str(InputIt begin, InputIt end, OutputIt it) {
|
543
|
-
return std::transform(begin, end, it,
|
554
|
+
return std::transform(begin, end, it,
|
555
|
+
[](char c) { return static_cast<char8_type>(c); });
|
544
556
|
}
|
545
557
|
|
546
558
|
#ifndef FMT_USE_GRISU
|
@@ -555,43 +567,13 @@ template <typename T> constexpr bool use_grisu() {
|
|
555
567
|
template <typename T>
|
556
568
|
template <typename U>
|
557
569
|
void buffer<T>::append(const U* begin, const U* end) {
|
558
|
-
|
570
|
+
size_t new_size = size_ + to_unsigned(end - begin);
|
559
571
|
reserve(new_size);
|
560
|
-
std::uninitialized_copy(begin, end,
|
572
|
+
std::uninitialized_copy(begin, end,
|
573
|
+
make_checked(ptr_ + size_, capacity_ - size_));
|
561
574
|
size_ = new_size;
|
562
575
|
}
|
563
|
-
} // namespace
|
564
|
-
|
565
|
-
// A range with an iterator appending to a buffer.
|
566
|
-
template <typename T>
|
567
|
-
class buffer_range : public internal::output_range<
|
568
|
-
std::back_insert_iterator<internal::buffer<T>>, T> {
|
569
|
-
public:
|
570
|
-
using iterator = std::back_insert_iterator<internal::buffer<T>>;
|
571
|
-
using internal::output_range<iterator, T>::output_range;
|
572
|
-
buffer_range(internal::buffer<T>& buf)
|
573
|
-
: internal::output_range<iterator, T>(std::back_inserter(buf)) {}
|
574
|
-
};
|
575
|
-
|
576
|
-
class FMT_DEPRECATED u8string_view
|
577
|
-
: public basic_string_view<internal::char8_type> {
|
578
|
-
public:
|
579
|
-
u8string_view(const char* s)
|
580
|
-
: basic_string_view<internal::char8_type>(
|
581
|
-
reinterpret_cast<const internal::char8_type*>(s)) {}
|
582
|
-
u8string_view(const char* s, size_t count) FMT_NOEXCEPT
|
583
|
-
: basic_string_view<internal::char8_type>(
|
584
|
-
reinterpret_cast<const internal::char8_type*>(s), count) {}
|
585
|
-
};
|
586
|
-
|
587
|
-
#if FMT_USE_USER_DEFINED_LITERALS
|
588
|
-
inline namespace literals {
|
589
|
-
FMT_DEPRECATED inline basic_string_view<internal::char8_type> operator"" _u(
|
590
|
-
const char* s, std::size_t n) {
|
591
|
-
return {reinterpret_cast<const internal::char8_type*>(s), n};
|
592
|
-
}
|
593
|
-
} // namespace literals
|
594
|
-
#endif
|
576
|
+
} // namespace detail
|
595
577
|
|
596
578
|
// The number of characters to store in the basic_memory_buffer object itself
|
597
579
|
// to avoid dynamic memory allocation.
|
@@ -626,27 +608,30 @@ enum { inline_buffer_size = 500 };
|
|
626
608
|
The output can be converted to an ``std::string`` with ``to_string(out)``.
|
627
609
|
\endrst
|
628
610
|
*/
|
629
|
-
template <typename T,
|
611
|
+
template <typename T, size_t SIZE = inline_buffer_size,
|
630
612
|
typename Allocator = std::allocator<T>>
|
631
|
-
class basic_memory_buffer :
|
613
|
+
class basic_memory_buffer : public detail::buffer<T> {
|
632
614
|
private:
|
633
615
|
T store_[SIZE];
|
634
616
|
|
617
|
+
// Don't inherit from Allocator avoid generating type_info for it.
|
618
|
+
Allocator alloc_;
|
619
|
+
|
635
620
|
// Deallocate memory allocated by the buffer.
|
636
621
|
void deallocate() {
|
637
622
|
T* data = this->data();
|
638
|
-
if (data != store_)
|
623
|
+
if (data != store_) alloc_.deallocate(data, this->capacity());
|
639
624
|
}
|
640
625
|
|
641
626
|
protected:
|
642
|
-
void grow(
|
627
|
+
void grow(size_t size) FMT_OVERRIDE;
|
643
628
|
|
644
629
|
public:
|
645
630
|
using value_type = T;
|
646
631
|
using const_reference = const T&;
|
647
632
|
|
648
633
|
explicit basic_memory_buffer(const Allocator& alloc = Allocator())
|
649
|
-
:
|
634
|
+
: alloc_(alloc) {
|
650
635
|
this->set(store_, SIZE);
|
651
636
|
}
|
652
637
|
~basic_memory_buffer() FMT_OVERRIDE { deallocate(); }
|
@@ -654,14 +639,13 @@ class basic_memory_buffer : private Allocator, public internal::buffer<T> {
|
|
654
639
|
private:
|
655
640
|
// Move data from other to this buffer.
|
656
641
|
void move(basic_memory_buffer& other) {
|
657
|
-
|
658
|
-
this_alloc = std::move(other_alloc);
|
642
|
+
alloc_ = std::move(other.alloc_);
|
659
643
|
T* data = other.data();
|
660
|
-
|
644
|
+
size_t size = other.size(), capacity = other.capacity();
|
661
645
|
if (data == other.store_) {
|
662
646
|
this->set(store_, capacity);
|
663
647
|
std::uninitialized_copy(other.store_, other.store_ + size,
|
664
|
-
|
648
|
+
detail::make_checked(store_, capacity));
|
665
649
|
} else {
|
666
650
|
this->set(data, capacity);
|
667
651
|
// Set pointer to the inline array so that delete is not called
|
@@ -693,32 +677,37 @@ class basic_memory_buffer : private Allocator, public internal::buffer<T> {
|
|
693
677
|
}
|
694
678
|
|
695
679
|
// Returns a copy of the allocator associated with this buffer.
|
696
|
-
Allocator get_allocator() const { return
|
680
|
+
Allocator get_allocator() const { return alloc_; }
|
697
681
|
};
|
698
682
|
|
699
|
-
template <typename T,
|
700
|
-
void basic_memory_buffer<T, SIZE, Allocator>::grow(
|
701
|
-
#ifdef
|
702
|
-
if (size >
|
683
|
+
template <typename T, size_t SIZE, typename Allocator>
|
684
|
+
void basic_memory_buffer<T, SIZE, Allocator>::grow(size_t size) {
|
685
|
+
#ifdef FMT_FUZZ
|
686
|
+
if (size > 5000) throw std::runtime_error("fuzz mode - won't grow that much");
|
703
687
|
#endif
|
704
|
-
|
705
|
-
|
688
|
+
size_t old_capacity = this->capacity();
|
689
|
+
size_t new_capacity = old_capacity + old_capacity / 2;
|
706
690
|
if (size > new_capacity) new_capacity = size;
|
707
691
|
T* old_data = this->data();
|
708
|
-
T* new_data =
|
692
|
+
T* new_data =
|
693
|
+
std::allocator_traits<Allocator>::allocate(alloc_, new_capacity);
|
709
694
|
// The following code doesn't throw, so the raw pointer above doesn't leak.
|
710
695
|
std::uninitialized_copy(old_data, old_data + this->size(),
|
711
|
-
|
696
|
+
detail::make_checked(new_data, new_capacity));
|
712
697
|
this->set(new_data, new_capacity);
|
713
698
|
// deallocate must not throw according to the standard, but even if it does,
|
714
699
|
// the buffer already uses the new storage and will deallocate it in
|
715
700
|
// destructor.
|
716
|
-
if (old_data != store_)
|
701
|
+
if (old_data != store_) alloc_.deallocate(old_data, old_capacity);
|
717
702
|
}
|
718
703
|
|
719
704
|
using memory_buffer = basic_memory_buffer<char>;
|
720
705
|
using wmemory_buffer = basic_memory_buffer<wchar_t>;
|
721
706
|
|
707
|
+
template <typename T, size_t SIZE, typename Allocator>
|
708
|
+
struct is_contiguous<basic_memory_buffer<T, SIZE, Allocator>> : std::true_type {
|
709
|
+
};
|
710
|
+
|
722
711
|
/** A formatting error such as invalid format string. */
|
723
712
|
FMT_CLASS_API
|
724
713
|
class FMT_API format_error : public std::runtime_error {
|
@@ -733,15 +722,20 @@ class FMT_API format_error : public std::runtime_error {
|
|
733
722
|
~format_error() FMT_NOEXCEPT FMT_OVERRIDE;
|
734
723
|
};
|
735
724
|
|
736
|
-
namespace
|
725
|
+
namespace detail {
|
726
|
+
|
727
|
+
template <typename T>
|
728
|
+
using is_signed =
|
729
|
+
std::integral_constant<bool, std::numeric_limits<T>::is_signed ||
|
730
|
+
std::is_same<T, int128_t>::value>;
|
737
731
|
|
738
732
|
// Returns true if value is negative, false otherwise.
|
739
733
|
// Same as `value < 0` but doesn't produce warnings if T is an unsigned type.
|
740
|
-
template <typename T, FMT_ENABLE_IF(
|
734
|
+
template <typename T, FMT_ENABLE_IF(is_signed<T>::value)>
|
741
735
|
FMT_CONSTEXPR bool is_negative(T value) {
|
742
736
|
return value < 0;
|
743
737
|
}
|
744
|
-
template <typename T, FMT_ENABLE_IF(!
|
738
|
+
template <typename T, FMT_ENABLE_IF(!is_signed<T>::value)>
|
745
739
|
FMT_CONSTEXPR bool is_negative(T) {
|
746
740
|
return false;
|
747
741
|
}
|
@@ -756,9 +750,9 @@ FMT_CONSTEXPR bool is_supported_floating_point(T) {
|
|
756
750
|
// Smallest of uint32_t, uint64_t, uint128_t that is large enough to
|
757
751
|
// represent all values of T.
|
758
752
|
template <typename T>
|
759
|
-
using uint32_or_64_or_128_t =
|
760
|
-
|
761
|
-
|
753
|
+
using uint32_or_64_or_128_t =
|
754
|
+
conditional_t<num_bits<T>() <= 32, uint32_t,
|
755
|
+
conditional_t<num_bits<T>() <= 64, uint64_t, uint128_t>>;
|
762
756
|
|
763
757
|
// Static data is placed in this class template for the header-only config.
|
764
758
|
template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data {
|
@@ -767,16 +761,22 @@ template <typename T = void> struct FMT_EXTERN_TEMPLATE_API basic_data {
|
|
767
761
|
static const uint64_t zero_or_powers_of_10_64[];
|
768
762
|
static const uint64_t pow10_significands[];
|
769
763
|
static const int16_t pow10_exponents[];
|
770
|
-
|
764
|
+
// GCC generates slightly better code for pairs than chars.
|
765
|
+
using digit_pair = char[2];
|
766
|
+
static const digit_pair digits[];
|
771
767
|
static const char hex_digits[];
|
772
768
|
static const char foreground_color[];
|
773
769
|
static const char background_color[];
|
774
770
|
static const char reset_color[5];
|
775
771
|
static const wchar_t wreset_color[5];
|
776
772
|
static const char signs[];
|
773
|
+
static const char left_padding_shifts[5];
|
774
|
+
static const char right_padding_shifts[5];
|
777
775
|
};
|
778
776
|
|
777
|
+
#ifndef FMT_EXPORTED
|
779
778
|
FMT_EXTERN template struct basic_data<void>;
|
779
|
+
#endif
|
780
780
|
|
781
781
|
// This is a struct rather than an alias to avoid shadowing warnings in gcc.
|
782
782
|
struct data : basic_data<> {};
|
@@ -834,7 +834,7 @@ template <unsigned BITS, typename UInt> inline int count_digits(UInt n) {
|
|
834
834
|
return num_digits;
|
835
835
|
}
|
836
836
|
|
837
|
-
template <> int count_digits<4>(
|
837
|
+
template <> int count_digits<4>(detail::fallback_uintptr n);
|
838
838
|
|
839
839
|
#if FMT_GCC_VERSION || FMT_CLANG_VERSION
|
840
840
|
# define FMT_ALWAYS_INLINE inline __attribute__((always_inline))
|
@@ -850,6 +850,12 @@ inline int count_digits(uint32_t n) {
|
|
850
850
|
}
|
851
851
|
#endif
|
852
852
|
|
853
|
+
template <typename Int> constexpr int digits10() FMT_NOEXCEPT {
|
854
|
+
return std::numeric_limits<Int>::digits10;
|
855
|
+
}
|
856
|
+
template <> constexpr int digits10<int128_t>() FMT_NOEXCEPT { return 38; }
|
857
|
+
template <> constexpr int digits10<uint128_t>() FMT_NOEXCEPT { return 38; }
|
858
|
+
|
853
859
|
template <typename Char> FMT_API std::string grouping_impl(locale_ref loc);
|
854
860
|
template <typename Char> inline std::string grouping(locale_ref loc) {
|
855
861
|
return grouping_impl<char>(loc);
|
@@ -874,57 +880,61 @@ template <> inline wchar_t decimal_point(locale_ref loc) {
|
|
874
880
|
return decimal_point_impl<wchar_t>(loc);
|
875
881
|
}
|
876
882
|
|
877
|
-
//
|
878
|
-
|
879
|
-
|
880
|
-
|
881
|
-
inline
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
|
883
|
+
// Compares two characters for equality.
|
884
|
+
template <typename Char> bool equal2(const Char* lhs, const char* rhs) {
|
885
|
+
return lhs[0] == rhs[0] && lhs[1] == rhs[1];
|
886
|
+
}
|
887
|
+
inline bool equal2(const char* lhs, const char* rhs) {
|
888
|
+
return memcmp(lhs, rhs, 2) == 0;
|
889
|
+
}
|
890
|
+
|
891
|
+
// Copies two characters from src to dst.
|
892
|
+
template <typename Char> void copy2(Char* dst, const char* src) {
|
893
|
+
*dst++ = static_cast<Char>(*src++);
|
894
|
+
*dst = static_cast<Char>(*src);
|
895
|
+
}
|
896
|
+
inline void copy2(char* dst, const char* src) { memcpy(dst, src, 2); }
|
897
|
+
|
898
|
+
template <typename Iterator> struct format_decimal_result {
|
899
|
+
Iterator begin;
|
900
|
+
Iterator end;
|
901
|
+
};
|
902
|
+
|
903
|
+
// Formats a decimal unsigned integer value writing into out pointing to a
|
904
|
+
// buffer of specified size. The caller must ensure that the buffer is large
|
905
|
+
// enough.
|
906
|
+
template <typename Char, typename UInt>
|
907
|
+
inline format_decimal_result<Char*> format_decimal(Char* out, UInt value,
|
908
|
+
int size) {
|
909
|
+
FMT_ASSERT(size >= count_digits(value), "invalid digit count");
|
910
|
+
out += size;
|
911
|
+
Char* end = out;
|
886
912
|
while (value >= 100) {
|
887
913
|
// Integer division is slow so do it for a group of two digits instead
|
888
914
|
// of for every digit. The idea comes from the talk by Alexandrescu
|
889
915
|
// "Three Optimization Tips for C++". See speed-test for a comparison.
|
890
|
-
|
916
|
+
out -= 2;
|
917
|
+
copy2(out, data::digits[value % 100]);
|
891
918
|
value /= 100;
|
892
|
-
*--buffer = static_cast<Char>(data::digits[index + 1]);
|
893
|
-
add_thousands_sep(buffer);
|
894
|
-
*--buffer = static_cast<Char>(data::digits[index]);
|
895
|
-
add_thousands_sep(buffer);
|
896
919
|
}
|
897
920
|
if (value < 10) {
|
898
|
-
*--
|
899
|
-
return end;
|
921
|
+
*--out = static_cast<Char>('0' + value);
|
922
|
+
return {out, end};
|
900
923
|
}
|
901
|
-
|
902
|
-
|
903
|
-
|
904
|
-
*--buffer = static_cast<Char>(data::digits[index]);
|
905
|
-
return end;
|
924
|
+
out -= 2;
|
925
|
+
copy2(out, data::digits[value]);
|
926
|
+
return {out, end};
|
906
927
|
}
|
907
928
|
|
908
|
-
template <typename
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
template <> constexpr int digits10<uint128_t>() FMT_NOEXCEPT { return 38; }
|
913
|
-
|
914
|
-
template <typename Char, typename UInt, typename Iterator, typename F>
|
915
|
-
inline Iterator format_decimal(Iterator out, UInt value, int num_digits,
|
916
|
-
F add_thousands_sep) {
|
917
|
-
FMT_ASSERT(num_digits >= 0, "invalid digit count");
|
929
|
+
template <typename Char, typename UInt, typename Iterator,
|
930
|
+
FMT_ENABLE_IF(!std::is_pointer<remove_cvref_t<Iterator>>::value)>
|
931
|
+
inline format_decimal_result<Iterator> format_decimal(Iterator out, UInt value,
|
932
|
+
int num_digits) {
|
918
933
|
// Buffer should be large enough to hold all digits (<= digits10 + 1).
|
919
934
|
enum { max_size = digits10<UInt>() + 1 };
|
920
935
|
Char buffer[2 * max_size];
|
921
|
-
auto end = format_decimal(buffer, value, num_digits
|
922
|
-
return
|
923
|
-
}
|
924
|
-
|
925
|
-
template <typename Char, typename It, typename UInt>
|
926
|
-
inline It format_decimal(It out, UInt value, int num_digits) {
|
927
|
-
return format_decimal<Char>(out, value, num_digits, [](Char*) {});
|
936
|
+
auto end = format_decimal(buffer, value, num_digits).end;
|
937
|
+
return {out, detail::copy_str<Char>(buffer, end, out)};
|
928
938
|
}
|
929
939
|
|
930
940
|
template <unsigned BASE_BITS, typename Char, typename UInt>
|
@@ -942,7 +952,7 @@ inline Char* format_uint(Char* buffer, UInt value, int num_digits,
|
|
942
952
|
}
|
943
953
|
|
944
954
|
template <unsigned BASE_BITS, typename Char>
|
945
|
-
Char* format_uint(Char* buffer,
|
955
|
+
Char* format_uint(Char* buffer, detail::fallback_uintptr n, int num_digits,
|
946
956
|
bool = false) {
|
947
957
|
auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
|
948
958
|
int start = (num_digits + char_digits - 1) / char_digits - 1;
|
@@ -968,7 +978,7 @@ inline It format_uint(It out, UInt value, int num_digits, bool upper = false) {
|
|
968
978
|
// Buffer should be large enough to hold all digits (digits / BASE_BITS + 1).
|
969
979
|
char buffer[num_bits<UInt>() / BASE_BITS + 1];
|
970
980
|
format_uint<BASE_BITS>(buffer, value, num_digits, upper);
|
971
|
-
return
|
981
|
+
return detail::copy_str<Char>(buffer, buffer + num_digits, out);
|
972
982
|
}
|
973
983
|
|
974
984
|
// A converter from UTF-8 to UTF-16.
|
@@ -1019,7 +1029,7 @@ template <typename Char> struct fill_t {
|
|
1019
1029
|
return fill;
|
1020
1030
|
}
|
1021
1031
|
};
|
1022
|
-
} // namespace
|
1032
|
+
} // namespace detail
|
1023
1033
|
|
1024
1034
|
// We cannot use enum classes as bit fields because of a gcc bug
|
1025
1035
|
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414.
|
@@ -1041,7 +1051,7 @@ template <typename Char> struct basic_format_specs {
|
|
1041
1051
|
align_t align : 4;
|
1042
1052
|
sign_t sign : 3;
|
1043
1053
|
bool alt : 1; // Alternate form ('#').
|
1044
|
-
|
1054
|
+
detail::fill_t<Char> fill;
|
1045
1055
|
|
1046
1056
|
constexpr basic_format_specs()
|
1047
1057
|
: width(0),
|
@@ -1050,12 +1060,12 @@ template <typename Char> struct basic_format_specs {
|
|
1050
1060
|
align(align::none),
|
1051
1061
|
sign(sign::none),
|
1052
1062
|
alt(false),
|
1053
|
-
fill(
|
1063
|
+
fill(detail::fill_t<Char>::make()) {}
|
1054
1064
|
};
|
1055
1065
|
|
1056
1066
|
using format_specs = basic_format_specs<char>;
|
1057
1067
|
|
1058
|
-
namespace
|
1068
|
+
namespace detail {
|
1059
1069
|
|
1060
1070
|
// A floating-point presentation format.
|
1061
1071
|
enum class float_format : unsigned char {
|
@@ -1071,7 +1081,6 @@ struct float_specs {
|
|
1071
1081
|
sign_t sign : 8;
|
1072
1082
|
bool upper : 1;
|
1073
1083
|
bool locale : 1;
|
1074
|
-
bool percent : 1;
|
1075
1084
|
bool binary32 : 1;
|
1076
1085
|
bool use_grisu : 1;
|
1077
1086
|
bool showpoint : 1;
|
@@ -1087,12 +1096,12 @@ template <typename Char, typename It> It write_exponent(int exp, It it) {
|
|
1087
1096
|
*it++ = static_cast<Char>('+');
|
1088
1097
|
}
|
1089
1098
|
if (exp >= 100) {
|
1090
|
-
const char* top = data::digits
|
1099
|
+
const char* top = data::digits[exp / 100];
|
1091
1100
|
if (exp >= 1000) *it++ = static_cast<Char>(top[0]);
|
1092
1101
|
*it++ = static_cast<Char>(top[1]);
|
1093
1102
|
exp %= 100;
|
1094
1103
|
}
|
1095
|
-
const char* d = data::digits
|
1104
|
+
const char* d = data::digits[exp];
|
1096
1105
|
*it++ = static_cast<Char>(d[0]);
|
1097
1106
|
*it++ = static_cast<Char>(d[1]);
|
1098
1107
|
return it;
|
@@ -1134,8 +1143,8 @@ template <typename Char> class float_writer {
|
|
1134
1143
|
*it++ = static_cast<Char>('0');
|
1135
1144
|
return it;
|
1136
1145
|
}
|
1137
|
-
#ifdef
|
1138
|
-
if (num_zeros >
|
1146
|
+
#ifdef FMT_FUZZ
|
1147
|
+
if (num_zeros > 5000)
|
1139
1148
|
throw std::runtime_error("fuzz mode - avoiding excessive cpu use");
|
1140
1149
|
#endif
|
1141
1150
|
it = std::fill_n(it, num_zeros, static_cast<Char>('0'));
|
@@ -1198,11 +1207,10 @@ template <typename Char> class float_writer {
|
|
1198
1207
|
}
|
1199
1208
|
|
1200
1209
|
size_t size() const { return size_; }
|
1201
|
-
size_t width() const { return size(); }
|
1202
1210
|
|
1203
|
-
template <typename It>
|
1211
|
+
template <typename It> It operator()(It it) const {
|
1204
1212
|
if (specs_.sign) *it++ = static_cast<Char>(data::signs[specs_.sign]);
|
1205
|
-
|
1213
|
+
return prettify(it);
|
1206
1214
|
}
|
1207
1215
|
};
|
1208
1216
|
|
@@ -1235,10 +1243,15 @@ FMT_CONSTEXPR void handle_int_type_spec(char spec, Handler&& handler) {
|
|
1235
1243
|
case 'o':
|
1236
1244
|
handler.on_oct();
|
1237
1245
|
break;
|
1246
|
+
#ifdef FMT_DEPRECATED_N_SPECIFIER
|
1238
1247
|
case 'n':
|
1248
|
+
#endif
|
1239
1249
|
case 'L':
|
1240
1250
|
handler.on_num();
|
1241
1251
|
break;
|
1252
|
+
case 'c':
|
1253
|
+
handler.on_chr();
|
1254
|
+
break;
|
1242
1255
|
default:
|
1243
1256
|
handler.on_error();
|
1244
1257
|
}
|
@@ -1274,19 +1287,16 @@ FMT_CONSTEXPR float_specs parse_float_type_spec(
|
|
1274
1287
|
result.format = float_format::fixed;
|
1275
1288
|
result.showpoint |= specs.precision != 0;
|
1276
1289
|
break;
|
1277
|
-
#if FMT_DEPRECATED_PERCENT
|
1278
|
-
case '%':
|
1279
|
-
result.format = float_format::fixed;
|
1280
|
-
result.percent = true;
|
1281
|
-
break;
|
1282
|
-
#endif
|
1283
1290
|
case 'A':
|
1284
1291
|
result.upper = true;
|
1285
1292
|
FMT_FALLTHROUGH;
|
1286
1293
|
case 'a':
|
1287
1294
|
result.format = float_format::hex;
|
1288
1295
|
break;
|
1296
|
+
#ifdef FMT_DEPRECATED_N_SPECIFIER
|
1289
1297
|
case 'n':
|
1298
|
+
#endif
|
1299
|
+
case 'L':
|
1290
1300
|
result.locale = true;
|
1291
1301
|
break;
|
1292
1302
|
default:
|
@@ -1335,6 +1345,7 @@ template <typename ErrorHandler> class int_type_checker : private ErrorHandler {
|
|
1335
1345
|
FMT_CONSTEXPR void on_bin() {}
|
1336
1346
|
FMT_CONSTEXPR void on_oct() {}
|
1337
1347
|
FMT_CONSTEXPR void on_num() {}
|
1348
|
+
FMT_CONSTEXPR void on_chr() {}
|
1338
1349
|
|
1339
1350
|
FMT_CONSTEXPR void on_error() {
|
1340
1351
|
ErrorHandler::on_error("invalid type specifier");
|
@@ -1366,38 +1377,6 @@ class cstring_type_checker : public ErrorHandler {
|
|
1366
1377
|
FMT_CONSTEXPR void on_pointer() {}
|
1367
1378
|
};
|
1368
1379
|
|
1369
|
-
template <typename Context>
|
1370
|
-
void arg_map<Context>::init(const basic_format_args<Context>& args) {
|
1371
|
-
if (map_) return;
|
1372
|
-
map_ = new entry[internal::to_unsigned(args.max_size())];
|
1373
|
-
if (args.is_packed()) {
|
1374
|
-
for (int i = 0;; ++i) {
|
1375
|
-
internal::type arg_type = args.type(i);
|
1376
|
-
if (arg_type == internal::type::none_type) return;
|
1377
|
-
if (arg_type == internal::type::named_arg_type)
|
1378
|
-
push_back(args.values_[i]);
|
1379
|
-
}
|
1380
|
-
}
|
1381
|
-
for (int i = 0, n = args.max_size(); i < n; ++i) {
|
1382
|
-
auto type = args.args_[i].type_;
|
1383
|
-
if (type == internal::type::named_arg_type) push_back(args.args_[i].value_);
|
1384
|
-
}
|
1385
|
-
}
|
1386
|
-
|
1387
|
-
template <typename Char> struct nonfinite_writer {
|
1388
|
-
sign_t sign;
|
1389
|
-
const char* str;
|
1390
|
-
static constexpr size_t str_size = 3;
|
1391
|
-
|
1392
|
-
size_t size() const { return str_size + (sign ? 1 : 0); }
|
1393
|
-
size_t width() const { return size(); }
|
1394
|
-
|
1395
|
-
template <typename It> void operator()(It&& it) const {
|
1396
|
-
if (sign) *it++ = static_cast<Char>(data::signs[sign]);
|
1397
|
-
it = copy_str<Char>(str, str + str_size, it);
|
1398
|
-
}
|
1399
|
-
};
|
1400
|
-
|
1401
1380
|
template <typename OutputIt, typename Char>
|
1402
1381
|
FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t<Char>& fill) {
|
1403
1382
|
auto fill_size = fill.size();
|
@@ -1406,375 +1385,474 @@ FMT_NOINLINE OutputIt fill(OutputIt it, size_t n, const fill_t<Char>& fill) {
|
|
1406
1385
|
return it;
|
1407
1386
|
}
|
1408
1387
|
|
1409
|
-
//
|
1410
|
-
//
|
1411
|
-
|
1412
|
-
|
1413
|
-
|
1414
|
-
|
1415
|
-
|
1416
|
-
|
1417
|
-
|
1418
|
-
|
1419
|
-
|
1420
|
-
|
1421
|
-
|
1422
|
-
|
1423
|
-
auto reserve(
|
1424
|
-
|
1425
|
-
|
1426
|
-
|
1427
|
-
|
1428
|
-
|
1429
|
-
|
1430
|
-
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1434
|
-
|
1435
|
-
|
1436
|
-
|
1437
|
-
|
1438
|
-
|
1439
|
-
|
1440
|
-
|
1441
|
-
|
1442
|
-
|
1443
|
-
|
1444
|
-
|
1445
|
-
|
1446
|
-
|
1447
|
-
|
1448
|
-
|
1449
|
-
|
1450
|
-
|
1451
|
-
|
1452
|
-
|
1388
|
+
// Writes the output of f, padded according to format specifications in specs.
|
1389
|
+
// size: output size in code units.
|
1390
|
+
// width: output display width in (terminal) column positions.
|
1391
|
+
template <align::type align = align::left, typename OutputIt, typename Char,
|
1392
|
+
typename F>
|
1393
|
+
inline OutputIt write_padded(OutputIt out,
|
1394
|
+
const basic_format_specs<Char>& specs, size_t size,
|
1395
|
+
size_t width, const F& f) {
|
1396
|
+
static_assert(align == align::left || align == align::right, "");
|
1397
|
+
unsigned spec_width = to_unsigned(specs.width);
|
1398
|
+
size_t padding = spec_width > width ? spec_width - width : 0;
|
1399
|
+
auto* shifts = align == align::left ? data::left_padding_shifts
|
1400
|
+
: data::right_padding_shifts;
|
1401
|
+
size_t left_padding = padding >> shifts[specs.align];
|
1402
|
+
auto it = reserve(out, size + padding * specs.fill.size());
|
1403
|
+
it = fill(it, left_padding, specs.fill);
|
1404
|
+
it = f(it);
|
1405
|
+
it = fill(it, padding - left_padding, specs.fill);
|
1406
|
+
return base_iterator(out, it);
|
1407
|
+
}
|
1408
|
+
|
1409
|
+
template <align::type align = align::left, typename OutputIt, typename Char,
|
1410
|
+
typename F>
|
1411
|
+
inline OutputIt write_padded(OutputIt out,
|
1412
|
+
const basic_format_specs<Char>& specs, size_t size,
|
1413
|
+
const F& f) {
|
1414
|
+
return write_padded<align>(out, specs, size, size, f);
|
1415
|
+
}
|
1416
|
+
|
1417
|
+
template <typename Char, typename OutputIt>
|
1418
|
+
OutputIt write_bytes(OutputIt out, string_view bytes,
|
1419
|
+
const basic_format_specs<Char>& specs) {
|
1420
|
+
using iterator = remove_reference_t<decltype(reserve(out, 0))>;
|
1421
|
+
return write_padded(out, specs, bytes.size(), [bytes](iterator it) {
|
1422
|
+
const char* data = bytes.data();
|
1423
|
+
return copy_str<Char>(data, data + bytes.size(), it);
|
1424
|
+
});
|
1425
|
+
}
|
1426
|
+
|
1427
|
+
// Data for write_int that doesn't depend on output iterator type. It is used to
|
1428
|
+
// avoid template code bloat.
|
1429
|
+
template <typename Char> struct write_int_data {
|
1430
|
+
size_t size;
|
1431
|
+
size_t padding;
|
1432
|
+
|
1433
|
+
write_int_data(int num_digits, string_view prefix,
|
1434
|
+
const basic_format_specs<Char>& specs)
|
1435
|
+
: size(prefix.size() + to_unsigned(num_digits)), padding(0) {
|
1453
1436
|
if (specs.align == align::numeric) {
|
1454
|
-
auto
|
1455
|
-
if (
|
1456
|
-
padding =
|
1457
|
-
size =
|
1437
|
+
auto width = to_unsigned(specs.width);
|
1438
|
+
if (width > size) {
|
1439
|
+
padding = width - size;
|
1440
|
+
size = width;
|
1458
1441
|
}
|
1459
1442
|
} else if (specs.precision > num_digits) {
|
1460
1443
|
size = prefix.size() + to_unsigned(specs.precision);
|
1461
1444
|
padding = to_unsigned(specs.precision - num_digits);
|
1462
|
-
fill = static_cast<char_type>('0');
|
1463
1445
|
}
|
1464
|
-
if (specs.align == align::none) specs.align = align::right;
|
1465
|
-
write_padded(specs, padded_int_writer<F>{size, prefix, fill, padding, f});
|
1466
1446
|
}
|
1447
|
+
};
|
1467
1448
|
|
1468
|
-
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1485
|
-
|
1486
|
-
|
1487
|
-
|
1488
|
-
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1495
|
-
|
1496
|
-
|
1497
|
-
|
1498
|
-
|
1499
|
-
|
1500
|
-
|
1501
|
-
|
1502
|
-
|
1503
|
-
|
1504
|
-
|
1449
|
+
// Writes an integer in the format
|
1450
|
+
// <left-padding><prefix><numeric-padding><digits><right-padding>
|
1451
|
+
// where <digits> are written by f(it).
|
1452
|
+
template <typename OutputIt, typename Char, typename F>
|
1453
|
+
OutputIt write_int(OutputIt out, int num_digits, string_view prefix,
|
1454
|
+
const basic_format_specs<Char>& specs, F f) {
|
1455
|
+
auto data = write_int_data<Char>(num_digits, prefix, specs);
|
1456
|
+
using iterator = remove_reference_t<decltype(reserve(out, 0))>;
|
1457
|
+
return write_padded<align::right>(out, specs, data.size, [=](iterator it) {
|
1458
|
+
if (prefix.size() != 0)
|
1459
|
+
it = copy_str<Char>(prefix.begin(), prefix.end(), it);
|
1460
|
+
it = std::fill_n(it, data.padding, static_cast<Char>('0'));
|
1461
|
+
return f(it);
|
1462
|
+
});
|
1463
|
+
}
|
1464
|
+
|
1465
|
+
template <typename StrChar, typename Char, typename OutputIt>
|
1466
|
+
OutputIt write(OutputIt out, basic_string_view<StrChar> s,
|
1467
|
+
const basic_format_specs<Char>& specs) {
|
1468
|
+
auto data = s.data();
|
1469
|
+
auto size = s.size();
|
1470
|
+
if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
|
1471
|
+
size = code_point_index(s, to_unsigned(specs.precision));
|
1472
|
+
auto width = specs.width != 0
|
1473
|
+
? count_code_points(basic_string_view<StrChar>(data, size))
|
1474
|
+
: 0;
|
1475
|
+
using iterator = remove_reference_t<decltype(reserve(out, 0))>;
|
1476
|
+
return write_padded(out, specs, size, width, [=](iterator it) {
|
1477
|
+
return copy_str<Char>(data, data + size, it);
|
1478
|
+
});
|
1479
|
+
}
|
1480
|
+
|
1481
|
+
// The handle_int_type_spec handler that writes an integer.
|
1482
|
+
template <typename OutputIt, typename Char, typename UInt> struct int_writer {
|
1483
|
+
OutputIt out;
|
1484
|
+
locale_ref locale;
|
1485
|
+
const basic_format_specs<Char>& specs;
|
1486
|
+
UInt abs_value;
|
1487
|
+
char prefix[4];
|
1488
|
+
unsigned prefix_size;
|
1489
|
+
|
1490
|
+
using iterator =
|
1491
|
+
remove_reference_t<decltype(reserve(std::declval<OutputIt&>(), 0))>;
|
1492
|
+
|
1493
|
+
string_view get_prefix() const { return string_view(prefix, prefix_size); }
|
1494
|
+
|
1495
|
+
template <typename Int>
|
1496
|
+
int_writer(OutputIt output, locale_ref loc, Int value,
|
1497
|
+
const basic_format_specs<Char>& s)
|
1498
|
+
: out(output),
|
1499
|
+
locale(loc),
|
1500
|
+
specs(s),
|
1501
|
+
abs_value(static_cast<UInt>(value)),
|
1502
|
+
prefix_size(0) {
|
1503
|
+
static_assert(std::is_same<uint32_or_64_or_128_t<Int>, UInt>::value, "");
|
1504
|
+
if (is_negative(value)) {
|
1505
|
+
prefix[0] = '-';
|
1506
|
+
++prefix_size;
|
1507
|
+
abs_value = 0 - abs_value;
|
1508
|
+
} else if (specs.sign != sign::none && specs.sign != sign::minus) {
|
1509
|
+
prefix[0] = specs.sign == sign::plus ? '+' : ' ';
|
1510
|
+
++prefix_size;
|
1505
1511
|
}
|
1512
|
+
}
|
1506
1513
|
|
1507
|
-
|
1508
|
-
|
1509
|
-
|
1510
|
-
|
1511
|
-
|
1512
|
-
|
1513
|
-
|
1514
|
-
};
|
1514
|
+
void on_dec() {
|
1515
|
+
auto num_digits = count_digits(abs_value);
|
1516
|
+
out = write_int(
|
1517
|
+
out, num_digits, get_prefix(), specs, [this, num_digits](iterator it) {
|
1518
|
+
return format_decimal<Char>(it, abs_value, num_digits).end;
|
1519
|
+
});
|
1520
|
+
}
|
1515
1521
|
|
1516
|
-
|
1517
|
-
|
1518
|
-
|
1519
|
-
|
1522
|
+
void on_hex() {
|
1523
|
+
if (specs.alt) {
|
1524
|
+
prefix[prefix_size++] = '0';
|
1525
|
+
prefix[prefix_size++] = specs.type;
|
1520
1526
|
}
|
1521
|
-
|
1522
|
-
|
1523
|
-
|
1524
|
-
|
1525
|
-
|
1526
|
-
|
1527
|
-
|
1528
|
-
|
1529
|
-
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1533
|
-
if (specs.alt) {
|
1534
|
-
prefix[prefix_size++] = '0';
|
1535
|
-
prefix[prefix_size++] = specs.type;
|
1536
|
-
}
|
1537
|
-
int num_digits = count_digits<4>(abs_value);
|
1538
|
-
writer.write_int(num_digits, get_prefix(), specs,
|
1539
|
-
hex_writer{*this, num_digits});
|
1527
|
+
int num_digits = count_digits<4>(abs_value);
|
1528
|
+
out = write_int(out, num_digits, get_prefix(), specs,
|
1529
|
+
[this, num_digits](iterator it) {
|
1530
|
+
return format_uint<4, Char>(it, abs_value, num_digits,
|
1531
|
+
specs.type != 'x');
|
1532
|
+
});
|
1533
|
+
}
|
1534
|
+
|
1535
|
+
void on_bin() {
|
1536
|
+
if (specs.alt) {
|
1537
|
+
prefix[prefix_size++] = '0';
|
1538
|
+
prefix[prefix_size++] = static_cast<char>(specs.type);
|
1540
1539
|
}
|
1541
|
-
|
1542
|
-
|
1543
|
-
|
1544
|
-
|
1545
|
-
|
1546
|
-
|
1547
|
-
|
1548
|
-
|
1549
|
-
|
1550
|
-
|
1551
|
-
|
1552
|
-
|
1553
|
-
|
1554
|
-
prefix[prefix_size++] = static_cast<char>(specs.type);
|
1555
|
-
}
|
1556
|
-
int num_digits = count_digits<1>(abs_value);
|
1557
|
-
writer.write_int(num_digits, get_prefix(), specs,
|
1558
|
-
bin_writer<1>{abs_value, num_digits});
|
1540
|
+
int num_digits = count_digits<1>(abs_value);
|
1541
|
+
out = write_int(out, num_digits, get_prefix(), specs,
|
1542
|
+
[this, num_digits](iterator it) {
|
1543
|
+
return format_uint<1, Char>(it, abs_value, num_digits);
|
1544
|
+
});
|
1545
|
+
}
|
1546
|
+
|
1547
|
+
void on_oct() {
|
1548
|
+
int num_digits = count_digits<3>(abs_value);
|
1549
|
+
if (specs.alt && specs.precision <= num_digits && abs_value != 0) {
|
1550
|
+
// Octal prefix '0' is counted as a digit, so only add it if precision
|
1551
|
+
// is not greater than the number of digits.
|
1552
|
+
prefix[prefix_size++] = '0';
|
1559
1553
|
}
|
1554
|
+
out = write_int(out, num_digits, get_prefix(), specs,
|
1555
|
+
[this, num_digits](iterator it) {
|
1556
|
+
return format_uint<3, Char>(it, abs_value, num_digits);
|
1557
|
+
});
|
1558
|
+
}
|
1560
1559
|
|
1561
|
-
|
1562
|
-
int num_digits = count_digits<3>(abs_value);
|
1563
|
-
if (specs.alt && specs.precision <= num_digits && abs_value != 0) {
|
1564
|
-
// Octal prefix '0' is counted as a digit, so only add it if precision
|
1565
|
-
// is not greater than the number of digits.
|
1566
|
-
prefix[prefix_size++] = '0';
|
1567
|
-
}
|
1568
|
-
writer.write_int(num_digits, get_prefix(), specs,
|
1569
|
-
bin_writer<3>{abs_value, num_digits});
|
1570
|
-
}
|
1560
|
+
enum { sep_size = 1 };
|
1571
1561
|
|
1572
|
-
|
1573
|
-
|
1574
|
-
|
1575
|
-
|
1576
|
-
|
1577
|
-
|
1578
|
-
|
1579
|
-
|
1580
|
-
|
1581
|
-
|
1582
|
-
|
1583
|
-
|
1584
|
-
|
1585
|
-
|
1586
|
-
|
1587
|
-
|
1588
|
-
|
1589
|
-
|
1590
|
-
|
1591
|
-
|
1592
|
-
|
1593
|
-
|
1594
|
-
|
1595
|
-
|
1596
|
-
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
std::string groups = grouping<char_type>(writer.locale_);
|
1605
|
-
if (groups.empty()) return on_dec();
|
1606
|
-
auto sep = thousands_sep<char_type>(writer.locale_);
|
1607
|
-
if (!sep) return on_dec();
|
1608
|
-
int num_digits = count_digits(abs_value);
|
1609
|
-
int size = num_digits;
|
1610
|
-
std::string::const_iterator group = groups.cbegin();
|
1611
|
-
while (group != groups.cend() && num_digits > *group && *group > 0 &&
|
1612
|
-
*group != max_value<char>()) {
|
1613
|
-
size += sep_size;
|
1614
|
-
num_digits -= *group;
|
1562
|
+
void on_num() {
|
1563
|
+
std::string groups = grouping<Char>(locale);
|
1564
|
+
if (groups.empty()) return on_dec();
|
1565
|
+
auto sep = thousands_sep<Char>(locale);
|
1566
|
+
if (!sep) return on_dec();
|
1567
|
+
int num_digits = count_digits(abs_value);
|
1568
|
+
int size = num_digits, n = num_digits;
|
1569
|
+
std::string::const_iterator group = groups.cbegin();
|
1570
|
+
while (group != groups.cend() && n > *group && *group > 0 &&
|
1571
|
+
*group != max_value<char>()) {
|
1572
|
+
size += sep_size;
|
1573
|
+
n -= *group;
|
1574
|
+
++group;
|
1575
|
+
}
|
1576
|
+
if (group == groups.cend()) size += sep_size * ((n - 1) / groups.back());
|
1577
|
+
char digits[40];
|
1578
|
+
format_decimal(digits, abs_value, num_digits);
|
1579
|
+
basic_memory_buffer<Char> buffer;
|
1580
|
+
size += prefix_size;
|
1581
|
+
buffer.resize(size);
|
1582
|
+
basic_string_view<Char> s(&sep, sep_size);
|
1583
|
+
// Index of a decimal digit with the least significant digit having index 0.
|
1584
|
+
int digit_index = 0;
|
1585
|
+
group = groups.cbegin();
|
1586
|
+
auto p = buffer.data() + size;
|
1587
|
+
for (int i = num_digits - 1; i >= 0; --i) {
|
1588
|
+
*--p = static_cast<Char>(digits[i]);
|
1589
|
+
if (*group <= 0 || ++digit_index % *group != 0 ||
|
1590
|
+
*group == max_value<char>())
|
1591
|
+
continue;
|
1592
|
+
if (group + 1 != groups.cend()) {
|
1593
|
+
digit_index = 0;
|
1615
1594
|
++group;
|
1616
1595
|
}
|
1617
|
-
|
1618
|
-
|
1619
|
-
|
1620
|
-
num_writer{abs_value, size, groups, sep});
|
1596
|
+
p -= s.size();
|
1597
|
+
std::uninitialized_copy(s.data(), s.data() + s.size(),
|
1598
|
+
make_checked(p, s.size()));
|
1621
1599
|
}
|
1600
|
+
if (prefix_size != 0) p[-1] = static_cast<Char>('-');
|
1601
|
+
using iterator = remove_reference_t<decltype(reserve(out, 0))>;
|
1602
|
+
auto data = buffer.data();
|
1603
|
+
out = write_padded<align::right>(out, specs, size, size, [=](iterator it) {
|
1604
|
+
return copy_str<Char>(data, data + size, it);
|
1605
|
+
});
|
1606
|
+
}
|
1622
1607
|
|
1623
|
-
|
1624
|
-
FMT_THROW(format_error("invalid type specifier"));
|
1625
|
-
}
|
1626
|
-
};
|
1627
|
-
|
1628
|
-
template <typename Char> struct str_writer {
|
1629
|
-
const Char* s;
|
1630
|
-
size_t size_;
|
1608
|
+
void on_chr() { *out++ = static_cast<Char>(abs_value); }
|
1631
1609
|
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1610
|
+
FMT_NORETURN void on_error() {
|
1611
|
+
FMT_THROW(format_error("invalid type specifier"));
|
1612
|
+
}
|
1613
|
+
};
|
1636
1614
|
|
1637
|
-
|
1638
|
-
|
1639
|
-
|
1615
|
+
template <typename Char, typename OutputIt>
|
1616
|
+
OutputIt write_nonfinite(OutputIt out, bool isinf,
|
1617
|
+
const basic_format_specs<Char>& specs,
|
1618
|
+
const float_specs& fspecs) {
|
1619
|
+
auto str =
|
1620
|
+
isinf ? (fspecs.upper ? "INF" : "inf") : (fspecs.upper ? "NAN" : "nan");
|
1621
|
+
constexpr size_t str_size = 3;
|
1622
|
+
auto sign = fspecs.sign;
|
1623
|
+
auto size = str_size + (sign ? 1 : 0);
|
1624
|
+
using iterator = remove_reference_t<decltype(reserve(out, 0))>;
|
1625
|
+
return write_padded(out, specs, size, [=](iterator it) {
|
1626
|
+
if (sign) *it++ = static_cast<Char>(data::signs[sign]);
|
1627
|
+
return copy_str<Char>(str, str + str_size, it);
|
1628
|
+
});
|
1629
|
+
}
|
1630
|
+
|
1631
|
+
template <typename Char, typename OutputIt, typename T,
|
1632
|
+
FMT_ENABLE_IF(std::is_floating_point<T>::value)>
|
1633
|
+
OutputIt write(OutputIt out, T value, basic_format_specs<Char> specs,
|
1634
|
+
locale_ref loc = {}) {
|
1635
|
+
if (const_check(!is_supported_floating_point(value))) return out;
|
1636
|
+
float_specs fspecs = parse_float_type_spec(specs);
|
1637
|
+
fspecs.sign = specs.sign;
|
1638
|
+
if (std::signbit(value)) { // value < 0 is false for NaN so use signbit.
|
1639
|
+
fspecs.sign = sign::minus;
|
1640
|
+
value = -value;
|
1641
|
+
} else if (fspecs.sign == sign::minus) {
|
1642
|
+
fspecs.sign = sign::none;
|
1643
|
+
}
|
1644
|
+
|
1645
|
+
if (!std::isfinite(value))
|
1646
|
+
return write_nonfinite(out, std::isinf(value), specs, fspecs);
|
1647
|
+
|
1648
|
+
if (specs.align == align::numeric && fspecs.sign) {
|
1649
|
+
auto it = reserve(out, 1);
|
1650
|
+
*it++ = static_cast<Char>(data::signs[fspecs.sign]);
|
1651
|
+
out = base_iterator(out, it);
|
1652
|
+
fspecs.sign = sign::none;
|
1653
|
+
if (specs.width != 0) --specs.width;
|
1654
|
+
}
|
1655
|
+
|
1656
|
+
memory_buffer buffer;
|
1657
|
+
if (fspecs.format == float_format::hex) {
|
1658
|
+
if (fspecs.sign) buffer.push_back(data::signs[fspecs.sign]);
|
1659
|
+
snprintf_float(promote_float(value), specs.precision, fspecs, buffer);
|
1660
|
+
return write_bytes(out, {buffer.data(), buffer.size()}, specs);
|
1661
|
+
}
|
1662
|
+
int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6;
|
1663
|
+
if (fspecs.format == float_format::exp) {
|
1664
|
+
if (precision == max_value<int>())
|
1665
|
+
FMT_THROW(format_error("number is too big"));
|
1666
|
+
else
|
1667
|
+
++precision;
|
1668
|
+
}
|
1669
|
+
if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
|
1670
|
+
fspecs.use_grisu = use_grisu<T>();
|
1671
|
+
int exp = format_float(promote_float(value), precision, fspecs, buffer);
|
1672
|
+
fspecs.precision = precision;
|
1673
|
+
Char point =
|
1674
|
+
fspecs.locale ? decimal_point<Char>(loc) : static_cast<Char>('.');
|
1675
|
+
float_writer<Char> w(buffer.data(), static_cast<int>(buffer.size()), exp,
|
1676
|
+
fspecs, point);
|
1677
|
+
return write_padded<align::right>(out, specs, w.size(), w);
|
1678
|
+
}
|
1679
|
+
|
1680
|
+
template <typename Char, typename OutputIt, typename T,
|
1681
|
+
FMT_ENABLE_IF(std::is_floating_point<T>::value)>
|
1682
|
+
OutputIt write(OutputIt out, T value) {
|
1683
|
+
if (const_check(!is_supported_floating_point(value))) return out;
|
1684
|
+
auto fspecs = float_specs();
|
1685
|
+
if (std::signbit(value)) { // value < 0 is false for NaN so use signbit.
|
1686
|
+
fspecs.sign = sign::minus;
|
1687
|
+
value = -value;
|
1688
|
+
}
|
1689
|
+
|
1690
|
+
auto specs = basic_format_specs<Char>();
|
1691
|
+
if (!std::isfinite(value))
|
1692
|
+
return write_nonfinite(out, std::isinf(value), specs, fspecs);
|
1693
|
+
|
1694
|
+
memory_buffer buffer;
|
1695
|
+
int precision = -1;
|
1696
|
+
if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
|
1697
|
+
fspecs.use_grisu = use_grisu<T>();
|
1698
|
+
int exp = format_float(promote_float(value), precision, fspecs, buffer);
|
1699
|
+
fspecs.precision = precision;
|
1700
|
+
float_writer<Char> w(buffer.data(), static_cast<int>(buffer.size()), exp,
|
1701
|
+
fspecs, static_cast<Char>('.'));
|
1702
|
+
return base_iterator(out, w(reserve(out, w.size())));
|
1703
|
+
}
|
1704
|
+
|
1705
|
+
template <typename Char, typename OutputIt>
|
1706
|
+
OutputIt write_char(OutputIt out, Char value,
|
1707
|
+
const basic_format_specs<Char>& specs) {
|
1708
|
+
using iterator = remove_reference_t<decltype(reserve(out, 0))>;
|
1709
|
+
return write_padded(out, specs, 1, [=](iterator it) {
|
1710
|
+
*it++ = value;
|
1711
|
+
return it;
|
1712
|
+
});
|
1713
|
+
}
|
1714
|
+
|
1715
|
+
template <typename Char, typename OutputIt, typename UIntPtr>
|
1716
|
+
OutputIt write_ptr(OutputIt out, UIntPtr value,
|
1717
|
+
const basic_format_specs<Char>* specs) {
|
1718
|
+
int num_digits = count_digits<4>(value);
|
1719
|
+
auto size = to_unsigned(num_digits) + size_t(2);
|
1720
|
+
using iterator = remove_reference_t<decltype(reserve(out, 0))>;
|
1721
|
+
auto write = [=](iterator it) {
|
1722
|
+
*it++ = static_cast<Char>('0');
|
1723
|
+
*it++ = static_cast<Char>('x');
|
1724
|
+
return format_uint<4, Char>(it, value, num_digits);
|
1640
1725
|
};
|
1726
|
+
return specs ? write_padded<align::right>(out, *specs, size, write)
|
1727
|
+
: base_iterator(out, write(reserve(out, size)));
|
1728
|
+
}
|
1641
1729
|
|
1642
|
-
|
1643
|
-
|
1730
|
+
template <typename T> struct is_integral : std::is_integral<T> {};
|
1731
|
+
template <> struct is_integral<int128_t> : std::true_type {};
|
1732
|
+
template <> struct is_integral<uint128_t> : std::true_type {};
|
1644
1733
|
|
1645
|
-
|
1646
|
-
|
1734
|
+
template <typename Char, typename OutputIt>
|
1735
|
+
OutputIt write(OutputIt out, monostate) {
|
1736
|
+
FMT_ASSERT(false, "");
|
1737
|
+
return out;
|
1738
|
+
}
|
1647
1739
|
|
1648
|
-
|
1649
|
-
|
1650
|
-
|
1651
|
-
|
1652
|
-
|
1740
|
+
template <typename Char, typename OutputIt,
|
1741
|
+
FMT_ENABLE_IF(!std::is_same<Char, char>::value)>
|
1742
|
+
OutputIt write(OutputIt out, string_view value) {
|
1743
|
+
auto it = reserve(out, value.size());
|
1744
|
+
it = copy_str<Char>(value.begin(), value.end(), it);
|
1745
|
+
return base_iterator(out, it);
|
1746
|
+
}
|
1653
1747
|
|
1654
|
-
|
1655
|
-
|
1656
|
-
|
1748
|
+
template <typename Char, typename OutputIt>
|
1749
|
+
OutputIt write(OutputIt out, basic_string_view<Char> value) {
|
1750
|
+
auto it = reserve(out, value.size());
|
1751
|
+
it = std::copy(value.begin(), value.end(), it);
|
1752
|
+
return base_iterator(out, it);
|
1753
|
+
}
|
1657
1754
|
|
1658
|
-
|
1659
|
-
|
1755
|
+
template <typename Char, typename OutputIt, typename T,
|
1756
|
+
FMT_ENABLE_IF(is_integral<T>::value &&
|
1757
|
+
!std::is_same<T, bool>::value &&
|
1758
|
+
!std::is_same<T, Char>::value)>
|
1759
|
+
OutputIt write(OutputIt out, T value) {
|
1760
|
+
auto abs_value = static_cast<uint32_or_64_or_128_t<T>>(value);
|
1761
|
+
bool negative = is_negative(value);
|
1762
|
+
// Don't do -abs_value since it trips unsigned-integer-overflow sanitizer.
|
1763
|
+
if (negative) abs_value = ~abs_value + 1;
|
1764
|
+
int num_digits = count_digits(abs_value);
|
1765
|
+
auto it = reserve(out, (negative ? 1 : 0) + static_cast<size_t>(num_digits));
|
1766
|
+
if (negative) *it++ = static_cast<Char>('-');
|
1767
|
+
it = format_decimal<Char>(it, abs_value, num_digits).end;
|
1768
|
+
return base_iterator(out, it);
|
1769
|
+
}
|
1660
1770
|
|
1661
|
-
|
1662
|
-
|
1663
|
-
|
1664
|
-
|
1665
|
-
}
|
1666
|
-
};
|
1771
|
+
template <typename Char, typename OutputIt>
|
1772
|
+
OutputIt write(OutputIt out, bool value) {
|
1773
|
+
return write<Char>(out, string_view(value ? "true" : "false"));
|
1774
|
+
}
|
1667
1775
|
|
1668
|
-
|
1669
|
-
|
1670
|
-
|
1671
|
-
|
1672
|
-
|
1673
|
-
|
1674
|
-
|
1675
|
-
|
1676
|
-
|
1677
|
-
|
1678
|
-
|
1679
|
-
|
1680
|
-
|
1681
|
-
|
1682
|
-
if (width <= num_code_points) return f(reserve(size));
|
1683
|
-
size_t padding = width - num_code_points;
|
1684
|
-
size_t fill_size = specs.fill.size();
|
1685
|
-
auto&& it = reserve(size + padding * fill_size);
|
1686
|
-
if (specs.align == align::right) {
|
1687
|
-
it = fill(it, padding, specs.fill);
|
1688
|
-
f(it);
|
1689
|
-
} else if (specs.align == align::center) {
|
1690
|
-
std::size_t left_padding = padding / 2;
|
1691
|
-
it = fill(it, left_padding, specs.fill);
|
1692
|
-
f(it);
|
1693
|
-
it = fill(it, padding - left_padding, specs.fill);
|
1694
|
-
} else {
|
1695
|
-
f(it);
|
1696
|
-
it = fill(it, padding, specs.fill);
|
1697
|
-
}
|
1776
|
+
template <typename Char, typename OutputIt>
|
1777
|
+
OutputIt write(OutputIt out, Char value) {
|
1778
|
+
auto it = reserve(out, 1);
|
1779
|
+
*it++ = value;
|
1780
|
+
return base_iterator(out, it);
|
1781
|
+
}
|
1782
|
+
|
1783
|
+
template <typename Char, typename OutputIt>
|
1784
|
+
OutputIt write(OutputIt out, const Char* value) {
|
1785
|
+
if (!value) {
|
1786
|
+
FMT_THROW(format_error("string pointer is null"));
|
1787
|
+
} else {
|
1788
|
+
auto length = std::char_traits<Char>::length(value);
|
1789
|
+
out = write(out, basic_string_view<Char>(value, length));
|
1698
1790
|
}
|
1791
|
+
return out;
|
1792
|
+
}
|
1699
1793
|
|
1700
|
-
|
1701
|
-
|
1702
|
-
|
1794
|
+
template <typename Char, typename OutputIt>
|
1795
|
+
OutputIt write(OutputIt out, const void* value) {
|
1796
|
+
return write_ptr<Char>(out, to_uintptr(value), nullptr);
|
1797
|
+
}
|
1703
1798
|
|
1704
|
-
|
1705
|
-
|
1706
|
-
|
1799
|
+
template <typename Char, typename OutputIt, typename T>
|
1800
|
+
auto write(OutputIt out, const T& value) -> typename std::enable_if<
|
1801
|
+
mapped_type_constant<T, basic_format_context<OutputIt, Char>>::value ==
|
1802
|
+
type::custom_type,
|
1803
|
+
OutputIt>::type {
|
1804
|
+
basic_format_context<OutputIt, Char> ctx(out, {}, {});
|
1805
|
+
return formatter<T>().format(value, ctx);
|
1806
|
+
}
|
1707
1807
|
|
1708
|
-
|
1709
|
-
|
1710
|
-
|
1711
|
-
|
1808
|
+
// An argument visitor that formats the argument and writes it via the output
|
1809
|
+
// iterator. It's a class and not a generic lambda for compatibility with C++11.
|
1810
|
+
template <typename OutputIt, typename Char> struct default_arg_formatter {
|
1811
|
+
using context = basic_format_context<OutputIt, Char>;
|
1712
1812
|
|
1713
|
-
|
1714
|
-
|
1715
|
-
|
1813
|
+
OutputIt out;
|
1814
|
+
basic_format_args<context> args;
|
1815
|
+
locale_ref loc;
|
1816
|
+
|
1817
|
+
template <typename T> OutputIt operator()(T value) {
|
1818
|
+
return write<Char>(out, value);
|
1716
1819
|
}
|
1717
1820
|
|
1718
|
-
|
1719
|
-
|
1720
|
-
|
1721
|
-
|
1722
|
-
|
1723
|
-
|
1724
|
-
|
1725
|
-
if (std::signbit(value)) { // value < 0 is false for NaN so use signbit.
|
1726
|
-
fspecs.sign = sign::minus;
|
1727
|
-
value = -value;
|
1728
|
-
} else if (fspecs.sign == sign::minus) {
|
1729
|
-
fspecs.sign = sign::none;
|
1730
|
-
}
|
1821
|
+
OutputIt operator()(typename basic_format_arg<context>::handle handle) {
|
1822
|
+
basic_format_parse_context<Char> parse_ctx({});
|
1823
|
+
basic_format_context<OutputIt, Char> format_ctx(out, args, loc);
|
1824
|
+
handle.format(parse_ctx, format_ctx);
|
1825
|
+
return format_ctx.out();
|
1826
|
+
}
|
1827
|
+
};
|
1731
1828
|
|
1732
|
-
|
1733
|
-
|
1734
|
-
|
1735
|
-
|
1736
|
-
|
1829
|
+
template <typename OutputIt, typename Char,
|
1830
|
+
typename ErrorHandler = error_handler>
|
1831
|
+
class arg_formatter_base {
|
1832
|
+
public:
|
1833
|
+
using iterator = OutputIt;
|
1834
|
+
using char_type = Char;
|
1835
|
+
using format_specs = basic_format_specs<Char>;
|
1737
1836
|
|
1738
|
-
|
1739
|
-
|
1740
|
-
|
1741
|
-
|
1742
|
-
auto&& it = reserve(1);
|
1743
|
-
*it++ = static_cast<char_type>(data::signs[fspecs.sign]);
|
1744
|
-
fspecs.sign = sign::none;
|
1745
|
-
if (specs.width != 0) --specs.width;
|
1746
|
-
}
|
1747
|
-
specs.align = align::right;
|
1748
|
-
}
|
1837
|
+
private:
|
1838
|
+
iterator out_;
|
1839
|
+
locale_ref locale_;
|
1840
|
+
format_specs* specs_;
|
1749
1841
|
|
1750
|
-
|
1751
|
-
|
1752
|
-
|
1753
|
-
|
1754
|
-
|
1755
|
-
|
1756
|
-
|
1757
|
-
|
1758
|
-
|
1759
|
-
|
1760
|
-
|
1761
|
-
|
1762
|
-
|
1763
|
-
|
1764
|
-
if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
|
1765
|
-
fspecs.use_grisu = use_grisu<T>();
|
1766
|
-
if (const_check(FMT_DEPRECATED_PERCENT) && fspecs.percent) value *= 100;
|
1767
|
-
int exp = format_float(promote_float(value), precision, fspecs, buffer);
|
1768
|
-
if (const_check(FMT_DEPRECATED_PERCENT) && fspecs.percent) {
|
1769
|
-
buffer.push_back('%');
|
1770
|
-
--exp; // Adjust decimal place position.
|
1771
|
-
}
|
1772
|
-
fspecs.precision = precision;
|
1773
|
-
char_type point = fspecs.locale ? decimal_point<char_type>(locale_)
|
1774
|
-
: static_cast<char_type>('.');
|
1775
|
-
write_padded(specs, float_writer<char_type>(buffer.data(),
|
1776
|
-
static_cast<int>(buffer.size()),
|
1777
|
-
exp, fspecs, point));
|
1842
|
+
// Attempts to reserve space for n extra characters in the output range.
|
1843
|
+
// Returns a pointer to the reserved range or a reference to out_.
|
1844
|
+
auto reserve(size_t n) -> decltype(detail::reserve(out_, n)) {
|
1845
|
+
return detail::reserve(out_, n);
|
1846
|
+
}
|
1847
|
+
|
1848
|
+
using reserve_iterator = remove_reference_t<decltype(
|
1849
|
+
detail::reserve(std::declval<iterator&>(), 0))>;
|
1850
|
+
|
1851
|
+
template <typename T> void write_int(T value, const format_specs& spec) {
|
1852
|
+
using uint_type = uint32_or_64_or_128_t<T>;
|
1853
|
+
int_writer<iterator, Char, uint_type> w(out_, locale_, value, spec);
|
1854
|
+
handle_int_type_spec(spec.type, w);
|
1855
|
+
out_ = w.out;
|
1778
1856
|
}
|
1779
1857
|
|
1780
1858
|
void write(char value) {
|
@@ -1782,198 +1860,151 @@ template <typename Range> class basic_writer {
|
|
1782
1860
|
*it++ = value;
|
1783
1861
|
}
|
1784
1862
|
|
1785
|
-
template <typename
|
1786
|
-
void write(
|
1787
|
-
|
1788
|
-
*it++ = value;
|
1863
|
+
template <typename Ch, FMT_ENABLE_IF(std::is_same<Ch, Char>::value)>
|
1864
|
+
void write(Ch value) {
|
1865
|
+
out_ = detail::write<Char>(out_, value);
|
1789
1866
|
}
|
1790
1867
|
|
1791
1868
|
void write(string_view value) {
|
1792
1869
|
auto&& it = reserve(value.size());
|
1793
|
-
it = copy_str<
|
1870
|
+
it = copy_str<Char>(value.begin(), value.end(), it);
|
1794
1871
|
}
|
1795
1872
|
void write(wstring_view value) {
|
1796
|
-
static_assert(std::is_same<
|
1873
|
+
static_assert(std::is_same<Char, wchar_t>::value, "");
|
1797
1874
|
auto&& it = reserve(value.size());
|
1798
1875
|
it = std::copy(value.begin(), value.end(), it);
|
1799
1876
|
}
|
1800
1877
|
|
1801
|
-
template <typename
|
1802
|
-
void write(const
|
1803
|
-
|
1804
|
-
|
1805
|
-
|
1806
|
-
|
1807
|
-
|
1808
|
-
|
1809
|
-
std::size_t size = s.size();
|
1810
|
-
if (specs.precision >= 0 && to_unsigned(specs.precision) < size)
|
1811
|
-
size = code_point_index(s, to_unsigned(specs.precision));
|
1812
|
-
write(data, size, specs);
|
1878
|
+
template <typename Ch>
|
1879
|
+
void write(const Ch* s, size_t size, const format_specs& specs) {
|
1880
|
+
auto width = specs.width != 0
|
1881
|
+
? count_code_points(basic_string_view<Ch>(s, size))
|
1882
|
+
: 0;
|
1883
|
+
out_ = write_padded(out_, specs, size, width, [=](reserve_iterator it) {
|
1884
|
+
return copy_str<Char>(s, s + size, it);
|
1885
|
+
});
|
1813
1886
|
}
|
1814
1887
|
|
1815
|
-
|
1816
|
-
|
1888
|
+
template <typename Ch>
|
1889
|
+
void write(basic_string_view<Ch> s, const format_specs& specs = {}) {
|
1890
|
+
out_ = detail::write(out_, s, specs);
|
1817
1891
|
}
|
1818
1892
|
|
1819
|
-
|
1820
|
-
|
1821
|
-
int num_digits = count_digits<4>(value);
|
1822
|
-
auto pw = pointer_writer<UIntPtr>{value, num_digits};
|
1823
|
-
if (!specs) return pw(reserve(to_unsigned(num_digits) + 2));
|
1824
|
-
format_specs specs_copy = *specs;
|
1825
|
-
if (specs_copy.align == align::none) specs_copy.align = align::right;
|
1826
|
-
write_padded(specs_copy, pw);
|
1893
|
+
void write_pointer(const void* p) {
|
1894
|
+
out_ = write_ptr<char_type>(out_, to_uintptr(p), specs_);
|
1827
1895
|
}
|
1828
|
-
};
|
1829
1896
|
|
1830
|
-
|
1831
|
-
|
1832
|
-
|
1833
|
-
template <> struct is_integral<int128_t> : std::true_type {};
|
1834
|
-
template <> struct is_integral<uint128_t> : std::true_type {};
|
1897
|
+
struct char_spec_handler : ErrorHandler {
|
1898
|
+
arg_formatter_base& formatter;
|
1899
|
+
Char value;
|
1835
1900
|
|
1836
|
-
|
1837
|
-
|
1838
|
-
public:
|
1839
|
-
using char_type = typename Range::value_type;
|
1840
|
-
using iterator = typename Range::iterator;
|
1841
|
-
using format_specs = basic_format_specs<char_type>;
|
1901
|
+
char_spec_handler(arg_formatter_base& f, Char val)
|
1902
|
+
: formatter(f), value(val) {}
|
1842
1903
|
|
1843
|
-
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1904
|
+
void on_int() {
|
1905
|
+
// char is only formatted as int if there are specs.
|
1906
|
+
formatter.write_int(static_cast<int>(value), *formatter.specs_);
|
1907
|
+
}
|
1908
|
+
void on_char() {
|
1909
|
+
if (formatter.specs_)
|
1910
|
+
formatter.out_ = write_char(formatter.out_, value, *formatter.specs_);
|
1911
|
+
else
|
1912
|
+
formatter.write(value);
|
1913
|
+
}
|
1914
|
+
};
|
1847
1915
|
|
1848
|
-
struct
|
1849
|
-
|
1916
|
+
struct cstring_spec_handler : error_handler {
|
1917
|
+
arg_formatter_base& formatter;
|
1918
|
+
const Char* value;
|
1850
1919
|
|
1851
|
-
|
1852
|
-
|
1920
|
+
cstring_spec_handler(arg_formatter_base& f, const Char* val)
|
1921
|
+
: formatter(f), value(val) {}
|
1853
1922
|
|
1854
|
-
|
1923
|
+
void on_string() { formatter.write(value); }
|
1924
|
+
void on_pointer() { formatter.write_pointer(value); }
|
1855
1925
|
};
|
1856
1926
|
|
1857
|
-
void write_char(char_type value) {
|
1858
|
-
if (specs_)
|
1859
|
-
writer_.write_padded(*specs_, char_writer{value});
|
1860
|
-
else
|
1861
|
-
writer_.write(value);
|
1862
|
-
}
|
1863
|
-
|
1864
|
-
void write_pointer(const void* p) {
|
1865
|
-
writer_.write_pointer(internal::to_uintptr(p), specs_);
|
1866
|
-
}
|
1867
|
-
|
1868
1927
|
protected:
|
1869
|
-
|
1870
|
-
FMT_DEPRECATED format_specs* spec() { return specs_; }
|
1928
|
+
iterator out() { return out_; }
|
1871
1929
|
format_specs* specs() { return specs_; }
|
1872
|
-
iterator out() { return writer_.out(); }
|
1873
1930
|
|
1874
1931
|
void write(bool value) {
|
1875
|
-
|
1876
|
-
|
1932
|
+
if (specs_)
|
1933
|
+
write(string_view(value ? "true" : "false"), *specs_);
|
1934
|
+
else
|
1935
|
+
out_ = detail::write<Char>(out_, value);
|
1877
1936
|
}
|
1878
1937
|
|
1879
|
-
void write(const
|
1938
|
+
void write(const Char* value) {
|
1880
1939
|
if (!value) {
|
1881
1940
|
FMT_THROW(format_error("string pointer is null"));
|
1882
1941
|
} else {
|
1883
1942
|
auto length = std::char_traits<char_type>::length(value);
|
1884
1943
|
basic_string_view<char_type> sv(value, length);
|
1885
|
-
specs_ ?
|
1944
|
+
specs_ ? write(sv, *specs_) : write(sv);
|
1886
1945
|
}
|
1887
1946
|
}
|
1888
1947
|
|
1889
1948
|
public:
|
1890
|
-
arg_formatter_base(
|
1891
|
-
:
|
1949
|
+
arg_formatter_base(OutputIt out, format_specs* s, locale_ref loc)
|
1950
|
+
: out_(out), locale_(loc), specs_(s) {}
|
1892
1951
|
|
1893
1952
|
iterator operator()(monostate) {
|
1894
1953
|
FMT_ASSERT(false, "invalid argument type");
|
1895
|
-
return
|
1954
|
+
return out_;
|
1896
1955
|
}
|
1897
1956
|
|
1898
1957
|
template <typename T, FMT_ENABLE_IF(is_integral<T>::value)>
|
1899
|
-
iterator operator()(T value) {
|
1958
|
+
FMT_INLINE iterator operator()(T value) {
|
1900
1959
|
if (specs_)
|
1901
|
-
|
1960
|
+
write_int(value, *specs_);
|
1902
1961
|
else
|
1903
|
-
|
1904
|
-
return
|
1962
|
+
out_ = detail::write<Char>(out_, value);
|
1963
|
+
return out_;
|
1905
1964
|
}
|
1906
1965
|
|
1907
|
-
iterator operator()(
|
1908
|
-
|
1909
|
-
|
1910
|
-
return
|
1966
|
+
iterator operator()(Char value) {
|
1967
|
+
handle_char_specs(specs_,
|
1968
|
+
char_spec_handler(*this, static_cast<Char>(value)));
|
1969
|
+
return out_;
|
1911
1970
|
}
|
1912
1971
|
|
1913
1972
|
iterator operator()(bool value) {
|
1914
1973
|
if (specs_ && specs_->type) return (*this)(value ? 1 : 0);
|
1915
1974
|
write(value != 0);
|
1916
|
-
return
|
1975
|
+
return out_;
|
1917
1976
|
}
|
1918
1977
|
|
1919
1978
|
template <typename T, FMT_ENABLE_IF(std::is_floating_point<T>::value)>
|
1920
1979
|
iterator operator()(T value) {
|
1980
|
+
auto specs = specs_ ? *specs_ : format_specs();
|
1921
1981
|
if (const_check(is_supported_floating_point(value)))
|
1922
|
-
|
1982
|
+
out_ = detail::write(out_, value, specs, locale_);
|
1923
1983
|
else
|
1924
1984
|
FMT_ASSERT(false, "unsupported float argument type");
|
1925
|
-
return
|
1985
|
+
return out_;
|
1926
1986
|
}
|
1927
1987
|
|
1928
|
-
|
1929
|
-
|
1930
|
-
|
1931
|
-
|
1932
|
-
char_spec_handler(arg_formatter_base& f, char_type val)
|
1933
|
-
: formatter(f), value(val) {}
|
1934
|
-
|
1935
|
-
void on_int() {
|
1936
|
-
if (formatter.specs_)
|
1937
|
-
formatter.writer_.write_int(value, *formatter.specs_);
|
1938
|
-
else
|
1939
|
-
formatter.writer_.write(value);
|
1940
|
-
}
|
1941
|
-
void on_char() { formatter.write_char(value); }
|
1942
|
-
};
|
1943
|
-
|
1944
|
-
struct cstring_spec_handler : internal::error_handler {
|
1945
|
-
arg_formatter_base& formatter;
|
1946
|
-
const char_type* value;
|
1947
|
-
|
1948
|
-
cstring_spec_handler(arg_formatter_base& f, const char_type* val)
|
1949
|
-
: formatter(f), value(val) {}
|
1950
|
-
|
1951
|
-
void on_string() { formatter.write(value); }
|
1952
|
-
void on_pointer() { formatter.write_pointer(value); }
|
1953
|
-
};
|
1954
|
-
|
1955
|
-
iterator operator()(const char_type* value) {
|
1956
|
-
if (!specs_) return write(value), out();
|
1957
|
-
internal::handle_cstring_type_spec(specs_->type,
|
1958
|
-
cstring_spec_handler(*this, value));
|
1959
|
-
return out();
|
1988
|
+
iterator operator()(const Char* value) {
|
1989
|
+
if (!specs_) return write(value), out_;
|
1990
|
+
handle_cstring_type_spec(specs_->type, cstring_spec_handler(*this, value));
|
1991
|
+
return out_;
|
1960
1992
|
}
|
1961
1993
|
|
1962
|
-
iterator operator()(basic_string_view<
|
1994
|
+
iterator operator()(basic_string_view<Char> value) {
|
1963
1995
|
if (specs_) {
|
1964
|
-
|
1965
|
-
|
1996
|
+
check_string_type_spec(specs_->type, error_handler());
|
1997
|
+
write(value, *specs_);
|
1966
1998
|
} else {
|
1967
|
-
|
1999
|
+
write(value);
|
1968
2000
|
}
|
1969
|
-
return
|
2001
|
+
return out_;
|
1970
2002
|
}
|
1971
2003
|
|
1972
2004
|
iterator operator()(const void* value) {
|
1973
|
-
if (specs_)
|
1974
|
-
check_pointer_type_spec(specs_->type, internal::error_handler());
|
2005
|
+
if (specs_) check_pointer_type_spec(specs_->type, error_handler());
|
1975
2006
|
write_pointer(value);
|
1976
|
-
return
|
2007
|
+
return out_;
|
1977
2008
|
}
|
1978
2009
|
};
|
1979
2010
|
|
@@ -2109,7 +2140,7 @@ template <typename Char> class specs_setter {
|
|
2109
2140
|
|
2110
2141
|
template <typename ErrorHandler> class numeric_specs_checker {
|
2111
2142
|
public:
|
2112
|
-
FMT_CONSTEXPR numeric_specs_checker(ErrorHandler& eh,
|
2143
|
+
FMT_CONSTEXPR numeric_specs_checker(ErrorHandler& eh, detail::type arg_type)
|
2113
2144
|
: error_handler_(eh), arg_type_(arg_type) {}
|
2114
2145
|
|
2115
2146
|
FMT_CONSTEXPR void require_numeric_argument() {
|
@@ -2132,18 +2163,24 @@ template <typename ErrorHandler> class numeric_specs_checker {
|
|
2132
2163
|
|
2133
2164
|
private:
|
2134
2165
|
ErrorHandler& error_handler_;
|
2135
|
-
|
2166
|
+
detail::type arg_type_;
|
2136
2167
|
};
|
2137
2168
|
|
2138
2169
|
// A format specifier handler that checks if specifiers are consistent with the
|
2139
2170
|
// argument type.
|
2140
2171
|
template <typename Handler> class specs_checker : public Handler {
|
2172
|
+
private:
|
2173
|
+
numeric_specs_checker<Handler> checker_;
|
2174
|
+
|
2175
|
+
// Suppress an MSVC warning about using this in initializer list.
|
2176
|
+
FMT_CONSTEXPR Handler& error_handler() { return *this; }
|
2177
|
+
|
2141
2178
|
public:
|
2142
|
-
FMT_CONSTEXPR specs_checker(const Handler& handler,
|
2143
|
-
: Handler(handler), checker_(
|
2179
|
+
FMT_CONSTEXPR specs_checker(const Handler& handler, detail::type arg_type)
|
2180
|
+
: Handler(handler), checker_(error_handler(), arg_type) {}
|
2144
2181
|
|
2145
2182
|
FMT_CONSTEXPR specs_checker(const specs_checker& other)
|
2146
|
-
: Handler(other), checker_(
|
2183
|
+
: Handler(other), checker_(error_handler(), other.arg_type_) {}
|
2147
2184
|
|
2148
2185
|
FMT_CONSTEXPR void on_align(align_t align) {
|
2149
2186
|
if (align == align::numeric) checker_.require_numeric_argument();
|
@@ -2176,9 +2213,6 @@ template <typename Handler> class specs_checker : public Handler {
|
|
2176
2213
|
}
|
2177
2214
|
|
2178
2215
|
FMT_CONSTEXPR void end_precision() { checker_.check_precision(); }
|
2179
|
-
|
2180
|
-
private:
|
2181
|
-
numeric_specs_checker<Handler> checker_;
|
2182
2216
|
};
|
2183
2217
|
|
2184
2218
|
template <template <typename> class Handler, typename FormatArg,
|
@@ -2191,10 +2225,10 @@ FMT_CONSTEXPR int get_dynamic_spec(FormatArg arg, ErrorHandler eh) {
|
|
2191
2225
|
|
2192
2226
|
struct auto_id {};
|
2193
2227
|
|
2194
|
-
template <typename Context>
|
2195
|
-
FMT_CONSTEXPR typename Context::format_arg get_arg(Context& ctx,
|
2228
|
+
template <typename Context, typename ID>
|
2229
|
+
FMT_CONSTEXPR typename Context::format_arg get_arg(Context& ctx, ID id) {
|
2196
2230
|
auto arg = ctx.arg(id);
|
2197
|
-
if (!arg) ctx.on_error("argument
|
2231
|
+
if (!arg) ctx.on_error("argument not found");
|
2198
2232
|
return arg;
|
2199
2233
|
}
|
2200
2234
|
|
@@ -2227,17 +2261,17 @@ class specs_handler : public specs_setter<typename Context::char_type> {
|
|
2227
2261
|
using format_arg = typename Context::format_arg;
|
2228
2262
|
|
2229
2263
|
FMT_CONSTEXPR format_arg get_arg(auto_id) {
|
2230
|
-
return
|
2264
|
+
return detail::get_arg(context_, parse_context_.next_arg_id());
|
2231
2265
|
}
|
2232
2266
|
|
2233
2267
|
FMT_CONSTEXPR format_arg get_arg(int arg_id) {
|
2234
2268
|
parse_context_.check_arg_id(arg_id);
|
2235
|
-
return
|
2269
|
+
return detail::get_arg(context_, arg_id);
|
2236
2270
|
}
|
2237
2271
|
|
2238
2272
|
FMT_CONSTEXPR format_arg get_arg(basic_string_view<char_type> arg_id) {
|
2239
2273
|
parse_context_.check_arg_id(arg_id);
|
2240
|
-
return context_
|
2274
|
+
return detail::get_arg(context_, arg_id);
|
2241
2275
|
}
|
2242
2276
|
|
2243
2277
|
ParseContext& parse_context_;
|
@@ -2424,7 +2458,7 @@ FMT_CONSTEXPR const Char* parse_align(const Char* begin, const Char* end,
|
|
2424
2458
|
case '>':
|
2425
2459
|
align = align::right;
|
2426
2460
|
break;
|
2427
|
-
#if
|
2461
|
+
#if FMT_DEPRECATED_NUMERIC_ALIGN
|
2428
2462
|
case '=':
|
2429
2463
|
align = align::numeric;
|
2430
2464
|
break;
|
@@ -2555,26 +2589,75 @@ template <>
|
|
2555
2589
|
inline bool find<false, char>(const char* first, const char* last, char value,
|
2556
2590
|
const char*& out) {
|
2557
2591
|
out = static_cast<const char*>(
|
2558
|
-
std::memchr(first, value,
|
2592
|
+
std::memchr(first, value, detail::to_unsigned(last - first)));
|
2559
2593
|
return out != nullptr;
|
2560
2594
|
}
|
2561
2595
|
|
2562
2596
|
template <typename Handler, typename Char> struct id_adapter {
|
2563
|
-
|
2564
|
-
|
2597
|
+
Handler& handler;
|
2598
|
+
int arg_id;
|
2599
|
+
|
2600
|
+
FMT_CONSTEXPR void operator()() { arg_id = handler.on_arg_id(); }
|
2601
|
+
FMT_CONSTEXPR void operator()(int id) { arg_id = handler.on_arg_id(id); }
|
2565
2602
|
FMT_CONSTEXPR void operator()(basic_string_view<Char> id) {
|
2566
|
-
handler.on_arg_id(id);
|
2603
|
+
arg_id = handler.on_arg_id(id);
|
2567
2604
|
}
|
2568
2605
|
FMT_CONSTEXPR void on_error(const char* message) {
|
2569
2606
|
handler.on_error(message);
|
2570
2607
|
}
|
2571
|
-
Handler& handler;
|
2572
2608
|
};
|
2573
2609
|
|
2610
|
+
template <typename Char, typename Handler>
|
2611
|
+
FMT_CONSTEXPR const Char* parse_replacement_field(const Char* begin,
|
2612
|
+
const Char* end,
|
2613
|
+
Handler&& handler) {
|
2614
|
+
++begin;
|
2615
|
+
if (begin == end) return handler.on_error("invalid format string"), end;
|
2616
|
+
if (static_cast<char>(*begin) == '}') {
|
2617
|
+
handler.on_replacement_field(handler.on_arg_id(), begin);
|
2618
|
+
} else if (*begin == '{') {
|
2619
|
+
handler.on_text(begin, begin + 1);
|
2620
|
+
} else {
|
2621
|
+
auto adapter = id_adapter<Handler, Char>{handler, 0};
|
2622
|
+
begin = parse_arg_id(begin, end, adapter);
|
2623
|
+
Char c = begin != end ? *begin : Char();
|
2624
|
+
if (c == '}') {
|
2625
|
+
handler.on_replacement_field(adapter.arg_id, begin);
|
2626
|
+
} else if (c == ':') {
|
2627
|
+
begin = handler.on_format_specs(adapter.arg_id, begin + 1, end);
|
2628
|
+
if (begin == end || *begin != '}')
|
2629
|
+
return handler.on_error("unknown format specifier"), end;
|
2630
|
+
} else {
|
2631
|
+
return handler.on_error("missing '}' in format string"), end;
|
2632
|
+
}
|
2633
|
+
}
|
2634
|
+
return begin + 1;
|
2635
|
+
}
|
2636
|
+
|
2574
2637
|
template <bool IS_CONSTEXPR, typename Char, typename Handler>
|
2575
|
-
|
2576
|
-
|
2577
|
-
|
2638
|
+
FMT_CONSTEXPR_DECL FMT_INLINE void parse_format_string(
|
2639
|
+
basic_string_view<Char> format_str, Handler&& handler) {
|
2640
|
+
auto begin = format_str.data();
|
2641
|
+
auto end = begin + format_str.size();
|
2642
|
+
if (end - begin < 32) {
|
2643
|
+
// Use a simple loop instead of memchr for small strings.
|
2644
|
+
const Char* p = begin;
|
2645
|
+
while (p != end) {
|
2646
|
+
auto c = *p++;
|
2647
|
+
if (c == '{') {
|
2648
|
+
handler.on_text(begin, p - 1);
|
2649
|
+
begin = p = parse_replacement_field(p - 1, end, handler);
|
2650
|
+
} else if (c == '}') {
|
2651
|
+
if (p == end || *p != '}')
|
2652
|
+
return handler.on_error("unmatched '}' in format string");
|
2653
|
+
handler.on_text(begin, p);
|
2654
|
+
begin = ++p;
|
2655
|
+
}
|
2656
|
+
}
|
2657
|
+
handler.on_text(begin, end);
|
2658
|
+
return;
|
2659
|
+
}
|
2660
|
+
struct writer {
|
2578
2661
|
FMT_CONSTEXPR void operator()(const Char* begin, const Char* end) {
|
2579
2662
|
if (begin == end) return;
|
2580
2663
|
for (;;) {
|
@@ -2590,8 +2673,6 @@ FMT_CONSTEXPR void parse_format_string(basic_string_view<Char> format_str,
|
|
2590
2673
|
}
|
2591
2674
|
Handler& handler_;
|
2592
2675
|
} write{handler};
|
2593
|
-
auto begin = format_str.data();
|
2594
|
-
auto end = begin + format_str.size();
|
2595
2676
|
while (begin != end) {
|
2596
2677
|
// Doing two passes with memchr (one for '{' and another for '}') is up to
|
2597
2678
|
// 2.5x faster than the naive one-pass implementation on big format strings.
|
@@ -2599,27 +2680,7 @@ FMT_CONSTEXPR void parse_format_string(basic_string_view<Char> format_str,
|
|
2599
2680
|
if (*begin != '{' && !find<IS_CONSTEXPR>(begin + 1, end, '{', p))
|
2600
2681
|
return write(begin, end);
|
2601
2682
|
write(begin, p);
|
2602
|
-
|
2603
|
-
if (p == end) return handler.on_error("invalid format string");
|
2604
|
-
if (static_cast<char>(*p) == '}') {
|
2605
|
-
handler.on_arg_id();
|
2606
|
-
handler.on_replacement_field(p);
|
2607
|
-
} else if (*p == '{') {
|
2608
|
-
handler.on_text(p, p + 1);
|
2609
|
-
} else {
|
2610
|
-
p = parse_arg_id(p, end, id_adapter<Handler, Char>{handler});
|
2611
|
-
Char c = p != end ? *p : Char();
|
2612
|
-
if (c == '}') {
|
2613
|
-
handler.on_replacement_field(p);
|
2614
|
-
} else if (c == ':') {
|
2615
|
-
p = handler.on_format_specs(p + 1, end);
|
2616
|
-
if (p == end || *p != '}')
|
2617
|
-
return handler.on_error("unknown format specifier");
|
2618
|
-
} else {
|
2619
|
-
return handler.on_error("missing '}' in format string");
|
2620
|
-
}
|
2621
|
-
}
|
2622
|
-
begin = p + 1;
|
2683
|
+
begin = parse_replacement_field(p, end, handler);
|
2623
2684
|
}
|
2624
2685
|
}
|
2625
2686
|
|
@@ -2629,44 +2690,121 @@ FMT_CONSTEXPR const typename ParseContext::char_type* parse_format_specs(
|
|
2629
2690
|
using char_type = typename ParseContext::char_type;
|
2630
2691
|
using context = buffer_context<char_type>;
|
2631
2692
|
using mapped_type =
|
2632
|
-
conditional_t<
|
2693
|
+
conditional_t<detail::mapped_type_constant<T, context>::value !=
|
2633
2694
|
type::custom_type,
|
2634
2695
|
decltype(arg_mapper<context>().map(std::declval<T>())), T>;
|
2635
2696
|
auto f = conditional_t<has_formatter<mapped_type, context>::value,
|
2636
2697
|
formatter<mapped_type, char_type>,
|
2637
|
-
|
2698
|
+
detail::fallback_formatter<T, char_type>>();
|
2638
2699
|
return f.parse(ctx);
|
2639
2700
|
}
|
2640
2701
|
|
2702
|
+
template <typename ArgFormatter, typename Char, typename Context>
|
2703
|
+
struct format_handler : detail::error_handler {
|
2704
|
+
basic_format_parse_context<Char> parse_context;
|
2705
|
+
Context context;
|
2706
|
+
|
2707
|
+
format_handler(typename ArgFormatter::iterator out,
|
2708
|
+
basic_string_view<Char> str,
|
2709
|
+
basic_format_args<Context> format_args, detail::locale_ref loc)
|
2710
|
+
: parse_context(str), context(out, format_args, loc) {}
|
2711
|
+
|
2712
|
+
void on_text(const Char* begin, const Char* end) {
|
2713
|
+
auto size = to_unsigned(end - begin);
|
2714
|
+
auto out = context.out();
|
2715
|
+
auto&& it = reserve(out, size);
|
2716
|
+
it = std::copy_n(begin, size, it);
|
2717
|
+
context.advance_to(out);
|
2718
|
+
}
|
2719
|
+
|
2720
|
+
int on_arg_id() { return parse_context.next_arg_id(); }
|
2721
|
+
int on_arg_id(int id) { return parse_context.check_arg_id(id), id; }
|
2722
|
+
int on_arg_id(basic_string_view<Char> id) {
|
2723
|
+
int arg_id = context.arg_id(id);
|
2724
|
+
if (arg_id < 0) on_error("argument not found");
|
2725
|
+
return arg_id;
|
2726
|
+
}
|
2727
|
+
|
2728
|
+
FMT_INLINE void on_replacement_field(int id, const Char*) {
|
2729
|
+
auto arg = get_arg(context, id);
|
2730
|
+
context.advance_to(visit_format_arg(
|
2731
|
+
default_arg_formatter<typename ArgFormatter::iterator, Char>{
|
2732
|
+
context.out(), context.args(), context.locale()},
|
2733
|
+
arg));
|
2734
|
+
}
|
2735
|
+
|
2736
|
+
const Char* on_format_specs(int id, const Char* begin, const Char* end) {
|
2737
|
+
advance_to(parse_context, begin);
|
2738
|
+
auto arg = get_arg(context, id);
|
2739
|
+
custom_formatter<Context> f(parse_context, context);
|
2740
|
+
if (visit_format_arg(f, arg)) return parse_context.begin();
|
2741
|
+
basic_format_specs<Char> specs;
|
2742
|
+
using parse_context_t = basic_format_parse_context<Char>;
|
2743
|
+
specs_checker<specs_handler<parse_context_t, Context>> handler(
|
2744
|
+
specs_handler<parse_context_t, Context>(specs, parse_context, context),
|
2745
|
+
arg.type());
|
2746
|
+
begin = parse_format_specs(begin, end, handler);
|
2747
|
+
if (begin == end || *begin != '}') on_error("missing '}' in format string");
|
2748
|
+
advance_to(parse_context, begin);
|
2749
|
+
context.advance_to(
|
2750
|
+
visit_format_arg(ArgFormatter(context, &parse_context, &specs), arg));
|
2751
|
+
return begin;
|
2752
|
+
}
|
2753
|
+
};
|
2754
|
+
|
2755
|
+
// A parse context with extra argument id checks. It is only used at compile
|
2756
|
+
// time because adding checks at runtime would introduce substantial overhead
|
2757
|
+
// and would be redundant since argument ids are checked when arguments are
|
2758
|
+
// retrieved anyway.
|
2759
|
+
template <typename Char, typename ErrorHandler = error_handler>
|
2760
|
+
class compile_parse_context
|
2761
|
+
: public basic_format_parse_context<Char, ErrorHandler> {
|
2762
|
+
private:
|
2763
|
+
int num_args_;
|
2764
|
+
using base = basic_format_parse_context<Char, ErrorHandler>;
|
2765
|
+
|
2766
|
+
public:
|
2767
|
+
explicit FMT_CONSTEXPR compile_parse_context(
|
2768
|
+
basic_string_view<Char> format_str, int num_args = max_value<int>(),
|
2769
|
+
ErrorHandler eh = {})
|
2770
|
+
: base(format_str, eh), num_args_(num_args) {}
|
2771
|
+
|
2772
|
+
FMT_CONSTEXPR int next_arg_id() {
|
2773
|
+
int id = base::next_arg_id();
|
2774
|
+
if (id >= num_args_) this->on_error("argument not found");
|
2775
|
+
return id;
|
2776
|
+
}
|
2777
|
+
|
2778
|
+
FMT_CONSTEXPR void check_arg_id(int id) {
|
2779
|
+
base::check_arg_id(id);
|
2780
|
+
if (id >= num_args_) this->on_error("argument not found");
|
2781
|
+
}
|
2782
|
+
using base::check_arg_id;
|
2783
|
+
};
|
2784
|
+
|
2641
2785
|
template <typename Char, typename ErrorHandler, typename... Args>
|
2642
2786
|
class format_string_checker {
|
2643
2787
|
public:
|
2644
2788
|
explicit FMT_CONSTEXPR format_string_checker(
|
2645
2789
|
basic_string_view<Char> format_str, ErrorHandler eh)
|
2646
|
-
:
|
2647
|
-
context_(format_str, eh),
|
2790
|
+
: context_(format_str, num_args, eh),
|
2648
2791
|
parse_funcs_{&parse_format_specs<Args, parse_context_type>...} {}
|
2649
2792
|
|
2650
2793
|
FMT_CONSTEXPR void on_text(const Char*, const Char*) {}
|
2651
2794
|
|
2652
|
-
FMT_CONSTEXPR
|
2653
|
-
|
2654
|
-
|
2655
|
-
}
|
2656
|
-
FMT_CONSTEXPR void on_arg_id(int id) {
|
2657
|
-
arg_id_ = id;
|
2658
|
-
context_.check_arg_id(id);
|
2659
|
-
check_arg_id();
|
2660
|
-
}
|
2661
|
-
FMT_CONSTEXPR void on_arg_id(basic_string_view<Char>) {
|
2795
|
+
FMT_CONSTEXPR int on_arg_id() { return context_.next_arg_id(); }
|
2796
|
+
FMT_CONSTEXPR int on_arg_id(int id) { return context_.check_arg_id(id), id; }
|
2797
|
+
FMT_CONSTEXPR int on_arg_id(basic_string_view<Char>) {
|
2662
2798
|
on_error("compile-time checks don't support named arguments");
|
2799
|
+
return 0;
|
2663
2800
|
}
|
2664
2801
|
|
2665
|
-
FMT_CONSTEXPR void on_replacement_field(const Char*) {}
|
2802
|
+
FMT_CONSTEXPR void on_replacement_field(int, const Char*) {}
|
2666
2803
|
|
2667
|
-
FMT_CONSTEXPR const Char* on_format_specs(
|
2804
|
+
FMT_CONSTEXPR const Char* on_format_specs(int id, const Char* begin,
|
2805
|
+
const Char*) {
|
2668
2806
|
advance_to(context_, begin);
|
2669
|
-
return
|
2807
|
+
return id < num_args ? parse_funcs_[id](context_) : begin;
|
2670
2808
|
}
|
2671
2809
|
|
2672
2810
|
FMT_CONSTEXPR void on_error(const char* message) {
|
@@ -2674,35 +2812,66 @@ class format_string_checker {
|
|
2674
2812
|
}
|
2675
2813
|
|
2676
2814
|
private:
|
2677
|
-
using parse_context_type =
|
2815
|
+
using parse_context_type = compile_parse_context<Char, ErrorHandler>;
|
2678
2816
|
enum { num_args = sizeof...(Args) };
|
2679
2817
|
|
2680
|
-
FMT_CONSTEXPR void check_arg_id() {
|
2681
|
-
if (arg_id_ >= num_args) context_.on_error("argument index out of range");
|
2682
|
-
}
|
2683
|
-
|
2684
2818
|
// Format specifier parsing function.
|
2685
2819
|
using parse_func = const Char* (*)(parse_context_type&);
|
2686
2820
|
|
2687
|
-
int arg_id_;
|
2688
2821
|
parse_context_type context_;
|
2689
2822
|
parse_func parse_funcs_[num_args > 0 ? num_args : 1];
|
2690
2823
|
};
|
2691
2824
|
|
2692
|
-
|
2693
|
-
|
2694
|
-
|
2695
|
-
|
2696
|
-
|
2697
|
-
|
2825
|
+
// Converts string literals to basic_string_view.
|
2826
|
+
template <typename Char, size_t N>
|
2827
|
+
FMT_CONSTEXPR basic_string_view<Char> compile_string_to_view(
|
2828
|
+
const Char (&s)[N]) {
|
2829
|
+
// Remove trailing null character if needed. Won't be present if this is used
|
2830
|
+
// with raw character array (i.e. not defined as a string).
|
2831
|
+
return {s,
|
2832
|
+
N - ((std::char_traits<Char>::to_int_type(s[N - 1]) == 0) ? 1 : 0)};
|
2833
|
+
}
|
2834
|
+
|
2835
|
+
// Converts string_view to basic_string_view.
|
2836
|
+
template <typename Char>
|
2837
|
+
FMT_CONSTEXPR basic_string_view<Char> compile_string_to_view(
|
2838
|
+
const std_string_view<Char>& s) {
|
2839
|
+
return {s.data(), s.size()};
|
2698
2840
|
}
|
2699
2841
|
|
2842
|
+
#define FMT_STRING_IMPL(s, base) \
|
2843
|
+
[] { \
|
2844
|
+
/* Use a macro-like name to avoid shadowing warnings. */ \
|
2845
|
+
struct FMT_COMPILE_STRING : base { \
|
2846
|
+
using char_type = fmt::remove_cvref_t<decltype(s[0])>; \
|
2847
|
+
FMT_MAYBE_UNUSED FMT_CONSTEXPR \
|
2848
|
+
operator fmt::basic_string_view<char_type>() const { \
|
2849
|
+
return fmt::detail::compile_string_to_view<char_type>(s); \
|
2850
|
+
} \
|
2851
|
+
}; \
|
2852
|
+
return FMT_COMPILE_STRING(); \
|
2853
|
+
}()
|
2854
|
+
|
2855
|
+
/**
|
2856
|
+
\rst
|
2857
|
+
Constructs a compile-time format string from a string literal *s*.
|
2858
|
+
|
2859
|
+
**Example**::
|
2860
|
+
|
2861
|
+
// A compile-time error because 'd' is an invalid specifier for strings.
|
2862
|
+
std::string s = fmt::format(FMT_STRING("{:d}"), "foo");
|
2863
|
+
\endrst
|
2864
|
+
*/
|
2865
|
+
#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::compile_string)
|
2866
|
+
|
2700
2867
|
template <typename... Args, typename S,
|
2701
2868
|
enable_if_t<(is_compile_string<S>::value), int>>
|
2702
2869
|
void check_format_string(S format_str) {
|
2703
|
-
FMT_CONSTEXPR_DECL
|
2704
|
-
|
2705
|
-
|
2870
|
+
FMT_CONSTEXPR_DECL auto s = to_string_view(format_str);
|
2871
|
+
using checker = format_string_checker<typename S::char_type, error_handler,
|
2872
|
+
remove_cvref_t<Args>...>;
|
2873
|
+
FMT_CONSTEXPR_DECL bool invalid_format =
|
2874
|
+
(parse_format_string<true>(s, checker(s, {})), true);
|
2706
2875
|
(void)invalid_format;
|
2707
2876
|
}
|
2708
2877
|
|
@@ -2713,44 +2882,37 @@ void handle_dynamic_spec(int& value, arg_ref<typename Context::char_type> ref,
|
|
2713
2882
|
case arg_id_kind::none:
|
2714
2883
|
break;
|
2715
2884
|
case arg_id_kind::index:
|
2716
|
-
value =
|
2717
|
-
|
2885
|
+
value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.val.index),
|
2886
|
+
ctx.error_handler());
|
2718
2887
|
break;
|
2719
2888
|
case arg_id_kind::name:
|
2720
|
-
value =
|
2721
|
-
|
2889
|
+
value = detail::get_dynamic_spec<Handler>(ctx.arg(ref.val.name),
|
2890
|
+
ctx.error_handler());
|
2722
2891
|
break;
|
2723
2892
|
}
|
2724
2893
|
}
|
2725
2894
|
|
2726
|
-
using format_func = void (*)(
|
2895
|
+
using format_func = void (*)(detail::buffer<char>&, int, string_view);
|
2727
2896
|
|
2728
2897
|
FMT_API void format_error_code(buffer<char>& out, int error_code,
|
2729
2898
|
string_view message) FMT_NOEXCEPT;
|
2730
2899
|
|
2731
2900
|
FMT_API void report_error(format_func func, int error_code,
|
2732
2901
|
string_view message) FMT_NOEXCEPT;
|
2733
|
-
} // namespace internal
|
2734
|
-
|
2735
|
-
template <typename Range>
|
2736
|
-
using basic_writer FMT_DEPRECATED_ALIAS = internal::basic_writer<Range>;
|
2737
|
-
using writer FMT_DEPRECATED_ALIAS = internal::writer;
|
2738
|
-
using wwriter FMT_DEPRECATED_ALIAS =
|
2739
|
-
internal::basic_writer<buffer_range<wchar_t>>;
|
2740
2902
|
|
2741
2903
|
/** The default argument formatter. */
|
2742
|
-
template <typename
|
2743
|
-
class arg_formatter : public
|
2904
|
+
template <typename OutputIt, typename Char>
|
2905
|
+
class arg_formatter : public arg_formatter_base<OutputIt, Char> {
|
2744
2906
|
private:
|
2745
|
-
using char_type =
|
2746
|
-
using base =
|
2747
|
-
using context_type = basic_format_context<
|
2907
|
+
using char_type = Char;
|
2908
|
+
using base = arg_formatter_base<OutputIt, Char>;
|
2909
|
+
using context_type = basic_format_context<OutputIt, Char>;
|
2748
2910
|
|
2749
2911
|
context_type& ctx_;
|
2750
2912
|
basic_format_parse_context<char_type>* parse_ctx_;
|
2913
|
+
const Char* ptr_;
|
2751
2914
|
|
2752
2915
|
public:
|
2753
|
-
using range = Range;
|
2754
2916
|
using iterator = typename base::iterator;
|
2755
2917
|
using format_specs = typename base::format_specs;
|
2756
2918
|
|
@@ -2764,19 +2926,26 @@ class arg_formatter : public internal::arg_formatter_base<Range> {
|
|
2764
2926
|
explicit arg_formatter(
|
2765
2927
|
context_type& ctx,
|
2766
2928
|
basic_format_parse_context<char_type>* parse_ctx = nullptr,
|
2767
|
-
format_specs* specs = nullptr)
|
2768
|
-
: base(
|
2929
|
+
format_specs* specs = nullptr, const Char* ptr = nullptr)
|
2930
|
+
: base(ctx.out(), specs, ctx.locale()),
|
2769
2931
|
ctx_(ctx),
|
2770
|
-
parse_ctx_(parse_ctx)
|
2932
|
+
parse_ctx_(parse_ctx),
|
2933
|
+
ptr_(ptr) {}
|
2771
2934
|
|
2772
2935
|
using base::operator();
|
2773
2936
|
|
2774
2937
|
/** Formats an argument of a user-defined type. */
|
2775
2938
|
iterator operator()(typename basic_format_arg<context_type>::handle handle) {
|
2939
|
+
if (ptr_) advance_to(*parse_ctx_, ptr_);
|
2776
2940
|
handle.format(*parse_ctx_, ctx_);
|
2777
2941
|
return ctx_.out();
|
2778
2942
|
}
|
2779
2943
|
};
|
2944
|
+
} // namespace detail
|
2945
|
+
|
2946
|
+
template <typename OutputIt, typename Char>
|
2947
|
+
using arg_formatter FMT_DEPRECATED_ALIAS =
|
2948
|
+
detail::arg_formatter<OutputIt, Char>;
|
2780
2949
|
|
2781
2950
|
/**
|
2782
2951
|
An error returned by an operating system or a language runtime,
|
@@ -2841,7 +3010,7 @@ class FMT_API system_error : public std::runtime_error {
|
|
2841
3010
|
may look like "Unknown error -1" and is platform-dependent.
|
2842
3011
|
\endrst
|
2843
3012
|
*/
|
2844
|
-
FMT_API void format_system_error(
|
3013
|
+
FMT_API void format_system_error(detail::buffer<char>& out, int error_code,
|
2845
3014
|
string_view message) FMT_NOEXCEPT;
|
2846
3015
|
|
2847
3016
|
// Reports a system error without throwing an exception.
|
@@ -2858,47 +3027,32 @@ class format_int {
|
|
2858
3027
|
mutable char buffer_[buffer_size];
|
2859
3028
|
char* str_;
|
2860
3029
|
|
2861
|
-
|
2862
|
-
|
2863
|
-
|
2864
|
-
while (value >= 100) {
|
2865
|
-
// Integer division is slow so do it for a group of two digits instead
|
2866
|
-
// of for every digit. The idea comes from the talk by Alexandrescu
|
2867
|
-
// "Three Optimization Tips for C++". See speed-test for a comparison.
|
2868
|
-
auto index = static_cast<unsigned>((value % 100) * 2);
|
2869
|
-
value /= 100;
|
2870
|
-
*--ptr = internal::data::digits[index + 1];
|
2871
|
-
*--ptr = internal::data::digits[index];
|
2872
|
-
}
|
2873
|
-
if (value < 10) {
|
2874
|
-
*--ptr = static_cast<char>('0' + value);
|
2875
|
-
return ptr;
|
2876
|
-
}
|
2877
|
-
auto index = static_cast<unsigned>(value * 2);
|
2878
|
-
*--ptr = internal::data::digits[index + 1];
|
2879
|
-
*--ptr = internal::data::digits[index];
|
2880
|
-
return ptr;
|
3030
|
+
template <typename UInt> char* format_unsigned(UInt value) {
|
3031
|
+
auto n = static_cast<detail::uint32_or_64_or_128_t<UInt>>(value);
|
3032
|
+
return detail::format_decimal(buffer_, n, buffer_size - 1).begin;
|
2881
3033
|
}
|
2882
3034
|
|
2883
|
-
|
2884
|
-
auto abs_value = static_cast<
|
3035
|
+
template <typename Int> char* format_signed(Int value) {
|
3036
|
+
auto abs_value = static_cast<detail::uint32_or_64_or_128_t<Int>>(value);
|
2885
3037
|
bool negative = value < 0;
|
2886
3038
|
if (negative) abs_value = 0 - abs_value;
|
2887
|
-
|
2888
|
-
if (negative) *--
|
3039
|
+
auto begin = format_unsigned(abs_value);
|
3040
|
+
if (negative) *--begin = '-';
|
3041
|
+
return begin;
|
2889
3042
|
}
|
2890
3043
|
|
2891
3044
|
public:
|
2892
|
-
explicit format_int(int value)
|
2893
|
-
explicit format_int(long value)
|
2894
|
-
explicit format_int(long long value)
|
2895
|
-
explicit format_int(unsigned value) : str_(
|
2896
|
-
explicit format_int(unsigned long value) : str_(
|
2897
|
-
explicit format_int(unsigned long long value)
|
3045
|
+
explicit format_int(int value) : str_(format_signed(value)) {}
|
3046
|
+
explicit format_int(long value) : str_(format_signed(value)) {}
|
3047
|
+
explicit format_int(long long value) : str_(format_signed(value)) {}
|
3048
|
+
explicit format_int(unsigned value) : str_(format_unsigned(value)) {}
|
3049
|
+
explicit format_int(unsigned long value) : str_(format_unsigned(value)) {}
|
3050
|
+
explicit format_int(unsigned long long value)
|
3051
|
+
: str_(format_unsigned(value)) {}
|
2898
3052
|
|
2899
3053
|
/** Returns the number of characters written to the output buffer. */
|
2900
|
-
|
2901
|
-
return
|
3054
|
+
size_t size() const {
|
3055
|
+
return detail::to_unsigned(buffer_ - str_ + buffer_size - 1);
|
2902
3056
|
}
|
2903
3057
|
|
2904
3058
|
/**
|
@@ -2924,75 +3078,71 @@ class format_int {
|
|
2924
3078
|
std::string str() const { return std::string(str_, size()); }
|
2925
3079
|
};
|
2926
3080
|
|
2927
|
-
// A formatter specialization for the core types corresponding to
|
3081
|
+
// A formatter specialization for the core types corresponding to detail::type
|
2928
3082
|
// constants.
|
2929
3083
|
template <typename T, typename Char>
|
2930
3084
|
struct formatter<T, Char,
|
2931
|
-
enable_if_t<
|
2932
|
-
|
3085
|
+
enable_if_t<detail::type_constant<T, Char>::value !=
|
3086
|
+
detail::type::custom_type>> {
|
2933
3087
|
FMT_CONSTEXPR formatter() = default;
|
2934
3088
|
|
2935
3089
|
// Parses format specifiers stopping either at the end of the range or at the
|
2936
3090
|
// terminating '}'.
|
2937
3091
|
template <typename ParseContext>
|
2938
3092
|
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
2939
|
-
using handler_type =
|
2940
|
-
auto type =
|
2941
|
-
|
2942
|
-
|
3093
|
+
using handler_type = detail::dynamic_specs_handler<ParseContext>;
|
3094
|
+
auto type = detail::type_constant<T, Char>::value;
|
3095
|
+
detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
|
3096
|
+
type);
|
2943
3097
|
auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
|
2944
3098
|
auto eh = ctx.error_handler();
|
2945
3099
|
switch (type) {
|
2946
|
-
case
|
2947
|
-
case internal::type::named_arg_type:
|
3100
|
+
case detail::type::none_type:
|
2948
3101
|
FMT_ASSERT(false, "invalid argument type");
|
2949
3102
|
break;
|
2950
|
-
case
|
2951
|
-
case
|
2952
|
-
case
|
2953
|
-
case
|
2954
|
-
case
|
2955
|
-
case
|
2956
|
-
case
|
3103
|
+
case detail::type::int_type:
|
3104
|
+
case detail::type::uint_type:
|
3105
|
+
case detail::type::long_long_type:
|
3106
|
+
case detail::type::ulong_long_type:
|
3107
|
+
case detail::type::int128_type:
|
3108
|
+
case detail::type::uint128_type:
|
3109
|
+
case detail::type::bool_type:
|
2957
3110
|
handle_int_type_spec(specs_.type,
|
2958
|
-
|
3111
|
+
detail::int_type_checker<decltype(eh)>(eh));
|
2959
3112
|
break;
|
2960
|
-
case
|
3113
|
+
case detail::type::char_type:
|
2961
3114
|
handle_char_specs(
|
2962
|
-
&specs_,
|
3115
|
+
&specs_, detail::char_specs_checker<decltype(eh)>(specs_.type, eh));
|
2963
3116
|
break;
|
2964
|
-
case
|
2965
|
-
if (
|
2966
|
-
|
2967
|
-
|
3117
|
+
case detail::type::float_type:
|
3118
|
+
if (detail::const_check(FMT_USE_FLOAT))
|
3119
|
+
detail::parse_float_type_spec(specs_, eh);
|
3120
|
+
else
|
2968
3121
|
FMT_ASSERT(false, "float support disabled");
|
2969
|
-
}
|
2970
3122
|
break;
|
2971
|
-
case
|
2972
|
-
if (
|
2973
|
-
|
2974
|
-
|
3123
|
+
case detail::type::double_type:
|
3124
|
+
if (detail::const_check(FMT_USE_DOUBLE))
|
3125
|
+
detail::parse_float_type_spec(specs_, eh);
|
3126
|
+
else
|
2975
3127
|
FMT_ASSERT(false, "double support disabled");
|
2976
|
-
}
|
2977
3128
|
break;
|
2978
|
-
case
|
2979
|
-
if (
|
2980
|
-
|
2981
|
-
|
3129
|
+
case detail::type::long_double_type:
|
3130
|
+
if (detail::const_check(FMT_USE_LONG_DOUBLE))
|
3131
|
+
detail::parse_float_type_spec(specs_, eh);
|
3132
|
+
else
|
2982
3133
|
FMT_ASSERT(false, "long double support disabled");
|
2983
|
-
}
|
2984
3134
|
break;
|
2985
|
-
case
|
2986
|
-
|
2987
|
-
specs_.type,
|
3135
|
+
case detail::type::cstring_type:
|
3136
|
+
detail::handle_cstring_type_spec(
|
3137
|
+
specs_.type, detail::cstring_type_checker<decltype(eh)>(eh));
|
2988
3138
|
break;
|
2989
|
-
case
|
2990
|
-
|
3139
|
+
case detail::type::string_type:
|
3140
|
+
detail::check_string_type_spec(specs_.type, eh);
|
2991
3141
|
break;
|
2992
|
-
case
|
2993
|
-
|
3142
|
+
case detail::type::pointer_type:
|
3143
|
+
detail::check_pointer_type_spec(specs_.type, eh);
|
2994
3144
|
break;
|
2995
|
-
case
|
3145
|
+
case detail::type::custom_type:
|
2996
3146
|
// Custom format specifiers should be checked in parse functions of
|
2997
3147
|
// formatter specializations.
|
2998
3148
|
break;
|
@@ -3002,19 +3152,18 @@ struct formatter<T, Char,
|
|
3002
3152
|
|
3003
3153
|
template <typename FormatContext>
|
3004
3154
|
auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
|
3005
|
-
|
3006
|
-
|
3007
|
-
|
3155
|
+
detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
|
3156
|
+
specs_.width_ref, ctx);
|
3157
|
+
detail::handle_dynamic_spec<detail::precision_checker>(
|
3008
3158
|
specs_.precision, specs_.precision_ref, ctx);
|
3009
|
-
using
|
3010
|
-
|
3011
|
-
|
3012
|
-
|
3013
|
-
internal::make_arg<FormatContext>(val));
|
3159
|
+
using af = detail::arg_formatter<typename FormatContext::iterator,
|
3160
|
+
typename FormatContext::char_type>;
|
3161
|
+
return visit_format_arg(af(ctx, nullptr, &specs_),
|
3162
|
+
detail::make_arg<FormatContext>(val));
|
3014
3163
|
}
|
3015
3164
|
|
3016
3165
|
private:
|
3017
|
-
|
3166
|
+
detail::dynamic_format_specs<Char> specs_;
|
3018
3167
|
};
|
3019
3168
|
|
3020
3169
|
#define FMT_FORMAT_AS(Type, Base) \
|
@@ -3035,7 +3184,7 @@ FMT_FORMAT_AS(unsigned long, unsigned long long);
|
|
3035
3184
|
FMT_FORMAT_AS(Char*, const Char*);
|
3036
3185
|
FMT_FORMAT_AS(std::basic_string<Char>, basic_string_view<Char>);
|
3037
3186
|
FMT_FORMAT_AS(std::nullptr_t, const void*);
|
3038
|
-
FMT_FORMAT_AS(
|
3187
|
+
FMT_FORMAT_AS(detail::std_string_view<Char>, basic_string_view<Char>);
|
3039
3188
|
|
3040
3189
|
template <typename Char>
|
3041
3190
|
struct formatter<void*, Char> : formatter<const void*, Char> {
|
@@ -3065,7 +3214,7 @@ struct formatter<Char[N], Char> : formatter<basic_string_view<Char>, Char> {
|
|
3065
3214
|
// };
|
3066
3215
|
template <typename Char = char> class dynamic_formatter {
|
3067
3216
|
private:
|
3068
|
-
struct null_handler :
|
3217
|
+
struct null_handler : detail::error_handler {
|
3069
3218
|
void on_align(align_t) {}
|
3070
3219
|
void on_plus() {}
|
3071
3220
|
void on_minus() {}
|
@@ -3078,16 +3227,15 @@ template <typename Char = char> class dynamic_formatter {
|
|
3078
3227
|
auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
3079
3228
|
format_str_ = ctx.begin();
|
3080
3229
|
// Checks are deferred to formatting time when the argument type is known.
|
3081
|
-
|
3230
|
+
detail::dynamic_specs_handler<ParseContext> handler(specs_, ctx);
|
3082
3231
|
return parse_format_specs(ctx.begin(), ctx.end(), handler);
|
3083
3232
|
}
|
3084
3233
|
|
3085
3234
|
template <typename T, typename FormatContext>
|
3086
3235
|
auto format(const T& val, FormatContext& ctx) -> decltype(ctx.out()) {
|
3087
3236
|
handle_specs(ctx);
|
3088
|
-
|
3089
|
-
null_handler(),
|
3090
|
-
internal::mapped_type_constant<T, FormatContext>::value);
|
3237
|
+
detail::specs_checker<null_handler> checker(
|
3238
|
+
null_handler(), detail::mapped_type_constant<T, FormatContext>::value);
|
3091
3239
|
checker.on_align(specs_.align);
|
3092
3240
|
switch (specs_.sign) {
|
3093
3241
|
case sign::none:
|
@@ -3104,104 +3252,47 @@ template <typename Char = char> class dynamic_formatter {
|
|
3104
3252
|
}
|
3105
3253
|
if (specs_.alt) checker.on_hash();
|
3106
3254
|
if (specs_.precision >= 0) checker.end_precision();
|
3107
|
-
using
|
3108
|
-
|
3109
|
-
visit_format_arg(
|
3110
|
-
|
3255
|
+
using af = detail::arg_formatter<typename FormatContext::iterator,
|
3256
|
+
typename FormatContext::char_type>;
|
3257
|
+
visit_format_arg(af(ctx, nullptr, &specs_),
|
3258
|
+
detail::make_arg<FormatContext>(val));
|
3111
3259
|
return ctx.out();
|
3112
3260
|
}
|
3113
3261
|
|
3114
3262
|
private:
|
3115
3263
|
template <typename Context> void handle_specs(Context& ctx) {
|
3116
|
-
|
3117
|
-
|
3118
|
-
|
3264
|
+
detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
|
3265
|
+
specs_.width_ref, ctx);
|
3266
|
+
detail::handle_dynamic_spec<detail::precision_checker>(
|
3119
3267
|
specs_.precision, specs_.precision_ref, ctx);
|
3120
3268
|
}
|
3121
3269
|
|
3122
|
-
|
3270
|
+
detail::dynamic_format_specs<Char> specs_;
|
3123
3271
|
const Char* format_str_;
|
3124
3272
|
};
|
3125
3273
|
|
3126
|
-
template <typename Range, typename Char>
|
3127
|
-
typename basic_format_context<Range, Char>::format_arg
|
3128
|
-
basic_format_context<Range, Char>::arg(basic_string_view<char_type> name) {
|
3129
|
-
map_.init(args_);
|
3130
|
-
format_arg arg = map_.find(name);
|
3131
|
-
if (arg.type() == internal::type::none_type)
|
3132
|
-
this->on_error("argument not found");
|
3133
|
-
return arg;
|
3134
|
-
}
|
3135
|
-
|
3136
3274
|
template <typename Char, typename ErrorHandler>
|
3137
3275
|
FMT_CONSTEXPR void advance_to(
|
3138
3276
|
basic_format_parse_context<Char, ErrorHandler>& ctx, const Char* p) {
|
3139
3277
|
ctx.advance_to(ctx.begin() + (p - &*ctx.begin()));
|
3140
3278
|
}
|
3141
3279
|
|
3142
|
-
template <typename ArgFormatter, typename Char, typename Context>
|
3143
|
-
struct format_handler : internal::error_handler {
|
3144
|
-
using range = typename ArgFormatter::range;
|
3145
|
-
|
3146
|
-
format_handler(range r, basic_string_view<Char> str,
|
3147
|
-
basic_format_args<Context> format_args,
|
3148
|
-
internal::locale_ref loc)
|
3149
|
-
: parse_context(str), context(r.begin(), format_args, loc) {}
|
3150
|
-
|
3151
|
-
void on_text(const Char* begin, const Char* end) {
|
3152
|
-
auto size = internal::to_unsigned(end - begin);
|
3153
|
-
auto out = context.out();
|
3154
|
-
auto&& it = internal::reserve(out, size);
|
3155
|
-
it = std::copy_n(begin, size, it);
|
3156
|
-
context.advance_to(out);
|
3157
|
-
}
|
3158
|
-
|
3159
|
-
void get_arg(int id) { arg = internal::get_arg(context, id); }
|
3160
|
-
|
3161
|
-
void on_arg_id() { get_arg(parse_context.next_arg_id()); }
|
3162
|
-
void on_arg_id(int id) {
|
3163
|
-
parse_context.check_arg_id(id);
|
3164
|
-
get_arg(id);
|
3165
|
-
}
|
3166
|
-
void on_arg_id(basic_string_view<Char> id) { arg = context.arg(id); }
|
3167
|
-
|
3168
|
-
void on_replacement_field(const Char* p) {
|
3169
|
-
advance_to(parse_context, p);
|
3170
|
-
context.advance_to(
|
3171
|
-
visit_format_arg(ArgFormatter(context, &parse_context), arg));
|
3172
|
-
}
|
3173
|
-
|
3174
|
-
const Char* on_format_specs(const Char* begin, const Char* end) {
|
3175
|
-
advance_to(parse_context, begin);
|
3176
|
-
internal::custom_formatter<Context> f(parse_context, context);
|
3177
|
-
if (visit_format_arg(f, arg)) return parse_context.begin();
|
3178
|
-
basic_format_specs<Char> specs;
|
3179
|
-
using internal::specs_handler;
|
3180
|
-
using parse_context_t = basic_format_parse_context<Char>;
|
3181
|
-
internal::specs_checker<specs_handler<parse_context_t, Context>> handler(
|
3182
|
-
specs_handler<parse_context_t, Context>(specs, parse_context, context),
|
3183
|
-
arg.type());
|
3184
|
-
begin = parse_format_specs(begin, end, handler);
|
3185
|
-
if (begin == end || *begin != '}') on_error("missing '}' in format string");
|
3186
|
-
advance_to(parse_context, begin);
|
3187
|
-
context.advance_to(
|
3188
|
-
visit_format_arg(ArgFormatter(context, &parse_context, &specs), arg));
|
3189
|
-
return begin;
|
3190
|
-
}
|
3191
|
-
|
3192
|
-
basic_format_parse_context<Char> parse_context;
|
3193
|
-
Context context;
|
3194
|
-
basic_format_arg<Context> arg;
|
3195
|
-
};
|
3196
|
-
|
3197
3280
|
/** Formats arguments and writes the output to the range. */
|
3198
3281
|
template <typename ArgFormatter, typename Char, typename Context>
|
3199
3282
|
typename Context::iterator vformat_to(
|
3200
|
-
typename ArgFormatter::
|
3283
|
+
typename ArgFormatter::iterator out, basic_string_view<Char> format_str,
|
3201
3284
|
basic_format_args<Context> args,
|
3202
|
-
|
3203
|
-
|
3204
|
-
|
3285
|
+
detail::locale_ref loc = detail::locale_ref()) {
|
3286
|
+
if (format_str.size() == 2 && detail::equal2(format_str.data(), "{}")) {
|
3287
|
+
auto arg = args.get(0);
|
3288
|
+
if (!arg) detail::error_handler().on_error("argument not found");
|
3289
|
+
using iterator = typename ArgFormatter::iterator;
|
3290
|
+
return visit_format_arg(
|
3291
|
+
detail::default_arg_formatter<iterator, Char>{out, args, loc}, arg);
|
3292
|
+
}
|
3293
|
+
detail::format_handler<ArgFormatter, Char, Context> h(out, format_str, args,
|
3294
|
+
loc);
|
3295
|
+
detail::parse_format_string<false>(format_str, h);
|
3205
3296
|
return h.context.out();
|
3206
3297
|
}
|
3207
3298
|
|
@@ -3228,44 +3319,42 @@ class bytes {
|
|
3228
3319
|
template <> struct formatter<bytes> {
|
3229
3320
|
template <typename ParseContext>
|
3230
3321
|
FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) {
|
3231
|
-
using handler_type =
|
3232
|
-
|
3233
|
-
|
3322
|
+
using handler_type = detail::dynamic_specs_handler<ParseContext>;
|
3323
|
+
detail::specs_checker<handler_type> handler(handler_type(specs_, ctx),
|
3324
|
+
detail::type::string_type);
|
3234
3325
|
auto it = parse_format_specs(ctx.begin(), ctx.end(), handler);
|
3235
|
-
|
3326
|
+
detail::check_string_type_spec(specs_.type, ctx.error_handler());
|
3236
3327
|
return it;
|
3237
3328
|
}
|
3238
3329
|
|
3239
3330
|
template <typename FormatContext>
|
3240
3331
|
auto format(bytes b, FormatContext& ctx) -> decltype(ctx.out()) {
|
3241
|
-
|
3242
|
-
|
3243
|
-
|
3332
|
+
detail::handle_dynamic_spec<detail::width_checker>(specs_.width,
|
3333
|
+
specs_.width_ref, ctx);
|
3334
|
+
detail::handle_dynamic_spec<detail::precision_checker>(
|
3244
3335
|
specs_.precision, specs_.precision_ref, ctx);
|
3245
|
-
|
3246
|
-
internal::output_range<typename FormatContext::iterator, char>;
|
3247
|
-
internal::basic_writer<range_type> writer(range_type(ctx.out()));
|
3248
|
-
writer.write_bytes(b.data_, specs_);
|
3249
|
-
return writer.out();
|
3336
|
+
return detail::write_bytes(ctx.out(), b.data_, specs_);
|
3250
3337
|
}
|
3251
3338
|
|
3252
3339
|
private:
|
3253
|
-
|
3340
|
+
detail::dynamic_format_specs<char> specs_;
|
3254
3341
|
};
|
3255
3342
|
|
3256
|
-
template <typename It, typename Char>
|
3343
|
+
template <typename It, typename Sentinel, typename Char>
|
3344
|
+
struct arg_join : detail::view {
|
3257
3345
|
It begin;
|
3258
|
-
|
3346
|
+
Sentinel end;
|
3259
3347
|
basic_string_view<Char> sep;
|
3260
3348
|
|
3261
|
-
arg_join(It b,
|
3349
|
+
arg_join(It b, Sentinel e, basic_string_view<Char> s)
|
3350
|
+
: begin(b), end(e), sep(s) {}
|
3262
3351
|
};
|
3263
3352
|
|
3264
|
-
template <typename It, typename Char>
|
3265
|
-
struct formatter<arg_join<It, Char>, Char>
|
3353
|
+
template <typename It, typename Sentinel, typename Char>
|
3354
|
+
struct formatter<arg_join<It, Sentinel, Char>, Char>
|
3266
3355
|
: formatter<typename std::iterator_traits<It>::value_type, Char> {
|
3267
3356
|
template <typename FormatContext>
|
3268
|
-
auto format(const arg_join<It, Char>& value, FormatContext& ctx)
|
3357
|
+
auto format(const arg_join<It, Sentinel, Char>& value, FormatContext& ctx)
|
3269
3358
|
-> decltype(ctx.out()) {
|
3270
3359
|
using base = formatter<typename std::iterator_traits<It>::value_type, Char>;
|
3271
3360
|
auto it = value.begin;
|
@@ -3286,13 +3375,13 @@ struct formatter<arg_join<It, Char>, Char>
|
|
3286
3375
|
Returns an object that formats the iterator range `[begin, end)` with elements
|
3287
3376
|
separated by `sep`.
|
3288
3377
|
*/
|
3289
|
-
template <typename It>
|
3290
|
-
arg_join<It, char> join(It begin,
|
3378
|
+
template <typename It, typename Sentinel>
|
3379
|
+
arg_join<It, Sentinel, char> join(It begin, Sentinel end, string_view sep) {
|
3291
3380
|
return {begin, end, sep};
|
3292
3381
|
}
|
3293
3382
|
|
3294
|
-
template <typename It>
|
3295
|
-
arg_join<It, wchar_t> join(It begin,
|
3383
|
+
template <typename It, typename Sentinel>
|
3384
|
+
arg_join<It, Sentinel, wchar_t> join(It begin, Sentinel end, wstring_view sep) {
|
3296
3385
|
return {begin, end, sep};
|
3297
3386
|
}
|
3298
3387
|
|
@@ -3313,14 +3402,15 @@ arg_join<It, wchar_t> join(It begin, It end, wstring_view sep) {
|
|
3313
3402
|
\endrst
|
3314
3403
|
*/
|
3315
3404
|
template <typename Range>
|
3316
|
-
arg_join<
|
3317
|
-
|
3405
|
+
arg_join<detail::iterator_t<const Range>, detail::sentinel_t<const Range>, char>
|
3406
|
+
join(const Range& range, string_view sep) {
|
3318
3407
|
return join(std::begin(range), std::end(range), sep);
|
3319
3408
|
}
|
3320
3409
|
|
3321
3410
|
template <typename Range>
|
3322
|
-
arg_join<
|
3323
|
-
|
3411
|
+
arg_join<detail::iterator_t<const Range>, detail::sentinel_t<const Range>,
|
3412
|
+
wchar_t>
|
3413
|
+
join(const Range& range, wstring_view sep) {
|
3324
3414
|
return join(std::begin(range), std::end(range), sep);
|
3325
3415
|
}
|
3326
3416
|
|
@@ -3335,8 +3425,21 @@ arg_join<internal::iterator_t<const Range>, wchar_t> join(const Range& range,
|
|
3335
3425
|
std::string answer = fmt::to_string(42);
|
3336
3426
|
\endrst
|
3337
3427
|
*/
|
3338
|
-
template <typename T
|
3339
|
-
|
3428
|
+
template <typename T, FMT_ENABLE_IF(!std::is_integral<T>::value)>
|
3429
|
+
inline std::string to_string(const T& value) {
|
3430
|
+
std::string result;
|
3431
|
+
detail::write<char>(std::back_inserter(result), value);
|
3432
|
+
return result;
|
3433
|
+
}
|
3434
|
+
|
3435
|
+
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
3436
|
+
inline std::string to_string(T value) {
|
3437
|
+
// The buffer should be large enough to store the number including the sign or
|
3438
|
+
// "false" for bool.
|
3439
|
+
constexpr int max_size = detail::digits10<T>() + 2;
|
3440
|
+
char buffer[max_size > 5 ? max_size : 5];
|
3441
|
+
char* begin = buffer;
|
3442
|
+
return std::string(begin, detail::write<char>(begin, value));
|
3340
3443
|
}
|
3341
3444
|
|
3342
3445
|
/**
|
@@ -3346,36 +3449,65 @@ template <typename T> inline std::wstring to_wstring(const T& value) {
|
|
3346
3449
|
return format(L"{}", value);
|
3347
3450
|
}
|
3348
3451
|
|
3349
|
-
template <typename Char,
|
3452
|
+
template <typename Char, size_t SIZE>
|
3350
3453
|
std::basic_string<Char> to_string(const basic_memory_buffer<Char, SIZE>& buf) {
|
3351
|
-
|
3454
|
+
auto size = buf.size();
|
3455
|
+
detail::assume(size < std::basic_string<Char>().max_size());
|
3456
|
+
return std::basic_string<Char>(buf.data(), size);
|
3352
3457
|
}
|
3353
3458
|
|
3354
3459
|
template <typename Char>
|
3355
|
-
typename buffer_context<Char>::iterator
|
3356
|
-
|
3460
|
+
typename buffer_context<Char>::iterator detail::vformat_to(
|
3461
|
+
detail::buffer<Char>& buf, basic_string_view<Char> format_str,
|
3357
3462
|
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
3358
|
-
using
|
3359
|
-
return vformat_to<
|
3360
|
-
|
3361
|
-
}
|
3463
|
+
using af = arg_formatter<typename buffer_context<Char>::iterator, Char>;
|
3464
|
+
return vformat_to<af>(std::back_inserter(buf), to_string_view(format_str),
|
3465
|
+
args);
|
3466
|
+
}
|
3467
|
+
|
3468
|
+
#ifndef FMT_HEADER_ONLY
|
3469
|
+
extern template format_context::iterator detail::vformat_to(
|
3470
|
+
detail::buffer<char>&, string_view, basic_format_args<format_context>);
|
3471
|
+
namespace detail {
|
3472
|
+
extern template FMT_API std::string grouping_impl<char>(locale_ref loc);
|
3473
|
+
extern template FMT_API std::string grouping_impl<wchar_t>(locale_ref loc);
|
3474
|
+
extern template FMT_API char thousands_sep_impl<char>(locale_ref loc);
|
3475
|
+
extern template FMT_API wchar_t thousands_sep_impl<wchar_t>(locale_ref loc);
|
3476
|
+
extern template FMT_API char decimal_point_impl(locale_ref loc);
|
3477
|
+
extern template FMT_API wchar_t decimal_point_impl(locale_ref loc);
|
3478
|
+
extern template int format_float<double>(double value, int precision,
|
3479
|
+
float_specs specs, buffer<char>& buf);
|
3480
|
+
extern template int format_float<long double>(long double value, int precision,
|
3481
|
+
float_specs specs,
|
3482
|
+
buffer<char>& buf);
|
3483
|
+
int snprintf_float(float value, int precision, float_specs specs,
|
3484
|
+
buffer<char>& buf) = delete;
|
3485
|
+
extern template int snprintf_float<double>(double value, int precision,
|
3486
|
+
float_specs specs,
|
3487
|
+
buffer<char>& buf);
|
3488
|
+
extern template int snprintf_float<long double>(long double value,
|
3489
|
+
int precision,
|
3490
|
+
float_specs specs,
|
3491
|
+
buffer<char>& buf);
|
3492
|
+
} // namespace detail
|
3493
|
+
#endif
|
3362
3494
|
|
3363
3495
|
template <typename S, typename Char = char_t<S>,
|
3364
|
-
FMT_ENABLE_IF(
|
3365
|
-
inline typename
|
3366
|
-
|
3367
|
-
basic_format_args<
|
3368
|
-
return
|
3496
|
+
FMT_ENABLE_IF(detail::is_string<S>::value)>
|
3497
|
+
inline typename FMT_BUFFER_CONTEXT(Char)::iterator vformat_to(
|
3498
|
+
detail::buffer<Char>& buf, const S& format_str,
|
3499
|
+
basic_format_args<FMT_BUFFER_CONTEXT(type_identity_t<Char>)> args) {
|
3500
|
+
return detail::vformat_to(buf, to_string_view(format_str), args);
|
3369
3501
|
}
|
3370
3502
|
|
3371
|
-
template <typename S, typename... Args,
|
3372
|
-
typename Char = enable_if_t<
|
3503
|
+
template <typename S, typename... Args, size_t SIZE = inline_buffer_size,
|
3504
|
+
typename Char = enable_if_t<detail::is_string<S>::value, char_t<S>>>
|
3373
3505
|
inline typename buffer_context<Char>::iterator format_to(
|
3374
3506
|
basic_memory_buffer<Char, SIZE>& buf, const S& format_str, Args&&... args) {
|
3375
|
-
|
3507
|
+
detail::check_format_string<Args...>(format_str);
|
3376
3508
|
using context = buffer_context<Char>;
|
3377
|
-
return
|
3378
|
-
|
3509
|
+
return detail::vformat_to(buf, to_string_view(format_str),
|
3510
|
+
make_format_args<context>(args...));
|
3379
3511
|
}
|
3380
3512
|
|
3381
3513
|
template <typename OutputIt, typename Char = char>
|
@@ -3384,16 +3516,15 @@ using format_context_t = basic_format_context<OutputIt, Char>;
|
|
3384
3516
|
template <typename OutputIt, typename Char = char>
|
3385
3517
|
using format_args_t = basic_format_args<format_context_t<OutputIt, Char>>;
|
3386
3518
|
|
3387
|
-
template <
|
3388
|
-
|
3389
|
-
|
3390
|
-
|
3519
|
+
template <
|
3520
|
+
typename S, typename OutputIt, typename... Args,
|
3521
|
+
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt>::value &&
|
3522
|
+
!detail::is_contiguous_back_insert_iterator<OutputIt>::value)>
|
3391
3523
|
inline OutputIt vformat_to(
|
3392
3524
|
OutputIt out, const S& format_str,
|
3393
3525
|
format_args_t<type_identity_t<OutputIt>, char_t<S>> args) {
|
3394
|
-
using
|
3395
|
-
return vformat_to<
|
3396
|
-
to_string_view(format_str), args);
|
3526
|
+
using af = detail::arg_formatter<OutputIt, char_t<S>>;
|
3527
|
+
return vformat_to<af>(out, to_string_view(format_str), args);
|
3397
3528
|
}
|
3398
3529
|
|
3399
3530
|
/**
|
@@ -3409,11 +3540,11 @@ inline OutputIt vformat_to(
|
|
3409
3540
|
*/
|
3410
3541
|
template <typename OutputIt, typename S, typename... Args,
|
3411
3542
|
FMT_ENABLE_IF(
|
3412
|
-
|
3413
|
-
!
|
3414
|
-
|
3543
|
+
detail::is_output_iterator<OutputIt>::value &&
|
3544
|
+
!detail::is_contiguous_back_insert_iterator<OutputIt>::value &&
|
3545
|
+
detail::is_string<S>::value)>
|
3415
3546
|
inline OutputIt format_to(OutputIt out, const S& format_str, Args&&... args) {
|
3416
|
-
|
3547
|
+
detail::check_format_string<Args...>(format_str);
|
3417
3548
|
using context = format_context_t<OutputIt, char_t<S>>;
|
3418
3549
|
return vformat_to(out, to_string_view(format_str),
|
3419
3550
|
make_format_args<context>(args...));
|
@@ -3423,12 +3554,12 @@ template <typename OutputIt> struct format_to_n_result {
|
|
3423
3554
|
/** Iterator past the end of the output range. */
|
3424
3555
|
OutputIt out;
|
3425
3556
|
/** Total (not truncated) output size. */
|
3426
|
-
|
3557
|
+
size_t size;
|
3427
3558
|
};
|
3428
3559
|
|
3429
3560
|
template <typename OutputIt, typename Char = typename OutputIt::value_type>
|
3430
3561
|
using format_to_n_context =
|
3431
|
-
format_context_t<
|
3562
|
+
format_context_t<detail::truncating_iterator<OutputIt>, Char>;
|
3432
3563
|
|
3433
3564
|
template <typename OutputIt, typename Char = typename OutputIt::value_type>
|
3434
3565
|
using format_to_n_args = basic_format_args<format_to_n_context<OutputIt, Char>>;
|
@@ -3441,11 +3572,11 @@ make_format_to_n_args(const Args&... args) {
|
|
3441
3572
|
}
|
3442
3573
|
|
3443
3574
|
template <typename OutputIt, typename Char, typename... Args,
|
3444
|
-
FMT_ENABLE_IF(
|
3575
|
+
FMT_ENABLE_IF(detail::is_output_iterator<OutputIt>::value)>
|
3445
3576
|
inline format_to_n_result<OutputIt> vformat_to_n(
|
3446
|
-
OutputIt out,
|
3577
|
+
OutputIt out, size_t n, basic_string_view<Char> format_str,
|
3447
3578
|
format_to_n_args<type_identity_t<OutputIt>, type_identity_t<Char>> args) {
|
3448
|
-
auto it = vformat_to(
|
3579
|
+
auto it = vformat_to(detail::truncating_iterator<OutputIt>(out, n),
|
3449
3580
|
format_str, args);
|
3450
3581
|
return {it.base(), it.count()};
|
3451
3582
|
}
|
@@ -3458,23 +3589,23 @@ inline format_to_n_result<OutputIt> vformat_to_n(
|
|
3458
3589
|
\endrst
|
3459
3590
|
*/
|
3460
3591
|
template <typename OutputIt, typename S, typename... Args,
|
3461
|
-
FMT_ENABLE_IF(
|
3462
|
-
|
3463
|
-
inline format_to_n_result<OutputIt> format_to_n(OutputIt out,
|
3592
|
+
FMT_ENABLE_IF(detail::is_string<S>::value&&
|
3593
|
+
detail::is_output_iterator<OutputIt>::value)>
|
3594
|
+
inline format_to_n_result<OutputIt> format_to_n(OutputIt out, size_t n,
|
3464
3595
|
const S& format_str,
|
3465
3596
|
const Args&... args) {
|
3466
|
-
|
3597
|
+
detail::check_format_string<Args...>(format_str);
|
3467
3598
|
using context = format_to_n_context<OutputIt, char_t<S>>;
|
3468
3599
|
return vformat_to_n(out, n, to_string_view(format_str),
|
3469
3600
|
make_format_args<context>(args...));
|
3470
3601
|
}
|
3471
3602
|
|
3472
|
-
template <typename Char
|
3473
|
-
|
3603
|
+
template <typename Char, enable_if_t<(!std::is_same<Char, char>::value), int>>
|
3604
|
+
std::basic_string<Char> detail::vformat(
|
3474
3605
|
basic_string_view<Char> format_str,
|
3475
3606
|
basic_format_args<buffer_context<type_identity_t<Char>>> args) {
|
3476
3607
|
basic_memory_buffer<Char> buffer;
|
3477
|
-
|
3608
|
+
detail::vformat_to(buffer, format_str, args);
|
3478
3609
|
return to_string(buffer);
|
3479
3610
|
}
|
3480
3611
|
|
@@ -3483,15 +3614,15 @@ inline std::basic_string<Char> internal::vformat(
|
|
3483
3614
|
``format(format_str, args...)``.
|
3484
3615
|
*/
|
3485
3616
|
template <typename... Args>
|
3486
|
-
inline
|
3487
|
-
return format_to(
|
3617
|
+
inline size_t formatted_size(string_view format_str, const Args&... args) {
|
3618
|
+
return format_to(detail::counting_iterator(), format_str, args...).count();
|
3488
3619
|
}
|
3489
3620
|
|
3490
3621
|
template <typename Char, FMT_ENABLE_IF(std::is_same<Char, wchar_t>::value)>
|
3491
3622
|
void vprint(std::FILE* f, basic_string_view<Char> format_str,
|
3492
3623
|
wformat_args args) {
|
3493
3624
|
wmemory_buffer buffer;
|
3494
|
-
|
3625
|
+
detail::vformat_to(buffer, format_str, args);
|
3495
3626
|
buffer.push_back(L'\0');
|
3496
3627
|
if (std::fputws(buffer.data(), f) == -1)
|
3497
3628
|
FMT_THROW(system_error(errno, "cannot write to file"));
|
@@ -3503,18 +3634,15 @@ void vprint(basic_string_view<Char> format_str, wformat_args args) {
|
|
3503
3634
|
}
|
3504
3635
|
|
3505
3636
|
#if FMT_USE_USER_DEFINED_LITERALS
|
3506
|
-
namespace
|
3637
|
+
namespace detail {
|
3507
3638
|
|
3508
3639
|
# if FMT_USE_UDL_TEMPLATE
|
3509
3640
|
template <typename Char, Char... CHARS> class udl_formatter {
|
3510
3641
|
public:
|
3511
3642
|
template <typename... Args>
|
3512
3643
|
std::basic_string<Char> operator()(Args&&... args) const {
|
3513
|
-
FMT_CONSTEXPR_DECL Char s[] = {CHARS..., '\0'};
|
3514
|
-
|
3515
|
-
do_check_format_string<Char, error_handler, remove_cvref_t<Args>...>(
|
3516
|
-
basic_string_view<Char>(s, sizeof...(CHARS)));
|
3517
|
-
(void)invalid_format;
|
3644
|
+
static FMT_CONSTEXPR_DECL Char s[] = {CHARS..., '\0'};
|
3645
|
+
check_format_string<remove_cvref_t<Args>...>(FMT_STRING(s));
|
3518
3646
|
return format(s, std::forward<Args>(args)...);
|
3519
3647
|
}
|
3520
3648
|
};
|
@@ -3530,39 +3658,23 @@ template <typename Char> struct udl_formatter {
|
|
3530
3658
|
# endif // FMT_USE_UDL_TEMPLATE
|
3531
3659
|
|
3532
3660
|
template <typename Char> struct udl_arg {
|
3533
|
-
|
3661
|
+
const Char* str;
|
3534
3662
|
|
3535
|
-
template <typename T> named_arg<
|
3663
|
+
template <typename T> named_arg<Char, T> operator=(T&& value) const {
|
3536
3664
|
return {str, std::forward<T>(value)};
|
3537
3665
|
}
|
3538
3666
|
};
|
3539
|
-
|
3540
|
-
// Converts string literals to basic_string_view.
|
3541
|
-
template <typename Char, size_t N>
|
3542
|
-
FMT_CONSTEXPR basic_string_view<Char> compile_string_to_view(
|
3543
|
-
const Char (&s)[N]) {
|
3544
|
-
// Remove trailing null character if needed. Won't be present if this is used
|
3545
|
-
// with raw character array (i.e. not defined as a string).
|
3546
|
-
return {s,
|
3547
|
-
N - ((std::char_traits<Char>::to_int_type(s[N - 1]) == 0) ? 1 : 0)};
|
3548
|
-
}
|
3549
|
-
|
3550
|
-
// Converts string_view to basic_string_view.
|
3551
|
-
template <typename Char>
|
3552
|
-
FMT_CONSTEXPR basic_string_view<Char> compile_string_to_view(
|
3553
|
-
const std_string_view<Char>& s) {
|
3554
|
-
return {s.data(), s.size()};
|
3555
|
-
}
|
3556
|
-
} // namespace internal
|
3667
|
+
} // namespace detail
|
3557
3668
|
|
3558
3669
|
inline namespace literals {
|
3559
3670
|
# if FMT_USE_UDL_TEMPLATE
|
3560
3671
|
# pragma GCC diagnostic push
|
3672
|
+
# pragma GCC diagnostic ignored "-Wpedantic"
|
3561
3673
|
# if FMT_CLANG_VERSION
|
3562
3674
|
# pragma GCC diagnostic ignored "-Wgnu-string-literal-operator-template"
|
3563
3675
|
# endif
|
3564
3676
|
template <typename Char, Char... CHARS>
|
3565
|
-
FMT_CONSTEXPR
|
3677
|
+
FMT_CONSTEXPR detail::udl_formatter<Char, CHARS...> operator""_format() {
|
3566
3678
|
return {};
|
3567
3679
|
}
|
3568
3680
|
# pragma GCC diagnostic pop
|
@@ -3577,12 +3689,12 @@ FMT_CONSTEXPR internal::udl_formatter<Char, CHARS...> operator""_format() {
|
|
3577
3689
|
std::string message = "The answer is {}"_format(42);
|
3578
3690
|
\endrst
|
3579
3691
|
*/
|
3580
|
-
FMT_CONSTEXPR
|
3581
|
-
|
3692
|
+
FMT_CONSTEXPR detail::udl_formatter<char> operator"" _format(const char* s,
|
3693
|
+
size_t n) {
|
3582
3694
|
return {{s, n}};
|
3583
3695
|
}
|
3584
|
-
FMT_CONSTEXPR
|
3585
|
-
const wchar_t* s,
|
3696
|
+
FMT_CONSTEXPR detail::udl_formatter<wchar_t> operator"" _format(
|
3697
|
+
const wchar_t* s, size_t n) {
|
3586
3698
|
return {{s, n}};
|
3587
3699
|
}
|
3588
3700
|
# endif // FMT_USE_UDL_TEMPLATE
|
@@ -3597,47 +3709,16 @@ FMT_CONSTEXPR internal::udl_formatter<wchar_t> operator"" _format(
|
|
3597
3709
|
fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23);
|
3598
3710
|
\endrst
|
3599
3711
|
*/
|
3600
|
-
FMT_CONSTEXPR
|
3601
|
-
|
3602
|
-
return {{s, n}};
|
3712
|
+
FMT_CONSTEXPR detail::udl_arg<char> operator"" _a(const char* s, size_t) {
|
3713
|
+
return {s};
|
3603
3714
|
}
|
3604
|
-
FMT_CONSTEXPR
|
3605
|
-
|
3606
|
-
return {{s, n}};
|
3715
|
+
FMT_CONSTEXPR detail::udl_arg<wchar_t> operator"" _a(const wchar_t* s, size_t) {
|
3716
|
+
return {s};
|
3607
3717
|
}
|
3608
3718
|
} // namespace literals
|
3609
3719
|
#endif // FMT_USE_USER_DEFINED_LITERALS
|
3610
3720
|
FMT_END_NAMESPACE
|
3611
3721
|
|
3612
|
-
#define FMT_STRING_IMPL(s, ...) \
|
3613
|
-
[] { \
|
3614
|
-
/* Use a macro-like name to avoid shadowing warnings. */ \
|
3615
|
-
struct FMT_COMPILE_STRING : fmt::compile_string { \
|
3616
|
-
using char_type = fmt::remove_cvref_t<decltype(s[0])>; \
|
3617
|
-
FMT_MAYBE_UNUSED __VA_ARGS__ FMT_CONSTEXPR \
|
3618
|
-
operator fmt::basic_string_view<char_type>() const { \
|
3619
|
-
return fmt::internal::compile_string_to_view<char_type>(s); \
|
3620
|
-
} \
|
3621
|
-
}; \
|
3622
|
-
return FMT_COMPILE_STRING(); \
|
3623
|
-
}()
|
3624
|
-
|
3625
|
-
/**
|
3626
|
-
\rst
|
3627
|
-
Constructs a compile-time format string from a string literal *s*.
|
3628
|
-
|
3629
|
-
**Example**::
|
3630
|
-
|
3631
|
-
// A compile-time error because 'd' is an invalid specifier for strings.
|
3632
|
-
std::string s = format(FMT_STRING("{:d}"), "foo");
|
3633
|
-
\endrst
|
3634
|
-
*/
|
3635
|
-
#define FMT_STRING(s) FMT_STRING_IMPL(s, )
|
3636
|
-
|
3637
|
-
#if defined(FMT_STRING_ALIAS) && FMT_STRING_ALIAS
|
3638
|
-
# define fmt(s) FMT_STRING_IMPL(s, [[deprecated]])
|
3639
|
-
#endif
|
3640
|
-
|
3641
3722
|
#ifdef FMT_HEADER_ONLY
|
3642
3723
|
# define FMT_FUNC inline
|
3643
3724
|
# include "format-inl.h"
|