From e3f1e1dc730244a4d2ec025e2815a09558164504 Mon Sep 17 00:00:00 2001 From: Joe Morton Date: Tue, 5 Sep 2023 08:52:10 +0100 Subject: [PATCH] Updated spdlog, Minor changes --- Editor/Source/ImGUIConsoleSink.h | 2 +- Editor/Source/InspectorPanel.cpp | 12 +- .../Shaders/CompiledSPV/ForwardPBR.frag.spv | Bin 48644 -> 48640 bytes .../CompiledSPV/Headers/ForwardPBRfragspv.hpp | 2934 +++++++++-------- Lumos/Assets/Shaders/ForwardPBR.frag | 2 + Lumos/Assets/Shaders/PBR.glslh | 4 +- Lumos/External/spdlog/.clang-format | 109 + Lumos/External/spdlog/.clang-tidy | 54 + Lumos/External/spdlog/CMakeLists.txt | 360 ++ Lumos/External/spdlog/INSTALL | 24 + Lumos/External/spdlog/README.md | 168 +- Lumos/External/spdlog/appveyor.yml | 89 + Lumos/External/spdlog/bench/CMakeLists.txt | 41 + Lumos/External/spdlog/bench/async_bench.cpp | 186 ++ Lumos/External/spdlog/bench/bench.cpp | 248 ++ .../External/spdlog/bench/formatter-bench.cpp | 80 + Lumos/External/spdlog/bench/latency.cpp | 189 ++ Lumos/External/spdlog/bench/utils.h | 34 + Lumos/External/spdlog/cmake/ide.cmake | 18 + Lumos/External/spdlog/cmake/pch.h.in | 258 ++ Lumos/External/spdlog/cmake/spdlog.pc.in | 13 + .../spdlog/cmake/spdlogConfig.cmake.in | 20 + Lumos/External/spdlog/cmake/utils.cmake | 62 + Lumos/External/spdlog/cmake/version.rc.in | 42 + Lumos/External/spdlog/example/CMakeLists.txt | 23 + Lumos/External/spdlog/example/example.cpp | 398 +++ Lumos/External/spdlog/include/spdlog/async.h | 14 +- .../spdlog/include/spdlog/async_logger-inl.h | 38 +- .../spdlog/include/spdlog/common-inl.h | 4 + Lumos/External/spdlog/include/spdlog/common.h | 206 +- .../include/spdlog/details/backtracer-inl.h | 6 + .../include/spdlog/details/backtracer.h | 1 + .../include/spdlog/details/circular_q.h | 5 + .../include/spdlog/details/file_helper-inl.h | 35 +- .../include/spdlog/details/file_helper.h | 5 +- .../include/spdlog/details/fmt_helper.h | 65 +- .../include/spdlog/details/mpmc_blocking_q.h | 32 +- .../include/spdlog/details/null_mutex.h | 4 - .../spdlog/include/spdlog/details/os-inl.h | 86 +- .../spdlog/include/spdlog/details/os.h | 8 +- .../spdlog/details/periodic_worker-inl.h | 21 - .../include/spdlog/details/periodic_worker.h | 22 +- .../include/spdlog/details/registry-inl.h | 18 +- .../spdlog/include/spdlog/details/registry.h | 12 +- .../spdlog/details/tcp_client-windows.h | 43 +- .../include/spdlog/details/tcp_client.h | 8 +- .../include/spdlog/details/thread_pool-inl.h | 24 +- .../include/spdlog/details/thread_pool.h | 5 +- .../spdlog/details/udp_client-windows.h | 113 + .../include/spdlog/details/udp_client.h | 94 + .../spdlog/include/spdlog/fmt/bin_to_hex.h | 72 +- .../spdlog/include/spdlog/fmt/bundled/args.h | 10 +- .../include/spdlog/fmt/bundled/chrono.h | 1209 +++++-- .../spdlog/include/spdlog/fmt/bundled/color.h | 244 +- .../include/spdlog/fmt/bundled/compile.h | 136 +- .../spdlog/include/spdlog/fmt/bundled/core.h | 1415 +++++--- .../spdlog/fmt/bundled/fmt.license.rst | 27 + .../include/spdlog/fmt/bundled/format-inl.h | 2523 +++++--------- .../include/spdlog/fmt/bundled/format.h | 2691 +++++++++++---- .../spdlog/include/spdlog/fmt/bundled/os.h | 147 +- .../include/spdlog/fmt/bundled/ostream.h | 246 +- .../include/spdlog/fmt/bundled/printf.h | 50 +- .../include/spdlog/fmt/bundled/ranges.h | 528 ++- .../spdlog/include/spdlog/fmt/bundled/std.h | 171 + .../spdlog/include/spdlog/fmt/bundled/xchar.h | 69 +- .../spdlog/include/spdlog/fmt/chrono.h | 16 +- .../spdlog/include/spdlog/fmt/compile.h | 18 +- .../External/spdlog/include/spdlog/fmt/fmt.h | 8 +- .../External/spdlog/include/spdlog/fmt/ostr.h | 16 +- .../spdlog/include/spdlog/fmt/ranges.h | 22 + .../External/spdlog/include/spdlog/fmt/std.h | 23 + .../spdlog/include/spdlog/fmt/xchar.h | 18 +- Lumos/External/spdlog/include/spdlog/fwd.h | 4 + .../spdlog/include/spdlog/logger-inl.h | 10 +- Lumos/External/spdlog/include/spdlog/logger.h | 189 +- .../include/spdlog/pattern_formatter-inl.h | 53 +- .../spdlog/include/spdlog/pattern_formatter.h | 4 +- .../include/spdlog/sinks/android_sink.h | 39 +- .../include/spdlog/sinks/ansicolor_sink-inl.h | 18 +- .../spdlog/include/spdlog/sinks/base_sink.h | 4 +- .../spdlog/sinks/basic_file_sink-inl.h | 3 +- .../include/spdlog/sinks/basic_file_sink.h | 12 +- .../include/spdlog/sinks/callback_sink.h | 61 + .../include/spdlog/sinks/daily_file_sink.h | 49 +- .../spdlog/include/spdlog/sinks/dist_sink.h | 22 +- .../include/spdlog/sinks/dup_filter_sink.h | 8 +- .../include/spdlog/sinks/hourly_file_sink.h | 26 +- .../spdlog/include/spdlog/sinks/kafka_sink.h | 133 + .../spdlog/include/spdlog/sinks/mongo_sink.h | 27 +- .../spdlog/include/spdlog/sinks/msvc_sink.h | 27 +- .../spdlog/include/spdlog/sinks/qt_sinks.h | 300 +- .../include/spdlog/sinks/ringbuffer_sink.h | 2 +- .../spdlog/sinks/rotating_file_sink-inl.h | 33 +- .../include/spdlog/sinks/rotating_file_sink.h | 17 +- .../include/spdlog/sinks/stdout_sinks-inl.h | 7 +- .../include/spdlog/sinks/systemd_sink.h | 51 +- .../spdlog/include/spdlog/sinks/udp_sink.h | 74 + .../include/spdlog/sinks/win_eventlog_sink.h | 45 +- .../include/spdlog/sinks/wincolor_sink-inl.h | 4 +- .../spdlog/include/spdlog/spdlog-inl.h | 10 +- Lumos/External/spdlog/include/spdlog/spdlog.h | 104 +- .../spdlog/include/spdlog/stopwatch.h | 16 +- .../External/spdlog/include/spdlog/tweakme.h | 22 +- .../External/spdlog/include/spdlog/version.h | 2 +- .../spdlog/logos/jetbrains-variant-4.svg | 43 + .../External/spdlog/scripts/ci_setup_clang.sh | 12 + .../spdlog/scripts/extract_version.py | 17 + Lumos/External/spdlog/scripts/format.sh | 16 + Lumos/External/spdlog/src/async.cpp | 2 - .../spdlog/src/bundled_fmtlib_format.cpp | 52 + Lumos/External/spdlog/src/fmt.cpp | 68 - Lumos/External/spdlog/tests/CMakeLists.txt | 86 + Lumos/External/spdlog/tests/includes.h | 36 + Lumos/External/spdlog/tests/main.cpp | 10 + Lumos/External/spdlog/tests/test_async.cpp | 198 ++ .../External/spdlog/tests/test_backtrace.cpp | 78 + .../External/spdlog/tests/test_bin_to_hex.cpp | 93 + Lumos/External/spdlog/tests/test_cfg.cpp | 183 + .../External/spdlog/tests/test_create_dir.cpp | 75 + .../spdlog/tests/test_custom_callbacks.cpp | 34 + .../spdlog/tests/test_daily_logger.cpp | 183 + .../External/spdlog/tests/test_dup_filter.cpp | 90 + Lumos/External/spdlog/tests/test_errors.cpp | 124 + Lumos/External/spdlog/tests/test_eventlog.cpp | 71 + .../spdlog/tests/test_file_helper.cpp | 168 + .../spdlog/tests/test_file_logging.cpp | 109 + .../External/spdlog/tests/test_fmt_helper.cpp | 90 + Lumos/External/spdlog/tests/test_macros.cpp | 54 + Lumos/External/spdlog/tests/test_misc.cpp | 180 + Lumos/External/spdlog/tests/test_mpmc_q.cpp | 126 + .../spdlog/tests/test_pattern_formatter.cpp | 501 +++ Lumos/External/spdlog/tests/test_registry.cpp | 116 + Lumos/External/spdlog/tests/test_sink.h | 79 + .../External/spdlog/tests/test_stdout_api.cpp | 98 + .../External/spdlog/tests/test_stopwatch.cpp | 44 + Lumos/External/spdlog/tests/test_systemd.cpp | 15 + .../External/spdlog/tests/test_time_point.cpp | 36 + Lumos/External/spdlog/tests/utils.cpp | 127 + Lumos/External/spdlog/tests/utils.h | 18 + Lumos/Source/Lumos/Core/CommandLine.h | 2 +- .../Lumos/Core/OS/Allocators/PoolAllocator.h | 97 + Lumos/Source/Lumos/Core/OS/Memory.h | 93 - Lumos/Source/Lumos/Core/OS/Window.h | 3 + Lumos/Source/Lumos/Graphics/Camera/Camera.cpp | 12 +- .../Lumos/Graphics/ModelLoader/GLTFLoader.cpp | 4 +- Lumos/Source/Lumos/Graphics/RHI/Definitions.h | 2 + Lumos/Source/Lumos/Graphics/RHI/Renderer.cpp | 3 + Lumos/Source/Lumos/Graphics/RHI/Renderer.h | 5 +- .../Lumos/Graphics/Renderers/RenderPasses.h | 3 + Lumos/Source/Lumos/ImGui/ImGuiUtilities.cpp | 6 +- Lumos/Source/Lumos/Maths/Frustum.cpp | 10 +- Lumos/Source/Lumos/Maths/Frustum.h | 4 +- .../LumosPhysicsEngine/LumosPhysicsEngine.h | 3 +- .../Narrowphase/CollisionDetection.cpp | 2 +- .../Lumos/Platform/OpenGL/GLContext.cpp | 6 +- .../Source/Lumos/Platform/Vulkan/VKShader.cpp | 2 +- .../Scene/Component/RigidBody3DComponent.cpp | 6 + .../Scene/Component/RigidBody3DComponent.h | 3 +- .../Source/Lumos/Scripting/Lua/LuaManager.cpp | 7 +- .../Source/Lumos/Scripting/Lua/PhysicsLua.cpp | 9 + Lumos/Source/Precompiled.h | 7 + README.md | 11 +- Resources/Screenshot 2023-09-04 100048.png | Bin 0 -> 953503 bytes 163 files changed, 14804 insertions(+), 6002 deletions(-) create mode 100644 Lumos/External/spdlog/.clang-format create mode 100644 Lumos/External/spdlog/.clang-tidy create mode 100644 Lumos/External/spdlog/CMakeLists.txt create mode 100644 Lumos/External/spdlog/INSTALL create mode 100644 Lumos/External/spdlog/appveyor.yml create mode 100644 Lumos/External/spdlog/bench/CMakeLists.txt create mode 100644 Lumos/External/spdlog/bench/async_bench.cpp create mode 100644 Lumos/External/spdlog/bench/bench.cpp create mode 100644 Lumos/External/spdlog/bench/formatter-bench.cpp create mode 100644 Lumos/External/spdlog/bench/latency.cpp create mode 100644 Lumos/External/spdlog/bench/utils.h create mode 100644 Lumos/External/spdlog/cmake/ide.cmake create mode 100644 Lumos/External/spdlog/cmake/pch.h.in create mode 100644 Lumos/External/spdlog/cmake/spdlog.pc.in create mode 100644 Lumos/External/spdlog/cmake/spdlogConfig.cmake.in create mode 100644 Lumos/External/spdlog/cmake/utils.cmake create mode 100644 Lumos/External/spdlog/cmake/version.rc.in create mode 100644 Lumos/External/spdlog/example/CMakeLists.txt create mode 100644 Lumos/External/spdlog/example/example.cpp create mode 100644 Lumos/External/spdlog/include/spdlog/details/udp_client-windows.h create mode 100644 Lumos/External/spdlog/include/spdlog/details/udp_client.h create mode 100644 Lumos/External/spdlog/include/spdlog/fmt/bundled/fmt.license.rst create mode 100644 Lumos/External/spdlog/include/spdlog/fmt/bundled/std.h create mode 100644 Lumos/External/spdlog/include/spdlog/fmt/ranges.h create mode 100644 Lumos/External/spdlog/include/spdlog/fmt/std.h create mode 100644 Lumos/External/spdlog/include/spdlog/sinks/callback_sink.h create mode 100644 Lumos/External/spdlog/include/spdlog/sinks/kafka_sink.h create mode 100644 Lumos/External/spdlog/include/spdlog/sinks/udp_sink.h create mode 100644 Lumos/External/spdlog/logos/jetbrains-variant-4.svg create mode 100644 Lumos/External/spdlog/scripts/ci_setup_clang.sh create mode 100644 Lumos/External/spdlog/scripts/extract_version.py create mode 100644 Lumos/External/spdlog/scripts/format.sh create mode 100644 Lumos/External/spdlog/src/bundled_fmtlib_format.cpp delete mode 100644 Lumos/External/spdlog/src/fmt.cpp create mode 100644 Lumos/External/spdlog/tests/CMakeLists.txt create mode 100644 Lumos/External/spdlog/tests/includes.h create mode 100644 Lumos/External/spdlog/tests/main.cpp create mode 100644 Lumos/External/spdlog/tests/test_async.cpp create mode 100644 Lumos/External/spdlog/tests/test_backtrace.cpp create mode 100644 Lumos/External/spdlog/tests/test_bin_to_hex.cpp create mode 100644 Lumos/External/spdlog/tests/test_cfg.cpp create mode 100644 Lumos/External/spdlog/tests/test_create_dir.cpp create mode 100644 Lumos/External/spdlog/tests/test_custom_callbacks.cpp create mode 100644 Lumos/External/spdlog/tests/test_daily_logger.cpp create mode 100644 Lumos/External/spdlog/tests/test_dup_filter.cpp create mode 100644 Lumos/External/spdlog/tests/test_errors.cpp create mode 100644 Lumos/External/spdlog/tests/test_eventlog.cpp create mode 100644 Lumos/External/spdlog/tests/test_file_helper.cpp create mode 100644 Lumos/External/spdlog/tests/test_file_logging.cpp create mode 100644 Lumos/External/spdlog/tests/test_fmt_helper.cpp create mode 100644 Lumos/External/spdlog/tests/test_macros.cpp create mode 100644 Lumos/External/spdlog/tests/test_misc.cpp create mode 100644 Lumos/External/spdlog/tests/test_mpmc_q.cpp create mode 100644 Lumos/External/spdlog/tests/test_pattern_formatter.cpp create mode 100644 Lumos/External/spdlog/tests/test_registry.cpp create mode 100644 Lumos/External/spdlog/tests/test_sink.h create mode 100644 Lumos/External/spdlog/tests/test_stdout_api.cpp create mode 100644 Lumos/External/spdlog/tests/test_stopwatch.cpp create mode 100644 Lumos/External/spdlog/tests/test_systemd.cpp create mode 100644 Lumos/External/spdlog/tests/test_time_point.cpp create mode 100644 Lumos/External/spdlog/tests/utils.cpp create mode 100644 Lumos/External/spdlog/tests/utils.h create mode 100644 Lumos/Source/Lumos/Core/OS/Allocators/PoolAllocator.h create mode 100644 Resources/Screenshot 2023-09-04 100048.png diff --git a/Editor/Source/ImGUIConsoleSink.h b/Editor/Source/ImGUIConsoleSink.h index d5bc8b2ca..878c89538 100644 --- a/Editor/Source/ImGUIConsoleSink.h +++ b/Editor/Source/ImGUIConsoleSink.h @@ -22,7 +22,7 @@ namespace Lumos spdlog::memory_buf_t formatted; spdlog::sinks::base_sink::formatter_->format(msg, formatted); std::string source = fmt::format("File : {0} | Function : {1} | Line : {2}", msg.source.filename, msg.source.funcname, msg.source.line); - const auto time = fmt::localtime(msg.time); + const auto time = fmt::localtime(std::chrono::system_clock::to_time_t(msg.time)); auto processed = fmt::format("{:%H:%M:%S}", time); auto message = CreateSharedPtr(fmt::to_string(formatted), GetMessageLevel(msg.level), source, static_cast(msg.thread_id), processed); diff --git a/Editor/Source/InspectorPanel.cpp b/Editor/Source/InspectorPanel.cpp index 204b0603f..df1c59886 100644 --- a/Editor/Source/InspectorPanel.cpp +++ b/Editor/Source/InspectorPanel.cpp @@ -794,13 +794,13 @@ end if(ImGuiUtilities::Property("Fov", fov, 1.0f, 120.0f)) camera.SetFOV(fov); - float near = camera.GetNear(); - if(ImGuiUtilities::Property("Near", near, 0.0f, 10.0f)) - camera.SetNear(near); + float n = camera.GetNear(); + if(ImGuiUtilities::Property("Near", n, 0.0f, 10.0f)) + camera.SetNear(n); - float far = camera.GetFar(); - if(ImGuiUtilities::Property("Far", far, 10.0f, 10000.0f)) - camera.SetFar(far); + float f = camera.GetFar(); + if(ImGuiUtilities::Property("Far", f, 10.0f, 10000.0f)) + camera.SetFar(f); float scale = camera.GetScale(); if(ImGuiUtilities::Property("Scale", scale, 0.0f, 1000.0f)) diff --git a/Lumos/Assets/Shaders/CompiledSPV/ForwardPBR.frag.spv b/Lumos/Assets/Shaders/CompiledSPV/ForwardPBR.frag.spv index a7e206bd84b3fc7bb91c10e3d9ff606efb4ddc92..40eeb66cd5474ff265898b184592742f7fe97712 100644 GIT binary patch delta 9132 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 R%{pondo~rX-;kF%?EeO>x)}ff diff --git a/Lumos/Assets/Shaders/CompiledSPV/Headers/ForwardPBRfragspv.hpp b/Lumos/Assets/Shaders/CompiledSPV/Headers/ForwardPBRfragspv.hpp index 5eb8c4fa8..c8c89c0b4 100644 --- a/Lumos/Assets/Shaders/CompiledSPV/Headers/ForwardPBRfragspv.hpp +++ b/Lumos/Assets/Shaders/CompiledSPV/Headers/ForwardPBRfragspv.hpp @@ -3,11 +3,11 @@ #include #include -constexpr uint32_t spirv_ForwardPBRfragspv_size = 48476; -constexpr std::array spirv_ForwardPBRfragspv = { - 0x07230203, 0x00010000, 0x000D000A, 0x000007C3, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, +constexpr uint32_t spirv_ForwardPBRfragspv_size = 48640; +constexpr std::array spirv_ForwardPBRfragspv = { + 0x07230203, 0x00010000, 0x000D000A, 0x000007C8, 0x00000000, 0x00020011, 0x00000001, 0x0006000B, 0x00000001, 0x4C534C47, 0x6474732E, 0x3035342E, 0x00000000, 0x0003000E, 0x00000000, 0x00000001, -0x0008000F, 0x00000004, 0x00000004, 0x6E69616D, 0x00000000, 0x000001FE, 0x0000059F, 0x00000666, +0x0008000F, 0x00000004, 0x00000004, 0x6E69616D, 0x00000000, 0x000001FC, 0x000005A0, 0x0000066C, 0x00030010, 0x00000004, 0x00000007, 0x00030003, 0x00000002, 0x000001C2, 0x00090004, 0x415F4C47, 0x735F4252, 0x72617065, 0x5F657461, 0x64616873, 0x6F5F7265, 0x63656A62, 0x00007374, 0x00090004, 0x415F4C47, 0x735F4252, 0x69646168, 0x6C5F676E, 0x75676E61, 0x5F656761, 0x70303234, 0x006B6361, @@ -59,1465 +59,1471 @@ constexpr std::array spirv_ForwardPBRfragspv = { 0x6465626C, 0x0000286F, 0x00060005, 0x00000073, 0x4D746547, 0x6C617465, 0x2863696C, 0x00000000, 0x00060005, 0x00000076, 0x52746547, 0x6867756F, 0x7373656E, 0x00000028, 0x00040005, 0x00000078, 0x41746547, 0x0000284F, 0x00070005, 0x0000007B, 0x45746547, 0x7373696D, 0x28657669, 0x3B336676, -0x00000000, 0x00040005, 0x0000007A, 0x65626C61, 0x00006F64, 0x00070005, 0x0000007D, 0x4E746547, -0x616D726F, 0x6F72466C, 0x70614D6D, 0x00000028, 0x00050005, 0x00000083, 0x73696F4E, 0x66762865, -0x00003B32, 0x00030005, 0x00000082, 0x00006F63, 0x00090005, 0x0000008B, 0x65676F56, 0x7369446C, -0x6D61536B, 0x28656C70, 0x693B3169, 0x31663B31, 0x0000003B, 0x00050005, 0x00000088, 0x706D6173, -0x6E49656C, 0x00786564, 0x00060005, 0x00000089, 0x706D6173, 0x4373656C, 0x746E756F, 0x00000000, -0x00030005, 0x0000008A, 0x00696870, 0x00090005, 0x00000091, 0x53746547, 0x6F646168, 0x61694277, -0x66762873, 0x66763B33, 0x31693B33, 0x0000003B, 0x00060005, 0x0000008E, 0x6867696C, 0x72694474, -0x69746365, 0x00006E6F, 0x00040005, 0x0000008F, 0x6D726F6E, 0x00006C61, 0x00050005, 0x00000090, -0x64616873, 0x6E49776F, 0x00786564, 0x00100005, 0x0000009E, 0x53464350, 0x6F646168, 0x72694477, -0x69746365, 0x6C616E6F, 0x6867694C, 0x41732874, 0x763B3132, 0x663B3466, 0x66763B31, 0x66763B33, -0x66763B33, 0x31693B33, 0x0000003B, 0x00050005, 0x00000097, 0x64616873, 0x614D776F, 0x00000070, -0x00060005, 0x00000098, 0x64616873, 0x6F43776F, 0x7364726F, 0x00000000, 0x00050005, 0x00000099, -0x61527675, 0x73756964, 0x00000000, 0x00060005, 0x0000009A, 0x6867696C, 0x72694474, 0x69746365, -0x00006E6F, 0x00040005, 0x0000009B, 0x6D726F6E, 0x00006C61, 0x00040005, 0x0000009C, 0x6F507377, -0x00000073, 0x00060005, 0x0000009D, 0x63736163, 0x49656461, 0x7865646E, 0x00000000, 0x00090005, -0x000000A2, 0x636C6143, 0x74616C75, 0x73614365, 0x65646163, 0x65646E49, 0x66762878, 0x00003B33, -0x00040005, 0x000000A1, 0x6F507377, 0x00000073, 0x000A0005, 0x000000A9, 0x636C6143, 0x74616C75, -0x61685365, 0x28776F64, 0x3B336676, 0x763B3169, 0x763B3366, 0x003B3366, 0x00040005, 0x000000A5, -0x6F507377, 0x00000073, 0x00060005, 0x000000A6, 0x63736163, 0x49656461, 0x7865646E, 0x00000000, -0x00060005, 0x000000A7, 0x6867696C, 0x72694474, 0x69746365, 0x00006E6F, 0x00040005, 0x000000A8, -0x6D726F6E, 0x00006C61, 0x00050005, 0x000000AB, 0x6574614D, 0x6C616972, 0x00000000, 0x00050006, -0x000000AB, 0x00000000, 0x65626C41, 0x00006F64, 0x00060006, 0x000000AB, 0x00000001, 0x6174654D, -0x63696C6C, 0x00000000, 0x00060006, 0x000000AB, 0x00000002, 0x67756F52, 0x73656E68, 0x00000073, -0x00080006, 0x000000AB, 0x00000003, 0x63726550, 0x75747065, 0x6F526C61, 0x6E686775, 0x00737365, -0x00060006, 0x000000AB, 0x00000004, 0x6C666552, 0x61746365, 0x0065636E, 0x00060006, 0x000000AB, -0x00000005, 0x73696D45, 0x65766973, 0x00000000, 0x00050006, 0x000000AB, 0x00000006, 0x6D726F4E, -0x00006C61, 0x00040006, 0x000000AB, 0x00000007, 0x00004F41, 0x00050006, 0x000000AB, 0x00000008, -0x77656956, 0x00000000, 0x00050006, 0x000000AB, 0x00000009, 0x746F444E, 0x00000056, 0x00040006, -0x000000AB, 0x0000000A, 0x00003046, 0x00080006, 0x000000AB, 0x0000000B, 0x72656E45, 0x6F437967, -0x6E65706D, 0x69746173, 0x00006E6F, 0x00040006, 0x000000AB, 0x0000000C, 0x00676664, 0x00040005, -0x000000AC, 0x6867694C, 0x00000074, 0x00050006, 0x000000AC, 0x00000000, 0x6F6C6F63, 0x00007275, -0x00060006, 0x000000AC, 0x00000001, 0x69736F70, 0x6E6F6974, 0x00000000, 0x00060006, 0x000000AC, -0x00000002, 0x65726964, 0x6F697463, 0x0000006E, 0x00060006, 0x000000AC, 0x00000003, 0x65746E69, -0x7469736E, 0x00000079, 0x00050006, 0x000000AC, 0x00000004, 0x69646172, 0x00007375, 0x00050006, -0x000000AC, 0x00000005, 0x65707974, 0x00000000, 0x00050006, 0x000000AC, 0x00000006, 0x6C676E61, -0x00000065, 0x00230005, 0x000000B5, 0x746F7349, 0x69706F72, 0x626F4C63, 0x74732865, 0x74637572, -0x74614D2D, 0x61697265, 0x66762D6C, 0x31662D34, 0x2D31662D, 0x662D3166, 0x66762D31, 0x66762D33, -0x31662D33, 0x3366762D, 0x2D31662D, 0x2D336676, 0x2D336676, 0x31326676, 0x7274733B, 0x2D746375, -0x6867694C, 0x66762D74, 0x66762D34, 0x66762D34, 0x31662D34, 0x2D31662D, 0x662D3166, 0x763B3131, -0x663B3366, 0x31663B31, 0x3B31663B, 0x003B3166, 0x00050005, 0x000000AE, 0x6574616D, 0x6C616972, -0x00000000, 0x00040005, 0x000000AF, 0x6867696C, 0x00000074, 0x00030005, 0x000000B0, 0x00000068, -0x00030005, 0x000000B1, 0x00566F4E, 0x00030005, 0x000000B2, 0x004C6F4E, 0x00030005, 0x000000B3, -0x00486F4E, 0x00030005, 0x000000B4, 0x00486F4C, 0x00180005, 0x000000BC, 0x66666944, 0x4C657375, -0x2865626F, 0x75727473, 0x4D2D7463, 0x72657461, 0x2D6C6169, 0x2D346676, 0x662D3166, 0x31662D31, -0x2D31662D, 0x2D336676, 0x2D336676, 0x762D3166, 0x662D3366, 0x66762D31, 0x66762D33, 0x66762D33, -0x663B3132, 0x31663B31, 0x3B31663B, 0x00000000, 0x00050005, 0x000000B8, 0x6574616D, 0x6C616972, -0x00000000, 0x00030005, 0x000000B9, 0x00566F4E, 0x00030005, 0x000000BA, 0x004C6F4E, 0x00030005, -0x000000BB, 0x00486F4C, 0x00230005, 0x000000C5, 0x63657053, 0x72616C75, 0x65626F4C, 0x72747328, -0x2D746375, 0x6574614D, 0x6C616972, 0x3466762D, 0x2D31662D, 0x662D3166, 0x31662D31, 0x3366762D, -0x3366762D, 0x2D31662D, 0x2D336676, 0x762D3166, 0x762D3366, 0x762D3366, 0x3B313266, 0x75727473, -0x4C2D7463, 0x74686769, 0x3466762D, 0x3466762D, 0x3466762D, 0x2D31662D, 0x662D3166, 0x31662D31, -0x66763B31, 0x31663B33, 0x3B31663B, 0x663B3166, 0x00003B31, 0x00050005, 0x000000BE, 0x6574616D, -0x6C616972, 0x00000000, 0x00040005, 0x000000BF, 0x6867696C, 0x00000074, 0x00030005, 0x000000C0, -0x00000068, 0x00030005, 0x000000C1, 0x00566F4E, 0x00030005, 0x000000C2, 0x004C6F4E, 0x00030005, -0x000000C3, 0x00486F4E, 0x00030005, 0x000000C4, 0x00486F4C, 0x00170005, 0x000000CC, 0x6867694C, -0x676E6974, 0x33667628, 0x3366763B, 0x7274733B, 0x2D746375, 0x6574614D, 0x6C616972, 0x3466762D, -0x2D31662D, 0x662D3166, 0x31662D31, 0x3366762D, 0x3366762D, 0x2D31662D, 0x2D336676, 0x762D3166, -0x762D3366, 0x762D3366, 0x3B313266, 0x00000000, 0x00030005, 0x000000C9, 0x00003046, 0x00040005, -0x000000CA, 0x6F507377, 0x00000073, 0x00050005, 0x000000CB, 0x6574616D, 0x6C616972, 0x00000000, -0x00150005, 0x000000D1, 0x284C4249, 0x3B336676, 0x3B336676, 0x75727473, 0x4D2D7463, 0x72657461, -0x2D6C6169, 0x2D346676, 0x662D3166, 0x31662D31, 0x2D31662D, 0x2D336676, 0x2D336676, 0x762D3166, -0x662D3366, 0x66762D31, 0x66762D33, 0x66762D33, 0x003B3132, 0x00030005, 0x000000CE, 0x00003046, -0x00030005, 0x000000CF, 0x0000724C, 0x00050005, 0x000000D0, 0x6574616D, 0x6C616972, 0x00000000, -0x00050005, 0x000000D4, 0x64616853, 0x6146776F, 0x00006564, 0x00030005, 0x000000D6, 0x00494850, -0x00030005, 0x000000D8, 0x00003278, 0x00040005, 0x000000E9, 0x61726170, 0x0000006D, 0x00030005, -0x000000FC, 0x0048784E, 0x00030005, 0x000000FE, 0x00000061, 0x00030005, 0x00000102, 0x0000006B, -0x00030005, 0x0000010C, 0x00000064, 0x00040005, 0x0000011C, 0x61726170, 0x0000006D, 0x00030005, -0x0000012E, 0x00303966, 0x00060005, 0x00000138, 0x6867696C, 0x61635374, 0x72657474, 0x00000000, -0x00040005, 0x00000139, 0x61726170, 0x0000006D, 0x00040005, 0x0000013A, 0x61726170, 0x0000006D, -0x00040005, 0x0000013C, 0x61726170, 0x0000006D, 0x00050005, 0x0000013F, 0x77656976, 0x74616353, -0x00726574, 0x00040005, 0x00000140, 0x61726170, 0x0000006D, 0x00040005, 0x00000141, 0x61726170, -0x0000006D, 0x00040005, 0x00000143, 0x61726170, 0x0000006D, 0x00030005, 0x0000014C, 0x00003261, -0x00040005, 0x00000150, 0x4C584747, 0x00000000, 0x00040005, 0x0000015E, 0x56584747, 0x00000000, -0x00050005, 0x00000172, 0x72657061, 0x65727574, 0x00000000, 0x00050005, 0x00000178, 0x7263696D, -0x6168536F, 0x00776F64, 0x00040005, 0x0000017C, 0x61726170, 0x0000006D, 0x00040005, 0x00000183, -0x61726170, 0x0000006D, 0x00040005, 0x00000185, 0x61726170, 0x0000006D, 0x00040005, 0x00000187, -0x61726170, 0x0000006D, 0x00040005, 0x00000189, 0x61726170, 0x0000006D, 0x00040005, 0x000001B0, -0x61726170, 0x0000006D, 0x00040005, 0x000001B2, 0x61726170, 0x0000006D, 0x00040005, 0x000001B7, -0x61726170, 0x0000006D, 0x00040005, 0x000001B9, 0x61726170, 0x0000006D, 0x00040005, 0x000001BB, -0x61726170, 0x0000006D, 0x00030005, 0x000001C0, 0x00303966, 0x00040005, 0x000001C4, 0x61726170, -0x0000006D, 0x00040005, 0x000001C6, 0x61726170, 0x0000006D, 0x00040005, 0x000001C8, 0x61726170, -0x0000006D, 0x00070005, 0x000001DD, 0x66696E55, 0x4D6D726F, 0x72657461, 0x446C6169, 0x00617461, -0x00070006, 0x000001DD, 0x00000000, 0x65626C41, 0x6F436F64, 0x72756F6C, 0x00000000, 0x00060006, -0x000001DD, 0x00000001, 0x67756F52, 0x73656E68, 0x00000073, 0x00060006, 0x000001DD, 0x00000002, -0x6174654D, 0x63696C6C, 0x00000000, 0x00060006, 0x000001DD, 0x00000003, 0x6C666552, 0x61746365, -0x0065636E, 0x00060006, 0x000001DD, 0x00000004, 0x73696D45, 0x65766973, 0x00000000, 0x00070006, -0x000001DD, 0x00000005, 0x65626C41, 0x614D6F64, 0x63614670, 0x00726F74, 0x00080006, 0x000001DD, -0x00000006, 0x6174654D, 0x63696C6C, 0x4670614D, 0x6F746361, 0x00000072, 0x00080006, 0x000001DD, -0x00000007, 0x67756F52, 0x73656E68, 0x70614D73, 0x74636146, 0x0000726F, 0x00070006, 0x000001DD, -0x00000008, 0x6D726F4E, 0x614D6C61, 0x63614670, 0x00726F74, 0x00080006, 0x000001DD, 0x00000009, -0x73696D45, 0x65766973, 0x4670614D, 0x6F746361, 0x00000072, 0x00060006, 0x000001DD, 0x0000000A, -0x614D4F41, 0x63614670, 0x00726F74, 0x00060006, 0x000001DD, 0x0000000B, 0x68706C41, 0x74754361, -0x0066664F, 0x00060006, 0x000001DD, 0x0000000C, 0x6B726F77, 0x776F6C66, 0x00000000, 0x00070005, -0x000001DF, 0x6574616D, 0x6C616972, 0x706F7250, 0x69747265, 0x00007365, 0x00050005, 0x000001F9, -0x6C415F75, 0x6F646562, 0x0070614D, 0x00050005, 0x000001FC, 0x74726556, 0x61447865, 0x00006174, -0x00050006, 0x000001FC, 0x00000000, 0x6F6C6F43, 0x00007275, 0x00060006, 0x000001FC, 0x00000001, -0x43786554, 0x64726F6F, 0x00000000, 0x00060006, 0x000001FC, 0x00000002, 0x69736F50, 0x6E6F6974, -0x00000000, 0x00050006, 0x000001FC, 0x00000003, 0x6D726F4E, 0x00006C61, 0x00060006, 0x000001FC, -0x00000004, 0x6C726F57, 0x726F4E64, 0x006C616D, 0x00060005, 0x000001FE, 0x74726556, 0x754F7865, -0x74757074, 0x00000000, 0x00040005, 0x00000204, 0x61726170, 0x0000006D, 0x00060005, 0x0000021D, -0x654D5F75, 0x6C6C6174, 0x614D6369, 0x00000070, 0x00060005, 0x00000239, 0x6F525F75, 0x6E686775, -0x4D737365, 0x00007061, 0x00040005, 0x00000250, 0x4F415F75, 0x0070614D, 0x00060005, 0x0000026C, -0x6D455F75, 0x69737369, 0x614D6576, 0x00000070, 0x00040005, 0x00000271, 0x61726170, 0x0000006D, -0x00040005, 0x00000284, 0x6D726F4E, 0x00006C61, 0x00050005, 0x00000285, 0x6F4E5F75, 0x6C616D72, -0x0070614D, 0x00050005, 0x000002A2, 0x646C6F47, 0x6E416E65, 0x00656C67, 0x00030005, 0x000002A4, -0x00000072, 0x00040005, 0x000002AD, 0x74656874, 0x00000061, 0x00040005, 0x000002B4, 0x656E6973, -0x00000000, 0x00040005, 0x000002B7, 0x69736F63, 0x0000656E, 0x00040005, 0x000002C3, 0x426E696D, -0x00736169, 0x00040005, 0x000002C4, 0x6867694C, 0x00000074, 0x00050006, 0x000002C4, 0x00000000, -0x6F6C6F63, 0x00007275, 0x00060006, 0x000002C4, 0x00000001, 0x69736F70, 0x6E6F6974, 0x00000000, -0x00060006, 0x000002C4, 0x00000002, 0x65726964, 0x6F697463, 0x0000006E, 0x00060006, 0x000002C4, -0x00000003, 0x65746E69, 0x7469736E, 0x00000079, 0x00050006, 0x000002C4, 0x00000004, 0x69646172, -0x00007375, 0x00050006, 0x000002C4, 0x00000005, 0x65707974, 0x00000000, 0x00050006, 0x000002C4, -0x00000006, 0x6C676E61, 0x00000065, 0x00050005, 0x000002CB, 0x4C4F4255, 0x74686769, 0x00000000, -0x00050006, 0x000002CB, 0x00000000, 0x6867696C, 0x00007374, 0x00070006, 0x000002CB, 0x00000001, -0x64616853, 0x7254776F, 0x66736E61, 0x006D726F, 0x00060006, 0x000002CB, 0x00000002, 0x77656956, -0x7274614D, 0x00007869, 0x00060006, 0x000002CB, 0x00000003, 0x6867694C, 0x65695674, 0x00000077, -0x00060006, 0x000002CB, 0x00000004, 0x73616942, 0x7274614D, 0x00007869, 0x00070006, 0x000002CB, -0x00000005, 0x656D6163, 0x6F506172, 0x69746973, 0x00006E6F, 0x00060006, 0x000002CB, 0x00000006, -0x696C7053, 0x70654474, 0x00736874, 0x00060006, 0x000002CB, 0x00000007, 0x6867694C, 0x7A695374, -0x00000065, 0x00070006, 0x000002CB, 0x00000008, 0x5378614D, 0x6F646168, 0x73694477, 0x00000074, -0x00060006, 0x000002CB, 0x00000009, 0x64616853, 0x6146776F, 0x00006564, 0x00060006, 0x000002CB, -0x0000000A, 0x63736143, 0x46656461, 0x00656461, 0x00060006, 0x000002CB, 0x0000000B, 0x6867694C, -0x756F4374, 0x0000746E, 0x00060006, 0x000002CB, 0x0000000C, 0x64616853, 0x6F43776F, 0x00746E75, -0x00050006, 0x000002CB, 0x0000000D, 0x65646F4D, 0x00000000, 0x00060006, 0x000002CB, 0x0000000E, -0x4D766E45, 0x6F437069, 0x00746E75, 0x00060006, 0x000002CB, 0x0000000F, 0x74696E49, 0x426C6169, -0x00736169, 0x00050006, 0x000002CB, 0x00000010, 0x74646957, 0x00000068, 0x00050006, 0x000002CB, -0x00000011, 0x67696548, 0x00007468, 0x00070006, 0x000002CB, 0x00000012, 0x64616873, 0x6E45776F, -0x656C6261, 0x00000064, 0x00030005, 0x000002CD, 0x006F6275, 0x00040005, 0x000002D1, 0x73616962, -0x00000000, 0x00040005, 0x000002DD, 0x73616962, 0x00000000, 0x00040005, 0x000002DE, 0x61726170, -0x0000006D, 0x00040005, 0x000002E0, 0x61726170, 0x0000006D, 0x00040005, 0x000002E2, 0x61726170, -0x0000006D, 0x00030005, 0x000002E5, 0x006D7573, 0x00040005, 0x000002E6, 0x73696F6E, 0x00000065, -0x00040005, 0x000002E7, 0x61726170, 0x0000006D, 0x00030005, 0x000002EB, 0x00000069, 0x00040005, -0x000002F3, 0x7366666F, 0x00007465, 0x00040005, 0x000002F4, 0x61726170, 0x0000006D, 0x00040005, -0x000002F6, 0x61726170, 0x0000006D, 0x00040005, 0x000002F7, 0x61726170, 0x0000006D, 0x00030005, -0x000002FD, 0x0000007A, 0x00060005, 0x0000031A, 0x63736163, 0x49656461, 0x7865646E, 0x00000000, -0x00040005, 0x0000031B, 0x77656976, 0x00736F50, 0x00030005, 0x00000325, 0x00000069, 0x00050005, -0x00000341, 0x64616873, 0x6F43776F, 0x0064726F, 0x00040005, 0x00000353, 0x5241454E, 0x00000000, -0x00050005, 0x00000355, 0x61527675, 0x73756964, 0x00000000, 0x00040005, 0x00000360, 0x77656976, -0x00736F50, 0x00060005, 0x00000369, 0x64616873, 0x6D41776F, 0x746E756F, 0x00000000, 0x00050005, -0x0000036A, 0x61685375, 0x4D776F64, 0x00007061, 0x00040005, 0x0000036B, 0x61726170, 0x0000006D, -0x00040005, 0x0000036D, 0x61726170, 0x0000006D, 0x00040005, 0x0000036F, 0x61726170, 0x0000006D, -0x00040005, 0x00000371, 0x61726170, 0x0000006D, 0x00040005, 0x00000373, 0x61726170, 0x0000006D, -0x00040005, 0x00000375, 0x61726170, 0x0000006D, 0x00050005, 0x00000378, 0x63736163, 0x46656461, -0x00656461, 0x00050005, 0x00000385, 0x63736163, 0x4E656461, 0x00747865, 0x00060005, 0x0000039F, -0x64616873, 0x6D41776F, 0x746E756F, 0x00000031, 0x00040005, 0x000003A0, 0x61726170, 0x0000006D, -0x00040005, 0x000003A2, 0x61726170, 0x0000006D, 0x00040005, 0x000003A4, 0x61726170, 0x0000006D, -0x00040005, 0x000003A6, 0x61726170, 0x0000006D, 0x00040005, 0x000003A8, 0x61726170, 0x0000006D, -0x00040005, 0x000003AA, 0x61726170, 0x0000006D, 0x00030005, 0x000003B8, 0x00000044, 0x00040005, -0x000003BA, 0x61726170, 0x0000006D, 0x00040005, 0x000003BC, 0x61726170, 0x0000006D, 0x00030005, -0x000003BF, 0x00000056, 0x00040005, 0x000003C0, 0x61726170, 0x0000006D, 0x00040005, 0x000003C2, -0x61726170, 0x0000006D, 0x00040005, 0x000003C4, 0x61726170, 0x0000006D, 0x00030005, 0x000003C7, -0x00000046, 0x00040005, 0x000003C9, 0x61726170, 0x0000006D, 0x00040005, 0x000003D5, 0x61726170, -0x0000006D, 0x00040005, 0x000003D7, 0x61726170, 0x0000006D, 0x00040005, 0x000003D9, 0x61726170, -0x0000006D, 0x00040005, 0x000003DB, 0x61726170, 0x0000006D, 0x00040005, 0x000003E1, 0x61726170, -0x0000006D, 0x00040005, 0x000003E3, 0x61726170, 0x0000006D, 0x00040005, 0x000003E5, 0x61726170, -0x0000006D, 0x00040005, 0x000003E7, 0x61726170, 0x0000006D, 0x00040005, 0x000003EC, 0x75736572, -0x0000746C, 0x00030005, 0x000003EE, 0x00000069, 0x00040005, 0x000003FA, 0x6867696C, 0x00000074, -0x00040005, 0x0000040D, 0x756C6176, 0x00000065, 0x00030005, 0x00000413, 0x0000004C, 0x00040005, -0x00000419, 0x74736964, 0x00000000, 0x00040005, 0x0000041E, 0x65747461, 0x0000006E, 0x00050005, -0x00000425, 0x65747461, 0x7461756E, 0x006E6F69, 0x00030005, 0x0000043E, 0x0000004C, 0x00050005, -0x00000444, 0x6F747563, 0x6E416666, 0x00656C67, 0x00040005, 0x00000448, 0x74736964, 0x00000000, -0x00040005, 0x0000044D, 0x74656874, 0x00000061, 0x00040005, 0x00000453, 0x69737065, 0x006E6F6C, -0x00050005, 0x00000459, 0x65747461, 0x7461756E, 0x006E6F69, 0x00060005, 0x0000046A, 0x63736163, -0x49656461, 0x7865646E, 0x00000000, 0x00040005, 0x0000046B, 0x61726170, 0x0000006D, 0x00040005, -0x00000474, 0x61726170, 0x0000006D, 0x00040005, 0x00000476, 0x61726170, 0x0000006D, 0x00040005, -0x00000478, 0x61726170, 0x0000006D, 0x00040005, 0x0000047C, 0x61726170, 0x0000006D, 0x00030005, -0x00000481, 0x0000694C, 0x00050005, 0x00000485, 0x6461724C, 0x636E6169, 0x00000065, 0x00030005, -0x0000048C, 0x0000684C, 0x00050005, 0x00000492, 0x6867696C, 0x4C6F4E74, 0x00000000, 0x00040005, -0x00000497, 0x61726170, 0x0000006D, 0x00030005, 0x00000499, 0x00000068, 0x00050005, 0x0000049F, -0x64616873, 0x5F676E69, 0x00566F4E, 0x00040005, 0x000004A5, 0x61726170, 0x0000006D, 0x00030005, -0x000004A7, 0x00566F4E, 0x00030005, 0x000004A9, 0x004C6F4E, 0x00040005, 0x000004AA, 0x61726170, -0x0000006D, 0x00030005, 0x000004AD, 0x00486F4E, 0x00040005, 0x000004B2, 0x61726170, 0x0000006D, -0x00030005, 0x000004B4, 0x00486F4C, 0x00040005, 0x000004B8, 0x61726170, 0x0000006D, 0x00030005, -0x000004BA, 0x00006446, 0x00040005, 0x000004BC, 0x61726170, 0x0000006D, 0x00040005, 0x000004BE, -0x61726170, 0x0000006D, 0x00040005, 0x000004C0, 0x61726170, 0x0000006D, 0x00030005, 0x000004C3, -0x00007246, 0x00040005, 0x000004C7, 0x61726170, 0x0000006D, 0x00040005, 0x000004C9, 0x61726170, -0x0000006D, 0x00040005, 0x000004CB, 0x61726170, 0x0000006D, 0x00040005, 0x000004CD, 0x61726170, -0x0000006D, 0x00040005, 0x000004D0, 0x6F6C6F63, 0x00007275, 0x00040005, 0x000004DA, 0x61726170, -0x0000006D, 0x00040005, 0x000004DC, 0x61726170, 0x0000006D, 0x00050005, 0x000004E9, 0x61727269, -0x6E616964, 0x00006563, 0x00040005, 0x000004ED, 0x72724975, 0x0070614D, 0x00030005, 0x000004F3, -0x00000046, 0x00040005, 0x000004F4, 0x61726170, 0x0000006D, 0x00040005, 0x000004F6, 0x61726170, -0x0000006D, 0x00040005, 0x000004F9, 0x61726170, 0x0000006D, 0x00030005, 0x000004FD, 0x0000646B, -0x00050005, 0x00000505, 0x66666964, 0x49657375, 0x00004C42, 0x00080005, 0x0000050B, 0x6E455F75, -0x64615276, 0x636E6169, 0x78655465, 0x6576654C, 0x0000736C, 0x00070005, 0x0000050F, 0x63657073, -0x72616C75, 0x61727249, 0x6E616964, 0x00006563, 0x00040005, 0x00000510, 0x766E4575, 0x0070614D, -0x00050005, 0x0000051A, 0x63657073, 0x72616C75, 0x004C4249, 0x00050005, 0x0000052D, 0x43786574, -0x756F6C6F, 0x00000072, 0x00050005, 0x00000537, 0x6174656D, 0x63696C6C, 0x00000000, 0x00050005, -0x00000538, 0x67756F72, 0x73656E68, 0x00000073, 0x00030005, 0x00000547, 0x00786574, 0x00030005, -0x0000056B, 0x00786574, 0x00050005, 0x00000589, 0x6574616D, 0x6C616972, 0x00000000, 0x00040005, -0x00000597, 0x61726170, 0x0000006D, 0x00030005, 0x0000059D, 0x00007675, 0x00060005, 0x0000059F, -0x465F6C67, 0x43676172, 0x64726F6F, 0x00000000, 0x00040005, 0x000005AA, 0x6F617373, 0x00000000, -0x00050005, 0x000005AB, 0x41535375, 0x70614D4F, 0x00000000, 0x00040005, 0x000005BA, 0x61726170, -0x0000006D, 0x00050005, 0x000005BF, 0x67756F72, 0x73656E68, 0x00003273, 0x00040005, 0x000005C3, -0x75646E64, 0x00000000, 0x00040005, 0x000005C7, 0x76646E64, 0x00000000, 0x00050005, 0x000005CB, -0x69726176, 0x65636E61, 0x00000000, 0x00070005, 0x000005D3, 0x6E72656B, 0x6F526C65, 0x6E686775, -0x32737365, 0x00000000, 0x00070005, 0x000005D8, 0x746C6966, 0x64657265, 0x67756F52, 0x73656E68, -0x00003273, 0x00040005, 0x000005DC, 0x61726170, 0x0000006D, 0x00040005, 0x000005E1, 0x6F507377, -0x00000073, 0x00050005, 0x000005F3, 0x44524275, 0x54554C46, 0x00000000, 0x00050005, 0x000005FD, -0x6C666572, 0x61746365, 0x0065636E, 0x00040005, 0x000005FE, 0x61726170, 0x0000006D, 0x00030005, -0x00000602, 0x00003046, 0x00040005, 0x00000605, 0x61726170, 0x0000006D, 0x00040005, 0x00000608, -0x61726170, 0x0000006D, 0x00040005, 0x0000061B, 0x61726170, 0x0000006D, 0x00060005, 0x00000625, -0x64616873, 0x6944776F, 0x6E617473, 0x00006563, 0x00070005, 0x00000628, 0x6E617274, 0x69746973, -0x69446E6F, 0x6E617473, 0x00006563, 0x00040005, 0x0000062B, 0x77656976, 0x00736F50, 0x00050005, -0x00000634, 0x74736964, 0x65636E61, 0x00000000, 0x00030005, 0x00000642, 0x0000724C, 0x00070005, -0x0000064C, 0x6867696C, 0x6E6F4374, 0x62697274, 0x6F697475, 0x0000006E, 0x00040005, 0x0000064D, -0x61726170, 0x0000006D, 0x00040005, 0x00000650, 0x61726170, 0x0000006D, 0x00040005, 0x00000652, -0x61726170, 0x0000006D, 0x00060005, 0x00000655, 0x436C6269, 0x72746E6F, 0x74756269, 0x006E6F69, -0x00040005, 0x00000656, 0x61726170, 0x0000006D, 0x00040005, 0x00000659, 0x61726170, 0x0000006D, -0x00040005, 0x0000065B, 0x61726170, 0x0000006D, 0x00050005, 0x0000065E, 0x616E6966, 0x6C6F436C, -0x0072756F, 0x00050005, 0x00000666, 0x4374756F, 0x726F6C6F, 0x00000000, 0x00060005, 0x000006A5, -0x63736163, 0x49656461, 0x7865646E, 0x00000000, 0x00040005, 0x000006A6, 0x61726170, 0x0000006D, -0x00050048, 0x000001DD, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x000001DD, 0x00000001, -0x00000023, 0x00000010, 0x00050048, 0x000001DD, 0x00000002, 0x00000023, 0x00000014, 0x00050048, -0x000001DD, 0x00000003, 0x00000023, 0x00000018, 0x00050048, 0x000001DD, 0x00000004, 0x00000023, -0x0000001C, 0x00050048, 0x000001DD, 0x00000005, 0x00000023, 0x00000020, 0x00050048, 0x000001DD, -0x00000006, 0x00000023, 0x00000024, 0x00050048, 0x000001DD, 0x00000007, 0x00000023, 0x00000028, -0x00050048, 0x000001DD, 0x00000008, 0x00000023, 0x0000002C, 0x00050048, 0x000001DD, 0x00000009, -0x00000023, 0x00000030, 0x00050048, 0x000001DD, 0x0000000A, 0x00000023, 0x00000034, 0x00050048, -0x000001DD, 0x0000000B, 0x00000023, 0x00000038, 0x00050048, 0x000001DD, 0x0000000C, 0x00000023, -0x0000003C, 0x00030047, 0x000001DD, 0x00000002, 0x00040047, 0x000001DF, 0x00000022, 0x00000001, -0x00040047, 0x000001DF, 0x00000021, 0x00000006, 0x00040047, 0x000001F9, 0x00000022, 0x00000001, -0x00040047, 0x000001F9, 0x00000021, 0x00000000, 0x00040047, 0x000001FE, 0x0000001E, 0x00000000, -0x00040047, 0x0000021D, 0x00000022, 0x00000001, 0x00040047, 0x0000021D, 0x00000021, 0x00000001, -0x00040047, 0x00000239, 0x00000022, 0x00000001, 0x00040047, 0x00000239, 0x00000021, 0x00000002, -0x00040047, 0x00000250, 0x00000022, 0x00000001, 0x00040047, 0x00000250, 0x00000021, 0x00000004, -0x00040047, 0x0000026C, 0x00000022, 0x00000001, 0x00040047, 0x0000026C, 0x00000021, 0x00000005, -0x00040047, 0x00000285, 0x00000022, 0x00000001, 0x00040047, 0x00000285, 0x00000021, 0x00000003, -0x00050048, 0x000002C4, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x000002C4, 0x00000001, -0x00000023, 0x00000010, 0x00050048, 0x000002C4, 0x00000002, 0x00000023, 0x00000020, 0x00050048, -0x000002C4, 0x00000003, 0x00000023, 0x00000030, 0x00050048, 0x000002C4, 0x00000004, 0x00000023, -0x00000034, 0x00050048, 0x000002C4, 0x00000005, 0x00000023, 0x00000038, 0x00050048, 0x000002C4, -0x00000006, 0x00000023, 0x0000003C, 0x00040047, 0x000002C6, 0x00000006, 0x00000040, 0x00040047, -0x000002C9, 0x00000006, 0x00000040, 0x00040047, 0x000002CA, 0x00000006, 0x00000010, 0x00050048, -0x000002CB, 0x00000000, 0x00000023, 0x00000000, 0x00040048, 0x000002CB, 0x00000001, 0x00000005, -0x00050048, 0x000002CB, 0x00000001, 0x00000023, 0x00000800, 0x00050048, 0x000002CB, 0x00000001, -0x00000007, 0x00000010, 0x00040048, 0x000002CB, 0x00000002, 0x00000005, 0x00050048, 0x000002CB, -0x00000002, 0x00000023, 0x00000900, 0x00050048, 0x000002CB, 0x00000002, 0x00000007, 0x00000010, -0x00040048, 0x000002CB, 0x00000003, 0x00000005, 0x00050048, 0x000002CB, 0x00000003, 0x00000023, -0x00000940, 0x00050048, 0x000002CB, 0x00000003, 0x00000007, 0x00000010, 0x00040048, 0x000002CB, -0x00000004, 0x00000005, 0x00050048, 0x000002CB, 0x00000004, 0x00000023, 0x00000980, 0x00050048, -0x000002CB, 0x00000004, 0x00000007, 0x00000010, 0x00050048, 0x000002CB, 0x00000005, 0x00000023, -0x000009C0, 0x00050048, 0x000002CB, 0x00000006, 0x00000023, 0x000009D0, 0x00050048, 0x000002CB, -0x00000007, 0x00000023, 0x00000A10, 0x00050048, 0x000002CB, 0x00000008, 0x00000023, 0x00000A14, -0x00050048, 0x000002CB, 0x00000009, 0x00000023, 0x00000A18, 0x00050048, 0x000002CB, 0x0000000A, -0x00000023, 0x00000A1C, 0x00050048, 0x000002CB, 0x0000000B, 0x00000023, 0x00000A20, 0x00050048, -0x000002CB, 0x0000000C, 0x00000023, 0x00000A24, 0x00050048, 0x000002CB, 0x0000000D, 0x00000023, -0x00000A28, 0x00050048, 0x000002CB, 0x0000000E, 0x00000023, 0x00000A2C, 0x00050048, 0x000002CB, -0x0000000F, 0x00000023, 0x00000A30, 0x00050048, 0x000002CB, 0x00000010, 0x00000023, 0x00000A34, -0x00050048, 0x000002CB, 0x00000011, 0x00000023, 0x00000A38, 0x00050048, 0x000002CB, 0x00000012, -0x00000023, 0x00000A3C, 0x00030047, 0x000002CB, 0x00000002, 0x00040047, 0x000002CD, 0x00000022, -0x00000002, 0x00040047, 0x000002CD, 0x00000021, 0x00000005, 0x00040047, 0x0000036A, 0x00000022, -0x00000002, 0x00040047, 0x0000036A, 0x00000021, 0x00000003, 0x00040047, 0x000004ED, 0x00000022, -0x00000002, 0x00040047, 0x000004ED, 0x00000021, 0x00000002, 0x00040047, 0x00000510, 0x00000022, -0x00000002, 0x00040047, 0x00000510, 0x00000021, 0x00000001, 0x00040047, 0x0000059F, 0x0000000B, -0x0000000F, 0x00040047, 0x000005AB, 0x00000022, 0x00000002, 0x00040047, 0x000005AB, 0x00000021, -0x00000004, 0x00040047, 0x000005F3, 0x00000022, 0x00000002, 0x00040047, 0x000005F3, 0x00000021, -0x00000000, 0x00040047, 0x00000666, 0x0000001E, 0x00000000, 0x00020013, 0x00000002, 0x00030021, -0x00000003, 0x00000002, 0x00030016, 0x00000006, 0x00000020, 0x00040020, 0x00000007, 0x00000007, -0x00000006, 0x00040021, 0x00000008, 0x00000006, 0x00000007, 0x00040017, 0x0000000C, 0x00000006, -0x00000003, 0x00040020, 0x0000000D, 0x00000007, 0x0000000C, 0x00040021, 0x0000000E, 0x0000000C, -0x0000000D, 0x00040017, 0x00000012, 0x00000006, 0x00000004, 0x00040020, 0x00000013, 0x00000007, -0x00000012, 0x00040021, 0x00000014, 0x00000012, 0x00000013, 0x00070021, 0x0000001B, 0x00000006, -0x00000007, 0x00000007, 0x0000000C, 0x0000000C, 0x00060021, 0x00000022, 0x0000000C, 0x0000000C, -0x00000007, 0x00000007, 0x00060021, 0x00000028, 0x00000006, 0x00000007, 0x00000007, 0x00000007, -0x00070021, 0x0000002E, 0x00000006, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00050021, -0x0000003A, 0x00000006, 0x00000007, 0x00000007, 0x00050021, 0x00000048, 0x0000000C, 0x00000012, -0x00000007, 0x00060021, 0x0000004D, 0x0000000C, 0x00000012, 0x00000007, 0x00000007, 0x00050021, -0x00000064, 0x0000000C, 0x0000000C, 0x00000007, 0x00060021, 0x00000069, 0x0000000C, 0x0000000D, -0x00000007, 0x00000007, 0x00030021, 0x0000006F, 0x00000012, 0x00030021, 0x00000072, 0x0000000C, -0x00030021, 0x00000075, 0x00000006, 0x00040017, 0x0000007F, 0x00000006, 0x00000002, 0x00040020, -0x00000080, 0x00000007, 0x0000007F, 0x00040021, 0x00000081, 0x00000006, 0x00000080, 0x00040015, -0x00000085, 0x00000020, 0x00000001, 0x00040020, 0x00000086, 0x00000007, 0x00000085, 0x00060021, -0x00000087, 0x0000007F, 0x00000086, 0x00000086, 0x00000007, 0x00060021, 0x0000008D, 0x00000006, -0x0000000D, 0x0000000D, 0x00000086, 0x00090019, 0x00000093, 0x00000006, 0x00000001, 0x00000000, -0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x0003001B, 0x00000094, 0x00000093, 0x00040020, -0x00000095, 0x00000000, 0x00000094, 0x000A0021, 0x00000096, 0x00000006, 0x00000095, 0x00000013, -0x00000007, 0x0000000D, 0x0000000D, 0x0000000D, 0x00000086, 0x00040021, 0x000000A0, 0x00000085, -0x0000000D, 0x00070021, 0x000000A4, 0x00000006, 0x0000000D, 0x00000086, 0x0000000D, 0x0000000D, -0x000F001E, 0x000000AB, 0x00000012, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x0000000C, -0x0000000C, 0x00000006, 0x0000000C, 0x00000006, 0x0000000C, 0x0000000C, 0x0000007F, 0x0009001E, -0x000000AC, 0x00000012, 0x00000012, 0x00000012, 0x00000006, 0x00000006, 0x00000006, 0x00000006, -0x000A0021, 0x000000AD, 0x0000000C, 0x000000AB, 0x000000AC, 0x0000000C, 0x00000007, 0x00000007, -0x00000007, 0x00000007, 0x00070021, 0x000000B7, 0x0000000C, 0x000000AB, 0x00000007, 0x00000007, -0x00000007, 0x00040020, 0x000000C7, 0x00000007, 0x000000AB, 0x00060021, 0x000000C8, 0x0000000C, -0x0000000D, 0x0000000D, 0x000000C7, 0x00040020, 0x000000D3, 0x00000006, 0x00000006, 0x0004003B, -0x000000D3, 0x000000D4, 0x00000006, 0x0004002B, 0x00000006, 0x000000D5, 0x3F800000, 0x0004003B, -0x000000D3, 0x000000D6, 0x00000006, 0x0004002B, 0x00000006, 0x000000D7, 0x3FCF1BBD, 0x0004002B, -0x00000006, 0x000000E4, 0x400CCCCD, 0x0006002C, 0x0000000C, 0x000000E5, 0x000000E4, 0x000000E4, -0x000000E4, 0x00040015, 0x000000ED, 0x00000020, 0x00000000, 0x0004002B, 0x000000ED, 0x000000EE, -0x00000003, 0x0004002B, 0x00000006, 0x000000F8, 0x00000000, 0x0004002B, 0x00000006, 0x00000110, -0x3EA2F983, 0x0004002B, 0x00000006, 0x00000113, 0x477FE000, 0x0004002B, 0x00000006, 0x00000128, -0x40A00000, 0x0004002B, 0x00000006, 0x0000012F, 0x3F000000, 0x0004002B, 0x00000006, 0x00000130, -0x40000000, 0x0004002B, 0x00000006, 0x00000174, 0x3F7FF972, 0x0004002B, 0x00000006, 0x0000018F, -0x38D1B717, 0x0004002B, 0x00000006, 0x000001A4, 0x3E23D70A, 0x0004002B, 0x00000006, 0x000001C1, -0x41840000, 0x0006002C, 0x0000000C, 0x000001C2, 0x000001C1, 0x000001C1, 0x000001C1, 0x000F001E, -0x000001DD, 0x00000012, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000006, -0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00040020, 0x000001DE, -0x00000002, 0x000001DD, 0x0004003B, 0x000001DE, 0x000001DF, 0x00000002, 0x0004002B, 0x00000085, -0x000001E0, 0x00000005, 0x00040020, 0x000001E1, 0x00000002, 0x00000006, 0x0004002B, 0x00000006, -0x000001E4, 0x3D4CCCCD, 0x00020014, 0x000001E5, 0x0004002B, 0x00000085, 0x000001E9, 0x00000000, -0x00040020, 0x000001EA, 0x00000002, 0x00000012, 0x00090019, 0x000001F6, 0x00000006, 0x00000001, -0x00000000, 0x00000000, 0x00000000, 0x00000001, 0x00000000, 0x0003001B, 0x000001F7, 0x000001F6, -0x00040020, 0x000001F8, 0x00000000, 0x000001F7, 0x0004003B, 0x000001F8, 0x000001F9, 0x00000000, -0x00040018, 0x000001FB, 0x0000000C, 0x00000003, 0x0007001E, 0x000001FC, 0x0000000C, 0x0000007F, -0x00000012, 0x0000000C, 0x000001FB, 0x00040020, 0x000001FD, 0x00000001, 0x000001FC, 0x0004003B, -0x000001FD, 0x000001FE, 0x00000001, 0x0004002B, 0x00000085, 0x000001FF, 0x00000001, 0x00040020, -0x00000200, 0x00000001, 0x0000007F, 0x0004002B, 0x00000085, 0x0000020A, 0x00000006, 0x0004002B, -0x00000085, 0x00000210, 0x00000002, 0x0004003B, 0x000001F8, 0x0000021D, 0x00000000, 0x0004002B, -0x00000085, 0x00000228, 0x00000007, 0x0004003B, 0x000001F8, 0x00000239, 0x00000000, 0x0004002B, -0x000000ED, 0x0000023E, 0x00000000, 0x0004002B, 0x00000085, 0x00000244, 0x0000000A, 0x0004003B, -0x000001F8, 0x00000250, 0x00000000, 0x0004002B, 0x00000085, 0x0000025A, 0x00000009, 0x0004002B, -0x00000085, 0x00000260, 0x00000004, 0x0004003B, 0x000001F8, 0x0000026C, 0x00000000, 0x0004002B, -0x00000085, 0x00000278, 0x00000008, 0x0004002B, 0x00000085, 0x0000027E, 0x00000003, 0x00040020, -0x0000027F, 0x00000001, 0x0000000C, 0x0004003B, 0x000001F8, 0x00000285, 0x00000000, 0x00040020, -0x0000028F, 0x00000001, 0x000001FB, 0x0004002B, 0x00000006, 0x00000298, 0x414FD639, 0x0004002B, -0x00000006, 0x00000299, 0x429C774C, 0x0005002C, 0x0000007F, 0x0000029A, 0x00000298, 0x00000299, -0x0004002B, 0x00000006, 0x0000029D, 0x472AEE8C, 0x0004002B, 0x00000006, 0x000002A3, 0x4019999A, -0x0009001E, 0x000002C4, 0x00000012, 0x00000012, 0x00000012, 0x00000006, 0x00000006, 0x00000006, -0x00000006, 0x0004002B, 0x000000ED, 0x000002C5, 0x00000020, 0x0004001C, 0x000002C6, 0x000002C4, -0x000002C5, 0x00040018, 0x000002C7, 0x00000012, 0x00000004, 0x0004002B, 0x000000ED, 0x000002C8, -0x00000004, 0x0004001C, 0x000002C9, 0x000002C7, 0x000002C8, 0x0004001C, 0x000002CA, 0x00000012, -0x000002C8, 0x0015001E, 0x000002CB, 0x000002C6, 0x000002C9, 0x000002C7, 0x000002C7, 0x000002C7, -0x00000012, 0x000002CA, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000085, 0x00000085, -0x00000085, 0x00000085, 0x00000006, 0x00000006, 0x00000006, 0x00000085, 0x00040020, 0x000002CC, -0x00000002, 0x000002CB, 0x0004003B, 0x000002CC, 0x000002CD, 0x00000002, 0x0004002B, 0x00000085, -0x000002CE, 0x0000000F, 0x0004002B, 0x00000006, 0x000002FA, 0x442F0000, 0x0004002B, 0x000000ED, -0x0000030A, 0x00000002, 0x0004002B, 0x00000006, 0x00000316, 0x41000000, 0x00040020, 0x0000031C, -0x00000002, 0x000002C7, 0x0004002B, 0x00000085, 0x0000032C, 0x0000000C, 0x00040020, 0x0000032D, -0x00000002, 0x00000085, 0x0004002B, 0x00000006, 0x00000354, 0x3C23D70A, 0x0004002B, 0x00000006, -0x0000035E, 0x3B03126F, 0x0004003B, 0x00000095, 0x0000036A, 0x00000000, 0x0006002C, 0x0000000C, -0x000003ED, 0x000000F8, 0x000000F8, 0x000000F8, 0x0004002B, 0x00000085, 0x000003F5, 0x0000000B, -0x00040020, 0x000003F9, 0x00000007, 0x000000AC, 0x00040020, 0x000003FC, 0x00000002, 0x000002C4, -0x0004002B, 0x00000006, 0x00000456, 0x3F666666, 0x0004002B, 0x00000085, 0x0000046E, 0x00000012, -0x00090019, 0x000004EA, 0x00000006, 0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000001, -0x00000000, 0x0003001B, 0x000004EB, 0x000004EA, 0x00040020, 0x000004EC, 0x00000000, 0x000004EB, -0x0004003B, 0x000004EC, 0x000004ED, 0x00000000, 0x0004002B, 0x00000085, 0x0000050C, 0x0000000E, -0x0004003B, 0x000004EC, 0x00000510, 0x00000000, 0x0004002B, 0x000000ED, 0x00000520, 0x00000001, -0x00040020, 0x0000059E, 0x00000001, 0x00000012, 0x0004003B, 0x0000059E, 0x0000059F, 0x00000001, -0x0004002B, 0x00000085, 0x000005A2, 0x00000010, 0x0004002B, 0x00000085, 0x000005A5, 0x00000011, -0x0004003B, 0x000001F8, 0x000005AB, 0x00000000, 0x0004002B, 0x00000006, 0x000005B7, 0x3D3851EC, -0x0004002B, 0x00000006, 0x000005D6, 0x3CA3D70A, 0x0004003B, 0x000001F8, 0x000005F3, 0x00000000, -0x0004002B, 0x00000006, 0x0000060F, 0x3DCCCCCD, 0x00040020, 0x00000665, 0x00000003, 0x00000012, -0x0004003B, 0x00000665, 0x00000666, 0x00000003, 0x0004002B, 0x00000085, 0x0000066C, 0x0000000D, -0x0004002B, 0x00000006, 0x000006B0, 0x3F4CCCCD, 0x0004002B, 0x00000006, 0x000006B1, 0x3E4CCCCD, -0x0007002C, 0x00000012, 0x000006B2, 0x000006B0, 0x000006B1, 0x000006B1, 0x000000D5, 0x0007002C, -0x00000012, 0x000006B6, 0x000006B1, 0x000006B0, 0x000006B1, 0x000000D5, 0x0007002C, 0x00000012, -0x000006BA, 0x000006B1, 0x000006B1, 0x000006B0, 0x000000D5, 0x0007002C, 0x00000012, 0x000006BE, -0x000006B0, 0x000006B0, 0x000006B1, 0x000000D5, 0x0004002B, 0x00000006, 0x000006C4, 0x40C90FDB, -0x0004002B, 0x00000006, 0x000006C5, 0x3727C5AC, 0x0004002B, 0x00000006, 0x000006C6, 0x3D23D70A, -0x0006002C, 0x0000000C, 0x000006C7, 0x000006C6, 0x000006C6, 0x000006C6, 0x0007002C, 0x00000012, -0x000006C8, 0x0000012F, 0x000000F8, 0x000000F8, 0x0000012F, 0x0007002C, 0x00000012, 0x000006C9, -0x000000F8, 0x0000012F, 0x000000F8, 0x0000012F, 0x0007002C, 0x00000012, 0x000006CA, 0x000000F8, -0x000000F8, 0x000000D5, 0x000000F8, 0x0007002C, 0x00000012, 0x000006CB, 0x000000F8, 0x000000F8, -0x000000F8, 0x000000D5, 0x0007002C, 0x000002C7, 0x000006CC, 0x000006C8, 0x000006C9, 0x000006CA, -0x000006CB, 0x0004002B, 0x000000ED, 0x000006CD, 0x00000010, 0x0004001C, 0x000006CE, 0x0000007F, -0x000006CD, 0x0004002B, 0x00000006, 0x000006CF, 0xBF7127FA, 0x0004002B, 0x00000006, 0x000006D0, -0xBECC51E0, 0x0005002C, 0x0000007F, 0x000006D1, 0x000006CF, 0x000006D0, 0x0004002B, 0x00000006, -0x000006D2, 0x3F7211EE, 0x0004002B, 0x00000006, 0x000006D3, 0xBF44D71B, 0x0005002C, 0x0000007F, -0x000006D4, 0x000006D2, 0x000006D3, 0x0004002B, 0x00000006, 0x000006D5, 0xBDC0E398, 0x0004002B, -0x00000006, 0x000006D6, 0xBF6DEC6B, 0x0005002C, 0x0000007F, 0x000006D7, 0x000006D5, 0x000006D6, -0x0004002B, 0x00000006, 0x000006D8, 0x3EB09E84, 0x0004002B, 0x00000006, 0x000006D9, 0x3E967720, -0x0005002C, 0x0000007F, 0x000006DA, 0x000006D8, 0x000006D9, 0x0004002B, 0x00000006, 0x000006DB, -0xBF6A777E, 0x0004002B, 0x00000006, 0x000006DC, 0x3EEA5988, 0x0005002C, 0x0000007F, 0x000006DD, -0x000006DB, 0x000006DC, 0x0004002B, 0x00000006, 0x000006DE, 0xBF50C0D4, 0x0004002B, 0x00000006, -0x000006DF, 0xBF610E50, 0x0005002C, 0x0000007F, 0x000006E0, 0x000006DE, 0x000006DF, 0x0004002B, -0x00000006, 0x000006E1, 0xBEC3FB24, 0x0004002B, 0x00000006, 0x000006E2, 0x3E8DB498, 0x0005002C, -0x0000007F, 0x000006E3, 0x000006E1, 0x000006E2, 0x0004002B, 0x00000006, 0x000006E4, 0x3F798F60, -0x0004002B, 0x00000006, 0x000006E5, 0x3F41A8EC, 0x0005002C, 0x0000007F, 0x000006E6, 0x000006E4, -0x000006E5, 0x0004002B, 0x00000006, 0x000006E7, 0x3EE2EF78, 0x0004002B, 0x00000006, 0x000006E8, -0xBF79A12C, 0x0005002C, 0x0000007F, 0x000006E9, 0x000006E7, 0x000006E8, 0x0004002B, 0x00000006, -0x000006EA, 0x3F099500, 0x0004002B, 0x00000006, 0x000006EB, 0xBEF28D4A, 0x0005002C, 0x0000007F, -0x000006EC, 0x000006EA, 0x000006EB, 0x0004002B, 0x00000006, 0x000006ED, 0xBE87AA08, 0x0004002B, -0x00000006, 0x000006EE, 0xBED67E06, 0x0005002C, 0x0000007F, 0x000006EF, 0x000006ED, 0x000006EE, -0x0004002B, 0x00000006, 0x000006F0, 0x3F4ABEE2, 0x0004002B, 0x00000006, 0x000006F1, 0x3E437BC8, -0x0005002C, 0x0000007F, 0x000006F2, 0x000006F0, 0x000006F1, 0x0004002B, 0x00000006, 0x000006F3, -0xBE77B198, 0x0004002B, 0x00000006, 0x000006F4, 0x3F7F3FA8, 0x0005002C, 0x0000007F, 0x000006F5, -0x000006F3, 0x000006F4, 0x0004002B, 0x00000006, 0x000006F6, 0xBF5068D4, 0x0004002B, 0x00000006, -0x000006F7, 0x3F6A148A, 0x0005002C, 0x0000007F, 0x000006F8, 0x000006F6, 0x000006F7, 0x0004002B, -0x00000006, 0x000006F9, 0x3E4CA330, 0x0004002B, 0x00000006, 0x000006FA, 0x3F495268, 0x0005002C, -0x0000007F, 0x000006FB, 0x000006F9, 0x000006FA, 0x0004002B, 0x00000006, 0x000006FC, 0x3E134898, -0x0004002B, 0x00000006, 0x000006FD, 0xBE106460, 0x0005002C, 0x0000007F, 0x000006FE, 0x000006FC, -0x000006FD, 0x0013002C, 0x000006CE, 0x000006FF, 0x000006D1, 0x000006D4, 0x000006D7, 0x000006DA, -0x000006DD, 0x000006E0, 0x000006E3, 0x000006E6, 0x000006E9, 0x000006EC, 0x000006EF, 0x000006F2, -0x000006F5, 0x000006F8, 0x000006FB, 0x000006FE, 0x0004002B, 0x000000ED, 0x00000700, 0x00000040, -0x0004001C, 0x00000701, 0x0000007F, 0x00000700, 0x0004002B, 0x00000006, 0x00000702, 0xBF625322, -0x0004002B, 0x00000006, 0x00000703, 0x3DFEF391, 0x0005002C, 0x0000007F, 0x00000704, 0x00000702, -0x00000703, 0x0004002B, 0x00000006, 0x00000705, 0xBF36E169, 0x0004002B, 0x00000006, 0x00000706, -0x3CE4E26D, 0x0005002C, 0x0000007F, 0x00000707, 0x00000705, 0x00000706, 0x0004002B, 0x00000006, -0x00000708, 0xBF3F7953, 0x0004002B, 0x00000006, 0x00000709, 0x3E696463, 0x0005002C, 0x0000007F, -0x0000070A, 0x00000708, 0x00000709, 0x0004002B, 0x00000006, 0x0000070B, 0xBF708A37, 0x0004002B, -0x00000006, 0x0000070C, 0x3E797B31, 0x0005002C, 0x0000007F, 0x0000070D, 0x0000070B, 0x0000070C, -0x0004002B, 0x00000006, 0x0000070E, 0xBF7C476F, 0x0004002B, 0x00000006, 0x0000070F, 0x3D3A81DC, -0x0005002C, 0x0000007F, 0x00000710, 0x0000070E, 0x0000070F, 0x0004002B, 0x00000006, 0x00000711, -0xBF5C828C, 0x0004002B, 0x00000006, 0x00000712, 0xBE0B7DC8, 0x0005002C, 0x0000007F, 0x00000713, -0x00000711, 0x00000712, 0x0004002B, 0x00000006, 0x00000714, 0xBF61C66D, 0x0004002B, 0x00000006, -0x00000715, 0x3ECB3786, 0x0005002C, 0x0000007F, 0x00000716, 0x00000714, 0x00000715, 0x0004002B, -0x00000006, 0x00000717, 0xBEEF127F, 0x0004002B, 0x00000006, 0x00000718, 0x3C6DFE76, 0x0005002C, -0x0000007F, 0x00000719, 0x00000717, 0x00000718, 0x0004002B, 0x00000006, 0x0000071A, 0xBF0EE6A7, -0x0004002B, 0x00000006, 0x0000071B, 0x3E59C411, 0x0005002C, 0x0000007F, 0x0000071C, 0x0000071A, -0x0000071B, 0x0004002B, 0x00000006, 0x0000071D, 0xBF14151A, 0x0004002B, 0x00000006, 0x0000071E, -0xBDC43E53, 0x0005002C, 0x0000007F, 0x0000071F, 0x0000071D, 0x0000071E, 0x0004002B, 0x00000006, -0x00000720, 0xBF3D8213, 0x0004002B, 0x00000006, 0x00000721, 0xBDC3DA30, 0x0005002C, 0x0000007F, -0x00000722, 0x00000720, 0x00000721, 0x0004002B, 0x00000006, 0x00000723, 0xBF406E2B, 0x0004002B, -0x00000006, 0x00000724, 0x3EF1F927, 0x0005002C, 0x0000007F, 0x00000725, 0x00000723, 0x00000724, -0x0004002B, 0x00000006, 0x00000726, 0xBF0D9B0B, 0x0004002B, 0x00000006, 0x00000727, 0xBE790364, -0x0005002C, 0x0000007F, 0x00000728, 0x00000726, 0x00000727, 0x0004002B, 0x00000006, 0x00000729, -0xBF2CBD34, 0x0004002B, 0x00000006, 0x0000072A, 0xBEA95571, 0x0005002C, 0x0000007F, 0x0000072B, -0x00000729, 0x0000072A, 0x0004002B, 0x00000006, 0x0000072C, 0xBECE3737, 0x0004002B, 0x00000006, -0x0000072D, 0xBDFA08C0, 0x0005002C, 0x0000007F, 0x0000072E, 0x0000072C, 0x0000072D, 0x0004002B, -0x00000006, 0x0000072F, 0xBEA3B9AE, 0x0004002B, 0x00000006, 0x00000730, 0xBE9FD439, 0x0005002C, -0x0000007F, 0x00000731, 0x0000072F, 0x00000730, 0x0004002B, 0x00000006, 0x00000732, 0xBED3EDB7, -0x0004002B, 0x00000006, 0x00000733, 0xBEE127D4, 0x0005002C, 0x0000007F, 0x00000734, 0x00000732, -0x00000733, 0x0004002B, 0x00000006, 0x00000735, 0xBF7AA9C5, 0x0004002B, 0x00000006, 0x00000736, -0xBE4E132B, 0x0005002C, 0x0000007F, 0x00000737, 0x00000735, 0x00000736, 0x0004002B, 0x00000006, -0x00000738, 0xBF5D9696, 0x0004002B, 0x00000006, 0x00000739, 0xBE93CFD5, 0x0005002C, 0x0000007F, -0x0000073A, 0x00000738, 0x00000739, 0x0004002B, 0x00000006, 0x0000073B, 0xBE798D8B, 0x0004002B, -0x00000006, 0x0000073C, 0xBE3ED9E0, 0x0005002C, 0x0000007F, 0x0000073D, 0x0000073B, 0x0000073C, -0x0004002B, 0x00000006, 0x0000073E, 0xBE96FFC1, 0x0004002B, 0x00000006, 0x0000073F, 0xBD645804, -0x0005002C, 0x0000007F, 0x00000740, 0x0000073E, 0x0000073F, 0x0004002B, 0x00000006, 0x00000741, -0xBF1ABD5E, 0x0004002B, 0x00000006, 0x00000742, 0xBF0B5409, 0x0005002C, 0x0000007F, 0x00000743, -0x00000741, 0x00000742, 0x0004002B, 0x00000006, 0x00000744, 0xBED60B70, 0x0004002B, 0x00000006, -0x00000745, 0xBF167222, 0x0005002C, 0x0000007F, 0x00000746, 0x00000744, 0x00000745, 0x0004002B, -0x00000006, 0x00000747, 0xBF0C957D, 0x0004002B, 0x00000006, 0x00000748, 0xBED4EDD5, 0x0005002C, -0x0000007F, 0x00000749, 0x00000747, 0x00000748, 0x0004002B, 0x00000006, 0x0000074A, 0xBE73CB3E, -0x0004002B, 0x00000006, 0x0000074B, 0xBF1C9C5E, 0x0005002C, 0x0000007F, 0x0000074C, 0x0000074A, -0x0000074B, 0x0004002B, 0x00000006, 0x0000074D, 0xBE88B4C0, 0x0004002B, 0x00000006, 0x0000074E, -0xBEEB5E0F, 0x0005002C, 0x0000007F, 0x0000074F, 0x0000074D, 0x0000074E, 0x0004002B, 0x00000006, -0x00000750, 0xBDCCCFF2, 0x0004002B, 0x00000006, 0x00000751, 0xBE6A9D62, 0x0005002C, 0x0000007F, -0x00000752, 0x00000750, 0x00000751, 0x0004002B, 0x00000006, 0x00000753, 0xBDD0BFA1, 0x0004002B, -0x00000006, 0x00000754, 0xBEC2C16E, 0x0005002C, 0x0000007F, 0x00000755, 0x00000753, 0x00000754, -0x0004002B, 0x00000006, 0x00000756, 0xBF2E749F, 0x0004002B, 0x00000006, 0x00000757, 0xBF3365DC, -0x0005002C, 0x0000007F, 0x00000758, 0x00000756, 0x00000757, 0x0004002B, 0x00000006, 0x00000759, -0xBF4373F3, 0x0004002B, 0x00000006, 0x0000075A, 0xBF0B1B58, 0x0005002C, 0x0000007F, 0x0000075B, -0x00000759, 0x0000075A, 0x0004002B, 0x00000006, 0x0000075C, 0xBF0C8D3B, 0x0004002B, 0x00000006, -0x0000075D, 0xBF403116, 0x0005002C, 0x0000007F, 0x0000075E, 0x0000075C, 0x0000075D, 0x0004002B, -0x00000006, 0x0000075F, 0xBF4F1D93, 0x0004002B, 0x00000006, 0x00000760, 0xBED1461B, 0x0005002C, -0x0000007F, 0x00000761, 0x0000075F, 0x00000760, 0x0004002B, 0x00000006, 0x00000762, 0xBEC6B980, -0x0004002B, 0x00000006, 0x00000763, 0xBF4600B0, 0x0005002C, 0x0000007F, 0x00000764, 0x00000762, -0x00000763, 0x0004002B, 0x00000006, 0x00000765, 0xBEDBD945, 0x0004002B, 0x00000006, 0x00000766, -0xBF6517A4, 0x0005002C, 0x0000007F, 0x00000767, 0x00000765, 0x00000766, 0x0004002B, 0x00000006, -0x00000768, 0xBE06C15D, 0x0004002B, 0x00000006, 0x00000769, 0x3D853D21, 0x0005002C, 0x0000007F, -0x0000076A, 0x00000768, 0x00000769, 0x0004002B, 0x00000006, 0x0000076B, 0xBE8CCD10, 0x0004002B, -0x00000006, 0x0000076C, 0x3DD2C8C5, 0x0005002C, 0x0000007F, 0x0000076D, 0x0000076B, 0x0000076C, -0x0004002B, 0x00000006, 0x0000076E, 0xBDD953DF, 0x0004002B, 0x00000006, 0x0000076F, 0xBD8BEF07, -0x0005002C, 0x0000007F, 0x00000770, 0x0000076E, 0x0000076F, 0x0004002B, 0x00000006, 0x00000771, -0xBE96D3FA, 0x0004002B, 0x00000006, 0x00000772, 0xBF643A54, 0x0005002C, 0x0000007F, 0x00000773, -0x00000771, 0x00000772, 0x0004002B, 0x00000006, 0x00000774, 0xBF21218A, 0x0004002B, 0x00000006, -0x00000775, 0x3EC23F03, 0x0005002C, 0x0000007F, 0x00000776, 0x00000774, 0x00000775, 0x0004002B, -0x00000006, 0x00000777, 0xBED083FD, 0x0004002B, 0x00000006, 0x00000778, 0x3EADF373, 0x0005002C, -0x0000007F, 0x00000779, 0x00000777, 0x00000778, 0x0004002B, 0x00000006, 0x0000077A, 0x3D92BD3C, -0x0004002B, 0x00000006, 0x0000077B, 0xBEC4C0DF, 0x0005002C, 0x0000007F, 0x0000077C, 0x0000077A, -0x0000077B, 0x0004002B, 0x00000006, 0x0000077D, 0x3CB45F18, 0x0004002B, 0x00000006, 0x0000077E, -0xBE870FE0, 0x0005002C, 0x0000007F, 0x0000077F, 0x0000077D, 0x0000077E, 0x0004002B, 0x00000006, -0x00000780, 0x3B7E36D2, 0x0004002B, 0x00000006, 0x00000781, 0xBE0B56B8, 0x0005002C, 0x0000007F, -0x00000782, 0x00000780, 0x00000781, 0x0004002B, 0x00000006, 0x00000783, 0xBE0CD573, 0x0004002B, -0x00000006, 0x00000784, 0xBF44916D, 0x0005002C, 0x0000007F, 0x00000785, 0x00000783, 0x00000784, -0x0004002B, 0x00000006, 0x00000786, 0xBD506141, 0x0004002B, 0x00000006, 0x00000787, 0xBF67F413, -0x0005002C, 0x0000007F, 0x00000788, 0x00000786, 0x00000787, 0x0004002B, 0x00000006, 0x00000789, -0x3DE9BE90, 0x0004002B, 0x00000006, 0x0000078A, 0xBD8F77F2, 0x0005002C, 0x0000007F, 0x0000078B, -0x00000789, 0x0000078A, 0x0004002B, 0x00000006, 0x0000078C, 0x3E273BC9, 0x0004002B, 0x00000006, -0x0000078D, 0xBE5E71CE, 0x0005002C, 0x0000007F, 0x0000078E, 0x0000078C, 0x0000078D, 0x0004002B, -0x00000006, 0x0000078F, 0xBDCD562A, 0x0004002B, 0x00000006, 0x00000790, 0xBF1686A5, 0x0005002C, -0x0000007F, 0x00000791, 0x0000078F, 0x00000790, 0x0004002B, 0x00000006, 0x00000792, 0xBBA1F080, -0x0004002B, 0x00000006, 0x00000793, 0x3E006078, 0x0005002C, 0x0000007F, 0x00000794, 0x00000792, -0x00000793, 0x0004002B, 0x00000006, 0x00000795, 0x3D1098D4, 0x0004002B, 0x00000006, 0x00000796, -0xBF1E8B1A, 0x0005002C, 0x0000007F, 0x00000797, 0x00000795, 0x00000796, 0x0004002B, 0x00000006, -0x00000798, 0x3E48576D, 0x0004002B, 0x00000006, 0x00000799, 0xBEEB04EE, 0x0005002C, 0x0000007F, -0x0000079A, 0x00000798, 0x00000799, 0x0004002B, 0x00000006, 0x0000079B, 0x3E9BA1D3, 0x0004002B, -0x00000006, 0x0000079C, 0xBEB1565C, 0x0005002C, 0x0000007F, 0x0000079D, 0x0000079B, 0x0000079C, -0x0004002B, 0x00000006, 0x0000079E, 0xBF2D9924, 0x0004002B, 0x00000006, 0x0000079F, 0x3F2F62A6, -0x0005002C, 0x0000007F, 0x000007A0, 0x0000079E, 0x0000079F, 0x0004002B, 0x00000006, 0x000007A1, -0xBF20E001, 0x0004002B, 0x00000006, 0x000007A2, 0x3F020AD9, 0x0005002C, 0x0000007F, 0x000007A3, -0x000007A1, 0x000007A2, 0x0004002B, 0x00000006, 0x000007A4, 0xBF022B49, 0x0004002B, 0x00000006, -0x000007A5, 0x3EEAE1AC, 0x0005002C, 0x0000007F, 0x000007A6, 0x000007A4, 0x000007A5, 0x0004002B, -0x00000006, 0x000007A7, 0x3D039EF1, 0x0004002B, 0x00000006, 0x000007A8, 0xBF48331E, 0x0005002C, -0x0000007F, 0x000007A9, 0x000007A7, 0x000007A8, 0x0004002B, 0x00000006, 0x000007AA, 0x3DFB1316, -0x0004002B, 0x00000006, 0x000007AB, 0x3E8F8A6E, 0x0005002C, 0x0000007F, 0x000007AC, 0x000007AA, -0x000007AB, 0x0004002B, 0x00000006, 0x000007AD, 0xBD32C301, 0x0004002B, 0x00000006, 0x000007AE, -0x3E9FCE10, 0x0005002C, 0x0000007F, 0x000007AF, 0x000007AD, 0x000007AE, 0x0004002B, 0x00000006, -0x000007B0, 0x3E082F51, 0x0004002B, 0x00000006, 0x000007B1, 0x3DAE6D9C, 0x0005002C, 0x0000007F, -0x000007B2, 0x000007B0, 0x000007B1, 0x0004002B, 0x00000006, 0x000007B3, 0xBE44B76F, 0x0004002B, -0x00000006, 0x000007B4, 0x3E925AAB, 0x0005002C, 0x0000007F, 0x000007B5, 0x000007B3, 0x000007B4, -0x0004002B, 0x00000006, 0x000007B6, 0x3E3C0725, 0x0004002B, 0x00000006, 0x000007B7, 0xBF369707, -0x0005002C, 0x0000007F, 0x000007B8, 0x000007B6, 0x000007B7, 0x0004002B, 0x00000006, 0x000007B9, -0x3E87CAEA, 0x0004002B, 0x00000006, 0x000007BA, 0xBF18C261, 0x0005002C, 0x0000007F, 0x000007BB, -0x000007B9, 0x000007BA, 0x0004002B, 0x00000006, 0x000007BC, 0xBC1DBEC2, 0x0004002B, 0x00000006, -0x000007BD, 0xBEF75361, 0x0005002C, 0x0000007F, 0x000007BE, 0x000007BC, 0x000007BD, 0x0004002B, -0x00000006, 0x000007BF, 0xBC97AEDE, 0x0004002B, 0x00000006, 0x000007C0, 0x3EDF1477, 0x0005002C, -0x0000007F, 0x000007C1, 0x000007BF, 0x000007C0, 0x0043002C, 0x00000701, 0x000007C2, 0x00000704, -0x00000707, 0x0000070A, 0x0000070D, 0x00000710, 0x00000713, 0x00000716, 0x00000719, 0x0000071C, -0x0000071F, 0x00000722, 0x00000725, 0x00000728, 0x0000072B, 0x0000072E, 0x00000731, 0x00000734, -0x00000737, 0x0000073A, 0x0000073D, 0x00000740, 0x00000743, 0x00000746, 0x00000749, 0x0000074C, -0x0000074F, 0x00000752, 0x00000755, 0x00000758, 0x0000075B, 0x0000075E, 0x00000761, 0x00000764, -0x00000767, 0x0000076A, 0x0000076D, 0x00000770, 0x00000773, 0x00000776, 0x00000779, 0x0000077C, -0x0000077F, 0x00000782, 0x00000785, 0x00000788, 0x0000078B, 0x0000078E, 0x00000791, 0x00000794, -0x00000797, 0x0000079A, 0x0000079D, 0x000007A0, 0x000007A3, 0x000007A6, 0x000007A9, 0x000007AC, -0x000007AF, 0x000007B2, 0x000007B5, 0x000007B8, 0x000007BB, 0x000007BE, 0x000007C1, 0x00050036, -0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200F8, 0x00000005, 0x0004003B, 0x00000013, -0x0000052D, 0x00000007, 0x0004003B, 0x00000007, 0x00000537, 0x00000007, 0x0004003B, 0x00000007, -0x00000538, 0x00000007, 0x0004003B, 0x0000000D, 0x00000547, 0x00000007, 0x0004003B, 0x0000000D, -0x0000056B, 0x00000007, 0x0004003B, 0x000000C7, 0x00000589, 0x00000007, 0x0004003B, 0x0000000D, -0x00000597, 0x00000007, 0x0004003B, 0x00000080, 0x0000059D, 0x00000007, 0x0004003B, 0x00000007, -0x000005AA, 0x00000007, 0x0004003B, 0x00000007, 0x000005BA, 0x00000007, 0x0004003B, 0x00000007, -0x000005BF, 0x00000007, 0x0004003B, 0x0000000D, 0x000005C3, 0x00000007, 0x0004003B, 0x0000000D, -0x000005C7, 0x00000007, 0x0004003B, 0x00000007, 0x000005CB, 0x00000007, 0x0004003B, 0x00000007, -0x000005D3, 0x00000007, 0x0004003B, 0x00000007, 0x000005D8, 0x00000007, 0x0004003B, 0x00000007, -0x000005DC, 0x00000007, 0x0004003B, 0x0000000D, 0x000005E1, 0x00000007, 0x0004003B, 0x00000007, -0x000005FD, 0x00000007, 0x0004003B, 0x00000007, 0x000005FE, 0x00000007, 0x0004003B, 0x0000000D, -0x00000602, 0x00000007, 0x0004003B, 0x00000007, 0x00000605, 0x00000007, 0x0004003B, 0x00000007, -0x00000608, 0x00000007, 0x0004003B, 0x00000007, 0x0000061B, 0x00000007, 0x0004003B, 0x00000007, -0x00000625, 0x00000007, 0x0004003B, 0x00000007, 0x00000628, 0x00000007, 0x0004003B, 0x00000013, -0x0000062B, 0x00000007, 0x0004003B, 0x00000007, 0x00000634, 0x00000007, 0x0004003B, 0x0000000D, -0x00000642, 0x00000007, 0x0004003B, 0x0000000D, 0x0000064C, 0x00000007, 0x0004003B, 0x0000000D, -0x0000064D, 0x00000007, 0x0004003B, 0x0000000D, 0x00000650, 0x00000007, 0x0004003B, 0x000000C7, -0x00000652, 0x00000007, 0x0004003B, 0x0000000D, 0x00000655, 0x00000007, 0x0004003B, 0x0000000D, -0x00000656, 0x00000007, 0x0004003B, 0x0000000D, 0x00000659, 0x00000007, 0x0004003B, 0x000000C7, -0x0000065B, 0x00000007, 0x0004003B, 0x0000000D, 0x0000065E, 0x00000007, 0x0004003B, 0x00000086, -0x000006A5, 0x00000007, 0x0004003B, 0x0000000D, 0x000006A6, 0x00000007, 0x0003003E, 0x000000D4, -0x000000D5, 0x0003003E, 0x000000D6, 0x000000D7, 0x00040039, 0x00000012, 0x0000052E, 0x00000070, -0x0003003E, 0x0000052D, 0x0000052E, 0x00050041, 0x00000007, 0x0000052F, 0x0000052D, 0x000000EE, -0x0004003D, 0x00000006, 0x00000530, 0x0000052F, 0x00050041, 0x000001E1, 0x00000531, 0x000001DF, -0x000003F5, 0x0004003D, 0x00000006, 0x00000532, 0x00000531, 0x000500B8, 0x000001E5, 0x00000533, -0x00000530, 0x00000532, 0x000300F7, 0x00000535, 0x00000000, 0x000400FA, 0x00000533, 0x00000534, -0x00000535, 0x000200F8, 0x00000534, 0x000100FC, 0x000200F8, 0x00000535, 0x0003003E, 0x00000537, -0x000000F8, 0x0003003E, 0x00000538, 0x000000F8, 0x00050041, 0x000001E1, 0x00000539, 0x000001DF, -0x0000032C, 0x0004003D, 0x00000006, 0x0000053A, 0x00000539, 0x000500B4, 0x000001E5, 0x0000053B, -0x0000053A, 0x000000F8, 0x000300F7, 0x0000053D, 0x00000000, 0x000400FA, 0x0000053B, 0x0000053C, -0x00000541, 0x000200F8, 0x0000053C, 0x00040039, 0x0000000C, 0x0000053E, 0x00000073, 0x00050051, -0x00000006, 0x0000053F, 0x0000053E, 0x00000000, 0x0003003E, 0x00000537, 0x0000053F, 0x00040039, -0x00000006, 0x00000540, 0x00000076, 0x0003003E, 0x00000538, 0x00000540, 0x000200F9, 0x0000053D, -0x000200F8, 0x00000541, 0x00050041, 0x000001E1, 0x00000542, 0x000001DF, 0x0000032C, 0x0004003D, -0x00000006, 0x00000543, 0x00000542, 0x000500B4, 0x000001E5, 0x00000544, 0x00000543, 0x000000D5, -0x000300F7, 0x00000546, 0x00000000, 0x000400FA, 0x00000544, 0x00000545, 0x00000565, 0x000200F8, -0x00000545, 0x0004003D, 0x000001F7, 0x00000548, 0x0000021D, 0x00050041, 0x00000200, 0x00000549, -0x000001FE, 0x000001FF, 0x0004003D, 0x0000007F, 0x0000054A, 0x00000549, 0x00050057, 0x00000012, -0x0000054B, 0x00000548, 0x0000054A, 0x0008004F, 0x0000000C, 0x0000054C, 0x0000054B, 0x0000054B, -0x00000000, 0x00000001, 0x00000002, 0x0003003E, 0x00000547, 0x0000054C, 0x00050041, 0x000001E1, -0x0000054D, 0x000001DF, 0x0000020A, 0x0004003D, 0x00000006, 0x0000054E, 0x0000054D, 0x00050083, -0x00000006, 0x0000054F, 0x000000D5, 0x0000054E, 0x00050041, 0x000001E1, 0x00000550, 0x000001DF, -0x00000210, 0x0004003D, 0x00000006, 0x00000551, 0x00000550, 0x00050085, 0x00000006, 0x00000552, -0x0000054F, 0x00000551, 0x00050041, 0x000001E1, 0x00000553, 0x000001DF, 0x0000020A, 0x0004003D, -0x00000006, 0x00000554, 0x00000553, 0x00050041, 0x00000007, 0x00000555, 0x00000547, 0x0000030A, +0x00000000, 0x00040005, 0x0000007A, 0x65626C61, 0x00006F64, 0x00050005, 0x00000081, 0x73696F4E, +0x66762865, 0x00003B32, 0x00030005, 0x00000080, 0x00006F63, 0x00090005, 0x00000089, 0x65676F56, +0x7369446C, 0x6D61536B, 0x28656C70, 0x693B3169, 0x31663B31, 0x0000003B, 0x00050005, 0x00000086, +0x706D6173, 0x6E49656C, 0x00786564, 0x00060005, 0x00000087, 0x706D6173, 0x4373656C, 0x746E756F, +0x00000000, 0x00030005, 0x00000088, 0x00696870, 0x00090005, 0x0000008F, 0x53746547, 0x6F646168, +0x61694277, 0x66762873, 0x66763B33, 0x31693B33, 0x0000003B, 0x00060005, 0x0000008C, 0x6867696C, +0x72694474, 0x69746365, 0x00006E6F, 0x00040005, 0x0000008D, 0x6D726F6E, 0x00006C61, 0x00050005, +0x0000008E, 0x64616873, 0x6E49776F, 0x00786564, 0x00100005, 0x0000009C, 0x53464350, 0x6F646168, +0x72694477, 0x69746365, 0x6C616E6F, 0x6867694C, 0x41732874, 0x763B3132, 0x663B3466, 0x66763B31, +0x66763B33, 0x66763B33, 0x31693B33, 0x0000003B, 0x00050005, 0x00000095, 0x64616873, 0x614D776F, +0x00000070, 0x00060005, 0x00000096, 0x64616873, 0x6F43776F, 0x7364726F, 0x00000000, 0x00050005, +0x00000097, 0x61527675, 0x73756964, 0x00000000, 0x00060005, 0x00000098, 0x6867696C, 0x72694474, +0x69746365, 0x00006E6F, 0x00040005, 0x00000099, 0x6D726F6E, 0x00006C61, 0x00040005, 0x0000009A, +0x6F507377, 0x00000073, 0x00060005, 0x0000009B, 0x63736163, 0x49656461, 0x7865646E, 0x00000000, +0x00090005, 0x000000A0, 0x636C6143, 0x74616C75, 0x73614365, 0x65646163, 0x65646E49, 0x66762878, +0x00003B33, 0x00040005, 0x0000009F, 0x6F507377, 0x00000073, 0x000A0005, 0x000000A7, 0x636C6143, +0x74616C75, 0x61685365, 0x28776F64, 0x3B336676, 0x763B3169, 0x763B3366, 0x003B3366, 0x00040005, +0x000000A3, 0x6F507377, 0x00000073, 0x00060005, 0x000000A4, 0x63736163, 0x49656461, 0x7865646E, +0x00000000, 0x00060005, 0x000000A5, 0x6867696C, 0x72694474, 0x69746365, 0x00006E6F, 0x00040005, +0x000000A6, 0x6D726F6E, 0x00006C61, 0x00050005, 0x000000A9, 0x6574614D, 0x6C616972, 0x00000000, +0x00050006, 0x000000A9, 0x00000000, 0x65626C41, 0x00006F64, 0x00060006, 0x000000A9, 0x00000001, +0x6174654D, 0x63696C6C, 0x00000000, 0x00060006, 0x000000A9, 0x00000002, 0x67756F52, 0x73656E68, +0x00000073, 0x00080006, 0x000000A9, 0x00000003, 0x63726550, 0x75747065, 0x6F526C61, 0x6E686775, +0x00737365, 0x00060006, 0x000000A9, 0x00000004, 0x6C666552, 0x61746365, 0x0065636E, 0x00060006, +0x000000A9, 0x00000005, 0x73696D45, 0x65766973, 0x00000000, 0x00050006, 0x000000A9, 0x00000006, +0x6D726F4E, 0x00006C61, 0x00040006, 0x000000A9, 0x00000007, 0x00004F41, 0x00050006, 0x000000A9, +0x00000008, 0x77656956, 0x00000000, 0x00050006, 0x000000A9, 0x00000009, 0x746F444E, 0x00000056, +0x00040006, 0x000000A9, 0x0000000A, 0x00003046, 0x00080006, 0x000000A9, 0x0000000B, 0x72656E45, +0x6F437967, 0x6E65706D, 0x69746173, 0x00006E6F, 0x00040006, 0x000000A9, 0x0000000C, 0x00676664, +0x00040005, 0x000000AA, 0x6867694C, 0x00000074, 0x00050006, 0x000000AA, 0x00000000, 0x6F6C6F63, +0x00007275, 0x00060006, 0x000000AA, 0x00000001, 0x69736F70, 0x6E6F6974, 0x00000000, 0x00060006, +0x000000AA, 0x00000002, 0x65726964, 0x6F697463, 0x0000006E, 0x00060006, 0x000000AA, 0x00000003, +0x65746E69, 0x7469736E, 0x00000079, 0x00050006, 0x000000AA, 0x00000004, 0x69646172, 0x00007375, +0x00050006, 0x000000AA, 0x00000005, 0x65707974, 0x00000000, 0x00050006, 0x000000AA, 0x00000006, +0x6C676E61, 0x00000065, 0x00230005, 0x000000B3, 0x746F7349, 0x69706F72, 0x626F4C63, 0x74732865, +0x74637572, 0x74614D2D, 0x61697265, 0x66762D6C, 0x31662D34, 0x2D31662D, 0x662D3166, 0x66762D31, +0x66762D33, 0x31662D33, 0x3366762D, 0x2D31662D, 0x2D336676, 0x2D336676, 0x31326676, 0x7274733B, +0x2D746375, 0x6867694C, 0x66762D74, 0x66762D34, 0x66762D34, 0x31662D34, 0x2D31662D, 0x662D3166, +0x763B3131, 0x663B3366, 0x31663B31, 0x3B31663B, 0x003B3166, 0x00050005, 0x000000AC, 0x6574616D, +0x6C616972, 0x00000000, 0x00040005, 0x000000AD, 0x6867696C, 0x00000074, 0x00030005, 0x000000AE, +0x00000068, 0x00030005, 0x000000AF, 0x00566F4E, 0x00030005, 0x000000B0, 0x004C6F4E, 0x00030005, +0x000000B1, 0x00486F4E, 0x00030005, 0x000000B2, 0x00486F4C, 0x00180005, 0x000000BA, 0x66666944, +0x4C657375, 0x2865626F, 0x75727473, 0x4D2D7463, 0x72657461, 0x2D6C6169, 0x2D346676, 0x662D3166, +0x31662D31, 0x2D31662D, 0x2D336676, 0x2D336676, 0x762D3166, 0x662D3366, 0x66762D31, 0x66762D33, +0x66762D33, 0x663B3132, 0x31663B31, 0x3B31663B, 0x00000000, 0x00050005, 0x000000B6, 0x6574616D, +0x6C616972, 0x00000000, 0x00030005, 0x000000B7, 0x00566F4E, 0x00030005, 0x000000B8, 0x004C6F4E, +0x00030005, 0x000000B9, 0x00486F4C, 0x00230005, 0x000000C3, 0x63657053, 0x72616C75, 0x65626F4C, +0x72747328, 0x2D746375, 0x6574614D, 0x6C616972, 0x3466762D, 0x2D31662D, 0x662D3166, 0x31662D31, +0x3366762D, 0x3366762D, 0x2D31662D, 0x2D336676, 0x762D3166, 0x762D3366, 0x762D3366, 0x3B313266, +0x75727473, 0x4C2D7463, 0x74686769, 0x3466762D, 0x3466762D, 0x3466762D, 0x2D31662D, 0x662D3166, +0x31662D31, 0x66763B31, 0x31663B33, 0x3B31663B, 0x663B3166, 0x00003B31, 0x00050005, 0x000000BC, +0x6574616D, 0x6C616972, 0x00000000, 0x00040005, 0x000000BD, 0x6867696C, 0x00000074, 0x00030005, +0x000000BE, 0x00000068, 0x00030005, 0x000000BF, 0x00566F4E, 0x00030005, 0x000000C0, 0x004C6F4E, +0x00030005, 0x000000C1, 0x00486F4E, 0x00030005, 0x000000C2, 0x00486F4C, 0x00170005, 0x000000CA, +0x6867694C, 0x676E6974, 0x33667628, 0x3366763B, 0x7274733B, 0x2D746375, 0x6574614D, 0x6C616972, +0x3466762D, 0x2D31662D, 0x662D3166, 0x31662D31, 0x3366762D, 0x3366762D, 0x2D31662D, 0x2D336676, +0x762D3166, 0x762D3366, 0x762D3366, 0x3B313266, 0x00000000, 0x00030005, 0x000000C7, 0x00003046, +0x00040005, 0x000000C8, 0x6F507377, 0x00000073, 0x00050005, 0x000000C9, 0x6574616D, 0x6C616972, +0x00000000, 0x00150005, 0x000000CF, 0x284C4249, 0x3B336676, 0x3B336676, 0x75727473, 0x4D2D7463, +0x72657461, 0x2D6C6169, 0x2D346676, 0x662D3166, 0x31662D31, 0x2D31662D, 0x2D336676, 0x2D336676, +0x762D3166, 0x662D3366, 0x66762D31, 0x66762D33, 0x66762D33, 0x003B3132, 0x00030005, 0x000000CC, +0x00003046, 0x00030005, 0x000000CD, 0x0000724C, 0x00050005, 0x000000CE, 0x6574616D, 0x6C616972, +0x00000000, 0x00050005, 0x000000D2, 0x64616853, 0x6146776F, 0x00006564, 0x00030005, 0x000000D4, +0x00494850, 0x00030005, 0x000000D6, 0x00003278, 0x00040005, 0x000000E7, 0x61726170, 0x0000006D, +0x00030005, 0x000000FA, 0x0048784E, 0x00030005, 0x000000FC, 0x00000061, 0x00030005, 0x00000100, +0x0000006B, 0x00030005, 0x0000010A, 0x00000064, 0x00040005, 0x0000011A, 0x61726170, 0x0000006D, +0x00030005, 0x0000012C, 0x00303966, 0x00060005, 0x00000136, 0x6867696C, 0x61635374, 0x72657474, +0x00000000, 0x00040005, 0x00000137, 0x61726170, 0x0000006D, 0x00040005, 0x00000138, 0x61726170, +0x0000006D, 0x00040005, 0x0000013A, 0x61726170, 0x0000006D, 0x00050005, 0x0000013D, 0x77656976, +0x74616353, 0x00726574, 0x00040005, 0x0000013E, 0x61726170, 0x0000006D, 0x00040005, 0x0000013F, +0x61726170, 0x0000006D, 0x00040005, 0x00000141, 0x61726170, 0x0000006D, 0x00030005, 0x0000014A, +0x00003261, 0x00040005, 0x0000014E, 0x4C584747, 0x00000000, 0x00040005, 0x0000015C, 0x56584747, +0x00000000, 0x00050005, 0x00000170, 0x72657061, 0x65727574, 0x00000000, 0x00050005, 0x00000176, +0x7263696D, 0x6168536F, 0x00776F64, 0x00040005, 0x0000017A, 0x61726170, 0x0000006D, 0x00040005, +0x00000181, 0x61726170, 0x0000006D, 0x00040005, 0x00000183, 0x61726170, 0x0000006D, 0x00040005, +0x00000185, 0x61726170, 0x0000006D, 0x00040005, 0x00000187, 0x61726170, 0x0000006D, 0x00040005, +0x000001AE, 0x61726170, 0x0000006D, 0x00040005, 0x000001B0, 0x61726170, 0x0000006D, 0x00040005, +0x000001B5, 0x61726170, 0x0000006D, 0x00040005, 0x000001B7, 0x61726170, 0x0000006D, 0x00040005, +0x000001B9, 0x61726170, 0x0000006D, 0x00030005, 0x000001BE, 0x00303966, 0x00040005, 0x000001C2, +0x61726170, 0x0000006D, 0x00040005, 0x000001C4, 0x61726170, 0x0000006D, 0x00040005, 0x000001C6, +0x61726170, 0x0000006D, 0x00070005, 0x000001DB, 0x66696E55, 0x4D6D726F, 0x72657461, 0x446C6169, +0x00617461, 0x00070006, 0x000001DB, 0x00000000, 0x65626C41, 0x6F436F64, 0x72756F6C, 0x00000000, +0x00060006, 0x000001DB, 0x00000001, 0x67756F52, 0x73656E68, 0x00000073, 0x00060006, 0x000001DB, +0x00000002, 0x6174654D, 0x63696C6C, 0x00000000, 0x00060006, 0x000001DB, 0x00000003, 0x6C666552, +0x61746365, 0x0065636E, 0x00060006, 0x000001DB, 0x00000004, 0x73696D45, 0x65766973, 0x00000000, +0x00070006, 0x000001DB, 0x00000005, 0x65626C41, 0x614D6F64, 0x63614670, 0x00726F74, 0x00080006, +0x000001DB, 0x00000006, 0x6174654D, 0x63696C6C, 0x4670614D, 0x6F746361, 0x00000072, 0x00080006, +0x000001DB, 0x00000007, 0x67756F52, 0x73656E68, 0x70614D73, 0x74636146, 0x0000726F, 0x00070006, +0x000001DB, 0x00000008, 0x6D726F4E, 0x614D6C61, 0x63614670, 0x00726F74, 0x00080006, 0x000001DB, +0x00000009, 0x73696D45, 0x65766973, 0x4670614D, 0x6F746361, 0x00000072, 0x00060006, 0x000001DB, +0x0000000A, 0x614D4F41, 0x63614670, 0x00726F74, 0x00060006, 0x000001DB, 0x0000000B, 0x68706C41, +0x74754361, 0x0066664F, 0x00060006, 0x000001DB, 0x0000000C, 0x6B726F77, 0x776F6C66, 0x00000000, +0x00070005, 0x000001DD, 0x6574616D, 0x6C616972, 0x706F7250, 0x69747265, 0x00007365, 0x00050005, +0x000001F7, 0x6C415F75, 0x6F646562, 0x0070614D, 0x00050005, 0x000001FA, 0x74726556, 0x61447865, +0x00006174, 0x00050006, 0x000001FA, 0x00000000, 0x6F6C6F43, 0x00007275, 0x00060006, 0x000001FA, +0x00000001, 0x43786554, 0x64726F6F, 0x00000000, 0x00060006, 0x000001FA, 0x00000002, 0x69736F50, +0x6E6F6974, 0x00000000, 0x00050006, 0x000001FA, 0x00000003, 0x6D726F4E, 0x00006C61, 0x00060006, +0x000001FA, 0x00000004, 0x6C726F57, 0x726F4E64, 0x006C616D, 0x00060005, 0x000001FC, 0x74726556, +0x754F7865, 0x74757074, 0x00000000, 0x00040005, 0x00000202, 0x61726170, 0x0000006D, 0x00060005, +0x0000021B, 0x654D5F75, 0x6C6C6174, 0x614D6369, 0x00000070, 0x00060005, 0x00000237, 0x6F525F75, +0x6E686775, 0x4D737365, 0x00007061, 0x00040005, 0x0000024E, 0x4F415F75, 0x0070614D, 0x00060005, +0x0000026A, 0x6D455F75, 0x69737369, 0x614D6576, 0x00000070, 0x00040005, 0x0000026F, 0x61726170, +0x0000006D, 0x00050005, 0x00000281, 0x646C6F47, 0x6E416E65, 0x00656C67, 0x00030005, 0x00000283, +0x00000072, 0x00040005, 0x0000028C, 0x74656874, 0x00000061, 0x00040005, 0x00000293, 0x656E6973, +0x00000000, 0x00040005, 0x00000296, 0x69736F63, 0x0000656E, 0x00040005, 0x000002A2, 0x426E696D, +0x00736169, 0x00040005, 0x000002A3, 0x6867694C, 0x00000074, 0x00050006, 0x000002A3, 0x00000000, +0x6F6C6F63, 0x00007275, 0x00060006, 0x000002A3, 0x00000001, 0x69736F70, 0x6E6F6974, 0x00000000, +0x00060006, 0x000002A3, 0x00000002, 0x65726964, 0x6F697463, 0x0000006E, 0x00060006, 0x000002A3, +0x00000003, 0x65746E69, 0x7469736E, 0x00000079, 0x00050006, 0x000002A3, 0x00000004, 0x69646172, +0x00007375, 0x00050006, 0x000002A3, 0x00000005, 0x65707974, 0x00000000, 0x00050006, 0x000002A3, +0x00000006, 0x6C676E61, 0x00000065, 0x00050005, 0x000002AA, 0x4C4F4255, 0x74686769, 0x00000000, +0x00050006, 0x000002AA, 0x00000000, 0x6867696C, 0x00007374, 0x00070006, 0x000002AA, 0x00000001, +0x64616853, 0x7254776F, 0x66736E61, 0x006D726F, 0x00060006, 0x000002AA, 0x00000002, 0x77656956, +0x7274614D, 0x00007869, 0x00060006, 0x000002AA, 0x00000003, 0x6867694C, 0x65695674, 0x00000077, +0x00060006, 0x000002AA, 0x00000004, 0x73616942, 0x7274614D, 0x00007869, 0x00070006, 0x000002AA, +0x00000005, 0x656D6163, 0x6F506172, 0x69746973, 0x00006E6F, 0x00060006, 0x000002AA, 0x00000006, +0x696C7053, 0x70654474, 0x00736874, 0x00060006, 0x000002AA, 0x00000007, 0x6867694C, 0x7A695374, +0x00000065, 0x00070006, 0x000002AA, 0x00000008, 0x5378614D, 0x6F646168, 0x73694477, 0x00000074, +0x00060006, 0x000002AA, 0x00000009, 0x64616853, 0x6146776F, 0x00006564, 0x00060006, 0x000002AA, +0x0000000A, 0x63736143, 0x46656461, 0x00656461, 0x00060006, 0x000002AA, 0x0000000B, 0x6867694C, +0x756F4374, 0x0000746E, 0x00060006, 0x000002AA, 0x0000000C, 0x64616853, 0x6F43776F, 0x00746E75, +0x00050006, 0x000002AA, 0x0000000D, 0x65646F4D, 0x00000000, 0x00060006, 0x000002AA, 0x0000000E, +0x4D766E45, 0x6F437069, 0x00746E75, 0x00060006, 0x000002AA, 0x0000000F, 0x74696E49, 0x426C6169, +0x00736169, 0x00050006, 0x000002AA, 0x00000010, 0x74646957, 0x00000068, 0x00050006, 0x000002AA, +0x00000011, 0x67696548, 0x00007468, 0x00070006, 0x000002AA, 0x00000012, 0x64616873, 0x6E45776F, +0x656C6261, 0x00000064, 0x00030005, 0x000002AC, 0x006F6275, 0x00040005, 0x000002B0, 0x73616962, +0x00000000, 0x00040005, 0x000002BC, 0x73616962, 0x00000000, 0x00040005, 0x000002BD, 0x61726170, +0x0000006D, 0x00040005, 0x000002BF, 0x61726170, 0x0000006D, 0x00040005, 0x000002C1, 0x61726170, +0x0000006D, 0x00030005, 0x000002C4, 0x006D7573, 0x00040005, 0x000002C5, 0x73696F6E, 0x00000065, +0x00040005, 0x000002C6, 0x61726170, 0x0000006D, 0x00030005, 0x000002CA, 0x00000069, 0x00040005, +0x000002D3, 0x7366666F, 0x00007465, 0x00040005, 0x000002D4, 0x61726170, 0x0000006D, 0x00040005, +0x000002D6, 0x61726170, 0x0000006D, 0x00040005, 0x000002D7, 0x61726170, 0x0000006D, 0x00030005, +0x000002DD, 0x0000007A, 0x00060005, 0x000002FA, 0x63736163, 0x49656461, 0x7865646E, 0x00000000, +0x00040005, 0x000002FB, 0x77656976, 0x00736F50, 0x00030005, 0x00000305, 0x00000069, 0x00050005, +0x00000321, 0x64616873, 0x6F43776F, 0x0064726F, 0x00040005, 0x00000333, 0x5241454E, 0x00000000, +0x00050005, 0x00000335, 0x61527675, 0x73756964, 0x00000000, 0x00040005, 0x00000340, 0x77656976, +0x00736F50, 0x00060005, 0x00000349, 0x64616873, 0x6D41776F, 0x746E756F, 0x00000000, 0x00050005, +0x0000034A, 0x61685375, 0x4D776F64, 0x00007061, 0x00040005, 0x0000034B, 0x61726170, 0x0000006D, +0x00040005, 0x0000034D, 0x61726170, 0x0000006D, 0x00040005, 0x0000034F, 0x61726170, 0x0000006D, +0x00040005, 0x00000351, 0x61726170, 0x0000006D, 0x00040005, 0x00000353, 0x61726170, 0x0000006D, +0x00040005, 0x00000355, 0x61726170, 0x0000006D, 0x00050005, 0x00000358, 0x63736163, 0x46656461, +0x00656461, 0x00050005, 0x00000365, 0x63736163, 0x4E656461, 0x00747865, 0x00060005, 0x0000037F, +0x64616873, 0x6D41776F, 0x746E756F, 0x00000031, 0x00040005, 0x00000380, 0x61726170, 0x0000006D, +0x00040005, 0x00000382, 0x61726170, 0x0000006D, 0x00040005, 0x00000384, 0x61726170, 0x0000006D, +0x00040005, 0x00000386, 0x61726170, 0x0000006D, 0x00040005, 0x00000388, 0x61726170, 0x0000006D, +0x00040005, 0x0000038A, 0x61726170, 0x0000006D, 0x00030005, 0x00000398, 0x00000044, 0x00040005, +0x0000039A, 0x61726170, 0x0000006D, 0x00040005, 0x0000039C, 0x61726170, 0x0000006D, 0x00030005, +0x0000039F, 0x00000056, 0x00040005, 0x000003A0, 0x61726170, 0x0000006D, 0x00040005, 0x000003A2, +0x61726170, 0x0000006D, 0x00040005, 0x000003A4, 0x61726170, 0x0000006D, 0x00030005, 0x000003A7, +0x00000046, 0x00040005, 0x000003A9, 0x61726170, 0x0000006D, 0x00040005, 0x000003B5, 0x61726170, +0x0000006D, 0x00040005, 0x000003B7, 0x61726170, 0x0000006D, 0x00040005, 0x000003B9, 0x61726170, +0x0000006D, 0x00040005, 0x000003BB, 0x61726170, 0x0000006D, 0x00040005, 0x000003C1, 0x61726170, +0x0000006D, 0x00040005, 0x000003C3, 0x61726170, 0x0000006D, 0x00040005, 0x000003C5, 0x61726170, +0x0000006D, 0x00040005, 0x000003C7, 0x61726170, 0x0000006D, 0x00040005, 0x000003CC, 0x75736572, +0x0000746C, 0x00030005, 0x000003CE, 0x00000069, 0x00040005, 0x000003DA, 0x6867696C, 0x00000074, +0x00040005, 0x000003EE, 0x756C6176, 0x00000065, 0x00030005, 0x000003F4, 0x0000004C, 0x00040005, +0x000003FA, 0x74736964, 0x00000000, 0x00040005, 0x000003FF, 0x65747461, 0x0000006E, 0x00050005, +0x00000406, 0x65747461, 0x7461756E, 0x006E6F69, 0x00030005, 0x0000041F, 0x0000004C, 0x00050005, +0x00000425, 0x6F747563, 0x6E416666, 0x00656C67, 0x00040005, 0x00000429, 0x74736964, 0x00000000, +0x00040005, 0x0000042E, 0x74656874, 0x00000061, 0x00040005, 0x00000434, 0x69737065, 0x006E6F6C, +0x00050005, 0x0000043A, 0x65747461, 0x7461756E, 0x006E6F69, 0x00060005, 0x0000044B, 0x63736163, +0x49656461, 0x7865646E, 0x00000000, 0x00040005, 0x0000044C, 0x61726170, 0x0000006D, 0x00040005, +0x00000455, 0x61726170, 0x0000006D, 0x00040005, 0x00000457, 0x61726170, 0x0000006D, 0x00040005, +0x00000459, 0x61726170, 0x0000006D, 0x00040005, 0x0000045D, 0x61726170, 0x0000006D, 0x00030005, +0x00000462, 0x0000694C, 0x00050005, 0x00000466, 0x6461724C, 0x636E6169, 0x00000065, 0x00030005, +0x0000046D, 0x0000684C, 0x00050005, 0x00000473, 0x6867696C, 0x4C6F4E74, 0x00000000, 0x00040005, +0x00000478, 0x61726170, 0x0000006D, 0x00030005, 0x0000047A, 0x00000068, 0x00050005, 0x00000480, +0x64616873, 0x5F676E69, 0x00566F4E, 0x00040005, 0x00000486, 0x61726170, 0x0000006D, 0x00030005, +0x00000488, 0x00566F4E, 0x00030005, 0x0000048A, 0x004C6F4E, 0x00040005, 0x0000048B, 0x61726170, +0x0000006D, 0x00030005, 0x0000048E, 0x00486F4E, 0x00040005, 0x00000493, 0x61726170, 0x0000006D, +0x00030005, 0x00000495, 0x00486F4C, 0x00040005, 0x00000499, 0x61726170, 0x0000006D, 0x00030005, +0x0000049B, 0x00006446, 0x00040005, 0x0000049D, 0x61726170, 0x0000006D, 0x00040005, 0x0000049F, +0x61726170, 0x0000006D, 0x00040005, 0x000004A1, 0x61726170, 0x0000006D, 0x00030005, 0x000004A4, +0x00007246, 0x00040005, 0x000004A8, 0x61726170, 0x0000006D, 0x00040005, 0x000004AA, 0x61726170, +0x0000006D, 0x00040005, 0x000004AC, 0x61726170, 0x0000006D, 0x00040005, 0x000004AE, 0x61726170, +0x0000006D, 0x00040005, 0x000004B1, 0x6F6C6F63, 0x00007275, 0x00040005, 0x000004BB, 0x61726170, +0x0000006D, 0x00040005, 0x000004BD, 0x61726170, 0x0000006D, 0x00050005, 0x000004CA, 0x61727269, +0x6E616964, 0x00006563, 0x00040005, 0x000004CE, 0x72724975, 0x0070614D, 0x00030005, 0x000004D4, +0x00000046, 0x00040005, 0x000004D5, 0x61726170, 0x0000006D, 0x00040005, 0x000004D7, 0x61726170, +0x0000006D, 0x00040005, 0x000004DA, 0x61726170, 0x0000006D, 0x00030005, 0x000004DE, 0x0000646B, +0x00050005, 0x000004E6, 0x66666964, 0x49657375, 0x00004C42, 0x00080005, 0x000004EC, 0x6E455F75, +0x64615276, 0x636E6169, 0x78655465, 0x6576654C, 0x0000736C, 0x00070005, 0x000004F0, 0x63657073, +0x72616C75, 0x61727249, 0x6E616964, 0x00006563, 0x00040005, 0x000004F1, 0x766E4575, 0x0070614D, +0x00050005, 0x000004FB, 0x63657073, 0x72616C75, 0x004C4249, 0x00050005, 0x0000050E, 0x43786574, +0x756F6C6F, 0x00000072, 0x00050005, 0x00000518, 0x6174656D, 0x63696C6C, 0x00000000, 0x00050005, +0x00000519, 0x67756F72, 0x73656E68, 0x00000073, 0x00030005, 0x00000528, 0x00786574, 0x00030005, +0x0000054C, 0x00786574, 0x00050005, 0x0000056A, 0x6574616D, 0x6C616972, 0x00000000, 0x00050005, +0x0000057F, 0x6F4E5F75, 0x6C616D72, 0x0070614D, 0x00040005, 0x00000598, 0x61726170, 0x0000006D, +0x00030005, 0x0000059E, 0x00007675, 0x00060005, 0x000005A0, 0x465F6C67, 0x43676172, 0x64726F6F, +0x00000000, 0x00040005, 0x000005AB, 0x6F617373, 0x00000000, 0x00050005, 0x000005AC, 0x41535375, +0x70614D4F, 0x00000000, 0x00040005, 0x000005BB, 0x61726170, 0x0000006D, 0x00050005, 0x000005C0, +0x67756F72, 0x73656E68, 0x00003273, 0x00040005, 0x000005C4, 0x75646E64, 0x00000000, 0x00040005, +0x000005C8, 0x76646E64, 0x00000000, 0x00050005, 0x000005CC, 0x69726176, 0x65636E61, 0x00000000, +0x00070005, 0x000005D4, 0x6E72656B, 0x6F526C65, 0x6E686775, 0x32737365, 0x00000000, 0x00070005, +0x000005D9, 0x746C6966, 0x64657265, 0x67756F52, 0x73656E68, 0x00003273, 0x00040005, 0x000005DD, +0x61726170, 0x0000006D, 0x00040005, 0x000005E7, 0x6F507377, 0x00000073, 0x00050005, 0x000005F9, +0x44524275, 0x54554C46, 0x00000000, 0x00050005, 0x00000603, 0x6C666572, 0x61746365, 0x0065636E, +0x00040005, 0x00000604, 0x61726170, 0x0000006D, 0x00030005, 0x00000608, 0x00003046, 0x00040005, +0x0000060B, 0x61726170, 0x0000006D, 0x00040005, 0x0000060E, 0x61726170, 0x0000006D, 0x00040005, +0x00000621, 0x61726170, 0x0000006D, 0x00060005, 0x0000062B, 0x64616873, 0x6944776F, 0x6E617473, +0x00006563, 0x00070005, 0x0000062E, 0x6E617274, 0x69746973, 0x69446E6F, 0x6E617473, 0x00006563, +0x00040005, 0x00000631, 0x77656976, 0x00736F50, 0x00050005, 0x0000063A, 0x74736964, 0x65636E61, +0x00000000, 0x00030005, 0x00000648, 0x0000724C, 0x00070005, 0x00000652, 0x6867696C, 0x6E6F4374, +0x62697274, 0x6F697475, 0x0000006E, 0x00040005, 0x00000653, 0x61726170, 0x0000006D, 0x00040005, +0x00000656, 0x61726170, 0x0000006D, 0x00040005, 0x00000658, 0x61726170, 0x0000006D, 0x00060005, +0x0000065B, 0x436C6269, 0x72746E6F, 0x74756269, 0x006E6F69, 0x00040005, 0x0000065C, 0x61726170, +0x0000006D, 0x00040005, 0x0000065F, 0x61726170, 0x0000006D, 0x00040005, 0x00000661, 0x61726170, +0x0000006D, 0x00050005, 0x00000664, 0x616E6966, 0x6C6F436C, 0x0072756F, 0x00050005, 0x0000066C, +0x4374756F, 0x726F6C6F, 0x00000000, 0x00060005, 0x000006AB, 0x63736163, 0x49656461, 0x7865646E, +0x00000000, 0x00040005, 0x000006AC, 0x61726170, 0x0000006D, 0x00050048, 0x000001DB, 0x00000000, +0x00000023, 0x00000000, 0x00050048, 0x000001DB, 0x00000001, 0x00000023, 0x00000010, 0x00050048, +0x000001DB, 0x00000002, 0x00000023, 0x00000014, 0x00050048, 0x000001DB, 0x00000003, 0x00000023, +0x00000018, 0x00050048, 0x000001DB, 0x00000004, 0x00000023, 0x0000001C, 0x00050048, 0x000001DB, +0x00000005, 0x00000023, 0x00000020, 0x00050048, 0x000001DB, 0x00000006, 0x00000023, 0x00000024, +0x00050048, 0x000001DB, 0x00000007, 0x00000023, 0x00000028, 0x00050048, 0x000001DB, 0x00000008, +0x00000023, 0x0000002C, 0x00050048, 0x000001DB, 0x00000009, 0x00000023, 0x00000030, 0x00050048, +0x000001DB, 0x0000000A, 0x00000023, 0x00000034, 0x00050048, 0x000001DB, 0x0000000B, 0x00000023, +0x00000038, 0x00050048, 0x000001DB, 0x0000000C, 0x00000023, 0x0000003C, 0x00030047, 0x000001DB, +0x00000002, 0x00040047, 0x000001DD, 0x00000022, 0x00000001, 0x00040047, 0x000001DD, 0x00000021, +0x00000006, 0x00040047, 0x000001F7, 0x00000022, 0x00000001, 0x00040047, 0x000001F7, 0x00000021, +0x00000000, 0x00040047, 0x000001FC, 0x0000001E, 0x00000000, 0x00040047, 0x0000021B, 0x00000022, +0x00000001, 0x00040047, 0x0000021B, 0x00000021, 0x00000001, 0x00040047, 0x00000237, 0x00000022, +0x00000001, 0x00040047, 0x00000237, 0x00000021, 0x00000002, 0x00040047, 0x0000024E, 0x00000022, +0x00000001, 0x00040047, 0x0000024E, 0x00000021, 0x00000004, 0x00040047, 0x0000026A, 0x00000022, +0x00000001, 0x00040047, 0x0000026A, 0x00000021, 0x00000005, 0x00050048, 0x000002A3, 0x00000000, +0x00000023, 0x00000000, 0x00050048, 0x000002A3, 0x00000001, 0x00000023, 0x00000010, 0x00050048, +0x000002A3, 0x00000002, 0x00000023, 0x00000020, 0x00050048, 0x000002A3, 0x00000003, 0x00000023, +0x00000030, 0x00050048, 0x000002A3, 0x00000004, 0x00000023, 0x00000034, 0x00050048, 0x000002A3, +0x00000005, 0x00000023, 0x00000038, 0x00050048, 0x000002A3, 0x00000006, 0x00000023, 0x0000003C, +0x00040047, 0x000002A5, 0x00000006, 0x00000040, 0x00040047, 0x000002A8, 0x00000006, 0x00000040, +0x00040047, 0x000002A9, 0x00000006, 0x00000010, 0x00050048, 0x000002AA, 0x00000000, 0x00000023, +0x00000000, 0x00040048, 0x000002AA, 0x00000001, 0x00000005, 0x00050048, 0x000002AA, 0x00000001, +0x00000023, 0x00000800, 0x00050048, 0x000002AA, 0x00000001, 0x00000007, 0x00000010, 0x00040048, +0x000002AA, 0x00000002, 0x00000005, 0x00050048, 0x000002AA, 0x00000002, 0x00000023, 0x00000900, +0x00050048, 0x000002AA, 0x00000002, 0x00000007, 0x00000010, 0x00040048, 0x000002AA, 0x00000003, +0x00000005, 0x00050048, 0x000002AA, 0x00000003, 0x00000023, 0x00000940, 0x00050048, 0x000002AA, +0x00000003, 0x00000007, 0x00000010, 0x00040048, 0x000002AA, 0x00000004, 0x00000005, 0x00050048, +0x000002AA, 0x00000004, 0x00000023, 0x00000980, 0x00050048, 0x000002AA, 0x00000004, 0x00000007, +0x00000010, 0x00050048, 0x000002AA, 0x00000005, 0x00000023, 0x000009C0, 0x00050048, 0x000002AA, +0x00000006, 0x00000023, 0x000009D0, 0x00050048, 0x000002AA, 0x00000007, 0x00000023, 0x00000A10, +0x00050048, 0x000002AA, 0x00000008, 0x00000023, 0x00000A14, 0x00050048, 0x000002AA, 0x00000009, +0x00000023, 0x00000A18, 0x00050048, 0x000002AA, 0x0000000A, 0x00000023, 0x00000A1C, 0x00050048, +0x000002AA, 0x0000000B, 0x00000023, 0x00000A20, 0x00050048, 0x000002AA, 0x0000000C, 0x00000023, +0x00000A24, 0x00050048, 0x000002AA, 0x0000000D, 0x00000023, 0x00000A28, 0x00050048, 0x000002AA, +0x0000000E, 0x00000023, 0x00000A2C, 0x00050048, 0x000002AA, 0x0000000F, 0x00000023, 0x00000A30, +0x00050048, 0x000002AA, 0x00000010, 0x00000023, 0x00000A34, 0x00050048, 0x000002AA, 0x00000011, +0x00000023, 0x00000A38, 0x00050048, 0x000002AA, 0x00000012, 0x00000023, 0x00000A3C, 0x00030047, +0x000002AA, 0x00000002, 0x00040047, 0x000002AC, 0x00000022, 0x00000002, 0x00040047, 0x000002AC, +0x00000021, 0x00000005, 0x00040047, 0x0000034A, 0x00000022, 0x00000002, 0x00040047, 0x0000034A, +0x00000021, 0x00000003, 0x00040047, 0x000004CE, 0x00000022, 0x00000002, 0x00040047, 0x000004CE, +0x00000021, 0x00000002, 0x00040047, 0x000004F1, 0x00000022, 0x00000002, 0x00040047, 0x000004F1, +0x00000021, 0x00000001, 0x00040047, 0x0000057F, 0x00000022, 0x00000001, 0x00040047, 0x0000057F, +0x00000021, 0x00000003, 0x00040047, 0x000005A0, 0x0000000B, 0x0000000F, 0x00040047, 0x000005AC, +0x00000022, 0x00000002, 0x00040047, 0x000005AC, 0x00000021, 0x00000004, 0x00040047, 0x000005F9, +0x00000022, 0x00000002, 0x00040047, 0x000005F9, 0x00000021, 0x00000000, 0x00040047, 0x0000066C, +0x0000001E, 0x00000000, 0x00020013, 0x00000002, 0x00030021, 0x00000003, 0x00000002, 0x00030016, +0x00000006, 0x00000020, 0x00040020, 0x00000007, 0x00000007, 0x00000006, 0x00040021, 0x00000008, +0x00000006, 0x00000007, 0x00040017, 0x0000000C, 0x00000006, 0x00000003, 0x00040020, 0x0000000D, +0x00000007, 0x0000000C, 0x00040021, 0x0000000E, 0x0000000C, 0x0000000D, 0x00040017, 0x00000012, +0x00000006, 0x00000004, 0x00040020, 0x00000013, 0x00000007, 0x00000012, 0x00040021, 0x00000014, +0x00000012, 0x00000013, 0x00070021, 0x0000001B, 0x00000006, 0x00000007, 0x00000007, 0x0000000C, +0x0000000C, 0x00060021, 0x00000022, 0x0000000C, 0x0000000C, 0x00000007, 0x00000007, 0x00060021, +0x00000028, 0x00000006, 0x00000007, 0x00000007, 0x00000007, 0x00070021, 0x0000002E, 0x00000006, +0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00050021, 0x0000003A, 0x00000006, 0x00000007, +0x00000007, 0x00050021, 0x00000048, 0x0000000C, 0x00000012, 0x00000007, 0x00060021, 0x0000004D, +0x0000000C, 0x00000012, 0x00000007, 0x00000007, 0x00050021, 0x00000064, 0x0000000C, 0x0000000C, +0x00000007, 0x00060021, 0x00000069, 0x0000000C, 0x0000000D, 0x00000007, 0x00000007, 0x00030021, +0x0000006F, 0x00000012, 0x00030021, 0x00000072, 0x0000000C, 0x00030021, 0x00000075, 0x00000006, +0x00040017, 0x0000007D, 0x00000006, 0x00000002, 0x00040020, 0x0000007E, 0x00000007, 0x0000007D, +0x00040021, 0x0000007F, 0x00000006, 0x0000007E, 0x00040015, 0x00000083, 0x00000020, 0x00000001, +0x00040020, 0x00000084, 0x00000007, 0x00000083, 0x00060021, 0x00000085, 0x0000007D, 0x00000084, +0x00000084, 0x00000007, 0x00060021, 0x0000008B, 0x00000006, 0x0000000D, 0x0000000D, 0x00000084, +0x00090019, 0x00000091, 0x00000006, 0x00000001, 0x00000000, 0x00000001, 0x00000000, 0x00000001, +0x00000000, 0x0003001B, 0x00000092, 0x00000091, 0x00040020, 0x00000093, 0x00000000, 0x00000092, +0x000A0021, 0x00000094, 0x00000006, 0x00000093, 0x00000013, 0x00000007, 0x0000000D, 0x0000000D, +0x0000000D, 0x00000084, 0x00040021, 0x0000009E, 0x00000083, 0x0000000D, 0x00070021, 0x000000A2, +0x00000006, 0x0000000D, 0x00000084, 0x0000000D, 0x0000000D, 0x000F001E, 0x000000A9, 0x00000012, +0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x0000000C, 0x0000000C, 0x00000006, 0x0000000C, +0x00000006, 0x0000000C, 0x0000000C, 0x0000007D, 0x0009001E, 0x000000AA, 0x00000012, 0x00000012, +0x00000012, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x000A0021, 0x000000AB, 0x0000000C, +0x000000A9, 0x000000AA, 0x0000000C, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00070021, +0x000000B5, 0x0000000C, 0x000000A9, 0x00000007, 0x00000007, 0x00000007, 0x00040020, 0x000000C5, +0x00000007, 0x000000A9, 0x00060021, 0x000000C6, 0x0000000C, 0x0000000D, 0x0000000D, 0x000000C5, +0x00040020, 0x000000D1, 0x00000006, 0x00000006, 0x0004003B, 0x000000D1, 0x000000D2, 0x00000006, +0x0004002B, 0x00000006, 0x000000D3, 0x3F800000, 0x0004003B, 0x000000D1, 0x000000D4, 0x00000006, +0x0004002B, 0x00000006, 0x000000D5, 0x3FCF1BBD, 0x0004002B, 0x00000006, 0x000000E2, 0x400CCCCD, +0x0006002C, 0x0000000C, 0x000000E3, 0x000000E2, 0x000000E2, 0x000000E2, 0x00040015, 0x000000EB, +0x00000020, 0x00000000, 0x0004002B, 0x000000EB, 0x000000EC, 0x00000003, 0x0004002B, 0x00000006, +0x000000F6, 0x00000000, 0x0004002B, 0x00000006, 0x0000010E, 0x3EA2F983, 0x0004002B, 0x00000006, +0x00000111, 0x477FE000, 0x0004002B, 0x00000006, 0x00000126, 0x40A00000, 0x0004002B, 0x00000006, +0x0000012D, 0x3F000000, 0x0004002B, 0x00000006, 0x0000012E, 0x40000000, 0x0004002B, 0x00000006, +0x00000172, 0x3F7FF972, 0x0004002B, 0x00000006, 0x0000018D, 0x38D1B717, 0x0004002B, 0x00000006, +0x000001A2, 0x3E23D70A, 0x0004002B, 0x00000006, 0x000001BF, 0x41840000, 0x0006002C, 0x0000000C, +0x000001C0, 0x000001BF, 0x000001BF, 0x000001BF, 0x000F001E, 0x000001DB, 0x00000012, 0x00000006, +0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000006, +0x00000006, 0x00000006, 0x00000006, 0x00040020, 0x000001DC, 0x00000002, 0x000001DB, 0x0004003B, +0x000001DC, 0x000001DD, 0x00000002, 0x0004002B, 0x00000083, 0x000001DE, 0x00000005, 0x00040020, +0x000001DF, 0x00000002, 0x00000006, 0x0004002B, 0x00000006, 0x000001E2, 0x3D4CCCCD, 0x00020014, +0x000001E3, 0x0004002B, 0x00000083, 0x000001E7, 0x00000000, 0x00040020, 0x000001E8, 0x00000002, +0x00000012, 0x00090019, 0x000001F4, 0x00000006, 0x00000001, 0x00000000, 0x00000000, 0x00000000, +0x00000001, 0x00000000, 0x0003001B, 0x000001F5, 0x000001F4, 0x00040020, 0x000001F6, 0x00000000, +0x000001F5, 0x0004003B, 0x000001F6, 0x000001F7, 0x00000000, 0x00040018, 0x000001F9, 0x0000000C, +0x00000003, 0x0007001E, 0x000001FA, 0x0000000C, 0x0000007D, 0x00000012, 0x0000000C, 0x000001F9, +0x00040020, 0x000001FB, 0x00000001, 0x000001FA, 0x0004003B, 0x000001FB, 0x000001FC, 0x00000001, +0x0004002B, 0x00000083, 0x000001FD, 0x00000001, 0x00040020, 0x000001FE, 0x00000001, 0x0000007D, +0x0004002B, 0x00000083, 0x00000208, 0x00000006, 0x0004002B, 0x00000083, 0x0000020E, 0x00000002, +0x0004003B, 0x000001F6, 0x0000021B, 0x00000000, 0x0004002B, 0x00000083, 0x00000226, 0x00000007, +0x0004003B, 0x000001F6, 0x00000237, 0x00000000, 0x0004002B, 0x000000EB, 0x0000023C, 0x00000000, +0x0004002B, 0x00000083, 0x00000242, 0x0000000A, 0x0004003B, 0x000001F6, 0x0000024E, 0x00000000, +0x0004002B, 0x00000083, 0x00000258, 0x00000009, 0x0004002B, 0x00000083, 0x0000025E, 0x00000004, +0x0004003B, 0x000001F6, 0x0000026A, 0x00000000, 0x0004002B, 0x00000006, 0x00000277, 0x414FD639, +0x0004002B, 0x00000006, 0x00000278, 0x429C774C, 0x0005002C, 0x0000007D, 0x00000279, 0x00000277, +0x00000278, 0x0004002B, 0x00000006, 0x0000027C, 0x472AEE8C, 0x0004002B, 0x00000006, 0x00000282, +0x4019999A, 0x0009001E, 0x000002A3, 0x00000012, 0x00000012, 0x00000012, 0x00000006, 0x00000006, +0x00000006, 0x00000006, 0x0004002B, 0x000000EB, 0x000002A4, 0x00000020, 0x0004001C, 0x000002A5, +0x000002A3, 0x000002A4, 0x00040018, 0x000002A6, 0x00000012, 0x00000004, 0x0004002B, 0x000000EB, +0x000002A7, 0x00000004, 0x0004001C, 0x000002A8, 0x000002A6, 0x000002A7, 0x0004001C, 0x000002A9, +0x00000012, 0x000002A7, 0x0015001E, 0x000002AA, 0x000002A5, 0x000002A8, 0x000002A6, 0x000002A6, +0x000002A6, 0x00000012, 0x000002A9, 0x00000006, 0x00000006, 0x00000006, 0x00000006, 0x00000083, +0x00000083, 0x00000083, 0x00000083, 0x00000006, 0x00000006, 0x00000006, 0x00000083, 0x00040020, +0x000002AB, 0x00000002, 0x000002AA, 0x0004003B, 0x000002AB, 0x000002AC, 0x00000002, 0x0004002B, +0x00000083, 0x000002AD, 0x0000000F, 0x0004002B, 0x00000083, 0x000002D1, 0x00000008, 0x0004002B, +0x00000006, 0x000002DA, 0x442F0000, 0x0004002B, 0x000000EB, 0x000002EA, 0x00000002, 0x0004002B, +0x00000006, 0x000002F6, 0x41000000, 0x00040020, 0x000002FC, 0x00000002, 0x000002A6, 0x0004002B, +0x00000083, 0x0000030C, 0x0000000C, 0x00040020, 0x0000030D, 0x00000002, 0x00000083, 0x0004002B, +0x00000006, 0x00000334, 0x3C23D70A, 0x0004002B, 0x00000006, 0x0000033E, 0x3B03126F, 0x0004003B, +0x00000093, 0x0000034A, 0x00000000, 0x0006002C, 0x0000000C, 0x000003CD, 0x000000F6, 0x000000F6, +0x000000F6, 0x0004002B, 0x00000083, 0x000003D5, 0x0000000B, 0x00040020, 0x000003D9, 0x00000007, +0x000000AA, 0x00040020, 0x000003DC, 0x00000002, 0x000002A3, 0x0004002B, 0x00000083, 0x000003E6, +0x00000003, 0x0004002B, 0x00000006, 0x00000437, 0x3F666666, 0x0004002B, 0x00000083, 0x0000044F, +0x00000012, 0x00090019, 0x000004CB, 0x00000006, 0x00000003, 0x00000000, 0x00000000, 0x00000000, +0x00000001, 0x00000000, 0x0003001B, 0x000004CC, 0x000004CB, 0x00040020, 0x000004CD, 0x00000000, +0x000004CC, 0x0004003B, 0x000004CD, 0x000004CE, 0x00000000, 0x0004002B, 0x00000083, 0x000004ED, +0x0000000E, 0x0004003B, 0x000004CD, 0x000004F1, 0x00000000, 0x0004002B, 0x000000EB, 0x00000501, +0x00000001, 0x00040020, 0x00000574, 0x00000001, 0x0000000C, 0x0004002B, 0x00000006, 0x0000057B, +0x3D23D70A, 0x0004003B, 0x000001F6, 0x0000057F, 0x00000000, 0x00040020, 0x0000058A, 0x00000001, +0x000001F9, 0x00040020, 0x0000059F, 0x00000001, 0x00000012, 0x0004003B, 0x0000059F, 0x000005A0, +0x00000001, 0x0004002B, 0x00000083, 0x000005A3, 0x00000010, 0x0004002B, 0x00000083, 0x000005A6, +0x00000011, 0x0004003B, 0x000001F6, 0x000005AC, 0x00000000, 0x0004002B, 0x00000006, 0x000005B8, +0x3D3851EC, 0x0004002B, 0x00000006, 0x000005D7, 0x3CA3D70A, 0x0004002B, 0x00000006, 0x000005E4, +0x3B04B5DD, 0x0004003B, 0x000001F6, 0x000005F9, 0x00000000, 0x0004002B, 0x00000006, 0x00000615, +0x3DCCCCCD, 0x00040020, 0x0000066B, 0x00000003, 0x00000012, 0x0004003B, 0x0000066B, 0x0000066C, +0x00000003, 0x0004002B, 0x00000083, 0x00000672, 0x0000000D, 0x0004002B, 0x00000006, 0x000006B6, +0x3F4CCCCD, 0x0004002B, 0x00000006, 0x000006B7, 0x3E4CCCCD, 0x0007002C, 0x00000012, 0x000006B8, +0x000006B6, 0x000006B7, 0x000006B7, 0x000000D3, 0x0007002C, 0x00000012, 0x000006BC, 0x000006B7, +0x000006B6, 0x000006B7, 0x000000D3, 0x0007002C, 0x00000012, 0x000006C0, 0x000006B7, 0x000006B7, +0x000006B6, 0x000000D3, 0x0007002C, 0x00000012, 0x000006C4, 0x000006B6, 0x000006B6, 0x000006B7, +0x000000D3, 0x0004002B, 0x00000006, 0x000006CA, 0x40C90FDB, 0x0004002B, 0x00000006, 0x000006CB, +0x3727C5AC, 0x0006002C, 0x0000000C, 0x000006CC, 0x0000057B, 0x0000057B, 0x0000057B, 0x0007002C, +0x00000012, 0x000006CD, 0x0000012D, 0x000000F6, 0x000000F6, 0x0000012D, 0x0007002C, 0x00000012, +0x000006CE, 0x000000F6, 0x0000012D, 0x000000F6, 0x0000012D, 0x0007002C, 0x00000012, 0x000006CF, +0x000000F6, 0x000000F6, 0x000000D3, 0x000000F6, 0x0007002C, 0x00000012, 0x000006D0, 0x000000F6, +0x000000F6, 0x000000F6, 0x000000D3, 0x0007002C, 0x000002A6, 0x000006D1, 0x000006CD, 0x000006CE, +0x000006CF, 0x000006D0, 0x0004002B, 0x000000EB, 0x000006D2, 0x00000010, 0x0004001C, 0x000006D3, +0x0000007D, 0x000006D2, 0x0004002B, 0x00000006, 0x000006D4, 0xBF7127FA, 0x0004002B, 0x00000006, +0x000006D5, 0xBECC51E0, 0x0005002C, 0x0000007D, 0x000006D6, 0x000006D4, 0x000006D5, 0x0004002B, +0x00000006, 0x000006D7, 0x3F7211EE, 0x0004002B, 0x00000006, 0x000006D8, 0xBF44D71B, 0x0005002C, +0x0000007D, 0x000006D9, 0x000006D7, 0x000006D8, 0x0004002B, 0x00000006, 0x000006DA, 0xBDC0E398, +0x0004002B, 0x00000006, 0x000006DB, 0xBF6DEC6B, 0x0005002C, 0x0000007D, 0x000006DC, 0x000006DA, +0x000006DB, 0x0004002B, 0x00000006, 0x000006DD, 0x3EB09E84, 0x0004002B, 0x00000006, 0x000006DE, +0x3E967720, 0x0005002C, 0x0000007D, 0x000006DF, 0x000006DD, 0x000006DE, 0x0004002B, 0x00000006, +0x000006E0, 0xBF6A777E, 0x0004002B, 0x00000006, 0x000006E1, 0x3EEA5988, 0x0005002C, 0x0000007D, +0x000006E2, 0x000006E0, 0x000006E1, 0x0004002B, 0x00000006, 0x000006E3, 0xBF50C0D4, 0x0004002B, +0x00000006, 0x000006E4, 0xBF610E50, 0x0005002C, 0x0000007D, 0x000006E5, 0x000006E3, 0x000006E4, +0x0004002B, 0x00000006, 0x000006E6, 0xBEC3FB24, 0x0004002B, 0x00000006, 0x000006E7, 0x3E8DB498, +0x0005002C, 0x0000007D, 0x000006E8, 0x000006E6, 0x000006E7, 0x0004002B, 0x00000006, 0x000006E9, +0x3F798F60, 0x0004002B, 0x00000006, 0x000006EA, 0x3F41A8EC, 0x0005002C, 0x0000007D, 0x000006EB, +0x000006E9, 0x000006EA, 0x0004002B, 0x00000006, 0x000006EC, 0x3EE2EF78, 0x0004002B, 0x00000006, +0x000006ED, 0xBF79A12C, 0x0005002C, 0x0000007D, 0x000006EE, 0x000006EC, 0x000006ED, 0x0004002B, +0x00000006, 0x000006EF, 0x3F099500, 0x0004002B, 0x00000006, 0x000006F0, 0xBEF28D4A, 0x0005002C, +0x0000007D, 0x000006F1, 0x000006EF, 0x000006F0, 0x0004002B, 0x00000006, 0x000006F2, 0xBE87AA08, +0x0004002B, 0x00000006, 0x000006F3, 0xBED67E06, 0x0005002C, 0x0000007D, 0x000006F4, 0x000006F2, +0x000006F3, 0x0004002B, 0x00000006, 0x000006F5, 0x3F4ABEE2, 0x0004002B, 0x00000006, 0x000006F6, +0x3E437BC8, 0x0005002C, 0x0000007D, 0x000006F7, 0x000006F5, 0x000006F6, 0x0004002B, 0x00000006, +0x000006F8, 0xBE77B198, 0x0004002B, 0x00000006, 0x000006F9, 0x3F7F3FA8, 0x0005002C, 0x0000007D, +0x000006FA, 0x000006F8, 0x000006F9, 0x0004002B, 0x00000006, 0x000006FB, 0xBF5068D4, 0x0004002B, +0x00000006, 0x000006FC, 0x3F6A148A, 0x0005002C, 0x0000007D, 0x000006FD, 0x000006FB, 0x000006FC, +0x0004002B, 0x00000006, 0x000006FE, 0x3E4CA330, 0x0004002B, 0x00000006, 0x000006FF, 0x3F495268, +0x0005002C, 0x0000007D, 0x00000700, 0x000006FE, 0x000006FF, 0x0004002B, 0x00000006, 0x00000701, +0x3E134898, 0x0004002B, 0x00000006, 0x00000702, 0xBE106460, 0x0005002C, 0x0000007D, 0x00000703, +0x00000701, 0x00000702, 0x0013002C, 0x000006D3, 0x00000704, 0x000006D6, 0x000006D9, 0x000006DC, +0x000006DF, 0x000006E2, 0x000006E5, 0x000006E8, 0x000006EB, 0x000006EE, 0x000006F1, 0x000006F4, +0x000006F7, 0x000006FA, 0x000006FD, 0x00000700, 0x00000703, 0x0004002B, 0x000000EB, 0x00000705, +0x00000040, 0x0004001C, 0x00000706, 0x0000007D, 0x00000705, 0x0004002B, 0x00000006, 0x00000707, +0xBF625322, 0x0004002B, 0x00000006, 0x00000708, 0x3DFEF391, 0x0005002C, 0x0000007D, 0x00000709, +0x00000707, 0x00000708, 0x0004002B, 0x00000006, 0x0000070A, 0xBF36E169, 0x0004002B, 0x00000006, +0x0000070B, 0x3CE4E26D, 0x0005002C, 0x0000007D, 0x0000070C, 0x0000070A, 0x0000070B, 0x0004002B, +0x00000006, 0x0000070D, 0xBF3F7953, 0x0004002B, 0x00000006, 0x0000070E, 0x3E696463, 0x0005002C, +0x0000007D, 0x0000070F, 0x0000070D, 0x0000070E, 0x0004002B, 0x00000006, 0x00000710, 0xBF708A37, +0x0004002B, 0x00000006, 0x00000711, 0x3E797B31, 0x0005002C, 0x0000007D, 0x00000712, 0x00000710, +0x00000711, 0x0004002B, 0x00000006, 0x00000713, 0xBF7C476F, 0x0004002B, 0x00000006, 0x00000714, +0x3D3A81DC, 0x0005002C, 0x0000007D, 0x00000715, 0x00000713, 0x00000714, 0x0004002B, 0x00000006, +0x00000716, 0xBF5C828C, 0x0004002B, 0x00000006, 0x00000717, 0xBE0B7DC8, 0x0005002C, 0x0000007D, +0x00000718, 0x00000716, 0x00000717, 0x0004002B, 0x00000006, 0x00000719, 0xBF61C66D, 0x0004002B, +0x00000006, 0x0000071A, 0x3ECB3786, 0x0005002C, 0x0000007D, 0x0000071B, 0x00000719, 0x0000071A, +0x0004002B, 0x00000006, 0x0000071C, 0xBEEF127F, 0x0004002B, 0x00000006, 0x0000071D, 0x3C6DFE76, +0x0005002C, 0x0000007D, 0x0000071E, 0x0000071C, 0x0000071D, 0x0004002B, 0x00000006, 0x0000071F, +0xBF0EE6A7, 0x0004002B, 0x00000006, 0x00000720, 0x3E59C411, 0x0005002C, 0x0000007D, 0x00000721, +0x0000071F, 0x00000720, 0x0004002B, 0x00000006, 0x00000722, 0xBF14151A, 0x0004002B, 0x00000006, +0x00000723, 0xBDC43E53, 0x0005002C, 0x0000007D, 0x00000724, 0x00000722, 0x00000723, 0x0004002B, +0x00000006, 0x00000725, 0xBF3D8213, 0x0004002B, 0x00000006, 0x00000726, 0xBDC3DA30, 0x0005002C, +0x0000007D, 0x00000727, 0x00000725, 0x00000726, 0x0004002B, 0x00000006, 0x00000728, 0xBF406E2B, +0x0004002B, 0x00000006, 0x00000729, 0x3EF1F927, 0x0005002C, 0x0000007D, 0x0000072A, 0x00000728, +0x00000729, 0x0004002B, 0x00000006, 0x0000072B, 0xBF0D9B0B, 0x0004002B, 0x00000006, 0x0000072C, +0xBE790364, 0x0005002C, 0x0000007D, 0x0000072D, 0x0000072B, 0x0000072C, 0x0004002B, 0x00000006, +0x0000072E, 0xBF2CBD34, 0x0004002B, 0x00000006, 0x0000072F, 0xBEA95571, 0x0005002C, 0x0000007D, +0x00000730, 0x0000072E, 0x0000072F, 0x0004002B, 0x00000006, 0x00000731, 0xBECE3737, 0x0004002B, +0x00000006, 0x00000732, 0xBDFA08C0, 0x0005002C, 0x0000007D, 0x00000733, 0x00000731, 0x00000732, +0x0004002B, 0x00000006, 0x00000734, 0xBEA3B9AE, 0x0004002B, 0x00000006, 0x00000735, 0xBE9FD439, +0x0005002C, 0x0000007D, 0x00000736, 0x00000734, 0x00000735, 0x0004002B, 0x00000006, 0x00000737, +0xBED3EDB7, 0x0004002B, 0x00000006, 0x00000738, 0xBEE127D4, 0x0005002C, 0x0000007D, 0x00000739, +0x00000737, 0x00000738, 0x0004002B, 0x00000006, 0x0000073A, 0xBF7AA9C5, 0x0004002B, 0x00000006, +0x0000073B, 0xBE4E132B, 0x0005002C, 0x0000007D, 0x0000073C, 0x0000073A, 0x0000073B, 0x0004002B, +0x00000006, 0x0000073D, 0xBF5D9696, 0x0004002B, 0x00000006, 0x0000073E, 0xBE93CFD5, 0x0005002C, +0x0000007D, 0x0000073F, 0x0000073D, 0x0000073E, 0x0004002B, 0x00000006, 0x00000740, 0xBE798D8B, +0x0004002B, 0x00000006, 0x00000741, 0xBE3ED9E0, 0x0005002C, 0x0000007D, 0x00000742, 0x00000740, +0x00000741, 0x0004002B, 0x00000006, 0x00000743, 0xBE96FFC1, 0x0004002B, 0x00000006, 0x00000744, +0xBD645804, 0x0005002C, 0x0000007D, 0x00000745, 0x00000743, 0x00000744, 0x0004002B, 0x00000006, +0x00000746, 0xBF1ABD5E, 0x0004002B, 0x00000006, 0x00000747, 0xBF0B5409, 0x0005002C, 0x0000007D, +0x00000748, 0x00000746, 0x00000747, 0x0004002B, 0x00000006, 0x00000749, 0xBED60B70, 0x0004002B, +0x00000006, 0x0000074A, 0xBF167222, 0x0005002C, 0x0000007D, 0x0000074B, 0x00000749, 0x0000074A, +0x0004002B, 0x00000006, 0x0000074C, 0xBF0C957D, 0x0004002B, 0x00000006, 0x0000074D, 0xBED4EDD5, +0x0005002C, 0x0000007D, 0x0000074E, 0x0000074C, 0x0000074D, 0x0004002B, 0x00000006, 0x0000074F, +0xBE73CB3E, 0x0004002B, 0x00000006, 0x00000750, 0xBF1C9C5E, 0x0005002C, 0x0000007D, 0x00000751, +0x0000074F, 0x00000750, 0x0004002B, 0x00000006, 0x00000752, 0xBE88B4C0, 0x0004002B, 0x00000006, +0x00000753, 0xBEEB5E0F, 0x0005002C, 0x0000007D, 0x00000754, 0x00000752, 0x00000753, 0x0004002B, +0x00000006, 0x00000755, 0xBDCCCFF2, 0x0004002B, 0x00000006, 0x00000756, 0xBE6A9D62, 0x0005002C, +0x0000007D, 0x00000757, 0x00000755, 0x00000756, 0x0004002B, 0x00000006, 0x00000758, 0xBDD0BFA1, +0x0004002B, 0x00000006, 0x00000759, 0xBEC2C16E, 0x0005002C, 0x0000007D, 0x0000075A, 0x00000758, +0x00000759, 0x0004002B, 0x00000006, 0x0000075B, 0xBF2E749F, 0x0004002B, 0x00000006, 0x0000075C, +0xBF3365DC, 0x0005002C, 0x0000007D, 0x0000075D, 0x0000075B, 0x0000075C, 0x0004002B, 0x00000006, +0x0000075E, 0xBF4373F3, 0x0004002B, 0x00000006, 0x0000075F, 0xBF0B1B58, 0x0005002C, 0x0000007D, +0x00000760, 0x0000075E, 0x0000075F, 0x0004002B, 0x00000006, 0x00000761, 0xBF0C8D3B, 0x0004002B, +0x00000006, 0x00000762, 0xBF403116, 0x0005002C, 0x0000007D, 0x00000763, 0x00000761, 0x00000762, +0x0004002B, 0x00000006, 0x00000764, 0xBF4F1D93, 0x0004002B, 0x00000006, 0x00000765, 0xBED1461B, +0x0005002C, 0x0000007D, 0x00000766, 0x00000764, 0x00000765, 0x0004002B, 0x00000006, 0x00000767, +0xBEC6B980, 0x0004002B, 0x00000006, 0x00000768, 0xBF4600B0, 0x0005002C, 0x0000007D, 0x00000769, +0x00000767, 0x00000768, 0x0004002B, 0x00000006, 0x0000076A, 0xBEDBD945, 0x0004002B, 0x00000006, +0x0000076B, 0xBF6517A4, 0x0005002C, 0x0000007D, 0x0000076C, 0x0000076A, 0x0000076B, 0x0004002B, +0x00000006, 0x0000076D, 0xBE06C15D, 0x0004002B, 0x00000006, 0x0000076E, 0x3D853D21, 0x0005002C, +0x0000007D, 0x0000076F, 0x0000076D, 0x0000076E, 0x0004002B, 0x00000006, 0x00000770, 0xBE8CCD10, +0x0004002B, 0x00000006, 0x00000771, 0x3DD2C8C5, 0x0005002C, 0x0000007D, 0x00000772, 0x00000770, +0x00000771, 0x0004002B, 0x00000006, 0x00000773, 0xBDD953DF, 0x0004002B, 0x00000006, 0x00000774, +0xBD8BEF07, 0x0005002C, 0x0000007D, 0x00000775, 0x00000773, 0x00000774, 0x0004002B, 0x00000006, +0x00000776, 0xBE96D3FA, 0x0004002B, 0x00000006, 0x00000777, 0xBF643A54, 0x0005002C, 0x0000007D, +0x00000778, 0x00000776, 0x00000777, 0x0004002B, 0x00000006, 0x00000779, 0xBF21218A, 0x0004002B, +0x00000006, 0x0000077A, 0x3EC23F03, 0x0005002C, 0x0000007D, 0x0000077B, 0x00000779, 0x0000077A, +0x0004002B, 0x00000006, 0x0000077C, 0xBED083FD, 0x0004002B, 0x00000006, 0x0000077D, 0x3EADF373, +0x0005002C, 0x0000007D, 0x0000077E, 0x0000077C, 0x0000077D, 0x0004002B, 0x00000006, 0x0000077F, +0x3D92BD3C, 0x0004002B, 0x00000006, 0x00000780, 0xBEC4C0DF, 0x0005002C, 0x0000007D, 0x00000781, +0x0000077F, 0x00000780, 0x0004002B, 0x00000006, 0x00000782, 0x3CB45F18, 0x0004002B, 0x00000006, +0x00000783, 0xBE870FE0, 0x0005002C, 0x0000007D, 0x00000784, 0x00000782, 0x00000783, 0x0004002B, +0x00000006, 0x00000785, 0x3B7E36D2, 0x0004002B, 0x00000006, 0x00000786, 0xBE0B56B8, 0x0005002C, +0x0000007D, 0x00000787, 0x00000785, 0x00000786, 0x0004002B, 0x00000006, 0x00000788, 0xBE0CD573, +0x0004002B, 0x00000006, 0x00000789, 0xBF44916D, 0x0005002C, 0x0000007D, 0x0000078A, 0x00000788, +0x00000789, 0x0004002B, 0x00000006, 0x0000078B, 0xBD506141, 0x0004002B, 0x00000006, 0x0000078C, +0xBF67F413, 0x0005002C, 0x0000007D, 0x0000078D, 0x0000078B, 0x0000078C, 0x0004002B, 0x00000006, +0x0000078E, 0x3DE9BE90, 0x0004002B, 0x00000006, 0x0000078F, 0xBD8F77F2, 0x0005002C, 0x0000007D, +0x00000790, 0x0000078E, 0x0000078F, 0x0004002B, 0x00000006, 0x00000791, 0x3E273BC9, 0x0004002B, +0x00000006, 0x00000792, 0xBE5E71CE, 0x0005002C, 0x0000007D, 0x00000793, 0x00000791, 0x00000792, +0x0004002B, 0x00000006, 0x00000794, 0xBDCD562A, 0x0004002B, 0x00000006, 0x00000795, 0xBF1686A5, +0x0005002C, 0x0000007D, 0x00000796, 0x00000794, 0x00000795, 0x0004002B, 0x00000006, 0x00000797, +0xBBA1F080, 0x0004002B, 0x00000006, 0x00000798, 0x3E006078, 0x0005002C, 0x0000007D, 0x00000799, +0x00000797, 0x00000798, 0x0004002B, 0x00000006, 0x0000079A, 0x3D1098D4, 0x0004002B, 0x00000006, +0x0000079B, 0xBF1E8B1A, 0x0005002C, 0x0000007D, 0x0000079C, 0x0000079A, 0x0000079B, 0x0004002B, +0x00000006, 0x0000079D, 0x3E48576D, 0x0004002B, 0x00000006, 0x0000079E, 0xBEEB04EE, 0x0005002C, +0x0000007D, 0x0000079F, 0x0000079D, 0x0000079E, 0x0004002B, 0x00000006, 0x000007A0, 0x3E9BA1D3, +0x0004002B, 0x00000006, 0x000007A1, 0xBEB1565C, 0x0005002C, 0x0000007D, 0x000007A2, 0x000007A0, +0x000007A1, 0x0004002B, 0x00000006, 0x000007A3, 0xBF2D9924, 0x0004002B, 0x00000006, 0x000007A4, +0x3F2F62A6, 0x0005002C, 0x0000007D, 0x000007A5, 0x000007A3, 0x000007A4, 0x0004002B, 0x00000006, +0x000007A6, 0xBF20E001, 0x0004002B, 0x00000006, 0x000007A7, 0x3F020AD9, 0x0005002C, 0x0000007D, +0x000007A8, 0x000007A6, 0x000007A7, 0x0004002B, 0x00000006, 0x000007A9, 0xBF022B49, 0x0004002B, +0x00000006, 0x000007AA, 0x3EEAE1AC, 0x0005002C, 0x0000007D, 0x000007AB, 0x000007A9, 0x000007AA, +0x0004002B, 0x00000006, 0x000007AC, 0x3D039EF1, 0x0004002B, 0x00000006, 0x000007AD, 0xBF48331E, +0x0005002C, 0x0000007D, 0x000007AE, 0x000007AC, 0x000007AD, 0x0004002B, 0x00000006, 0x000007AF, +0x3DFB1316, 0x0004002B, 0x00000006, 0x000007B0, 0x3E8F8A6E, 0x0005002C, 0x0000007D, 0x000007B1, +0x000007AF, 0x000007B0, 0x0004002B, 0x00000006, 0x000007B2, 0xBD32C301, 0x0004002B, 0x00000006, +0x000007B3, 0x3E9FCE10, 0x0005002C, 0x0000007D, 0x000007B4, 0x000007B2, 0x000007B3, 0x0004002B, +0x00000006, 0x000007B5, 0x3E082F51, 0x0004002B, 0x00000006, 0x000007B6, 0x3DAE6D9C, 0x0005002C, +0x0000007D, 0x000007B7, 0x000007B5, 0x000007B6, 0x0004002B, 0x00000006, 0x000007B8, 0xBE44B76F, +0x0004002B, 0x00000006, 0x000007B9, 0x3E925AAB, 0x0005002C, 0x0000007D, 0x000007BA, 0x000007B8, +0x000007B9, 0x0004002B, 0x00000006, 0x000007BB, 0x3E3C0725, 0x0004002B, 0x00000006, 0x000007BC, +0xBF369707, 0x0005002C, 0x0000007D, 0x000007BD, 0x000007BB, 0x000007BC, 0x0004002B, 0x00000006, +0x000007BE, 0x3E87CAEA, 0x0004002B, 0x00000006, 0x000007BF, 0xBF18C261, 0x0005002C, 0x0000007D, +0x000007C0, 0x000007BE, 0x000007BF, 0x0004002B, 0x00000006, 0x000007C1, 0xBC1DBEC2, 0x0004002B, +0x00000006, 0x000007C2, 0xBEF75361, 0x0005002C, 0x0000007D, 0x000007C3, 0x000007C1, 0x000007C2, +0x0004002B, 0x00000006, 0x000007C4, 0xBC97AEDE, 0x0004002B, 0x00000006, 0x000007C5, 0x3EDF1477, +0x0005002C, 0x0000007D, 0x000007C6, 0x000007C4, 0x000007C5, 0x0043002C, 0x00000706, 0x000007C7, +0x00000709, 0x0000070C, 0x0000070F, 0x00000712, 0x00000715, 0x00000718, 0x0000071B, 0x0000071E, +0x00000721, 0x00000724, 0x00000727, 0x0000072A, 0x0000072D, 0x00000730, 0x00000733, 0x00000736, +0x00000739, 0x0000073C, 0x0000073F, 0x00000742, 0x00000745, 0x00000748, 0x0000074B, 0x0000074E, +0x00000751, 0x00000754, 0x00000757, 0x0000075A, 0x0000075D, 0x00000760, 0x00000763, 0x00000766, +0x00000769, 0x0000076C, 0x0000076F, 0x00000772, 0x00000775, 0x00000778, 0x0000077B, 0x0000077E, +0x00000781, 0x00000784, 0x00000787, 0x0000078A, 0x0000078D, 0x00000790, 0x00000793, 0x00000796, +0x00000799, 0x0000079C, 0x0000079F, 0x000007A2, 0x000007A5, 0x000007A8, 0x000007AB, 0x000007AE, +0x000007B1, 0x000007B4, 0x000007B7, 0x000007BA, 0x000007BD, 0x000007C0, 0x000007C3, 0x000007C6, +0x00050036, 0x00000002, 0x00000004, 0x00000000, 0x00000003, 0x000200F8, 0x00000005, 0x0004003B, +0x00000013, 0x0000050E, 0x00000007, 0x0004003B, 0x00000007, 0x00000518, 0x00000007, 0x0004003B, +0x00000007, 0x00000519, 0x00000007, 0x0004003B, 0x0000000D, 0x00000528, 0x00000007, 0x0004003B, +0x0000000D, 0x0000054C, 0x00000007, 0x0004003B, 0x000000C5, 0x0000056A, 0x00000007, 0x0004003B, +0x0000000D, 0x00000598, 0x00000007, 0x0004003B, 0x0000007E, 0x0000059E, 0x00000007, 0x0004003B, +0x00000007, 0x000005AB, 0x00000007, 0x0004003B, 0x00000007, 0x000005BB, 0x00000007, 0x0004003B, +0x00000007, 0x000005C0, 0x00000007, 0x0004003B, 0x0000000D, 0x000005C4, 0x00000007, 0x0004003B, +0x0000000D, 0x000005C8, 0x00000007, 0x0004003B, 0x00000007, 0x000005CC, 0x00000007, 0x0004003B, +0x00000007, 0x000005D4, 0x00000007, 0x0004003B, 0x00000007, 0x000005D9, 0x00000007, 0x0004003B, +0x00000007, 0x000005DD, 0x00000007, 0x0004003B, 0x0000000D, 0x000005E7, 0x00000007, 0x0004003B, +0x00000007, 0x00000603, 0x00000007, 0x0004003B, 0x00000007, 0x00000604, 0x00000007, 0x0004003B, +0x0000000D, 0x00000608, 0x00000007, 0x0004003B, 0x00000007, 0x0000060B, 0x00000007, 0x0004003B, +0x00000007, 0x0000060E, 0x00000007, 0x0004003B, 0x00000007, 0x00000621, 0x00000007, 0x0004003B, +0x00000007, 0x0000062B, 0x00000007, 0x0004003B, 0x00000007, 0x0000062E, 0x00000007, 0x0004003B, +0x00000013, 0x00000631, 0x00000007, 0x0004003B, 0x00000007, 0x0000063A, 0x00000007, 0x0004003B, +0x0000000D, 0x00000648, 0x00000007, 0x0004003B, 0x0000000D, 0x00000652, 0x00000007, 0x0004003B, +0x0000000D, 0x00000653, 0x00000007, 0x0004003B, 0x0000000D, 0x00000656, 0x00000007, 0x0004003B, +0x000000C5, 0x00000658, 0x00000007, 0x0004003B, 0x0000000D, 0x0000065B, 0x00000007, 0x0004003B, +0x0000000D, 0x0000065C, 0x00000007, 0x0004003B, 0x0000000D, 0x0000065F, 0x00000007, 0x0004003B, +0x000000C5, 0x00000661, 0x00000007, 0x0004003B, 0x0000000D, 0x00000664, 0x00000007, 0x0004003B, +0x00000084, 0x000006AB, 0x00000007, 0x0004003B, 0x0000000D, 0x000006AC, 0x00000007, 0x0003003E, +0x000000D2, 0x000000D3, 0x0003003E, 0x000000D4, 0x000000D5, 0x00040039, 0x00000012, 0x0000050F, +0x00000070, 0x0003003E, 0x0000050E, 0x0000050F, 0x00050041, 0x00000007, 0x00000510, 0x0000050E, +0x000000EC, 0x0004003D, 0x00000006, 0x00000511, 0x00000510, 0x00050041, 0x000001DF, 0x00000512, +0x000001DD, 0x000003D5, 0x0004003D, 0x00000006, 0x00000513, 0x00000512, 0x000500B8, 0x000001E3, +0x00000514, 0x00000511, 0x00000513, 0x000300F7, 0x00000516, 0x00000000, 0x000400FA, 0x00000514, +0x00000515, 0x00000516, 0x000200F8, 0x00000515, 0x000100FC, 0x000200F8, 0x00000516, 0x0003003E, +0x00000518, 0x000000F6, 0x0003003E, 0x00000519, 0x000000F6, 0x00050041, 0x000001DF, 0x0000051A, +0x000001DD, 0x0000030C, 0x0004003D, 0x00000006, 0x0000051B, 0x0000051A, 0x000500B4, 0x000001E3, +0x0000051C, 0x0000051B, 0x000000F6, 0x000300F7, 0x0000051E, 0x00000000, 0x000400FA, 0x0000051C, +0x0000051D, 0x00000522, 0x000200F8, 0x0000051D, 0x00040039, 0x0000000C, 0x0000051F, 0x00000073, +0x00050051, 0x00000006, 0x00000520, 0x0000051F, 0x00000000, 0x0003003E, 0x00000518, 0x00000520, +0x00040039, 0x00000006, 0x00000521, 0x00000076, 0x0003003E, 0x00000519, 0x00000521, 0x000200F9, +0x0000051E, 0x000200F8, 0x00000522, 0x00050041, 0x000001DF, 0x00000523, 0x000001DD, 0x0000030C, +0x0004003D, 0x00000006, 0x00000524, 0x00000523, 0x000500B4, 0x000001E3, 0x00000525, 0x00000524, +0x000000D3, 0x000300F7, 0x00000527, 0x00000000, 0x000400FA, 0x00000525, 0x00000526, 0x00000546, +0x000200F8, 0x00000526, 0x0004003D, 0x000001F5, 0x00000529, 0x0000021B, 0x00050041, 0x000001FE, +0x0000052A, 0x000001FC, 0x000001FD, 0x0004003D, 0x0000007D, 0x0000052B, 0x0000052A, 0x00050057, +0x00000012, 0x0000052C, 0x00000529, 0x0000052B, 0x0008004F, 0x0000000C, 0x0000052D, 0x0000052C, +0x0000052C, 0x00000000, 0x00000001, 0x00000002, 0x0003003E, 0x00000528, 0x0000052D, 0x00050041, +0x000001DF, 0x0000052E, 0x000001DD, 0x00000208, 0x0004003D, 0x00000006, 0x0000052F, 0x0000052E, +0x00050083, 0x00000006, 0x00000530, 0x000000D3, 0x0000052F, 0x00050041, 0x000001DF, 0x00000531, +0x000001DD, 0x0000020E, 0x0004003D, 0x00000006, 0x00000532, 0x00000531, 0x00050085, 0x00000006, +0x00000533, 0x00000530, 0x00000532, 0x00050041, 0x000001DF, 0x00000534, 0x000001DD, 0x00000208, +0x0004003D, 0x00000006, 0x00000535, 0x00000534, 0x00050041, 0x00000007, 0x00000536, 0x00000528, +0x000002EA, 0x0004003D, 0x00000006, 0x00000537, 0x00000536, 0x00050085, 0x00000006, 0x00000538, +0x00000535, 0x00000537, 0x00050081, 0x00000006, 0x00000539, 0x00000533, 0x00000538, 0x0003003E, +0x00000518, 0x00000539, 0x00050041, 0x000001DF, 0x0000053A, 0x000001DD, 0x00000208, 0x0004003D, +0x00000006, 0x0000053B, 0x0000053A, 0x00050083, 0x00000006, 0x0000053C, 0x000000D3, 0x0000053B, +0x00050041, 0x000001DF, 0x0000053D, 0x000001DD, 0x000001FD, 0x0004003D, 0x00000006, 0x0000053E, +0x0000053D, 0x00050085, 0x00000006, 0x0000053F, 0x0000053C, 0x0000053E, 0x00050041, 0x000001DF, +0x00000540, 0x000001DD, 0x00000208, 0x0004003D, 0x00000006, 0x00000541, 0x00000540, 0x00050041, +0x00000007, 0x00000542, 0x00000528, 0x00000501, 0x0004003D, 0x00000006, 0x00000543, 0x00000542, +0x00050085, 0x00000006, 0x00000544, 0x00000541, 0x00000543, 0x00050081, 0x00000006, 0x00000545, +0x0000053F, 0x00000544, 0x0003003E, 0x00000519, 0x00000545, 0x000200F9, 0x00000527, 0x000200F8, +0x00000546, 0x00050041, 0x000001DF, 0x00000547, 0x000001DD, 0x0000030C, 0x0004003D, 0x00000006, +0x00000548, 0x00000547, 0x000500B4, 0x000001E3, 0x00000549, 0x00000548, 0x0000012E, 0x000300F7, +0x0000054B, 0x00000000, 0x000400FA, 0x00000549, 0x0000054A, 0x0000054B, 0x000200F8, 0x0000054A, +0x0004003D, 0x000001F5, 0x0000054D, 0x0000021B, 0x00050041, 0x000001FE, 0x0000054E, 0x000001FC, +0x000001FD, 0x0004003D, 0x0000007D, 0x0000054F, 0x0000054E, 0x00050057, 0x00000012, 0x00000550, +0x0000054D, 0x0000054F, 0x0008004F, 0x0000000C, 0x00000551, 0x00000550, 0x00000550, 0x00000000, +0x00000001, 0x00000002, 0x0003003E, 0x0000054C, 0x00000551, 0x00050041, 0x000001DF, 0x00000552, +0x000001DD, 0x00000208, 0x0004003D, 0x00000006, 0x00000553, 0x00000552, 0x00050083, 0x00000006, +0x00000554, 0x000000D3, 0x00000553, 0x00050041, 0x000001DF, 0x00000555, 0x000001DD, 0x0000020E, 0x0004003D, 0x00000006, 0x00000556, 0x00000555, 0x00050085, 0x00000006, 0x00000557, 0x00000554, -0x00000556, 0x00050081, 0x00000006, 0x00000558, 0x00000552, 0x00000557, 0x0003003E, 0x00000537, -0x00000558, 0x00050041, 0x000001E1, 0x00000559, 0x000001DF, 0x0000020A, 0x0004003D, 0x00000006, -0x0000055A, 0x00000559, 0x00050083, 0x00000006, 0x0000055B, 0x000000D5, 0x0000055A, 0x00050041, -0x000001E1, 0x0000055C, 0x000001DF, 0x000001FF, 0x0004003D, 0x00000006, 0x0000055D, 0x0000055C, -0x00050085, 0x00000006, 0x0000055E, 0x0000055B, 0x0000055D, 0x00050041, 0x000001E1, 0x0000055F, -0x000001DF, 0x0000020A, 0x0004003D, 0x00000006, 0x00000560, 0x0000055F, 0x00050041, 0x00000007, -0x00000561, 0x00000547, 0x00000520, 0x0004003D, 0x00000006, 0x00000562, 0x00000561, 0x00050085, -0x00000006, 0x00000563, 0x00000560, 0x00000562, 0x00050081, 0x00000006, 0x00000564, 0x0000055E, -0x00000563, 0x0003003E, 0x00000538, 0x00000564, 0x000200F9, 0x00000546, 0x000200F8, 0x00000565, -0x00050041, 0x000001E1, 0x00000566, 0x000001DF, 0x0000032C, 0x0004003D, 0x00000006, 0x00000567, -0x00000566, 0x000500B4, 0x000001E5, 0x00000568, 0x00000567, 0x00000130, 0x000300F7, 0x0000056A, -0x00000000, 0x000400FA, 0x00000568, 0x00000569, 0x0000056A, 0x000200F8, 0x00000569, 0x0004003D, -0x000001F7, 0x0000056C, 0x0000021D, 0x00050041, 0x00000200, 0x0000056D, 0x000001FE, 0x000001FF, -0x0004003D, 0x0000007F, 0x0000056E, 0x0000056D, 0x00050057, 0x00000012, 0x0000056F, 0x0000056C, -0x0000056E, 0x0008004F, 0x0000000C, 0x00000570, 0x0000056F, 0x0000056F, 0x00000000, 0x00000001, -0x00000002, 0x0003003E, 0x0000056B, 0x00000570, 0x00050041, 0x000001E1, 0x00000571, 0x000001DF, -0x0000020A, 0x0004003D, 0x00000006, 0x00000572, 0x00000571, 0x00050083, 0x00000006, 0x00000573, -0x000000D5, 0x00000572, 0x00050041, 0x000001E1, 0x00000574, 0x000001DF, 0x00000210, 0x0004003D, -0x00000006, 0x00000575, 0x00000574, 0x00050085, 0x00000006, 0x00000576, 0x00000573, 0x00000575, -0x00050041, 0x000001E1, 0x00000577, 0x000001DF, 0x0000020A, 0x0004003D, 0x00000006, 0x00000578, -0x00000577, 0x00050041, 0x00000007, 0x00000579, 0x0000056B, 0x0000030A, 0x0004003D, 0x00000006, -0x0000057A, 0x00000579, 0x00050085, 0x00000006, 0x0000057B, 0x00000578, 0x0000057A, 0x00050081, -0x00000006, 0x0000057C, 0x00000576, 0x0000057B, 0x0003003E, 0x00000537, 0x0000057C, 0x00050041, -0x000001E1, 0x0000057D, 0x000001DF, 0x0000020A, 0x0004003D, 0x00000006, 0x0000057E, 0x0000057D, -0x00050083, 0x00000006, 0x0000057F, 0x000000D5, 0x0000057E, 0x00050041, 0x000001E1, 0x00000580, -0x000001DF, 0x000001FF, 0x0004003D, 0x00000006, 0x00000581, 0x00000580, 0x00050085, 0x00000006, -0x00000582, 0x0000057F, 0x00000581, 0x00050041, 0x000001E1, 0x00000583, 0x000001DF, 0x0000020A, -0x0004003D, 0x00000006, 0x00000584, 0x00000583, 0x00050041, 0x00000007, 0x00000585, 0x0000056B, -0x00000520, 0x0004003D, 0x00000006, 0x00000586, 0x00000585, 0x00050085, 0x00000006, 0x00000587, -0x00000584, 0x00000586, 0x00050081, 0x00000006, 0x00000588, 0x00000582, 0x00000587, 0x0003003E, -0x00000538, 0x00000588, 0x000200F9, 0x0000056A, 0x000200F8, 0x0000056A, 0x000200F9, 0x00000546, -0x000200F8, 0x00000546, 0x000200F9, 0x0000053D, 0x000200F8, 0x0000053D, 0x0004003D, 0x00000012, -0x0000058A, 0x0000052D, 0x00050041, 0x00000013, 0x0000058B, 0x00000589, 0x000001E9, 0x0003003E, -0x0000058B, 0x0000058A, 0x0004003D, 0x00000006, 0x0000058C, 0x00000537, 0x00050041, 0x00000007, -0x0000058D, 0x00000589, 0x000001FF, 0x0003003E, 0x0000058D, 0x0000058C, 0x0004003D, 0x00000006, -0x0000058E, 0x00000538, 0x00050041, 0x00000007, 0x0000058F, 0x00000589, 0x0000027E, 0x0003003E, -0x0000058F, 0x0000058E, 0x00050041, 0x000001E1, 0x00000590, 0x000001DF, 0x0000027E, 0x0004003D, -0x00000006, 0x00000591, 0x00000590, 0x00050041, 0x00000007, 0x00000592, 0x00000589, 0x00000260, -0x0003003E, 0x00000592, 0x00000591, 0x00040039, 0x0000000C, 0x00000593, 0x0000007D, 0x00050041, -0x0000000D, 0x00000594, 0x00000589, 0x0000020A, 0x0003003E, 0x00000594, 0x00000593, 0x00040039, -0x00000006, 0x00000595, 0x00000078, 0x00050041, 0x00000007, 0x00000596, 0x00000589, 0x00000228, -0x0003003E, 0x00000596, 0x00000595, 0x00050041, 0x00000013, 0x00000598, 0x00000589, 0x000001E9, -0x0004003D, 0x00000012, 0x00000599, 0x00000598, 0x0008004F, 0x0000000C, 0x0000059A, 0x00000599, -0x00000599, 0x00000000, 0x00000001, 0x00000002, 0x0003003E, 0x00000597, 0x0000059A, 0x00050039, -0x0000000C, 0x0000059B, 0x0000007B, 0x00000597, 0x00050041, 0x0000000D, 0x0000059C, 0x00000589, -0x000001E0, 0x0003003E, 0x0000059C, 0x0000059B, 0x0004003D, 0x00000012, 0x000005A0, 0x0000059F, -0x0007004F, 0x0000007F, 0x000005A1, 0x000005A0, 0x000005A0, 0x00000000, 0x00000001, 0x00050041, -0x000001E1, 0x000005A3, 0x000002CD, 0x000005A2, 0x0004003D, 0x00000006, 0x000005A4, 0x000005A3, -0x00050041, 0x000001E1, 0x000005A6, 0x000002CD, 0x000005A5, 0x0004003D, 0x00000006, 0x000005A7, -0x000005A6, 0x00050050, 0x0000007F, 0x000005A8, 0x000005A4, 0x000005A7, 0x00050088, 0x0000007F, -0x000005A9, 0x000005A1, 0x000005A8, 0x0003003E, 0x0000059D, 0x000005A9, 0x0004003D, 0x000001F7, -0x000005AC, 0x000005AB, 0x0004003D, 0x0000007F, 0x000005AD, 0x0000059D, 0x00050057, 0x00000012, -0x000005AE, 0x000005AC, 0x000005AD, 0x00050051, 0x00000006, 0x000005AF, 0x000005AE, 0x00000000, -0x0003003E, 0x000005AA, 0x000005AF, 0x0004003D, 0x00000006, 0x000005B0, 0x000005AA, 0x00050041, -0x00000013, 0x000005B1, 0x00000589, 0x000001E9, 0x0004003D, 0x00000012, 0x000005B2, 0x000005B1, -0x0005008E, 0x00000012, 0x000005B3, 0x000005B2, 0x000005B0, 0x00050041, 0x00000013, 0x000005B4, -0x00000589, 0x000001E9, 0x0003003E, 0x000005B4, 0x000005B3, 0x00050041, 0x00000007, 0x000005B5, -0x00000589, 0x0000027E, 0x0004003D, 0x00000006, 0x000005B6, 0x000005B5, 0x0008000C, 0x00000006, -0x000005B8, 0x00000001, 0x0000002B, 0x000005B6, 0x000005B7, 0x000000D5, 0x00050041, 0x00000007, -0x000005B9, 0x00000589, 0x0000027E, 0x0003003E, 0x000005B9, 0x000005B8, 0x00050041, 0x00000007, -0x000005BB, 0x00000589, 0x00000210, 0x0004003D, 0x00000006, 0x000005BC, 0x000005BB, 0x0003003E, -0x000005BA, 0x000005BC, 0x00050039, 0x00000006, 0x000005BD, 0x00000057, 0x000005BA, 0x00050041, -0x00000007, 0x000005BE, 0x00000589, 0x00000210, 0x0003003E, 0x000005BE, 0x000005BD, 0x0004003D, -0x00000006, 0x000005C0, 0x00000538, 0x0004003D, 0x00000006, 0x000005C1, 0x00000538, 0x00050085, -0x00000006, 0x000005C2, 0x000005C0, 0x000005C1, 0x0003003E, 0x000005BF, 0x000005C2, 0x00050041, -0x0000000D, 0x000005C4, 0x00000589, 0x0000020A, 0x0004003D, 0x0000000C, 0x000005C5, 0x000005C4, -0x000400CF, 0x0000000C, 0x000005C6, 0x000005C5, 0x0003003E, 0x000005C3, 0x000005C6, 0x00050041, -0x0000000D, 0x000005C8, 0x00000589, 0x0000020A, 0x0004003D, 0x0000000C, 0x000005C9, 0x000005C8, -0x000400D0, 0x0000000C, 0x000005CA, 0x000005C9, 0x0003003E, 0x000005C7, 0x000005CA, 0x0004003D, -0x0000000C, 0x000005CC, 0x000005C3, 0x0004003D, 0x0000000C, 0x000005CD, 0x000005C3, 0x00050094, -0x00000006, 0x000005CE, 0x000005CC, 0x000005CD, 0x0004003D, 0x0000000C, 0x000005CF, 0x000005C7, -0x0004003D, 0x0000000C, 0x000005D0, 0x000005C7, 0x00050094, 0x00000006, 0x000005D1, 0x000005CF, -0x000005D0, 0x00050081, 0x00000006, 0x000005D2, 0x000005CE, 0x000005D1, 0x0003003E, 0x000005CB, -0x000005D2, 0x0004003D, 0x00000006, 0x000005D4, 0x000005CB, 0x00050085, 0x00000006, 0x000005D5, -0x000005D4, 0x000000D5, 0x0007000C, 0x00000006, 0x000005D7, 0x00000001, 0x00000025, 0x000005D5, -0x000005D6, 0x0003003E, 0x000005D3, 0x000005D7, 0x0004003D, 0x00000006, 0x000005D9, 0x000005BF, -0x0004003D, 0x00000006, 0x000005DA, 0x000005D3, 0x00050081, 0x00000006, 0x000005DB, 0x000005D9, -0x000005DA, 0x0003003E, 0x000005DC, 0x000005DB, 0x00050039, 0x00000006, 0x000005DD, 0x00000019, -0x000005DC, 0x0003003E, 0x000005D8, 0x000005DD, 0x0004003D, 0x00000006, 0x000005DE, 0x000005D8, -0x0006000C, 0x00000006, 0x000005DF, 0x00000001, 0x0000001F, 0x000005DE, 0x00050041, 0x00000007, -0x000005E0, 0x00000589, 0x00000210, 0x0003003E, 0x000005E0, 0x000005DF, 0x00050041, 0x0000059E, -0x000005E2, 0x000001FE, 0x00000210, 0x0004003D, 0x00000012, 0x000005E3, 0x000005E2, 0x0008004F, -0x0000000C, 0x000005E4, 0x000005E3, 0x000005E3, 0x00000000, 0x00000001, 0x00000002, 0x0003003E, -0x000005E1, 0x000005E4, 0x00050041, 0x000001EA, 0x000005E5, 0x000002CD, 0x000001E0, 0x0004003D, -0x00000012, 0x000005E6, 0x000005E5, 0x0008004F, 0x0000000C, 0x000005E7, 0x000005E6, 0x000005E6, -0x00000000, 0x00000001, 0x00000002, 0x0004003D, 0x0000000C, 0x000005E8, 0x000005E1, 0x00050083, -0x0000000C, 0x000005E9, 0x000005E7, 0x000005E8, 0x0006000C, 0x0000000C, 0x000005EA, 0x00000001, -0x00000045, 0x000005E9, 0x00050041, 0x0000000D, 0x000005EB, 0x00000589, 0x00000278, 0x0003003E, -0x000005EB, 0x000005EA, 0x00050041, 0x0000000D, 0x000005EC, 0x00000589, 0x0000020A, 0x0004003D, -0x0000000C, 0x000005ED, 0x000005EC, 0x00050041, 0x0000000D, 0x000005EE, 0x00000589, 0x00000278, -0x0004003D, 0x0000000C, 0x000005EF, 0x000005EE, 0x00050094, 0x00000006, 0x000005F0, 0x000005ED, -0x000005EF, 0x0007000C, 0x00000006, 0x000005F1, 0x00000001, 0x00000028, 0x000005F0, 0x0000018F, -0x00050041, 0x00000007, 0x000005F2, 0x00000589, 0x0000025A, 0x0003003E, 0x000005F2, 0x000005F1, -0x0004003D, 0x000001F7, 0x000005F4, 0x000005F3, 0x00050041, 0x00000007, 0x000005F5, 0x00000589, -0x0000025A, 0x0004003D, 0x00000006, 0x000005F6, 0x000005F5, 0x00050041, 0x00000007, 0x000005F7, -0x00000589, 0x0000027E, 0x0004003D, 0x00000006, 0x000005F8, 0x000005F7, 0x00050050, 0x0000007F, -0x000005F9, 0x000005F6, 0x000005F8, 0x00050057, 0x00000012, 0x000005FA, 0x000005F4, 0x000005F9, -0x0007004F, 0x0000007F, 0x000005FB, 0x000005FA, 0x000005FA, 0x00000000, 0x00000001, 0x00050041, -0x00000080, 0x000005FC, 0x00000589, 0x0000032C, 0x0003003E, 0x000005FC, 0x000005FB, 0x00050041, -0x00000007, 0x000005FF, 0x00000589, 0x00000260, 0x0004003D, 0x00000006, 0x00000600, 0x000005FF, -0x0003003E, 0x000005FE, 0x00000600, 0x00050039, 0x00000006, 0x00000601, 0x00000054, 0x000005FE, -0x0003003E, 0x000005FD, 0x00000601, 0x00050041, 0x00000013, 0x00000603, 0x00000589, 0x000001E9, -0x0004003D, 0x00000012, 0x00000604, 0x00000603, 0x00050041, 0x00000007, 0x00000606, 0x00000589, -0x000001FF, 0x0004003D, 0x00000006, 0x00000607, 0x00000606, 0x0003003E, 0x00000605, 0x00000607, -0x0004003D, 0x00000006, 0x00000609, 0x000005FD, 0x0003003E, 0x00000608, 0x00000609, 0x00070039, -0x0000000C, 0x0000060A, 0x00000051, 0x00000604, 0x00000605, 0x00000608, 0x0003003E, 0x00000602, -0x0000060A, 0x0004003D, 0x0000000C, 0x0000060B, 0x00000602, 0x00050041, 0x0000000D, 0x0000060C, -0x00000589, 0x00000244, 0x0003003E, 0x0000060C, 0x0000060B, 0x00050041, 0x0000000D, 0x0000060D, -0x00000589, 0x00000244, 0x0004003D, 0x0000000C, 0x0000060E, 0x0000060D, 0x00060041, 0x00000007, -0x00000610, 0x00000589, 0x0000032C, 0x00000520, 0x0004003D, 0x00000006, 0x00000611, 0x00000610, -0x0007000C, 0x00000006, 0x00000612, 0x00000001, 0x00000028, 0x0000060F, 0x00000611, 0x00050088, -0x00000006, 0x00000613, 0x000000D5, 0x00000612, 0x00050083, 0x00000006, 0x00000614, 0x00000613, -0x000000D5, 0x0005008E, 0x0000000C, 0x00000615, 0x0000060E, 0x00000614, 0x00060050, 0x0000000C, -0x00000616, 0x000000D5, 0x000000D5, 0x000000D5, 0x00050081, 0x0000000C, 0x00000617, 0x00000616, -0x00000615, 0x00050041, 0x0000000D, 0x00000618, 0x00000589, 0x000003F5, 0x0003003E, 0x00000618, -0x00000617, 0x00050041, 0x00000013, 0x00000619, 0x00000589, 0x000001E9, 0x0004003D, 0x00000012, -0x0000061A, 0x00000619, 0x00050041, 0x00000007, 0x0000061C, 0x00000589, 0x000001FF, 0x0004003D, -0x00000006, 0x0000061D, 0x0000061C, 0x0003003E, 0x0000061B, 0x0000061D, 0x00060039, 0x0000000C, -0x0000061E, 0x0000004B, 0x0000061A, 0x0000061B, 0x00060041, 0x00000007, 0x0000061F, 0x00000589, -0x000001E9, 0x0000023E, 0x00050051, 0x00000006, 0x00000620, 0x0000061E, 0x00000000, 0x0003003E, -0x0000061F, 0x00000620, 0x00060041, 0x00000007, 0x00000621, 0x00000589, 0x000001E9, 0x00000520, -0x00050051, 0x00000006, 0x00000622, 0x0000061E, 0x00000001, 0x0003003E, 0x00000621, 0x00000622, -0x00060041, 0x00000007, 0x00000623, 0x00000589, 0x000001E9, 0x0000030A, 0x00050051, 0x00000006, -0x00000624, 0x0000061E, 0x00000002, 0x0003003E, 0x00000623, 0x00000624, 0x00050041, 0x000001E1, -0x00000626, 0x000002CD, 0x00000278, 0x0004003D, 0x00000006, 0x00000627, 0x00000626, 0x0003003E, -0x00000625, 0x00000627, 0x00050041, 0x000001E1, 0x00000629, 0x000002CD, 0x0000025A, 0x0004003D, -0x00000006, 0x0000062A, 0x00000629, 0x0003003E, 0x00000628, 0x0000062A, 0x00050041, 0x0000031C, -0x0000062C, 0x000002CD, 0x00000210, 0x0004003D, 0x000002C7, 0x0000062D, 0x0000062C, 0x0004003D, -0x0000000C, 0x0000062E, 0x000005E1, 0x00050051, 0x00000006, 0x0000062F, 0x0000062E, 0x00000000, -0x00050051, 0x00000006, 0x00000630, 0x0000062E, 0x00000001, 0x00050051, 0x00000006, 0x00000631, -0x0000062E, 0x00000002, 0x00070050, 0x00000012, 0x00000632, 0x0000062F, 0x00000630, 0x00000631, -0x000000D5, 0x00050091, 0x00000012, 0x00000633, 0x0000062D, 0x00000632, 0x0003003E, 0x0000062B, -0x00000633, 0x0004003D, 0x00000012, 0x00000635, 0x0000062B, 0x0006000C, 0x00000006, 0x00000636, -0x00000001, 0x00000042, 0x00000635, 0x0003003E, 0x00000634, 0x00000636, 0x0004003D, 0x00000006, -0x00000637, 0x00000634, 0x0004003D, 0x00000006, 0x00000638, 0x00000625, 0x0004003D, 0x00000006, -0x00000639, 0x00000628, 0x00050083, 0x00000006, 0x0000063A, 0x00000638, 0x00000639, 0x00050083, -0x00000006, 0x0000063B, 0x00000637, 0x0000063A, 0x0003003E, 0x000000D4, 0x0000063B, 0x0004003D, -0x00000006, 0x0000063C, 0x00000628, 0x0004003D, 0x00000006, 0x0000063D, 0x000000D4, 0x00050088, -0x00000006, 0x0000063E, 0x0000063D, 0x0000063C, 0x0003003E, 0x000000D4, 0x0000063E, 0x0004003D, -0x00000006, 0x0000063F, 0x000000D4, 0x00050083, 0x00000006, 0x00000640, 0x000000D5, 0x0000063F, -0x0008000C, 0x00000006, 0x00000641, 0x00000001, 0x0000002B, 0x00000640, 0x000000F8, 0x000000D5, -0x0003003E, 0x000000D4, 0x00000641, 0x00050041, 0x00000007, 0x00000643, 0x00000589, 0x0000025A, -0x0004003D, 0x00000006, 0x00000644, 0x00000643, 0x00050085, 0x00000006, 0x00000645, 0x00000130, -0x00000644, 0x00050041, 0x0000000D, 0x00000646, 0x00000589, 0x0000020A, 0x0004003D, 0x0000000C, -0x00000647, 0x00000646, 0x0005008E, 0x0000000C, 0x00000648, 0x00000647, 0x00000645, 0x00050041, -0x0000000D, 0x00000649, 0x00000589, 0x00000278, 0x0004003D, 0x0000000C, 0x0000064A, 0x00000649, -0x00050083, 0x0000000C, 0x0000064B, 0x00000648, 0x0000064A, 0x0003003E, 0x00000642, 0x0000064B, -0x00050041, 0x0000000D, 0x0000064E, 0x00000589, 0x00000244, 0x0004003D, 0x0000000C, 0x0000064F, -0x0000064E, 0x0003003E, 0x0000064D, 0x0000064F, 0x0004003D, 0x0000000C, 0x00000651, 0x000005E1, -0x0003003E, 0x00000650, 0x00000651, 0x0004003D, 0x000000AB, 0x00000653, 0x00000589, 0x0003003E, -0x00000652, 0x00000653, 0x00070039, 0x0000000C, 0x00000654, 0x000000CC, 0x0000064D, 0x00000650, -0x00000652, 0x0003003E, 0x0000064C, 0x00000654, 0x00050041, 0x0000000D, 0x00000657, 0x00000589, -0x00000244, 0x0004003D, 0x0000000C, 0x00000658, 0x00000657, 0x0003003E, 0x00000656, 0x00000658, -0x0004003D, 0x0000000C, 0x0000065A, 0x00000642, 0x0003003E, 0x00000659, 0x0000065A, 0x0004003D, -0x000000AB, 0x0000065C, 0x00000589, 0x0003003E, 0x0000065B, 0x0000065C, 0x00070039, 0x0000000C, -0x0000065D, 0x000000D1, 0x00000656, 0x00000659, 0x0000065B, 0x0003003E, 0x00000655, 0x0000065D, -0x0004003D, 0x0000000C, 0x0000065F, 0x0000064C, 0x0004003D, 0x0000000C, 0x00000660, 0x00000655, -0x00050081, 0x0000000C, 0x00000661, 0x0000065F, 0x00000660, 0x00050041, 0x0000000D, 0x00000662, -0x00000589, 0x000001E0, 0x0004003D, 0x0000000C, 0x00000663, 0x00000662, 0x00050081, 0x0000000C, -0x00000664, 0x00000661, 0x00000663, 0x0003003E, 0x0000065E, 0x00000664, 0x0004003D, 0x0000000C, -0x00000667, 0x0000065E, 0x00050051, 0x00000006, 0x00000668, 0x00000667, 0x00000000, 0x00050051, -0x00000006, 0x00000669, 0x00000667, 0x00000001, 0x00050051, 0x00000006, 0x0000066A, 0x00000667, -0x00000002, 0x00070050, 0x00000012, 0x0000066B, 0x00000668, 0x00000669, 0x0000066A, 0x000000D5, -0x0003003E, 0x00000666, 0x0000066B, 0x00050041, 0x0000032D, 0x0000066D, 0x000002CD, 0x0000066C, -0x0004003D, 0x00000085, 0x0000066E, 0x0000066D, 0x000500AD, 0x000001E5, 0x0000066F, 0x0000066E, -0x000001E9, 0x000300F7, 0x00000671, 0x00000000, 0x000400FA, 0x0000066F, 0x00000670, 0x00000671, -0x000200F8, 0x00000670, 0x00050041, 0x0000032D, 0x00000672, 0x000002CD, 0x0000066C, 0x0004003D, -0x00000085, 0x00000673, 0x00000672, 0x000300F7, 0x0000067B, 0x00000000, 0x001100FB, 0x00000673, -0x0000067B, 0x00000001, 0x00000674, 0x00000002, 0x00000675, 0x00000003, 0x00000676, 0x00000004, -0x00000677, 0x00000005, 0x00000678, 0x00000006, 0x00000679, 0x00000007, 0x0000067A, 0x000200F8, -0x00000674, 0x00050041, 0x00000013, 0x0000067C, 0x00000589, 0x000001E9, 0x0004003D, 0x00000012, -0x0000067D, 0x0000067C, 0x0003003E, 0x00000666, 0x0000067D, 0x000200F9, 0x0000067B, 0x000200F8, -0x00000675, 0x00050041, 0x00000007, 0x0000067F, 0x00000589, 0x000001FF, 0x0004003D, 0x00000006, -0x00000680, 0x0000067F, 0x00060050, 0x0000000C, 0x00000681, 0x00000680, 0x00000680, 0x00000680, -0x00050051, 0x00000006, 0x00000682, 0x00000681, 0x00000000, 0x00050051, 0x00000006, 0x00000683, -0x00000681, 0x00000001, 0x00050051, 0x00000006, 0x00000684, 0x00000681, 0x00000002, 0x00070050, -0x00000012, 0x00000685, 0x00000682, 0x00000683, 0x00000684, 0x000000D5, 0x0003003E, 0x00000666, -0x00000685, 0x000200F9, 0x0000067B, 0x000200F8, 0x00000676, 0x00050041, 0x00000007, 0x00000687, -0x00000589, 0x0000027E, 0x0004003D, 0x00000006, 0x00000688, 0x00000687, 0x00060050, 0x0000000C, -0x00000689, 0x00000688, 0x00000688, 0x00000688, 0x00050051, 0x00000006, 0x0000068A, 0x00000689, -0x00000000, 0x00050051, 0x00000006, 0x0000068B, 0x00000689, 0x00000001, 0x00050051, 0x00000006, -0x0000068C, 0x00000689, 0x00000002, 0x00070050, 0x00000012, 0x0000068D, 0x0000068A, 0x0000068B, -0x0000068C, 0x000000D5, 0x0003003E, 0x00000666, 0x0000068D, 0x000200F9, 0x0000067B, 0x000200F8, -0x00000677, 0x00050041, 0x00000007, 0x0000068F, 0x00000589, 0x00000228, 0x0004003D, 0x00000006, -0x00000690, 0x0000068F, 0x00060050, 0x0000000C, 0x00000691, 0x00000690, 0x00000690, 0x00000690, -0x00050051, 0x00000006, 0x00000692, 0x00000691, 0x00000000, 0x00050051, 0x00000006, 0x00000693, -0x00000691, 0x00000001, 0x00050051, 0x00000006, 0x00000694, 0x00000691, 0x00000002, 0x00070050, -0x00000012, 0x00000695, 0x00000692, 0x00000693, 0x00000694, 0x000000D5, 0x0003003E, 0x00000666, -0x00000695, 0x000200F9, 0x0000067B, 0x000200F8, 0x00000678, 0x00050041, 0x0000000D, 0x00000697, -0x00000589, 0x000001E0, 0x0004003D, 0x0000000C, 0x00000698, 0x00000697, 0x00050051, 0x00000006, -0x00000699, 0x00000698, 0x00000000, 0x00050051, 0x00000006, 0x0000069A, 0x00000698, 0x00000001, -0x00050051, 0x00000006, 0x0000069B, 0x00000698, 0x00000002, 0x00070050, 0x00000012, 0x0000069C, -0x00000699, 0x0000069A, 0x0000069B, 0x000000D5, 0x0003003E, 0x00000666, 0x0000069C, 0x000200F9, -0x0000067B, 0x000200F8, 0x00000679, 0x00050041, 0x0000000D, 0x0000069E, 0x00000589, 0x0000020A, -0x0004003D, 0x0000000C, 0x0000069F, 0x0000069E, 0x00050051, 0x00000006, 0x000006A0, 0x0000069F, -0x00000000, 0x00050051, 0x00000006, 0x000006A1, 0x0000069F, 0x00000001, 0x00050051, 0x00000006, -0x000006A2, 0x0000069F, 0x00000002, 0x00070050, 0x00000012, 0x000006A3, 0x000006A0, 0x000006A1, -0x000006A2, 0x000000D5, 0x0003003E, 0x00000666, 0x000006A3, 0x000200F9, 0x0000067B, 0x000200F8, -0x0000067A, 0x0004003D, 0x0000000C, 0x000006A7, 0x000005E1, 0x0003003E, 0x000006A6, 0x000006A7, -0x00050039, 0x00000085, 0x000006A8, 0x000000A2, 0x000006A6, 0x0003003E, 0x000006A5, 0x000006A8, -0x0004003D, 0x00000085, 0x000006A9, 0x000006A5, 0x000300F7, 0x000006AE, 0x00000000, 0x000B00FB, -0x000006A9, 0x000006AE, 0x00000000, 0x000006AA, 0x00000001, 0x000006AB, 0x00000002, 0x000006AC, -0x00000003, 0x000006AD, 0x000200F8, 0x000006AA, 0x0004003D, 0x00000012, 0x000006AF, 0x00000666, -0x00050085, 0x00000012, 0x000006B3, 0x000006AF, 0x000006B2, 0x0003003E, 0x00000666, 0x000006B3, -0x000200F9, 0x000006AE, 0x000200F8, 0x000006AB, 0x0004003D, 0x00000012, 0x000006B5, 0x00000666, -0x00050085, 0x00000012, 0x000006B7, 0x000006B5, 0x000006B6, 0x0003003E, 0x00000666, 0x000006B7, -0x000200F9, 0x000006AE, 0x000200F8, 0x000006AC, 0x0004003D, 0x00000012, 0x000006B9, 0x00000666, -0x00050085, 0x00000012, 0x000006BB, 0x000006B9, 0x000006BA, 0x0003003E, 0x00000666, 0x000006BB, -0x000200F9, 0x000006AE, 0x000200F8, 0x000006AD, 0x0004003D, 0x00000012, 0x000006BD, 0x00000666, -0x00050085, 0x00000012, 0x000006BF, 0x000006BD, 0x000006BE, 0x0003003E, 0x00000666, 0x000006BF, -0x000200F9, 0x000006AE, 0x000200F8, 0x000006AE, 0x000200F9, 0x0000067B, 0x000200F8, 0x0000067B, -0x000200F9, 0x00000671, 0x000200F8, 0x00000671, 0x000100FD, 0x00010038, 0x00050036, 0x00000006, -0x0000000A, 0x00000000, 0x00000008, 0x00030037, 0x00000007, 0x00000009, 0x000200F8, 0x0000000B, -0x0004003B, 0x00000007, 0x000000D8, 0x00000007, 0x0004003D, 0x00000006, 0x000000D9, 0x00000009, -0x0004003D, 0x00000006, 0x000000DA, 0x00000009, 0x00050085, 0x00000006, 0x000000DB, 0x000000D9, -0x000000DA, 0x0003003E, 0x000000D8, 0x000000DB, 0x0004003D, 0x00000006, 0x000000DC, 0x000000D8, -0x0004003D, 0x00000006, 0x000000DD, 0x000000D8, 0x00050085, 0x00000006, 0x000000DE, 0x000000DC, -0x000000DD, 0x0004003D, 0x00000006, 0x000000DF, 0x00000009, 0x00050085, 0x00000006, 0x000000E0, -0x000000DE, 0x000000DF, 0x000200FE, 0x000000E0, 0x00010038, 0x00050036, 0x0000000C, 0x00000010, -0x00000000, 0x0000000E, 0x00030037, 0x0000000D, 0x0000000F, 0x000200F8, 0x00000011, 0x0004003D, -0x0000000C, 0x000000E3, 0x0000000F, 0x0007000C, 0x0000000C, 0x000000E6, 0x00000001, 0x0000001A, -0x000000E3, 0x000000E5, 0x000200FE, 0x000000E6, 0x00010038, 0x00050036, 0x00000012, 0x00000016, -0x00000000, 0x00000014, 0x00030037, 0x00000013, 0x00000015, 0x000200F8, 0x00000017, 0x0004003B, -0x0000000D, 0x000000E9, 0x00000007, 0x0004003D, 0x00000012, 0x000000EA, 0x00000015, 0x0008004F, -0x0000000C, 0x000000EB, 0x000000EA, 0x000000EA, 0x00000000, 0x00000001, 0x00000002, 0x0003003E, -0x000000E9, 0x000000EB, 0x00050039, 0x0000000C, 0x000000EC, 0x00000010, 0x000000E9, 0x00050041, -0x00000007, 0x000000EF, 0x00000015, 0x000000EE, 0x0004003D, 0x00000006, 0x000000F0, 0x000000EF, -0x00050051, 0x00000006, 0x000000F1, 0x000000EC, 0x00000000, 0x00050051, 0x00000006, 0x000000F2, -0x000000EC, 0x00000001, 0x00050051, 0x00000006, 0x000000F3, 0x000000EC, 0x00000002, 0x00070050, -0x00000012, 0x000000F4, 0x000000F1, 0x000000F2, 0x000000F3, 0x000000F0, 0x000200FE, 0x000000F4, -0x00010038, 0x00050036, 0x00000006, 0x00000019, 0x00000000, 0x00000008, 0x00030037, 0x00000007, -0x00000018, 0x000200F8, 0x0000001A, 0x0004003D, 0x00000006, 0x000000F7, 0x00000018, 0x0008000C, -0x00000006, 0x000000F9, 0x00000001, 0x0000002B, 0x000000F7, 0x000000F8, 0x000000D5, 0x000200FE, -0x000000F9, 0x00010038, 0x00050036, 0x00000006, 0x00000020, 0x00000000, 0x0000001B, 0x00030037, -0x00000007, 0x0000001C, 0x00030037, 0x00000007, 0x0000001D, 0x00030037, 0x0000000C, 0x0000001E, -0x00030037, 0x0000000C, 0x0000001F, 0x000200F8, 0x00000021, 0x0004003B, 0x0000000D, 0x000000FC, -0x00000007, 0x0004003B, 0x00000007, 0x000000FE, 0x00000007, 0x0004003B, 0x00000007, 0x00000102, -0x00000007, 0x0004003B, 0x00000007, 0x0000010C, 0x00000007, 0x0007000C, 0x0000000C, 0x000000FD, -0x00000001, 0x00000044, 0x0000001E, 0x0000001F, 0x0003003E, 0x000000FC, 0x000000FD, 0x0004003D, -0x00000006, 0x000000FF, 0x0000001D, 0x0004003D, 0x00000006, 0x00000100, 0x0000001C, 0x00050085, -0x00000006, 0x00000101, 0x000000FF, 0x00000100, 0x0003003E, 0x000000FE, 0x00000101, 0x0004003D, -0x00000006, 0x00000103, 0x0000001C, 0x0004003D, 0x0000000C, 0x00000104, 0x000000FC, 0x0004003D, -0x0000000C, 0x00000105, 0x000000FC, 0x00050094, 0x00000006, 0x00000106, 0x00000104, 0x00000105, -0x0004003D, 0x00000006, 0x00000107, 0x000000FE, 0x0004003D, 0x00000006, 0x00000108, 0x000000FE, -0x00050085, 0x00000006, 0x00000109, 0x00000107, 0x00000108, 0x00050081, 0x00000006, 0x0000010A, -0x00000106, 0x00000109, 0x00050088, 0x00000006, 0x0000010B, 0x00000103, 0x0000010A, 0x0003003E, -0x00000102, 0x0000010B, 0x0004003D, 0x00000006, 0x0000010D, 0x00000102, 0x0004003D, 0x00000006, -0x0000010E, 0x00000102, 0x00050085, 0x00000006, 0x0000010F, 0x0000010D, 0x0000010E, 0x00050085, -0x00000006, 0x00000111, 0x0000010F, 0x00000110, 0x0003003E, 0x0000010C, 0x00000111, 0x0004003D, -0x00000006, 0x00000112, 0x0000010C, 0x0007000C, 0x00000006, 0x00000114, 0x00000001, 0x00000025, -0x00000112, 0x00000113, 0x000200FE, 0x00000114, 0x00010038, 0x00050036, 0x0000000C, 0x00000026, -0x00000000, 0x00000022, 0x00030037, 0x0000000C, 0x00000023, 0x00030037, 0x00000007, 0x00000024, -0x00030037, 0x00000007, 0x00000025, 0x000200F8, 0x00000027, 0x0004003B, 0x00000007, 0x0000011C, -0x00000007, 0x0004003D, 0x00000006, 0x00000117, 0x00000024, 0x00060050, 0x0000000C, 0x00000118, -0x00000117, 0x00000117, 0x00000117, 0x00050083, 0x0000000C, 0x00000119, 0x00000118, 0x00000023, -0x0004003D, 0x00000006, 0x0000011A, 0x00000025, 0x00050083, 0x00000006, 0x0000011B, 0x000000D5, -0x0000011A, 0x0003003E, 0x0000011C, 0x0000011B, 0x00050039, 0x00000006, 0x0000011D, 0x0000000A, -0x0000011C, 0x0005008E, 0x0000000C, 0x0000011E, 0x00000119, 0x0000011D, 0x00050081, 0x0000000C, -0x0000011F, 0x00000023, 0x0000011E, 0x000200FE, 0x0000011F, 0x00010038, 0x00050036, 0x00000006, -0x0000002C, 0x00000000, 0x00000028, 0x00030037, 0x00000007, 0x00000029, 0x00030037, 0x00000007, -0x0000002A, 0x00030037, 0x00000007, 0x0000002B, 0x000200F8, 0x0000002D, 0x0004003D, 0x00000006, -0x00000122, 0x0000002A, 0x0004003D, 0x00000006, 0x00000123, 0x0000002B, 0x0004003D, 0x00000006, -0x00000124, 0x0000002A, 0x00050083, 0x00000006, 0x00000125, 0x00000123, 0x00000124, 0x0004003D, -0x00000006, 0x00000126, 0x00000029, 0x00050083, 0x00000006, 0x00000127, 0x000000D5, 0x00000126, -0x0007000C, 0x00000006, 0x00000129, 0x00000001, 0x0000001A, 0x00000127, 0x00000128, 0x00050085, -0x00000006, 0x0000012A, 0x00000125, 0x00000129, 0x00050081, 0x00000006, 0x0000012B, 0x00000122, -0x0000012A, 0x000200FE, 0x0000012B, 0x00010038, 0x00050036, 0x00000006, 0x00000033, 0x00000000, -0x0000002E, 0x00030037, 0x00000007, 0x0000002F, 0x00030037, 0x00000007, 0x00000030, 0x00030037, -0x00000007, 0x00000031, 0x00030037, 0x00000007, 0x00000032, 0x000200F8, 0x00000034, 0x0004003B, -0x00000007, 0x0000012E, 0x00000007, 0x0004003B, 0x00000007, 0x00000138, 0x00000007, 0x0004003B, -0x00000007, 0x00000139, 0x00000007, 0x0004003B, 0x00000007, 0x0000013A, 0x00000007, 0x0004003B, -0x00000007, 0x0000013C, 0x00000007, 0x0004003B, 0x00000007, 0x0000013F, 0x00000007, 0x0004003B, -0x00000007, 0x00000140, 0x00000007, 0x0004003B, 0x00000007, 0x00000141, 0x00000007, 0x0004003B, -0x00000007, 0x00000143, 0x00000007, 0x0004003D, 0x00000006, 0x00000131, 0x0000002F, 0x00050085, -0x00000006, 0x00000132, 0x00000130, 0x00000131, 0x0004003D, 0x00000006, 0x00000133, 0x00000032, -0x00050085, 0x00000006, 0x00000134, 0x00000132, 0x00000133, 0x0004003D, 0x00000006, 0x00000135, -0x00000032, 0x00050085, 0x00000006, 0x00000136, 0x00000134, 0x00000135, 0x00050081, 0x00000006, -0x00000137, 0x0000012F, 0x00000136, 0x0003003E, 0x0000012E, 0x00000137, 0x0003003E, 0x00000139, -0x000000D5, 0x0004003D, 0x00000006, 0x0000013B, 0x0000012E, 0x0003003E, 0x0000013A, 0x0000013B, -0x0004003D, 0x00000006, 0x0000013D, 0x00000031, 0x0003003E, 0x0000013C, 0x0000013D, 0x00070039, -0x00000006, 0x0000013E, 0x0000002C, 0x00000139, 0x0000013A, 0x0000013C, 0x0003003E, 0x00000138, -0x0000013E, 0x0003003E, 0x00000140, 0x000000D5, 0x0004003D, 0x00000006, 0x00000142, 0x0000012E, -0x0003003E, 0x00000141, 0x00000142, 0x0004003D, 0x00000006, 0x00000144, 0x00000030, 0x0003003E, -0x00000143, 0x00000144, 0x00070039, 0x00000006, 0x00000145, 0x0000002C, 0x00000140, 0x00000141, -0x00000143, 0x0003003E, 0x0000013F, 0x00000145, 0x0004003D, 0x00000006, 0x00000146, 0x00000138, -0x0004003D, 0x00000006, 0x00000147, 0x0000013F, 0x00050085, 0x00000006, 0x00000148, 0x00000146, -0x00000147, 0x00050085, 0x00000006, 0x00000149, 0x00000148, 0x00000110, 0x000200FE, 0x00000149, -0x00010038, 0x00050036, 0x00000006, 0x00000038, 0x00000000, 0x00000028, 0x00030037, 0x00000007, -0x00000035, 0x00030037, 0x00000007, 0x00000036, 0x00030037, 0x00000007, 0x00000037, 0x000200F8, -0x00000039, 0x0004003B, 0x00000007, 0x0000014C, 0x00000007, 0x0004003B, 0x00000007, 0x00000150, -0x00000007, 0x0004003B, 0x00000007, 0x0000015E, 0x00000007, 0x0004003D, 0x00000006, 0x0000014D, -0x00000037, 0x0004003D, 0x00000006, 0x0000014E, 0x00000037, 0x00050085, 0x00000006, 0x0000014F, -0x0000014D, 0x0000014E, 0x0003003E, 0x0000014C, 0x0000014F, 0x0004003D, 0x00000006, 0x00000151, -0x00000035, 0x0004003D, 0x00000006, 0x00000152, 0x00000036, 0x0004007F, 0x00000006, 0x00000153, -0x00000152, 0x0004003D, 0x00000006, 0x00000154, 0x0000014C, 0x00050085, 0x00000006, 0x00000155, -0x00000153, 0x00000154, 0x0004003D, 0x00000006, 0x00000156, 0x00000036, 0x00050081, 0x00000006, -0x00000157, 0x00000155, 0x00000156, 0x0004003D, 0x00000006, 0x00000158, 0x00000036, 0x00050085, -0x00000006, 0x00000159, 0x00000157, 0x00000158, 0x0004003D, 0x00000006, 0x0000015A, 0x0000014C, -0x00050081, 0x00000006, 0x0000015B, 0x00000159, 0x0000015A, 0x0006000C, 0x00000006, 0x0000015C, -0x00000001, 0x0000001F, 0x0000015B, 0x00050085, 0x00000006, 0x0000015D, 0x00000151, 0x0000015C, -0x0003003E, 0x00000150, 0x0000015D, 0x0004003D, 0x00000006, 0x0000015F, 0x00000036, 0x0004003D, -0x00000006, 0x00000160, 0x00000035, 0x0004007F, 0x00000006, 0x00000161, 0x00000160, 0x0004003D, -0x00000006, 0x00000162, 0x0000014C, 0x00050085, 0x00000006, 0x00000163, 0x00000161, 0x00000162, -0x0004003D, 0x00000006, 0x00000164, 0x00000035, 0x00050081, 0x00000006, 0x00000165, 0x00000163, -0x00000164, 0x0004003D, 0x00000006, 0x00000166, 0x00000035, 0x00050085, 0x00000006, 0x00000167, -0x00000165, 0x00000166, 0x0004003D, 0x00000006, 0x00000168, 0x0000014C, 0x00050081, 0x00000006, -0x00000169, 0x00000167, 0x00000168, 0x0006000C, 0x00000006, 0x0000016A, 0x00000001, 0x0000001F, -0x00000169, 0x00050085, 0x00000006, 0x0000016B, 0x0000015F, 0x0000016A, 0x0003003E, 0x0000015E, -0x0000016B, 0x0004003D, 0x00000006, 0x0000016C, 0x0000015E, 0x0004003D, 0x00000006, 0x0000016D, -0x00000150, 0x00050081, 0x00000006, 0x0000016E, 0x0000016C, 0x0000016D, 0x00050088, 0x00000006, -0x0000016F, 0x0000012F, 0x0000016E, 0x000200FE, 0x0000016F, 0x00010038, 0x00050036, 0x00000006, -0x0000003D, 0x00000000, 0x0000003A, 0x00030037, 0x00000007, 0x0000003B, 0x00030037, 0x00000007, -0x0000003C, 0x000200F8, 0x0000003E, 0x0004003B, 0x00000007, 0x00000172, 0x00000007, 0x0004003B, -0x00000007, 0x00000178, 0x00000007, 0x0004003B, 0x00000007, 0x0000017C, 0x00000007, 0x0004003D, -0x00000006, 0x00000173, 0x0000003C, 0x0007000C, 0x00000006, 0x00000175, 0x00000001, 0x00000025, -0x00000173, 0x00000174, 0x00050083, 0x00000006, 0x00000176, 0x000000D5, 0x00000175, 0x0006000C, -0x00000006, 0x00000177, 0x00000001, 0x00000020, 0x00000176, 0x0003003E, 0x00000172, 0x00000177, -0x0004003D, 0x00000006, 0x00000179, 0x0000003B, 0x0004003D, 0x00000006, 0x0000017A, 0x00000172, -0x00050085, 0x00000006, 0x0000017B, 0x00000179, 0x0000017A, 0x0003003E, 0x0000017C, 0x0000017B, -0x00050039, 0x00000006, 0x0000017D, 0x00000019, 0x0000017C, 0x0003003E, 0x00000178, 0x0000017D, -0x0004003D, 0x00000006, 0x0000017E, 0x00000178, 0x0004003D, 0x00000006, 0x0000017F, 0x00000178, -0x00050085, 0x00000006, 0x00000180, 0x0000017E, 0x0000017F, 0x000200FE, 0x00000180, 0x00010038, -0x00050036, 0x00000006, 0x00000043, 0x00000000, 0x0000002E, 0x00030037, 0x00000007, 0x0000003F, -0x00030037, 0x00000007, 0x00000040, 0x00030037, 0x00000007, 0x00000041, 0x00030037, 0x00000007, -0x00000042, 0x000200F8, 0x00000044, 0x0004003B, 0x00000007, 0x00000183, 0x00000007, 0x0004003B, -0x00000007, 0x00000185, 0x00000007, 0x0004003B, 0x00000007, 0x00000187, 0x00000007, 0x0004003B, -0x00000007, 0x00000189, 0x00000007, 0x0004003D, 0x00000006, 0x00000184, 0x0000003F, 0x0003003E, -0x00000183, 0x00000184, 0x0004003D, 0x00000006, 0x00000186, 0x00000040, 0x0003003E, 0x00000185, -0x00000186, 0x0004003D, 0x00000006, 0x00000188, 0x00000041, 0x0003003E, 0x00000187, 0x00000188, -0x0004003D, 0x00000006, 0x0000018A, 0x00000042, 0x0003003E, 0x00000189, 0x0000018A, 0x00080039, -0x00000006, 0x0000018B, 0x00000033, 0x00000183, 0x00000185, 0x00000187, 0x00000189, 0x000200FE, -0x0000018B, 0x00010038, 0x00050036, 0x00000006, 0x00000046, 0x00000000, 0x00000008, 0x00030037, -0x00000007, 0x00000045, 0x000200F8, 0x00000047, 0x0004003D, 0x00000006, 0x0000018E, 0x00000045, -0x0007000C, 0x00000006, 0x00000190, 0x00000001, 0x00000028, 0x0000018E, 0x0000018F, 0x000200FE, -0x00000190, 0x00010038, 0x00050036, 0x0000000C, 0x0000004B, 0x00000000, 0x00000048, 0x00030037, -0x00000012, 0x00000049, 0x00030037, 0x00000007, 0x0000004A, 0x000200F8, 0x0000004C, 0x0008004F, -0x0000000C, 0x00000193, 0x00000049, 0x00000049, 0x00000000, 0x00000001, 0x00000002, 0x0004003D, -0x00000006, 0x00000194, 0x0000004A, 0x00050083, 0x00000006, 0x00000195, 0x000000D5, 0x00000194, -0x0005008E, 0x0000000C, 0x00000196, 0x00000193, 0x00000195, 0x000200FE, 0x00000196, 0x00010038, -0x00050036, 0x0000000C, 0x00000051, 0x00000000, 0x0000004D, 0x00030037, 0x00000012, 0x0000004E, -0x00030037, 0x00000007, 0x0000004F, 0x00030037, 0x00000007, 0x00000050, 0x000200F8, 0x00000052, -0x0008004F, 0x0000000C, 0x00000199, 0x0000004E, 0x0000004E, 0x00000000, 0x00000001, 0x00000002, -0x0004003D, 0x00000006, 0x0000019A, 0x0000004F, 0x0005008E, 0x0000000C, 0x0000019B, 0x00000199, -0x0000019A, 0x0004003D, 0x00000006, 0x0000019C, 0x00000050, 0x0004003D, 0x00000006, 0x0000019D, -0x0000004F, 0x00050083, 0x00000006, 0x0000019E, 0x000000D5, 0x0000019D, 0x00050085, 0x00000006, -0x0000019F, 0x0000019C, 0x0000019E, 0x00060050, 0x0000000C, 0x000001A0, 0x0000019F, 0x0000019F, -0x0000019F, 0x00050081, 0x0000000C, 0x000001A1, 0x0000019B, 0x000001A0, 0x000200FE, 0x000001A1, -0x00010038, 0x00050036, 0x00000006, 0x00000054, 0x00000000, 0x00000008, 0x00030037, 0x00000007, -0x00000053, 0x000200F8, 0x00000055, 0x0004003D, 0x00000006, 0x000001A5, 0x00000053, 0x00050085, -0x00000006, 0x000001A6, 0x000001A4, 0x000001A5, 0x0004003D, 0x00000006, 0x000001A7, 0x00000053, -0x00050085, 0x00000006, 0x000001A8, 0x000001A6, 0x000001A7, 0x000200FE, 0x000001A8, 0x00010038, -0x00050036, 0x00000006, 0x00000057, 0x00000000, 0x00000008, 0x00030037, 0x00000007, 0x00000056, -0x000200F8, 0x00000058, 0x0004003D, 0x00000006, 0x000001AB, 0x00000056, 0x0004003D, 0x00000006, -0x000001AC, 0x00000056, 0x00050085, 0x00000006, 0x000001AD, 0x000001AB, 0x000001AC, 0x000200FE, -0x000001AD, 0x00010038, 0x00050036, 0x00000006, 0x0000005D, 0x00000000, 0x0000001B, 0x00030037, -0x00000007, 0x00000059, 0x00030037, 0x00000007, 0x0000005A, 0x00030037, 0x0000000C, 0x0000005B, -0x00030037, 0x0000000C, 0x0000005C, 0x000200F8, 0x0000005E, 0x0004003B, 0x00000007, 0x000001B0, -0x00000007, 0x0004003B, 0x00000007, 0x000001B2, 0x00000007, 0x0004003D, 0x00000006, 0x000001B1, -0x00000059, 0x0003003E, 0x000001B0, 0x000001B1, 0x0004003D, 0x00000006, 0x000001B3, 0x0000005A, -0x0003003E, 0x000001B2, 0x000001B3, 0x00080039, 0x00000006, 0x000001B4, 0x00000020, 0x000001B0, -0x000001B2, 0x0000005C, 0x0000005B, 0x000200FE, 0x000001B4, 0x00010038, 0x00050036, 0x00000006, -0x00000062, 0x00000000, 0x00000028, 0x00030037, 0x00000007, 0x0000005F, 0x00030037, 0x00000007, -0x00000060, 0x00030037, 0x00000007, 0x00000061, 0x000200F8, 0x00000063, 0x0004003B, 0x00000007, -0x000001B7, 0x00000007, 0x0004003B, 0x00000007, 0x000001B9, 0x00000007, 0x0004003B, 0x00000007, -0x000001BB, 0x00000007, 0x0004003D, 0x00000006, 0x000001B8, 0x0000005F, 0x0003003E, 0x000001B7, -0x000001B8, 0x0004003D, 0x00000006, 0x000001BA, 0x00000060, 0x0003003E, 0x000001B9, 0x000001BA, -0x0004003D, 0x00000006, 0x000001BC, 0x00000061, 0x0003003E, 0x000001BB, 0x000001BC, 0x00070039, -0x00000006, 0x000001BD, 0x00000038, 0x000001B7, 0x000001B9, 0x000001BB, 0x000200FE, 0x000001BD, -0x00010038, 0x00050036, 0x0000000C, 0x00000067, 0x00000000, 0x00000064, 0x00030037, 0x0000000C, -0x00000065, 0x00030037, 0x00000007, 0x00000066, 0x000200F8, 0x00000068, 0x0004003B, 0x00000007, -0x000001C0, 0x00000007, 0x0004003B, 0x00000007, 0x000001C4, 0x00000007, 0x0004003B, 0x00000007, -0x000001C6, 0x00000007, 0x0004003B, 0x00000007, 0x000001C8, 0x00000007, 0x00050094, 0x00000006, -0x000001C3, 0x00000065, 0x000001C2, 0x0003003E, 0x000001C4, 0x000001C3, 0x00050039, 0x00000006, -0x000001C5, 0x00000019, 0x000001C4, 0x0003003E, 0x000001C0, 0x000001C5, 0x0004003D, 0x00000006, -0x000001C7, 0x000001C0, 0x0003003E, 0x000001C6, 0x000001C7, 0x0004003D, 0x00000006, 0x000001C9, -0x00000066, 0x0003003E, 0x000001C8, 0x000001C9, 0x00070039, 0x0000000C, 0x000001CA, 0x00000026, -0x00000065, 0x000001C6, 0x000001C8, 0x000200FE, 0x000001CA, 0x00010038, 0x00050036, 0x0000000C, -0x0000006D, 0x00000000, 0x00000069, 0x00030037, 0x0000000D, 0x0000006A, 0x00030037, 0x00000007, -0x0000006B, 0x00030037, 0x00000007, 0x0000006C, 0x000200F8, 0x0000006E, 0x0004003D, 0x0000000C, -0x000001CD, 0x0000006A, 0x0004003D, 0x00000006, 0x000001CE, 0x0000006C, 0x00050083, 0x00000006, -0x000001CF, 0x000000D5, 0x000001CE, 0x00060050, 0x0000000C, 0x000001D0, 0x000001CF, 0x000001CF, -0x000001CF, 0x0004003D, 0x0000000C, 0x000001D1, 0x0000006A, 0x0007000C, 0x0000000C, 0x000001D2, -0x00000001, 0x00000028, 0x000001D0, 0x000001D1, 0x0004003D, 0x0000000C, 0x000001D3, 0x0000006A, -0x00050083, 0x0000000C, 0x000001D4, 0x000001D2, 0x000001D3, 0x0004003D, 0x00000006, 0x000001D5, -0x0000006B, 0x00050083, 0x00000006, 0x000001D6, 0x000000D5, 0x000001D5, 0x0007000C, 0x00000006, -0x000001D7, 0x00000001, 0x00000028, 0x000001D6, 0x000000F8, 0x0007000C, 0x00000006, 0x000001D8, -0x00000001, 0x0000001A, 0x000001D7, 0x00000128, 0x0005008E, 0x0000000C, 0x000001D9, 0x000001D4, -0x000001D8, 0x00050081, 0x0000000C, 0x000001DA, 0x000001CD, 0x000001D9, 0x000200FE, 0x000001DA, -0x00010038, 0x00050036, 0x00000012, 0x00000070, 0x00000000, 0x0000006F, 0x000200F8, 0x00000071, -0x0004003B, 0x00000013, 0x00000204, 0x00000007, 0x00050041, 0x000001E1, 0x000001E2, 0x000001DF, -0x000001E0, 0x0004003D, 0x00000006, 0x000001E3, 0x000001E2, 0x000500B8, 0x000001E5, 0x000001E6, -0x000001E3, 0x000001E4, 0x000300F7, 0x000001E8, 0x00000000, 0x000400FA, 0x000001E6, 0x000001E7, -0x000001E8, 0x000200F8, 0x000001E7, 0x00050041, 0x000001EA, 0x000001EB, 0x000001DF, 0x000001E9, -0x0004003D, 0x00000012, 0x000001EC, 0x000001EB, 0x000200FE, 0x000001EC, 0x000200F8, 0x000001E8, -0x00050041, 0x000001E1, 0x000001EE, 0x000001DF, 0x000001E0, 0x0004003D, 0x00000006, 0x000001EF, -0x000001EE, 0x00050083, 0x00000006, 0x000001F0, 0x000000D5, 0x000001EF, 0x00050041, 0x000001EA, -0x000001F1, 0x000001DF, 0x000001E9, 0x0004003D, 0x00000012, 0x000001F2, 0x000001F1, 0x0005008E, -0x00000012, 0x000001F3, 0x000001F2, 0x000001F0, 0x00050041, 0x000001E1, 0x000001F4, 0x000001DF, -0x000001E0, 0x0004003D, 0x00000006, 0x000001F5, 0x000001F4, 0x0004003D, 0x000001F7, 0x000001FA, -0x000001F9, 0x00050041, 0x00000200, 0x00000201, 0x000001FE, 0x000001FF, 0x0004003D, 0x0000007F, -0x00000202, 0x00000201, 0x00050057, 0x00000012, 0x00000203, 0x000001FA, 0x00000202, 0x0003003E, -0x00000204, 0x00000203, 0x00050039, 0x00000012, 0x00000205, 0x00000016, 0x00000204, 0x0005008E, -0x00000012, 0x00000206, 0x00000205, 0x000001F5, 0x00050081, 0x00000012, 0x00000207, 0x000001F3, -0x00000206, 0x000200FE, 0x00000207, 0x00010038, 0x00050036, 0x0000000C, 0x00000073, 0x00000000, -0x00000072, 0x000200F8, 0x00000074, 0x00050041, 0x000001E1, 0x0000020B, 0x000001DF, 0x0000020A, -0x0004003D, 0x00000006, 0x0000020C, 0x0000020B, 0x000500B8, 0x000001E5, 0x0000020D, 0x0000020C, -0x000001E4, 0x000300F7, 0x0000020F, 0x00000000, 0x000400FA, 0x0000020D, 0x0000020E, 0x0000020F, -0x000200F8, 0x0000020E, 0x00050041, 0x000001E1, 0x00000211, 0x000001DF, 0x00000210, 0x0004003D, -0x00000006, 0x00000212, 0x00000211, 0x00060050, 0x0000000C, 0x00000213, 0x00000212, 0x00000212, -0x00000212, 0x000200FE, 0x00000213, 0x000200F8, 0x0000020F, 0x00050041, 0x000001E1, 0x00000215, -0x000001DF, 0x0000020A, 0x0004003D, 0x00000006, 0x00000216, 0x00000215, 0x00050083, 0x00000006, -0x00000217, 0x000000D5, 0x00000216, 0x00050041, 0x000001E1, 0x00000218, 0x000001DF, 0x00000210, -0x0004003D, 0x00000006, 0x00000219, 0x00000218, 0x00050085, 0x00000006, 0x0000021A, 0x00000217, -0x00000219, 0x00050041, 0x000001E1, 0x0000021B, 0x000001DF, 0x0000020A, 0x0004003D, 0x00000006, -0x0000021C, 0x0000021B, 0x0004003D, 0x000001F7, 0x0000021E, 0x0000021D, 0x00050041, 0x00000200, -0x0000021F, 0x000001FE, 0x000001FF, 0x0004003D, 0x0000007F, 0x00000220, 0x0000021F, 0x00050057, -0x00000012, 0x00000221, 0x0000021E, 0x00000220, 0x0008004F, 0x0000000C, 0x00000222, 0x00000221, -0x00000221, 0x00000000, 0x00000001, 0x00000002, 0x0005008E, 0x0000000C, 0x00000223, 0x00000222, -0x0000021C, 0x00060050, 0x0000000C, 0x00000224, 0x0000021A, 0x0000021A, 0x0000021A, 0x00050081, -0x0000000C, 0x00000225, 0x00000224, 0x00000223, 0x000200FE, 0x00000225, 0x00010038, 0x00050036, -0x00000006, 0x00000076, 0x00000000, 0x00000075, 0x000200F8, 0x00000077, 0x00050041, 0x000001E1, -0x00000229, 0x000001DF, 0x00000228, 0x0004003D, 0x00000006, 0x0000022A, 0x00000229, 0x000500B8, -0x000001E5, 0x0000022B, 0x0000022A, 0x000001E4, 0x000300F7, 0x0000022D, 0x00000000, 0x000400FA, -0x0000022B, 0x0000022C, 0x0000022D, 0x000200F8, 0x0000022C, 0x00050041, 0x000001E1, 0x0000022E, -0x000001DF, 0x000001FF, 0x0004003D, 0x00000006, 0x0000022F, 0x0000022E, 0x000200FE, 0x0000022F, -0x000200F8, 0x0000022D, 0x00050041, 0x000001E1, 0x00000231, 0x000001DF, 0x00000228, 0x0004003D, -0x00000006, 0x00000232, 0x00000231, 0x00050083, 0x00000006, 0x00000233, 0x000000D5, 0x00000232, -0x00050041, 0x000001E1, 0x00000234, 0x000001DF, 0x000001FF, 0x0004003D, 0x00000006, 0x00000235, -0x00000234, 0x00050085, 0x00000006, 0x00000236, 0x00000233, 0x00000235, 0x00050041, 0x000001E1, -0x00000237, 0x000001DF, 0x00000228, 0x0004003D, 0x00000006, 0x00000238, 0x00000237, 0x0004003D, -0x000001F7, 0x0000023A, 0x00000239, 0x00050041, 0x00000200, 0x0000023B, 0x000001FE, 0x000001FF, -0x0004003D, 0x0000007F, 0x0000023C, 0x0000023B, 0x00050057, 0x00000012, 0x0000023D, 0x0000023A, -0x0000023C, 0x00050051, 0x00000006, 0x0000023F, 0x0000023D, 0x00000000, 0x00050085, 0x00000006, -0x00000240, 0x00000238, 0x0000023F, 0x00050081, 0x00000006, 0x00000241, 0x00000236, 0x00000240, -0x000200FE, 0x00000241, 0x00010038, 0x00050036, 0x00000006, 0x00000078, 0x00000000, 0x00000075, -0x000200F8, 0x00000079, 0x00050041, 0x000001E1, 0x00000245, 0x000001DF, 0x00000244, 0x0004003D, -0x00000006, 0x00000246, 0x00000245, 0x000500B8, 0x000001E5, 0x00000247, 0x00000246, 0x000001E4, -0x000300F7, 0x00000249, 0x00000000, 0x000400FA, 0x00000247, 0x00000248, 0x00000249, 0x000200F8, -0x00000248, 0x000200FE, 0x000000D5, 0x000200F8, 0x00000249, 0x00050041, 0x000001E1, 0x0000024B, -0x000001DF, 0x00000244, 0x0004003D, 0x00000006, 0x0000024C, 0x0000024B, 0x00050083, 0x00000006, -0x0000024D, 0x000000D5, 0x0000024C, 0x00050041, 0x000001E1, 0x0000024E, 0x000001DF, 0x00000244, -0x0004003D, 0x00000006, 0x0000024F, 0x0000024E, 0x0004003D, 0x000001F7, 0x00000251, 0x00000250, -0x00050041, 0x00000200, 0x00000252, 0x000001FE, 0x000001FF, 0x0004003D, 0x0000007F, 0x00000253, -0x00000252, 0x00050057, 0x00000012, 0x00000254, 0x00000251, 0x00000253, 0x00050051, 0x00000006, -0x00000255, 0x00000254, 0x00000000, 0x00050085, 0x00000006, 0x00000256, 0x0000024F, 0x00000255, -0x00050081, 0x00000006, 0x00000257, 0x0000024D, 0x00000256, 0x000200FE, 0x00000257, 0x00010038, -0x00050036, 0x0000000C, 0x0000007B, 0x00000000, 0x0000000E, 0x00030037, 0x0000000D, 0x0000007A, -0x000200F8, 0x0000007C, 0x0004003B, 0x0000000D, 0x00000271, 0x00000007, 0x00050041, 0x000001E1, -0x0000025B, 0x000001DF, 0x0000025A, 0x0004003D, 0x00000006, 0x0000025C, 0x0000025B, 0x000500B8, -0x000001E5, 0x0000025D, 0x0000025C, 0x000001E4, 0x000300F7, 0x0000025F, 0x00000000, 0x000400FA, -0x0000025D, 0x0000025E, 0x0000025F, 0x000200F8, 0x0000025E, 0x00050041, 0x000001E1, 0x00000261, -0x000001DF, 0x00000260, 0x0004003D, 0x00000006, 0x00000262, 0x00000261, 0x0004003D, 0x0000000C, -0x00000263, 0x0000007A, 0x0005008E, 0x0000000C, 0x00000264, 0x00000263, 0x00000262, 0x000200FE, -0x00000264, 0x000200F8, 0x0000025F, 0x00050041, 0x000001E1, 0x00000266, 0x000001DF, 0x00000260, -0x0004003D, 0x00000006, 0x00000267, 0x00000266, 0x0004003D, 0x0000000C, 0x00000268, 0x0000007A, -0x0005008E, 0x0000000C, 0x00000269, 0x00000268, 0x00000267, 0x00050041, 0x000001E1, 0x0000026A, -0x000001DF, 0x0000025A, 0x0004003D, 0x00000006, 0x0000026B, 0x0000026A, 0x0004003D, 0x000001F7, -0x0000026D, 0x0000026C, 0x00050041, 0x00000200, 0x0000026E, 0x000001FE, 0x000001FF, 0x0004003D, -0x0000007F, 0x0000026F, 0x0000026E, 0x00050057, 0x00000012, 0x00000270, 0x0000026D, 0x0000026F, -0x0008004F, 0x0000000C, 0x00000272, 0x00000270, 0x00000270, 0x00000000, 0x00000001, 0x00000002, -0x0003003E, 0x00000271, 0x00000272, 0x00050039, 0x0000000C, 0x00000273, 0x00000010, 0x00000271, -0x0005008E, 0x0000000C, 0x00000274, 0x00000273, 0x0000026B, 0x00050081, 0x0000000C, 0x00000275, -0x00000269, 0x00000274, 0x000200FE, 0x00000275, 0x00010038, 0x00050036, 0x0000000C, 0x0000007D, -0x00000000, 0x00000072, 0x000200F8, 0x0000007E, 0x0004003B, 0x0000000D, 0x00000284, 0x00000007, -0x00050041, 0x000001E1, 0x00000279, 0x000001DF, 0x00000278, 0x0004003D, 0x00000006, 0x0000027A, -0x00000279, 0x000500B8, 0x000001E5, 0x0000027B, 0x0000027A, 0x000001E4, 0x000300F7, 0x0000027D, -0x00000000, 0x000400FA, 0x0000027B, 0x0000027C, 0x0000027D, 0x000200F8, 0x0000027C, 0x00050041, -0x0000027F, 0x00000280, 0x000001FE, 0x0000027E, 0x0004003D, 0x0000000C, 0x00000281, 0x00000280, -0x0006000C, 0x0000000C, 0x00000282, 0x00000001, 0x00000045, 0x00000281, 0x000200FE, 0x00000282, -0x000200F8, 0x0000027D, 0x0004003D, 0x000001F7, 0x00000286, 0x00000285, 0x00050041, 0x00000200, -0x00000287, 0x000001FE, 0x000001FF, 0x0004003D, 0x0000007F, 0x00000288, 0x00000287, 0x00050057, -0x00000012, 0x00000289, 0x00000286, 0x00000288, 0x0008004F, 0x0000000C, 0x0000028A, 0x00000289, -0x00000289, 0x00000000, 0x00000001, 0x00000002, 0x0005008E, 0x0000000C, 0x0000028B, 0x0000028A, -0x00000130, 0x00060050, 0x0000000C, 0x0000028C, 0x000000D5, 0x000000D5, 0x000000D5, 0x00050083, -0x0000000C, 0x0000028D, 0x0000028B, 0x0000028C, 0x0006000C, 0x0000000C, 0x0000028E, 0x00000001, -0x00000045, 0x0000028D, 0x0003003E, 0x00000284, 0x0000028E, 0x00050041, 0x0000028F, 0x00000290, -0x000001FE, 0x00000260, 0x0004003D, 0x000001FB, 0x00000291, 0x00000290, 0x0004003D, 0x0000000C, -0x00000292, 0x00000284, 0x00050091, 0x0000000C, 0x00000293, 0x00000291, 0x00000292, 0x0006000C, -0x0000000C, 0x00000294, 0x00000001, 0x00000045, 0x00000293, 0x000200FE, 0x00000294, 0x00010038, -0x00050036, 0x00000006, 0x00000083, 0x00000000, 0x00000081, 0x00030037, 0x00000080, 0x00000082, -0x000200F8, 0x00000084, 0x0004003D, 0x0000007F, 0x00000297, 0x00000082, 0x00050094, 0x00000006, -0x0000029B, 0x00000297, 0x0000029A, 0x0006000C, 0x00000006, 0x0000029C, 0x00000001, 0x0000000D, -0x0000029B, 0x00050085, 0x00000006, 0x0000029E, 0x0000029C, 0x0000029D, 0x0006000C, 0x00000006, -0x0000029F, 0x00000001, 0x0000000A, 0x0000029E, 0x000200FE, 0x0000029F, 0x00010038, 0x00050036, -0x0000007F, 0x0000008B, 0x00000000, 0x00000087, 0x00030037, 0x00000086, 0x00000088, 0x00030037, -0x00000086, 0x00000089, 0x00030037, 0x00000007, 0x0000008A, 0x000200F8, 0x0000008C, 0x0004003B, -0x00000007, 0x000002A2, 0x00000007, 0x0004003B, 0x00000007, 0x000002A4, 0x00000007, 0x0004003B, -0x00000007, 0x000002AD, 0x00000007, 0x0004003B, 0x00000007, 0x000002B4, 0x00000007, 0x0004003B, -0x00000007, 0x000002B7, 0x00000007, 0x0003003E, 0x000002A2, 0x000002A3, 0x0004003D, 0x00000085, -0x000002A5, 0x00000088, 0x0004006F, 0x00000006, 0x000002A6, 0x000002A5, 0x00050081, 0x00000006, -0x000002A7, 0x000002A6, 0x0000012F, 0x0006000C, 0x00000006, 0x000002A8, 0x00000001, 0x0000001F, -0x000002A7, 0x0004003D, 0x00000085, 0x000002A9, 0x00000089, 0x0004006F, 0x00000006, 0x000002AA, -0x000002A9, 0x0006000C, 0x00000006, 0x000002AB, 0x00000001, 0x0000001F, 0x000002AA, 0x00050088, -0x00000006, 0x000002AC, 0x000002A8, 0x000002AB, 0x0003003E, 0x000002A4, 0x000002AC, 0x0004003D, -0x00000085, 0x000002AE, 0x00000088, 0x0004006F, 0x00000006, 0x000002AF, 0x000002AE, 0x0004003D, -0x00000006, 0x000002B0, 0x000002A2, 0x00050085, 0x00000006, 0x000002B1, 0x000002AF, 0x000002B0, -0x0004003D, 0x00000006, 0x000002B2, 0x0000008A, 0x00050081, 0x00000006, 0x000002B3, 0x000002B1, -0x000002B2, 0x0003003E, 0x000002AD, 0x000002B3, 0x0004003D, 0x00000006, 0x000002B5, 0x000002AD, -0x0006000C, 0x00000006, 0x000002B6, 0x00000001, 0x0000000D, 0x000002B5, 0x0003003E, 0x000002B4, -0x000002B6, 0x0004003D, 0x00000006, 0x000002B8, 0x000002AD, 0x0006000C, 0x00000006, 0x000002B9, -0x00000001, 0x0000000E, 0x000002B8, 0x0003003E, 0x000002B7, 0x000002B9, 0x0004003D, 0x00000006, -0x000002BA, 0x000002A4, 0x0004003D, 0x00000006, 0x000002BB, 0x000002B7, 0x00050085, 0x00000006, -0x000002BC, 0x000002BA, 0x000002BB, 0x0004003D, 0x00000006, 0x000002BD, 0x000002A4, 0x0004003D, -0x00000006, 0x000002BE, 0x000002B4, 0x00050085, 0x00000006, 0x000002BF, 0x000002BD, 0x000002BE, -0x00050050, 0x0000007F, 0x000002C0, 0x000002BC, 0x000002BF, 0x000200FE, 0x000002C0, 0x00010038, -0x00050036, 0x00000006, 0x00000091, 0x00000000, 0x0000008D, 0x00030037, 0x0000000D, 0x0000008E, -0x00030037, 0x0000000D, 0x0000008F, 0x00030037, 0x00000086, 0x00000090, 0x000200F8, 0x00000092, -0x0004003B, 0x00000007, 0x000002C3, 0x00000007, 0x0004003B, 0x00000007, 0x000002D1, 0x00000007, -0x00050041, 0x000001E1, 0x000002CF, 0x000002CD, 0x000002CE, 0x0004003D, 0x00000006, 0x000002D0, -0x000002CF, 0x0003003E, 0x000002C3, 0x000002D0, 0x0004003D, 0x00000006, 0x000002D2, 0x000002C3, -0x0004003D, 0x0000000C, 0x000002D3, 0x0000008F, 0x0004003D, 0x0000000C, 0x000002D4, 0x0000008E, -0x00050094, 0x00000006, 0x000002D5, 0x000002D3, 0x000002D4, 0x00050083, 0x00000006, 0x000002D6, -0x000000D5, 0x000002D5, 0x00050085, 0x00000006, 0x000002D7, 0x000002D2, 0x000002D6, 0x0004003D, -0x00000006, 0x000002D8, 0x000002C3, 0x0007000C, 0x00000006, 0x000002D9, 0x00000001, 0x00000028, -0x000002D7, 0x000002D8, 0x0003003E, 0x000002D1, 0x000002D9, 0x0004003D, 0x00000006, 0x000002DA, -0x000002D1, 0x000200FE, 0x000002DA, 0x00010038, 0x00050036, 0x00000006, 0x0000009E, 0x00000000, -0x00000096, 0x00030037, 0x00000095, 0x00000097, 0x00030037, 0x00000013, 0x00000098, 0x00030037, -0x00000007, 0x00000099, 0x00030037, 0x0000000D, 0x0000009A, 0x00030037, 0x0000000D, 0x0000009B, -0x00030037, 0x0000000D, 0x0000009C, 0x00030037, 0x00000086, 0x0000009D, 0x000200F8, 0x0000009F, -0x0004003B, 0x00000007, 0x000002DD, 0x00000007, 0x0004003B, 0x0000000D, 0x000002DE, 0x00000007, -0x0004003B, 0x0000000D, 0x000002E0, 0x00000007, 0x0004003B, 0x00000086, 0x000002E2, 0x00000007, -0x0004003B, 0x00000007, 0x000002E5, 0x00000007, 0x0004003B, 0x00000007, 0x000002E6, 0x00000007, -0x0004003B, 0x00000080, 0x000002E7, 0x00000007, 0x0004003B, 0x00000086, 0x000002EB, 0x00000007, -0x0004003B, 0x00000080, 0x000002F3, 0x00000007, 0x0004003B, 0x00000086, 0x000002F4, 0x00000007, -0x0004003B, 0x00000086, 0x000002F6, 0x00000007, 0x0004003B, 0x00000007, 0x000002F7, 0x00000007, -0x0004003B, 0x00000007, 0x000002FD, 0x00000007, 0x0004003D, 0x0000000C, 0x000002DF, 0x0000009A, -0x0003003E, 0x000002DE, 0x000002DF, 0x0004003D, 0x0000000C, 0x000002E1, 0x0000009B, 0x0003003E, -0x000002E0, 0x000002E1, 0x0004003D, 0x00000085, 0x000002E3, 0x0000009D, 0x0003003E, 0x000002E2, -0x000002E3, 0x00070039, 0x00000006, 0x000002E4, 0x00000091, 0x000002DE, 0x000002E0, 0x000002E2, -0x0003003E, 0x000002DD, 0x000002E4, 0x0003003E, 0x000002E5, 0x000000F8, 0x0004003D, 0x0000000C, -0x000002E8, 0x0000009C, 0x0007004F, 0x0000007F, 0x000002E9, 0x000002E8, 0x000002E8, 0x00000000, -0x00000001, 0x0003003E, 0x000002E7, 0x000002E9, 0x00050039, 0x00000006, 0x000002EA, 0x00000083, -0x000002E7, 0x0003003E, 0x000002E6, 0x000002EA, 0x0003003E, 0x000002EB, 0x000001E9, 0x000200F9, -0x000002EC, 0x000200F8, 0x000002EC, 0x000400F6, 0x000002EE, 0x000002EF, 0x00000000, 0x000200F9, -0x000002F0, 0x000200F8, 0x000002F0, 0x0004003D, 0x00000085, 0x000002F1, 0x000002EB, 0x000500B1, -0x000001E5, 0x000002F2, 0x000002F1, 0x00000278, 0x000400FA, 0x000002F2, 0x000002ED, 0x000002EE, -0x000200F8, 0x000002ED, 0x0004003D, 0x00000085, 0x000002F5, 0x000002EB, 0x0003003E, 0x000002F4, -0x000002F5, 0x0003003E, 0x000002F6, 0x00000278, 0x0004003D, 0x00000006, 0x000002F8, 0x000002E6, -0x0003003E, 0x000002F7, 0x000002F8, 0x00070039, 0x0000007F, 0x000002F9, 0x0000008B, 0x000002F4, -0x000002F6, 0x000002F7, 0x00050050, 0x0000007F, 0x000002FB, 0x000002FA, 0x000002FA, 0x00050088, -0x0000007F, 0x000002FC, 0x000002F9, 0x000002FB, 0x0003003E, 0x000002F3, 0x000002FC, 0x0004003D, -0x00000094, 0x000002FE, 0x00000097, 0x0004003D, 0x00000012, 0x000002FF, 0x00000098, 0x0007004F, -0x0000007F, 0x00000300, 0x000002FF, 0x000002FF, 0x00000000, 0x00000001, 0x0004003D, 0x0000007F, -0x00000301, 0x000002F3, 0x00050081, 0x0000007F, 0x00000302, 0x00000300, 0x00000301, 0x0004003D, -0x00000085, 0x00000303, 0x0000009D, 0x0004006F, 0x00000006, 0x00000304, 0x00000303, 0x00050051, -0x00000006, 0x00000305, 0x00000302, 0x00000000, 0x00050051, 0x00000006, 0x00000306, 0x00000302, -0x00000001, 0x00060050, 0x0000000C, 0x00000307, 0x00000305, 0x00000306, 0x00000304, 0x00050057, -0x00000012, 0x00000308, 0x000002FE, 0x00000307, 0x00050051, 0x00000006, 0x00000309, 0x00000308, -0x00000000, 0x0003003E, 0x000002FD, 0x00000309, 0x00050041, 0x00000007, 0x0000030B, 0x00000098, -0x0000030A, 0x0004003D, 0x00000006, 0x0000030C, 0x0000030B, 0x0004003D, 0x00000006, 0x0000030D, -0x000002DD, 0x00050083, 0x00000006, 0x0000030E, 0x0000030C, 0x0000030D, 0x0004003D, 0x00000006, -0x0000030F, 0x000002FD, 0x0007000C, 0x00000006, 0x00000310, 0x00000001, 0x00000030, 0x0000030E, -0x0000030F, 0x0004003D, 0x00000006, 0x00000311, 0x000002E5, 0x00050081, 0x00000006, 0x00000312, -0x00000311, 0x00000310, 0x0003003E, 0x000002E5, 0x00000312, 0x000200F9, 0x000002EF, 0x000200F8, -0x000002EF, 0x0004003D, 0x00000085, 0x00000313, 0x000002EB, 0x00050080, 0x00000085, 0x00000314, -0x00000313, 0x000001FF, 0x0003003E, 0x000002EB, 0x00000314, 0x000200F9, 0x000002EC, 0x000200F8, -0x000002EE, 0x0004003D, 0x00000006, 0x00000315, 0x000002E5, 0x00050088, 0x00000006, 0x00000317, -0x00000315, 0x00000316, 0x000200FE, 0x00000317, 0x00010038, 0x00050036, 0x00000085, 0x000000A2, -0x00000000, 0x000000A0, 0x00030037, 0x0000000D, 0x000000A1, 0x000200F8, 0x000000A3, 0x0004003B, -0x00000086, 0x0000031A, 0x00000007, 0x0004003B, 0x00000013, 0x0000031B, 0x00000007, 0x0004003B, -0x00000086, 0x00000325, 0x00000007, 0x0003003E, 0x0000031A, 0x000001E9, 0x00050041, 0x0000031C, -0x0000031D, 0x000002CD, 0x00000210, 0x0004003D, 0x000002C7, 0x0000031E, 0x0000031D, 0x0004003D, -0x0000000C, 0x0000031F, 0x000000A1, 0x00050051, 0x00000006, 0x00000320, 0x0000031F, 0x00000000, -0x00050051, 0x00000006, 0x00000321, 0x0000031F, 0x00000001, 0x00050051, 0x00000006, 0x00000322, -0x0000031F, 0x00000002, 0x00070050, 0x00000012, 0x00000323, 0x00000320, 0x00000321, 0x00000322, -0x000000D5, 0x00050091, 0x00000012, 0x00000324, 0x0000031E, 0x00000323, 0x0003003E, 0x0000031B, -0x00000324, 0x0003003E, 0x00000325, 0x000001E9, 0x000200F9, 0x00000326, 0x000200F8, 0x00000326, -0x000400F6, 0x00000328, 0x00000329, 0x00000000, 0x000200F9, 0x0000032A, 0x000200F8, 0x0000032A, -0x0004003D, 0x00000085, 0x0000032B, 0x00000325, 0x00050041, 0x0000032D, 0x0000032E, 0x000002CD, -0x0000032C, 0x0004003D, 0x00000085, 0x0000032F, 0x0000032E, 0x00050082, 0x00000085, 0x00000330, -0x0000032F, 0x000001FF, 0x000500B1, 0x000001E5, 0x00000331, 0x0000032B, 0x00000330, 0x000400FA, -0x00000331, 0x00000327, 0x00000328, 0x000200F8, 0x00000327, 0x00050041, 0x00000007, 0x00000332, -0x0000031B, 0x0000030A, 0x0004003D, 0x00000006, 0x00000333, 0x00000332, 0x0004003D, 0x00000085, -0x00000334, 0x00000325, 0x00070041, 0x000001E1, 0x00000335, 0x000002CD, 0x0000020A, 0x00000334, -0x0000023E, 0x0004003D, 0x00000006, 0x00000336, 0x00000335, 0x000500B8, 0x000001E5, 0x00000337, -0x00000333, 0x00000336, 0x000300F7, 0x00000339, 0x00000000, 0x000400FA, 0x00000337, 0x00000338, -0x00000339, 0x000200F8, 0x00000338, 0x0004003D, 0x00000085, 0x0000033A, 0x00000325, 0x00050080, -0x00000085, 0x0000033B, 0x0000033A, 0x000001FF, 0x0003003E, 0x0000031A, 0x0000033B, 0x000200F9, -0x00000339, 0x000200F8, 0x00000339, 0x000200F9, 0x00000329, 0x000200F8, 0x00000329, 0x0004003D, -0x00000085, 0x0000033C, 0x00000325, 0x00050080, 0x00000085, 0x0000033D, 0x0000033C, 0x000001FF, -0x0003003E, 0x00000325, 0x0000033D, 0x000200F9, 0x00000326, 0x000200F8, 0x00000328, 0x0004003D, -0x00000085, 0x0000033E, 0x0000031A, 0x000200FE, 0x0000033E, 0x00010038, 0x00050036, 0x00000006, -0x000000A9, 0x00000000, 0x000000A4, 0x00030037, 0x0000000D, 0x000000A5, 0x00030037, 0x00000086, -0x000000A6, 0x00030037, 0x0000000D, 0x000000A7, 0x00030037, 0x0000000D, 0x000000A8, 0x000200F8, -0x000000AA, 0x0004003B, 0x00000013, 0x00000341, 0x00000007, 0x0004003B, 0x00000007, 0x00000353, -0x00000007, 0x0004003B, 0x00000007, 0x00000355, 0x00000007, 0x0004003B, 0x00000013, 0x00000360, -0x00000007, 0x0004003B, 0x00000007, 0x00000369, 0x00000007, 0x0004003B, 0x00000013, 0x0000036B, -0x00000007, 0x0004003B, 0x00000007, 0x0000036D, 0x00000007, 0x0004003B, 0x0000000D, 0x0000036F, -0x00000007, 0x0004003B, 0x0000000D, 0x00000371, 0x00000007, 0x0004003B, 0x0000000D, 0x00000373, -0x00000007, 0x0004003B, 0x00000086, 0x00000375, 0x00000007, 0x0004003B, 0x00000007, 0x00000378, -0x00000007, 0x0004003B, 0x00000086, 0x00000385, 0x00000007, 0x0004003B, 0x00000007, 0x0000039F, -0x00000007, 0x0004003B, 0x00000013, 0x000003A0, 0x00000007, 0x0004003B, 0x00000007, 0x000003A2, -0x00000007, 0x0004003B, 0x0000000D, 0x000003A4, 0x00000007, 0x0004003B, 0x0000000D, 0x000003A6, -0x00000007, 0x0004003B, 0x0000000D, 0x000003A8, 0x00000007, 0x0004003B, 0x00000086, 0x000003AA, -0x00000007, 0x00050041, 0x0000031C, 0x00000342, 0x000002CD, 0x00000260, 0x0004003D, 0x000002C7, -0x00000343, 0x00000342, 0x0004003D, 0x00000085, 0x00000344, 0x000000A6, 0x00060041, 0x0000031C, -0x00000345, 0x000002CD, 0x000001FF, 0x00000344, 0x0004003D, 0x000002C7, 0x00000346, 0x00000345, -0x00050092, 0x000002C7, 0x00000347, 0x00000343, 0x00000346, 0x0004003D, 0x0000000C, 0x00000348, -0x000000A5, 0x00050051, 0x00000006, 0x00000349, 0x00000348, 0x00000000, 0x00050051, 0x00000006, -0x0000034A, 0x00000348, 0x00000001, 0x00050051, 0x00000006, 0x0000034B, 0x00000348, 0x00000002, -0x00070050, 0x00000012, 0x0000034C, 0x00000349, 0x0000034A, 0x0000034B, 0x000000D5, 0x00050091, -0x00000012, 0x0000034D, 0x00000347, 0x0000034C, 0x0003003E, 0x00000341, 0x0000034D, 0x0004003D, -0x00000012, 0x0000034E, 0x00000341, 0x00050041, 0x00000007, 0x0000034F, 0x00000341, 0x000000EE, -0x0004003D, 0x00000006, 0x00000350, 0x0000034F, 0x00050088, 0x00000006, 0x00000351, 0x000000D5, -0x00000350, 0x0005008E, 0x00000012, 0x00000352, 0x0000034E, 0x00000351, 0x0003003E, 0x00000341, -0x00000352, 0x0003003E, 0x00000353, 0x00000354, 0x00050041, 0x000001E1, 0x00000356, 0x000002CD, -0x00000228, 0x0004003D, 0x00000006, 0x00000357, 0x00000356, 0x0004003D, 0x00000006, 0x00000358, -0x00000353, 0x00050085, 0x00000006, 0x00000359, 0x00000357, 0x00000358, 0x00050041, 0x00000007, -0x0000035A, 0x00000341, 0x0000030A, 0x0004003D, 0x00000006, 0x0000035B, 0x0000035A, 0x00050088, -0x00000006, 0x0000035C, 0x00000359, 0x0000035B, 0x0003003E, 0x00000355, 0x0000035C, 0x0004003D, -0x00000006, 0x0000035D, 0x00000355, 0x0007000C, 0x00000006, 0x0000035F, 0x00000001, 0x00000025, -0x0000035D, 0x0000035E, 0x0003003E, 0x00000355, 0x0000035F, 0x00050041, 0x0000031C, 0x00000361, -0x000002CD, 0x00000210, 0x0004003D, 0x000002C7, 0x00000362, 0x00000361, 0x0004003D, 0x0000000C, -0x00000363, 0x000000A5, 0x00050051, 0x00000006, 0x00000364, 0x00000363, 0x00000000, 0x00050051, -0x00000006, 0x00000365, 0x00000363, 0x00000001, 0x00050051, 0x00000006, 0x00000366, 0x00000363, -0x00000002, 0x00070050, 0x00000012, 0x00000367, 0x00000364, 0x00000365, 0x00000366, 0x000000D5, -0x00050091, 0x00000012, 0x00000368, 0x00000362, 0x00000367, 0x0003003E, 0x00000360, 0x00000368, -0x0003003E, 0x00000369, 0x000000D5, 0x0004003D, 0x00000012, 0x0000036C, 0x00000341, 0x0003003E, -0x0000036B, 0x0000036C, 0x0004003D, 0x00000006, 0x0000036E, 0x00000355, 0x0003003E, 0x0000036D, -0x0000036E, 0x0004003D, 0x0000000C, 0x00000370, 0x000000A7, 0x0003003E, 0x0000036F, 0x00000370, -0x0004003D, 0x0000000C, 0x00000372, 0x000000A8, 0x0003003E, 0x00000371, 0x00000372, 0x0004003D, -0x0000000C, 0x00000374, 0x000000A5, 0x0003003E, 0x00000373, 0x00000374, 0x0004003D, 0x00000085, -0x00000376, 0x000000A6, 0x0003003E, 0x00000375, 0x00000376, 0x000B0039, 0x00000006, 0x00000377, -0x0000009E, 0x0000036A, 0x0000036B, 0x0000036D, 0x0000036F, 0x00000371, 0x00000373, 0x00000375, -0x0003003E, 0x00000369, 0x00000377, 0x0004003D, 0x00000085, 0x00000379, 0x000000A6, 0x00070041, -0x000001E1, 0x0000037A, 0x000002CD, 0x0000020A, 0x00000379, 0x0000023E, 0x0004003D, 0x00000006, -0x0000037B, 0x0000037A, 0x00050041, 0x000001E1, 0x0000037C, 0x000002CD, 0x00000244, 0x0004003D, -0x00000006, 0x0000037D, 0x0000037C, 0x00050081, 0x00000006, 0x0000037E, 0x0000037B, 0x0000037D, -0x0004003D, 0x00000085, 0x0000037F, 0x000000A6, 0x00070041, 0x000001E1, 0x00000380, 0x000002CD, -0x0000020A, 0x0000037F, 0x0000023E, 0x0004003D, 0x00000006, 0x00000381, 0x00000380, 0x00050041, -0x00000007, 0x00000382, 0x00000360, 0x0000030A, 0x0004003D, 0x00000006, 0x00000383, 0x00000382, -0x0008000C, 0x00000006, 0x00000384, 0x00000001, 0x00000031, 0x0000037E, 0x00000381, 0x00000383, -0x0003003E, 0x00000378, 0x00000384, 0x0004003D, 0x00000085, 0x00000386, 0x000000A6, 0x00050080, -0x00000085, 0x00000387, 0x00000386, 0x000001FF, 0x0003003E, 0x00000385, 0x00000387, 0x0004003D, -0x00000006, 0x00000388, 0x00000378, 0x000500BA, 0x000001E5, 0x00000389, 0x00000388, 0x000000F8, -0x000300F7, 0x0000038B, 0x00000000, 0x000400FA, 0x00000389, 0x0000038A, 0x0000038B, 0x000200F8, -0x0000038A, 0x0004003D, 0x00000085, 0x0000038C, 0x00000385, 0x00050041, 0x0000032D, 0x0000038D, -0x000002CD, 0x0000032C, 0x0004003D, 0x00000085, 0x0000038E, 0x0000038D, 0x000500B1, 0x000001E5, -0x0000038F, 0x0000038C, 0x0000038E, 0x000200F9, 0x0000038B, 0x000200F8, 0x0000038B, 0x000700F5, -0x000001E5, 0x00000390, 0x00000389, 0x000000AA, 0x0000038F, 0x0000038A, 0x000300F7, 0x00000392, -0x00000000, 0x000400FA, 0x00000390, 0x00000391, 0x00000392, 0x000200F8, 0x00000391, 0x00050041, -0x0000031C, 0x00000393, 0x000002CD, 0x00000260, 0x0004003D, 0x000002C7, 0x00000394, 0x00000393, -0x0004003D, 0x00000085, 0x00000395, 0x00000385, 0x00060041, 0x0000031C, 0x00000396, 0x000002CD, -0x000001FF, 0x00000395, 0x0004003D, 0x000002C7, 0x00000397, 0x00000396, 0x00050092, 0x000002C7, -0x00000398, 0x00000394, 0x00000397, 0x0004003D, 0x0000000C, 0x00000399, 0x000000A5, 0x00050051, -0x00000006, 0x0000039A, 0x00000399, 0x00000000, 0x00050051, 0x00000006, 0x0000039B, 0x00000399, -0x00000001, 0x00050051, 0x00000006, 0x0000039C, 0x00000399, 0x00000002, 0x00070050, 0x00000012, -0x0000039D, 0x0000039A, 0x0000039B, 0x0000039C, 0x000000D5, 0x00050091, 0x00000012, 0x0000039E, -0x00000398, 0x0000039D, 0x0003003E, 0x00000341, 0x0000039E, 0x0004003D, 0x00000012, 0x000003A1, -0x00000341, 0x0003003E, 0x000003A0, 0x000003A1, 0x0004003D, 0x00000006, 0x000003A3, 0x00000355, -0x0003003E, 0x000003A2, 0x000003A3, 0x0004003D, 0x0000000C, 0x000003A5, 0x000000A7, 0x0003003E, -0x000003A4, 0x000003A5, 0x0004003D, 0x0000000C, 0x000003A7, 0x000000A8, 0x0003003E, 0x000003A6, -0x000003A7, 0x0004003D, 0x0000000C, 0x000003A9, 0x000000A5, 0x0003003E, 0x000003A8, 0x000003A9, -0x0004003D, 0x00000085, 0x000003AB, 0x00000385, 0x0003003E, 0x000003AA, 0x000003AB, 0x000B0039, -0x00000006, 0x000003AC, 0x0000009E, 0x0000036A, 0x000003A0, 0x000003A2, 0x000003A4, 0x000003A6, -0x000003A8, 0x000003AA, 0x0003003E, 0x0000039F, 0x000003AC, 0x0004003D, 0x00000006, 0x000003AD, -0x00000369, 0x0004003D, 0x00000006, 0x000003AE, 0x0000039F, 0x0004003D, 0x00000006, 0x000003AF, -0x00000378, 0x0008000C, 0x00000006, 0x000003B0, 0x00000001, 0x0000002E, 0x000003AD, 0x000003AE, -0x000003AF, 0x0003003E, 0x00000369, 0x000003B0, 0x000200F9, 0x00000392, 0x000200F8, 0x00000392, -0x0004003D, 0x00000006, 0x000003B1, 0x00000369, 0x00050083, 0x00000006, 0x000003B2, 0x000000D5, -0x000003B1, 0x0004003D, 0x00000006, 0x000003B3, 0x000000D4, 0x00050085, 0x00000006, 0x000003B4, -0x000003B2, 0x000003B3, 0x00050083, 0x00000006, 0x000003B5, 0x000000D5, 0x000003B4, 0x000200FE, -0x000003B5, 0x00010038, 0x00050036, 0x0000000C, 0x000000B5, 0x00000000, 0x000000AD, 0x00030037, -0x000000AB, 0x000000AE, 0x00030037, 0x000000AC, 0x000000AF, 0x00030037, 0x0000000C, 0x000000B0, -0x00030037, 0x00000007, 0x000000B1, 0x00030037, 0x00000007, 0x000000B2, 0x00030037, 0x00000007, -0x000000B3, 0x00030037, 0x00000007, 0x000000B4, 0x000200F8, 0x000000B6, 0x0004003B, 0x00000007, -0x000003B8, 0x00000007, 0x0004003B, 0x00000007, 0x000003BA, 0x00000007, 0x0004003B, 0x00000007, -0x000003BC, 0x00000007, 0x0004003B, 0x00000007, 0x000003BF, 0x00000007, 0x0004003B, 0x00000007, -0x000003C0, 0x00000007, 0x0004003B, 0x00000007, 0x000003C2, 0x00000007, 0x0004003B, 0x00000007, -0x000003C4, 0x00000007, 0x0004003B, 0x0000000D, 0x000003C7, 0x00000007, 0x0004003B, 0x00000007, -0x000003C9, 0x00000007, 0x00050051, 0x0000000C, 0x000003B9, 0x000000AE, 0x00000006, 0x00050051, -0x00000006, 0x000003BB, 0x000000AE, 0x00000002, 0x0003003E, 0x000003BA, 0x000003BB, 0x0004003D, -0x00000006, 0x000003BD, 0x000000B3, 0x0003003E, 0x000003BC, 0x000003BD, 0x00080039, 0x00000006, -0x000003BE, 0x0000005D, 0x000003BA, 0x000003BC, 0x000003B9, 0x000000B0, 0x0003003E, 0x000003B8, -0x000003BE, 0x00050051, 0x00000006, 0x000003C1, 0x000000AE, 0x00000002, 0x0003003E, 0x000003C0, -0x000003C1, 0x0004003D, 0x00000006, 0x000003C3, 0x000000B1, 0x0003003E, 0x000003C2, 0x000003C3, -0x0004003D, 0x00000006, 0x000003C5, 0x000000B2, 0x0003003E, 0x000003C4, 0x000003C5, 0x00070039, -0x00000006, 0x000003C6, 0x00000062, 0x000003C0, 0x000003C2, 0x000003C4, 0x0003003E, 0x000003BF, -0x000003C6, 0x00050051, 0x0000000C, 0x000003C8, 0x000000AE, 0x0000000A, 0x0004003D, 0x00000006, -0x000003CA, 0x000000B4, 0x0003003E, 0x000003C9, 0x000003CA, 0x00060039, 0x0000000C, 0x000003CB, -0x00000067, 0x000003C8, 0x000003C9, 0x0003003E, 0x000003C7, 0x000003CB, 0x0004003D, 0x00000006, -0x000003CC, 0x000003B8, 0x0004003D, 0x00000006, 0x000003CD, 0x000003BF, 0x00050085, 0x00000006, -0x000003CE, 0x000003CC, 0x000003CD, 0x0004003D, 0x0000000C, 0x000003CF, 0x000003C7, 0x0005008E, -0x0000000C, 0x000003D0, 0x000003CF, 0x000003CE, 0x000200FE, 0x000003D0, 0x00010038, 0x00050036, -0x0000000C, 0x000000BC, 0x00000000, 0x000000B7, 0x00030037, 0x000000AB, 0x000000B8, 0x00030037, -0x00000007, 0x000000B9, 0x00030037, 0x00000007, 0x000000BA, 0x00030037, 0x00000007, 0x000000BB, -0x000200F8, 0x000000BD, 0x0004003B, 0x00000007, 0x000003D5, 0x00000007, 0x0004003B, 0x00000007, -0x000003D7, 0x00000007, 0x0004003B, 0x00000007, 0x000003D9, 0x00000007, 0x0004003B, 0x00000007, -0x000003DB, 0x00000007, 0x00050051, 0x00000012, 0x000003D3, 0x000000B8, 0x00000000, 0x0008004F, -0x0000000C, 0x000003D4, 0x000003D3, 0x000003D3, 0x00000000, 0x00000001, 0x00000002, 0x00050051, -0x00000006, 0x000003D6, 0x000000B8, 0x00000002, 0x0003003E, 0x000003D5, 0x000003D6, 0x0004003D, -0x00000006, 0x000003D8, 0x000000B9, 0x0003003E, 0x000003D7, 0x000003D8, 0x0004003D, 0x00000006, -0x000003DA, 0x000000BA, 0x0003003E, 0x000003D9, 0x000003DA, 0x0004003D, 0x00000006, 0x000003DC, -0x000000BB, 0x0003003E, 0x000003DB, 0x000003DC, 0x00080039, 0x00000006, 0x000003DD, 0x00000043, -0x000003D5, 0x000003D7, 0x000003D9, 0x000003DB, 0x0005008E, 0x0000000C, 0x000003DE, 0x000003D4, -0x000003DD, 0x000200FE, 0x000003DE, 0x00010038, 0x00050036, 0x0000000C, 0x000000C5, 0x00000000, -0x000000AD, 0x00030037, 0x000000AB, 0x000000BE, 0x00030037, 0x000000AC, 0x000000BF, 0x00030037, -0x0000000C, 0x000000C0, 0x00030037, 0x00000007, 0x000000C1, 0x00030037, 0x00000007, 0x000000C2, -0x00030037, 0x00000007, 0x000000C3, 0x00030037, 0x00000007, 0x000000C4, 0x000200F8, 0x000000C6, -0x0004003B, 0x00000007, 0x000003E1, 0x00000007, 0x0004003B, 0x00000007, 0x000003E3, 0x00000007, -0x0004003B, 0x00000007, 0x000003E5, 0x00000007, 0x0004003B, 0x00000007, 0x000003E7, 0x00000007, -0x0004003D, 0x00000006, 0x000003E2, 0x000000C1, 0x0003003E, 0x000003E1, 0x000003E2, 0x0004003D, -0x00000006, 0x000003E4, 0x000000C2, 0x0003003E, 0x000003E3, 0x000003E4, 0x0004003D, 0x00000006, -0x000003E6, 0x000000C3, 0x0003003E, 0x000003E5, 0x000003E6, 0x0004003D, 0x00000006, 0x000003E8, -0x000000C4, 0x0003003E, 0x000003E7, 0x000003E8, 0x000B0039, 0x0000000C, 0x000003E9, 0x000000B5, -0x000000BE, 0x000000BF, 0x000000C0, 0x000003E1, 0x000003E3, 0x000003E5, 0x000003E7, 0x000200FE, -0x000003E9, 0x00010038, 0x00050036, 0x0000000C, 0x000000CC, 0x00000000, 0x000000C8, 0x00030037, -0x0000000D, 0x000000C9, 0x00030037, 0x0000000D, 0x000000CA, 0x00030037, 0x000000C7, 0x000000CB, -0x000200F8, 0x000000CD, 0x0004003B, 0x0000000D, 0x000003EC, 0x00000007, 0x0004003B, 0x00000086, -0x000003EE, 0x00000007, 0x0004003B, 0x000003F9, 0x000003FA, 0x00000007, 0x0004003B, 0x00000007, -0x0000040D, 0x00000007, 0x0004003B, 0x0000000D, 0x00000413, 0x00000007, 0x0004003B, 0x00000007, -0x00000419, 0x00000007, 0x0004003B, 0x00000007, 0x0000041E, 0x00000007, 0x0004003B, 0x00000007, -0x00000425, 0x00000007, 0x0004003B, 0x0000000D, 0x0000043E, 0x00000007, 0x0004003B, 0x00000007, -0x00000444, 0x00000007, 0x0004003B, 0x00000007, 0x00000448, 0x00000007, 0x0004003B, 0x00000007, -0x0000044D, 0x00000007, 0x0004003B, 0x00000007, 0x00000453, 0x00000007, 0x0004003B, 0x00000007, -0x00000459, 0x00000007, 0x0004003B, 0x00000086, 0x0000046A, 0x00000007, 0x0004003B, 0x0000000D, -0x0000046B, 0x00000007, 0x0004003B, 0x0000000D, 0x00000474, 0x00000007, 0x0004003B, 0x00000086, -0x00000476, 0x00000007, 0x0004003B, 0x0000000D, 0x00000478, 0x00000007, 0x0004003B, 0x0000000D, -0x0000047C, 0x00000007, 0x0004003B, 0x0000000D, 0x00000481, 0x00000007, 0x0004003B, 0x0000000D, -0x00000485, 0x00000007, 0x0004003B, 0x0000000D, 0x0000048C, 0x00000007, 0x0004003B, 0x00000007, -0x00000492, 0x00000007, 0x0004003B, 0x00000007, 0x00000497, 0x00000007, 0x0004003B, 0x0000000D, -0x00000499, 0x00000007, 0x0004003B, 0x00000007, 0x0000049F, 0x00000007, 0x0004003B, 0x00000007, -0x000004A5, 0x00000007, 0x0004003B, 0x00000007, 0x000004A7, 0x00000007, 0x0004003B, 0x00000007, -0x000004A9, 0x00000007, 0x0004003B, 0x00000007, 0x000004AA, 0x00000007, 0x0004003B, 0x00000007, -0x000004AD, 0x00000007, 0x0004003B, 0x00000007, 0x000004B2, 0x00000007, 0x0004003B, 0x00000007, -0x000004B4, 0x00000007, 0x0004003B, 0x00000007, 0x000004B8, 0x00000007, 0x0004003B, 0x0000000D, -0x000004BA, 0x00000007, 0x0004003B, 0x00000007, 0x000004BC, 0x00000007, 0x0004003B, 0x00000007, -0x000004BE, 0x00000007, 0x0004003B, 0x00000007, 0x000004C0, 0x00000007, 0x0004003B, 0x0000000D, -0x000004C3, 0x00000007, 0x0004003B, 0x00000007, 0x000004C7, 0x00000007, 0x0004003B, 0x00000007, -0x000004C9, 0x00000007, 0x0004003B, 0x00000007, 0x000004CB, 0x00000007, 0x0004003B, 0x00000007, -0x000004CD, 0x00000007, 0x0004003B, 0x0000000D, 0x000004D0, 0x00000007, 0x0004003B, 0x00000007, -0x000004DA, 0x00000007, 0x0004003B, 0x00000007, 0x000004DC, 0x00000007, 0x0003003E, 0x000003EC, -0x000003ED, 0x0003003E, 0x000003EE, 0x000001E9, 0x000200F9, 0x000003EF, 0x000200F8, 0x000003EF, -0x000400F6, 0x000003F1, 0x000003F2, 0x00000000, 0x000200F9, 0x000003F3, 0x000200F8, 0x000003F3, -0x0004003D, 0x00000085, 0x000003F4, 0x000003EE, 0x00050041, 0x0000032D, 0x000003F6, 0x000002CD, -0x000003F5, 0x0004003D, 0x00000085, 0x000003F7, 0x000003F6, 0x000500B1, 0x000001E5, 0x000003F8, -0x000003F4, 0x000003F7, 0x000400FA, 0x000003F8, 0x000003F0, 0x000003F1, 0x000200F8, 0x000003F0, -0x0004003D, 0x00000085, 0x000003FB, 0x000003EE, 0x00060041, 0x000003FC, 0x000003FD, 0x000002CD, -0x000001E9, 0x000003FB, 0x0004003D, 0x000002C4, 0x000003FE, 0x000003FD, 0x00050051, 0x00000012, -0x000003FF, 0x000003FE, 0x00000000, 0x00050041, 0x00000013, 0x00000400, 0x000003FA, 0x000001E9, -0x0003003E, 0x00000400, 0x000003FF, 0x00050051, 0x00000012, 0x00000401, 0x000003FE, 0x00000001, -0x00050041, 0x00000013, 0x00000402, 0x000003FA, 0x000001FF, 0x0003003E, 0x00000402, 0x00000401, -0x00050051, 0x00000012, 0x00000403, 0x000003FE, 0x00000002, 0x00050041, 0x00000013, 0x00000404, -0x000003FA, 0x00000210, 0x0003003E, 0x00000404, 0x00000403, 0x00050051, 0x00000006, 0x00000405, -0x000003FE, 0x00000003, 0x00050041, 0x00000007, 0x00000406, 0x000003FA, 0x0000027E, 0x0003003E, -0x00000406, 0x00000405, 0x00050051, 0x00000006, 0x00000407, 0x000003FE, 0x00000004, 0x00050041, -0x00000007, 0x00000408, 0x000003FA, 0x00000260, 0x0003003E, 0x00000408, 0x00000407, 0x00050051, -0x00000006, 0x00000409, 0x000003FE, 0x00000005, 0x00050041, 0x00000007, 0x0000040A, 0x000003FA, -0x000001E0, 0x0003003E, 0x0000040A, 0x00000409, 0x00050051, 0x00000006, 0x0000040B, 0x000003FE, -0x00000006, 0x00050041, 0x00000007, 0x0000040C, 0x000003FA, 0x0000020A, 0x0003003E, 0x0000040C, -0x0000040B, 0x0003003E, 0x0000040D, 0x000000F8, 0x00050041, 0x00000007, 0x0000040E, 0x000003FA, -0x000001E0, 0x0004003D, 0x00000006, 0x0000040F, 0x0000040E, 0x000500B4, 0x000001E5, 0x00000410, -0x0000040F, 0x00000130, 0x000300F7, 0x00000412, 0x00000000, 0x000400FA, 0x00000410, 0x00000411, -0x00000438, 0x000200F8, 0x00000411, 0x00050041, 0x00000013, 0x00000414, 0x000003FA, 0x000001FF, -0x0004003D, 0x00000012, 0x00000415, 0x00000414, 0x0008004F, 0x0000000C, 0x00000416, 0x00000415, -0x00000415, 0x00000000, 0x00000001, 0x00000002, 0x0004003D, 0x0000000C, 0x00000417, 0x000000CA, -0x00050083, 0x0000000C, 0x00000418, 0x00000416, 0x00000417, 0x0003003E, 0x00000413, 0x00000418, -0x0004003D, 0x0000000C, 0x0000041A, 0x00000413, 0x0006000C, 0x00000006, 0x0000041B, 0x00000001, -0x00000042, 0x0000041A, 0x0003003E, 0x00000419, 0x0000041B, 0x0004003D, 0x0000000C, 0x0000041C, -0x00000413, 0x0006000C, 0x0000000C, 0x0000041D, 0x00000001, 0x00000045, 0x0000041C, 0x0003003E, -0x00000413, 0x0000041D, 0x00050041, 0x00000007, 0x0000041F, 0x000003FA, 0x00000260, 0x0004003D, -0x00000006, 0x00000420, 0x0000041F, 0x0004003D, 0x00000006, 0x00000421, 0x00000419, 0x0007000C, -0x00000006, 0x00000422, 0x00000001, 0x0000001A, 0x00000421, 0x00000130, 0x00050081, 0x00000006, -0x00000423, 0x00000422, 0x000000D5, 0x00050088, 0x00000006, 0x00000424, 0x00000420, 0x00000423, -0x0003003E, 0x0000041E, 0x00000424, 0x0004003D, 0x00000006, 0x00000426, 0x00000419, 0x0004003D, -0x00000006, 0x00000427, 0x00000419, 0x00050085, 0x00000006, 0x00000428, 0x00000426, 0x00000427, -0x00050041, 0x00000007, 0x00000429, 0x000003FA, 0x00000260, 0x0004003D, 0x00000006, 0x0000042A, -0x00000429, 0x00050041, 0x00000007, 0x0000042B, 0x000003FA, 0x00000260, 0x0004003D, 0x00000006, -0x0000042C, 0x0000042B, 0x00050085, 0x00000006, 0x0000042D, 0x0000042A, 0x0000042C, 0x00050088, -0x00000006, 0x0000042E, 0x00000428, 0x0000042D, 0x00050083, 0x00000006, 0x0000042F, 0x000000D5, -0x0000042E, 0x0008000C, 0x00000006, 0x00000430, 0x00000001, 0x0000002B, 0x0000042F, 0x000000F8, -0x000000D5, 0x0003003E, 0x00000425, 0x00000430, 0x0004003D, 0x00000006, 0x00000431, 0x00000425, -0x0003003E, 0x0000040D, 0x00000431, 0x0004003D, 0x0000000C, 0x00000432, 0x00000413, 0x00050051, -0x00000006, 0x00000433, 0x00000432, 0x00000000, 0x00050051, 0x00000006, 0x00000434, 0x00000432, -0x00000001, 0x00050051, 0x00000006, 0x00000435, 0x00000432, 0x00000002, 0x00070050, 0x00000012, -0x00000436, 0x00000433, 0x00000434, 0x00000435, 0x000000D5, 0x00050041, 0x00000013, 0x00000437, -0x000003FA, 0x00000210, 0x0003003E, 0x00000437, 0x00000436, 0x000200F9, 0x00000412, 0x000200F8, -0x00000438, 0x00050041, 0x00000007, 0x00000439, 0x000003FA, 0x000001E0, 0x0004003D, 0x00000006, -0x0000043A, 0x00000439, 0x000500B4, 0x000001E5, 0x0000043B, 0x0000043A, 0x000000D5, 0x000300F7, -0x0000043D, 0x00000000, 0x000400FA, 0x0000043B, 0x0000043C, 0x00000469, 0x000200F8, 0x0000043C, -0x00050041, 0x00000013, 0x0000043F, 0x000003FA, 0x000001FF, 0x0004003D, 0x00000012, 0x00000440, -0x0000043F, 0x0008004F, 0x0000000C, 0x00000441, 0x00000440, 0x00000440, 0x00000000, 0x00000001, -0x00000002, 0x0004003D, 0x0000000C, 0x00000442, 0x000000CA, 0x00050083, 0x0000000C, 0x00000443, -0x00000441, 0x00000442, 0x0003003E, 0x0000043E, 0x00000443, 0x00050041, 0x00000007, 0x00000445, -0x000003FA, 0x0000020A, 0x0004003D, 0x00000006, 0x00000446, 0x00000445, 0x00050083, 0x00000006, -0x00000447, 0x000000D5, 0x00000446, 0x0003003E, 0x00000444, 0x00000447, 0x0004003D, 0x0000000C, -0x00000449, 0x0000043E, 0x0006000C, 0x00000006, 0x0000044A, 0x00000001, 0x00000042, 0x00000449, -0x0003003E, 0x00000448, 0x0000044A, 0x0004003D, 0x0000000C, 0x0000044B, 0x0000043E, 0x0006000C, -0x0000000C, 0x0000044C, 0x00000001, 0x00000045, 0x0000044B, 0x0003003E, 0x0000043E, 0x0000044C, -0x0004003D, 0x0000000C, 0x0000044E, 0x0000043E, 0x00050041, 0x00000013, 0x0000044F, 0x000003FA, -0x00000210, 0x0004003D, 0x00000012, 0x00000450, 0x0000044F, 0x0008004F, 0x0000000C, 0x00000451, -0x00000450, 0x00000450, 0x00000000, 0x00000001, 0x00000002, 0x00050094, 0x00000006, 0x00000452, -0x0000044E, 0x00000451, 0x0003003E, 0x0000044D, 0x00000452, 0x0004003D, 0x00000006, 0x00000454, -0x00000444, 0x0004003D, 0x00000006, 0x00000455, 0x00000444, 0x00050085, 0x00000006, 0x00000457, -0x00000455, 0x00000456, 0x00050083, 0x00000006, 0x00000458, 0x00000454, 0x00000457, 0x0003003E, -0x00000453, 0x00000458, 0x0004003D, 0x00000006, 0x0000045A, 0x0000044D, 0x0004003D, 0x00000006, -0x0000045B, 0x00000444, 0x00050083, 0x00000006, 0x0000045C, 0x0000045A, 0x0000045B, 0x0004003D, -0x00000006, 0x0000045D, 0x00000453, 0x00050088, 0x00000006, 0x0000045E, 0x0000045C, 0x0000045D, -0x0003003E, 0x00000459, 0x0000045E, 0x00050041, 0x00000007, 0x0000045F, 0x000003FA, 0x00000260, -0x0004003D, 0x00000006, 0x00000460, 0x0000045F, 0x0004003D, 0x00000006, 0x00000461, 0x00000448, -0x0007000C, 0x00000006, 0x00000462, 0x00000001, 0x0000001A, 0x00000461, 0x00000130, 0x00050081, -0x00000006, 0x00000463, 0x00000462, 0x000000D5, 0x00050088, 0x00000006, 0x00000464, 0x00000460, -0x00000463, 0x0004003D, 0x00000006, 0x00000465, 0x00000459, 0x00050085, 0x00000006, 0x00000466, -0x00000465, 0x00000464, 0x0003003E, 0x00000459, 0x00000466, 0x0004003D, 0x00000006, 0x00000467, -0x00000459, 0x0008000C, 0x00000006, 0x00000468, 0x00000001, 0x0000002B, 0x00000467, 0x000000F8, -0x000000D5, 0x0003003E, 0x0000040D, 0x00000468, 0x000200F9, 0x0000043D, 0x000200F8, 0x00000469, -0x0004003D, 0x0000000C, 0x0000046C, 0x000000CA, 0x0003003E, 0x0000046B, 0x0000046C, 0x00050039, -0x00000085, 0x0000046D, 0x000000A2, 0x0000046B, 0x0003003E, 0x0000046A, 0x0000046D, 0x00050041, -0x0000032D, 0x0000046F, 0x000002CD, 0x0000046E, 0x0004003D, 0x00000085, 0x00000470, 0x0000046F, -0x000500AD, 0x000001E5, 0x00000471, 0x00000470, 0x000001E9, 0x000300F7, 0x00000473, 0x00000000, -0x000400FA, 0x00000471, 0x00000472, 0x00000480, 0x000200F8, 0x00000472, 0x0004003D, 0x0000000C, -0x00000475, 0x000000CA, 0x0003003E, 0x00000474, 0x00000475, 0x0004003D, 0x00000085, 0x00000477, -0x0000046A, 0x0003003E, 0x00000476, 0x00000477, 0x00050041, 0x00000013, 0x00000479, 0x000003FA, -0x00000210, 0x0004003D, 0x00000012, 0x0000047A, 0x00000479, 0x0008004F, 0x0000000C, 0x0000047B, -0x0000047A, 0x0000047A, 0x00000000, 0x00000001, 0x00000002, 0x0003003E, 0x00000478, 0x0000047B, -0x00050041, 0x0000000D, 0x0000047D, 0x000000CB, 0x0000020A, 0x0004003D, 0x0000000C, 0x0000047E, -0x0000047D, 0x0003003E, 0x0000047C, 0x0000047E, 0x00080039, 0x00000006, 0x0000047F, 0x000000A9, -0x00000474, 0x00000476, 0x00000478, 0x0000047C, 0x0003003E, 0x0000040D, 0x0000047F, 0x000200F9, -0x00000473, 0x000200F8, 0x00000480, 0x0003003E, 0x0000040D, 0x000000D5, 0x000200F9, 0x00000473, -0x000200F8, 0x00000473, 0x000200F9, 0x0000043D, 0x000200F8, 0x0000043D, 0x000200F9, 0x00000412, -0x000200F8, 0x00000412, 0x00050041, 0x00000013, 0x00000482, 0x000003FA, 0x00000210, 0x0004003D, -0x00000012, 0x00000483, 0x00000482, 0x0008004F, 0x0000000C, 0x00000484, 0x00000483, 0x00000483, -0x00000000, 0x00000001, 0x00000002, 0x0003003E, 0x00000481, 0x00000484, 0x00050041, 0x00000013, -0x00000486, 0x000003FA, 0x000001E9, 0x0004003D, 0x00000012, 0x00000487, 0x00000486, 0x0008004F, -0x0000000C, 0x00000488, 0x00000487, 0x00000487, 0x00000000, 0x00000001, 0x00000002, 0x00050041, -0x00000007, 0x00000489, 0x000003FA, 0x0000027E, 0x0004003D, 0x00000006, 0x0000048A, 0x00000489, -0x0005008E, 0x0000000C, 0x0000048B, 0x00000488, 0x0000048A, 0x0003003E, 0x00000485, 0x0000048B, -0x0004003D, 0x0000000C, 0x0000048D, 0x00000481, 0x00050041, 0x0000000D, 0x0000048E, 0x000000CB, -0x00000278, 0x0004003D, 0x0000000C, 0x0000048F, 0x0000048E, 0x00050081, 0x0000000C, 0x00000490, -0x0000048D, 0x0000048F, 0x0006000C, 0x0000000C, 0x00000491, 0x00000001, 0x00000045, 0x00000490, -0x0003003E, 0x0000048C, 0x00000491, 0x00050041, 0x0000000D, 0x00000493, 0x000000CB, 0x0000020A, -0x0004003D, 0x0000000C, 0x00000494, 0x00000493, 0x0004003D, 0x0000000C, 0x00000495, 0x00000481, -0x00050094, 0x00000006, 0x00000496, 0x00000494, 0x00000495, 0x0003003E, 0x00000497, 0x00000496, -0x00050039, 0x00000006, 0x00000498, 0x00000019, 0x00000497, 0x0003003E, 0x00000492, 0x00000498, -0x00050041, 0x0000000D, 0x0000049A, 0x000000CB, 0x00000278, 0x0004003D, 0x0000000C, 0x0000049B, -0x0000049A, 0x0004003D, 0x0000000C, 0x0000049C, 0x00000481, 0x00050081, 0x0000000C, 0x0000049D, -0x0000049B, 0x0000049C, 0x0006000C, 0x0000000C, 0x0000049E, 0x00000001, 0x00000045, 0x0000049D, -0x0003003E, 0x00000499, 0x0000049E, 0x00050041, 0x0000000D, 0x000004A0, 0x000000CB, 0x0000020A, -0x0004003D, 0x0000000C, 0x000004A1, 0x000004A0, 0x00050041, 0x0000000D, 0x000004A2, 0x000000CB, -0x00000278, 0x0004003D, 0x0000000C, 0x000004A3, 0x000004A2, 0x00050094, 0x00000006, 0x000004A4, -0x000004A1, 0x000004A3, 0x0003003E, 0x000004A5, 0x000004A4, 0x00050039, 0x00000006, 0x000004A6, -0x00000046, 0x000004A5, 0x0003003E, 0x0000049F, 0x000004A6, 0x0004003D, 0x00000006, 0x000004A8, -0x0000049F, 0x0003003E, 0x000004A7, 0x000004A8, 0x0004003D, 0x00000006, 0x000004AB, 0x00000492, -0x0003003E, 0x000004AA, 0x000004AB, 0x00050039, 0x00000006, 0x000004AC, 0x00000019, 0x000004AA, -0x0003003E, 0x000004A9, 0x000004AC, 0x00050041, 0x0000000D, 0x000004AE, 0x000000CB, 0x0000020A, -0x0004003D, 0x0000000C, 0x000004AF, 0x000004AE, 0x0004003D, 0x0000000C, 0x000004B0, 0x00000499, -0x00050094, 0x00000006, 0x000004B1, 0x000004AF, 0x000004B0, 0x0003003E, 0x000004B2, 0x000004B1, -0x00050039, 0x00000006, 0x000004B3, 0x00000019, 0x000004B2, 0x0003003E, 0x000004AD, 0x000004B3, -0x0004003D, 0x0000000C, 0x000004B5, 0x00000481, 0x0004003D, 0x0000000C, 0x000004B6, 0x00000499, -0x00050094, 0x00000006, 0x000004B7, 0x000004B5, 0x000004B6, 0x0003003E, 0x000004B8, 0x000004B7, -0x00050039, 0x00000006, 0x000004B9, 0x00000019, 0x000004B8, 0x0003003E, 0x000004B4, 0x000004B9, -0x0004003D, 0x000000AB, 0x000004BB, 0x000000CB, 0x0004003D, 0x00000006, 0x000004BD, 0x000004A7, -0x0003003E, 0x000004BC, 0x000004BD, 0x0004003D, 0x00000006, 0x000004BF, 0x000004A9, 0x0003003E, -0x000004BE, 0x000004BF, 0x0004003D, 0x00000006, 0x000004C1, 0x000004B4, 0x0003003E, 0x000004C0, -0x000004C1, 0x00080039, 0x0000000C, 0x000004C2, 0x000000BC, 0x000004BB, 0x000004BC, 0x000004BE, -0x000004C0, 0x0003003E, 0x000004BA, 0x000004C2, 0x0004003D, 0x000000AB, 0x000004C4, 0x000000CB, -0x0004003D, 0x000000AC, 0x000004C5, 0x000003FA, 0x0004003D, 0x0000000C, 0x000004C6, 0x00000499, -0x0004003D, 0x00000006, 0x000004C8, 0x000004A7, 0x0003003E, 0x000004C7, 0x000004C8, 0x0004003D, -0x00000006, 0x000004CA, 0x000004A9, 0x0003003E, 0x000004C9, 0x000004CA, 0x0004003D, 0x00000006, -0x000004CC, 0x000004AD, 0x0003003E, 0x000004CB, 0x000004CC, 0x0004003D, 0x00000006, 0x000004CE, -0x000004B4, 0x0003003E, 0x000004CD, 0x000004CE, 0x000B0039, 0x0000000C, 0x000004CF, 0x000000C5, -0x000004C4, 0x000004C5, 0x000004C6, 0x000004C7, 0x000004C9, 0x000004CB, 0x000004CD, 0x0003003E, -0x000004C3, 0x000004CF, 0x0004003D, 0x0000000C, 0x000004D1, 0x000004BA, 0x0004003D, 0x0000000C, -0x000004D2, 0x000004C3, 0x00050081, 0x0000000C, 0x000004D3, 0x000004D1, 0x000004D2, 0x0003003E, -0x000004D0, 0x000004D3, 0x0004003D, 0x0000000C, 0x000004D4, 0x000004D0, 0x0004003D, 0x0000000C, -0x000004D5, 0x00000485, 0x00050085, 0x0000000C, 0x000004D6, 0x000004D4, 0x000004D5, 0x0004003D, -0x00000006, 0x000004D7, 0x0000040D, 0x0004003D, 0x00000006, 0x000004D8, 0x000004A9, 0x00050085, -0x00000006, 0x000004D9, 0x000004D7, 0x000004D8, 0x0004003D, 0x00000006, 0x000004DB, 0x000004A9, -0x0003003E, 0x000004DA, 0x000004DB, 0x00050041, 0x00000007, 0x000004DD, 0x000000CB, 0x00000228, -0x0004003D, 0x00000006, 0x000004DE, 0x000004DD, 0x0003003E, 0x000004DC, 0x000004DE, 0x00060039, -0x00000006, 0x000004DF, 0x0000003D, 0x000004DA, 0x000004DC, 0x00050085, 0x00000006, 0x000004E0, -0x000004D9, 0x000004DF, 0x0005008E, 0x0000000C, 0x000004E1, 0x000004D6, 0x000004E0, 0x0004003D, -0x0000000C, 0x000004E2, 0x000003EC, 0x00050081, 0x0000000C, 0x000004E3, 0x000004E2, 0x000004E1, -0x0003003E, 0x000003EC, 0x000004E3, 0x000200F9, 0x000003F2, 0x000200F8, 0x000003F2, 0x0004003D, -0x00000085, 0x000004E4, 0x000003EE, 0x00050080, 0x00000085, 0x000004E5, 0x000004E4, 0x000001FF, -0x0003003E, 0x000003EE, 0x000004E5, 0x000200F9, 0x000003EF, 0x000200F8, 0x000003F1, 0x0004003D, -0x0000000C, 0x000004E6, 0x000003EC, 0x000200FE, 0x000004E6, 0x00010038, 0x00050036, 0x0000000C, -0x000000D1, 0x00000000, 0x000000C8, 0x00030037, 0x0000000D, 0x000000CE, 0x00030037, 0x0000000D, -0x000000CF, 0x00030037, 0x000000C7, 0x000000D0, 0x000200F8, 0x000000D2, 0x0004003B, 0x0000000D, -0x000004E9, 0x00000007, 0x0004003B, 0x0000000D, 0x000004F3, 0x00000007, 0x0004003B, 0x0000000D, -0x000004F4, 0x00000007, 0x0004003B, 0x00000007, 0x000004F6, 0x00000007, 0x0004003B, 0x00000007, -0x000004F9, 0x00000007, 0x0004003B, 0x0000000D, 0x000004FD, 0x00000007, 0x0004003B, 0x0000000D, -0x00000505, 0x00000007, 0x0004003B, 0x00000086, 0x0000050B, 0x00000007, 0x0004003B, 0x0000000D, -0x0000050F, 0x00000007, 0x0004003B, 0x0000000D, 0x0000051A, 0x00000007, 0x0004003D, 0x000004EB, -0x000004EE, 0x000004ED, 0x00050041, 0x0000000D, 0x000004EF, 0x000000D0, 0x0000020A, 0x0004003D, -0x0000000C, 0x000004F0, 0x000004EF, 0x00050057, 0x00000012, 0x000004F1, 0x000004EE, 0x000004F0, -0x0008004F, 0x0000000C, 0x000004F2, 0x000004F1, 0x000004F1, 0x00000000, 0x00000001, 0x00000002, -0x0003003E, 0x000004E9, 0x000004F2, 0x0004003D, 0x0000000C, 0x000004F5, 0x000000CE, 0x0003003E, -0x000004F4, 0x000004F5, 0x00050041, 0x00000007, 0x000004F7, 0x000000D0, 0x0000025A, 0x0004003D, -0x00000006, 0x000004F8, 0x000004F7, 0x0003003E, 0x000004F6, 0x000004F8, 0x00050041, 0x00000007, -0x000004FA, 0x000000D0, 0x00000210, 0x0004003D, 0x00000006, 0x000004FB, 0x000004FA, 0x0003003E, -0x000004F9, 0x000004FB, 0x00070039, 0x0000000C, 0x000004FC, 0x0000006D, 0x000004F4, 0x000004F6, -0x000004F9, 0x0003003E, 0x000004F3, 0x000004FC, 0x0004003D, 0x0000000C, 0x000004FE, 0x000004F3, -0x00060050, 0x0000000C, 0x000004FF, 0x000000D5, 0x000000D5, 0x000000D5, 0x00050083, 0x0000000C, -0x00000500, 0x000004FF, 0x000004FE, 0x00050041, 0x00000007, 0x00000501, 0x000000D0, 0x000001FF, -0x0004003D, 0x00000006, 0x00000502, 0x00000501, 0x00050083, 0x00000006, 0x00000503, 0x000000D5, -0x00000502, 0x0005008E, 0x0000000C, 0x00000504, 0x00000500, 0x00000503, 0x0003003E, 0x000004FD, -0x00000504, 0x00050041, 0x00000013, 0x00000506, 0x000000D0, 0x000001E9, 0x0004003D, 0x00000012, -0x00000507, 0x00000506, 0x0008004F, 0x0000000C, 0x00000508, 0x00000507, 0x00000507, 0x00000000, -0x00000001, 0x00000002, 0x0004003D, 0x0000000C, 0x00000509, 0x000004E9, 0x00050085, 0x0000000C, -0x0000050A, 0x00000508, 0x00000509, 0x0003003E, 0x00000505, 0x0000050A, 0x00050041, 0x0000032D, -0x0000050D, 0x000002CD, 0x0000050C, 0x0004003D, 0x00000085, 0x0000050E, 0x0000050D, 0x0003003E, -0x0000050B, 0x0000050E, 0x0004003D, 0x000004EB, 0x00000511, 0x00000510, 0x0004003D, 0x0000000C, -0x00000512, 0x000000CF, 0x00050041, 0x00000007, 0x00000513, 0x000000D0, 0x0000027E, 0x0004003D, -0x00000006, 0x00000514, 0x00000513, 0x0004003D, 0x00000085, 0x00000515, 0x0000050B, 0x0004006F, -0x00000006, 0x00000516, 0x00000515, 0x00050085, 0x00000006, 0x00000517, 0x00000514, 0x00000516, -0x00070058, 0x00000012, 0x00000518, 0x00000511, 0x00000512, 0x00000002, 0x00000517, 0x0008004F, -0x0000000C, 0x00000519, 0x00000518, 0x00000518, 0x00000000, 0x00000001, 0x00000002, 0x0003003E, -0x0000050F, 0x00000519, 0x0004003D, 0x0000000C, 0x0000051B, 0x0000050F, 0x0004003D, 0x0000000C, -0x0000051C, 0x000004F3, 0x00060041, 0x00000007, 0x0000051D, 0x000000D0, 0x0000032C, 0x0000023E, -0x0004003D, 0x00000006, 0x0000051E, 0x0000051D, 0x0005008E, 0x0000000C, 0x0000051F, 0x0000051C, -0x0000051E, 0x00060041, 0x00000007, 0x00000521, 0x000000D0, 0x0000032C, 0x00000520, 0x0004003D, -0x00000006, 0x00000522, 0x00000521, 0x00060050, 0x0000000C, 0x00000523, 0x00000522, 0x00000522, -0x00000522, 0x00050081, 0x0000000C, 0x00000524, 0x0000051F, 0x00000523, 0x00050085, 0x0000000C, -0x00000525, 0x0000051B, 0x00000524, 0x0003003E, 0x0000051A, 0x00000525, 0x0004003D, 0x0000000C, -0x00000526, 0x000004FD, 0x0004003D, 0x0000000C, 0x00000527, 0x00000505, 0x00050085, 0x0000000C, -0x00000528, 0x00000526, 0x00000527, 0x0004003D, 0x0000000C, 0x00000529, 0x0000051A, 0x00050081, -0x0000000C, 0x0000052A, 0x00000528, 0x00000529, 0x000200FE, 0x0000052A, 0x00010038, +0x00000556, 0x00050041, 0x000001DF, 0x00000558, 0x000001DD, 0x00000208, 0x0004003D, 0x00000006, +0x00000559, 0x00000558, 0x00050041, 0x00000007, 0x0000055A, 0x0000054C, 0x000002EA, 0x0004003D, +0x00000006, 0x0000055B, 0x0000055A, 0x00050085, 0x00000006, 0x0000055C, 0x00000559, 0x0000055B, +0x00050081, 0x00000006, 0x0000055D, 0x00000557, 0x0000055C, 0x0003003E, 0x00000518, 0x0000055D, +0x00050041, 0x000001DF, 0x0000055E, 0x000001DD, 0x00000208, 0x0004003D, 0x00000006, 0x0000055F, +0x0000055E, 0x00050083, 0x00000006, 0x00000560, 0x000000D3, 0x0000055F, 0x00050041, 0x000001DF, +0x00000561, 0x000001DD, 0x000001FD, 0x0004003D, 0x00000006, 0x00000562, 0x00000561, 0x00050085, +0x00000006, 0x00000563, 0x00000560, 0x00000562, 0x00050041, 0x000001DF, 0x00000564, 0x000001DD, +0x00000208, 0x0004003D, 0x00000006, 0x00000565, 0x00000564, 0x00050041, 0x00000007, 0x00000566, +0x0000054C, 0x00000501, 0x0004003D, 0x00000006, 0x00000567, 0x00000566, 0x00050085, 0x00000006, +0x00000568, 0x00000565, 0x00000567, 0x00050081, 0x00000006, 0x00000569, 0x00000563, 0x00000568, +0x0003003E, 0x00000519, 0x00000569, 0x000200F9, 0x0000054B, 0x000200F8, 0x0000054B, 0x000200F9, +0x00000527, 0x000200F8, 0x00000527, 0x000200F9, 0x0000051E, 0x000200F8, 0x0000051E, 0x0004003D, +0x00000012, 0x0000056B, 0x0000050E, 0x00050041, 0x00000013, 0x0000056C, 0x0000056A, 0x000001E7, +0x0003003E, 0x0000056C, 0x0000056B, 0x0004003D, 0x00000006, 0x0000056D, 0x00000518, 0x00050041, +0x00000007, 0x0000056E, 0x0000056A, 0x000001FD, 0x0003003E, 0x0000056E, 0x0000056D, 0x0004003D, +0x00000006, 0x0000056F, 0x00000519, 0x00050041, 0x00000007, 0x00000570, 0x0000056A, 0x000003E6, +0x0003003E, 0x00000570, 0x0000056F, 0x00050041, 0x000001DF, 0x00000571, 0x000001DD, 0x000003E6, +0x0004003D, 0x00000006, 0x00000572, 0x00000571, 0x00050041, 0x00000007, 0x00000573, 0x0000056A, +0x0000025E, 0x0003003E, 0x00000573, 0x00000572, 0x00050041, 0x00000574, 0x00000575, 0x000001FC, +0x000003E6, 0x0004003D, 0x0000000C, 0x00000576, 0x00000575, 0x0006000C, 0x0000000C, 0x00000577, +0x00000001, 0x00000045, 0x00000576, 0x00050041, 0x0000000D, 0x00000578, 0x0000056A, 0x00000208, +0x0003003E, 0x00000578, 0x00000577, 0x00050041, 0x000001DF, 0x00000579, 0x000001DD, 0x000002D1, +0x0004003D, 0x00000006, 0x0000057A, 0x00000579, 0x000500BA, 0x000001E3, 0x0000057C, 0x0000057A, +0x0000057B, 0x000300F7, 0x0000057E, 0x00000000, 0x000400FA, 0x0000057C, 0x0000057D, 0x0000057E, +0x000200F8, 0x0000057D, 0x0004003D, 0x000001F5, 0x00000580, 0x0000057F, 0x00050041, 0x000001FE, +0x00000581, 0x000001FC, 0x000001FD, 0x0004003D, 0x0000007D, 0x00000582, 0x00000581, 0x00050057, +0x00000012, 0x00000583, 0x00000580, 0x00000582, 0x0008004F, 0x0000000C, 0x00000584, 0x00000583, +0x00000583, 0x00000000, 0x00000001, 0x00000002, 0x0005008E, 0x0000000C, 0x00000585, 0x00000584, +0x0000012E, 0x00060050, 0x0000000C, 0x00000586, 0x000000D3, 0x000000D3, 0x000000D3, 0x00050083, +0x0000000C, 0x00000587, 0x00000585, 0x00000586, 0x0006000C, 0x0000000C, 0x00000588, 0x00000001, +0x00000045, 0x00000587, 0x00050041, 0x0000000D, 0x00000589, 0x0000056A, 0x00000208, 0x0003003E, +0x00000589, 0x00000588, 0x00050041, 0x0000058A, 0x0000058B, 0x000001FC, 0x0000025E, 0x0004003D, +0x000001F9, 0x0000058C, 0x0000058B, 0x00050041, 0x0000000D, 0x0000058D, 0x0000056A, 0x00000208, +0x0004003D, 0x0000000C, 0x0000058E, 0x0000058D, 0x00050091, 0x0000000C, 0x0000058F, 0x0000058C, +0x0000058E, 0x0006000C, 0x0000000C, 0x00000590, 0x00000001, 0x00000045, 0x0000058F, 0x00050041, +0x0000000D, 0x00000591, 0x0000056A, 0x00000208, 0x0003003E, 0x00000591, 0x00000590, 0x00050041, +0x0000000D, 0x00000592, 0x0000056A, 0x00000208, 0x0004003D, 0x0000000C, 0x00000593, 0x00000592, +0x0006000C, 0x0000000C, 0x00000594, 0x00000001, 0x00000045, 0x00000593, 0x00050041, 0x0000000D, +0x00000595, 0x0000056A, 0x00000208, 0x0003003E, 0x00000595, 0x00000594, 0x000200F9, 0x0000057E, +0x000200F8, 0x0000057E, 0x00040039, 0x00000006, 0x00000596, 0x00000078, 0x00050041, 0x00000007, +0x00000597, 0x0000056A, 0x00000226, 0x0003003E, 0x00000597, 0x00000596, 0x00050041, 0x00000013, +0x00000599, 0x0000056A, 0x000001E7, 0x0004003D, 0x00000012, 0x0000059A, 0x00000599, 0x0008004F, +0x0000000C, 0x0000059B, 0x0000059A, 0x0000059A, 0x00000000, 0x00000001, 0x00000002, 0x0003003E, +0x00000598, 0x0000059B, 0x00050039, 0x0000000C, 0x0000059C, 0x0000007B, 0x00000598, 0x00050041, +0x0000000D, 0x0000059D, 0x0000056A, 0x000001DE, 0x0003003E, 0x0000059D, 0x0000059C, 0x0004003D, +0x00000012, 0x000005A1, 0x000005A0, 0x0007004F, 0x0000007D, 0x000005A2, 0x000005A1, 0x000005A1, +0x00000000, 0x00000001, 0x00050041, 0x000001DF, 0x000005A4, 0x000002AC, 0x000005A3, 0x0004003D, +0x00000006, 0x000005A5, 0x000005A4, 0x00050041, 0x000001DF, 0x000005A7, 0x000002AC, 0x000005A6, +0x0004003D, 0x00000006, 0x000005A8, 0x000005A7, 0x00050050, 0x0000007D, 0x000005A9, 0x000005A5, +0x000005A8, 0x00050088, 0x0000007D, 0x000005AA, 0x000005A2, 0x000005A9, 0x0003003E, 0x0000059E, +0x000005AA, 0x0004003D, 0x000001F5, 0x000005AD, 0x000005AC, 0x0004003D, 0x0000007D, 0x000005AE, +0x0000059E, 0x00050057, 0x00000012, 0x000005AF, 0x000005AD, 0x000005AE, 0x00050051, 0x00000006, +0x000005B0, 0x000005AF, 0x00000000, 0x0003003E, 0x000005AB, 0x000005B0, 0x0004003D, 0x00000006, +0x000005B1, 0x000005AB, 0x00050041, 0x00000013, 0x000005B2, 0x0000056A, 0x000001E7, 0x0004003D, +0x00000012, 0x000005B3, 0x000005B2, 0x0005008E, 0x00000012, 0x000005B4, 0x000005B3, 0x000005B1, +0x00050041, 0x00000013, 0x000005B5, 0x0000056A, 0x000001E7, 0x0003003E, 0x000005B5, 0x000005B4, +0x00050041, 0x00000007, 0x000005B6, 0x0000056A, 0x000003E6, 0x0004003D, 0x00000006, 0x000005B7, +0x000005B6, 0x0008000C, 0x00000006, 0x000005B9, 0x00000001, 0x0000002B, 0x000005B7, 0x000005B8, +0x000000D3, 0x00050041, 0x00000007, 0x000005BA, 0x0000056A, 0x000003E6, 0x0003003E, 0x000005BA, +0x000005B9, 0x00050041, 0x00000007, 0x000005BC, 0x0000056A, 0x0000020E, 0x0004003D, 0x00000006, +0x000005BD, 0x000005BC, 0x0003003E, 0x000005BB, 0x000005BD, 0x00050039, 0x00000006, 0x000005BE, +0x00000057, 0x000005BB, 0x00050041, 0x00000007, 0x000005BF, 0x0000056A, 0x0000020E, 0x0003003E, +0x000005BF, 0x000005BE, 0x0004003D, 0x00000006, 0x000005C1, 0x00000519, 0x0004003D, 0x00000006, +0x000005C2, 0x00000519, 0x00050085, 0x00000006, 0x000005C3, 0x000005C1, 0x000005C2, 0x0003003E, +0x000005C0, 0x000005C3, 0x00050041, 0x0000000D, 0x000005C5, 0x0000056A, 0x00000208, 0x0004003D, +0x0000000C, 0x000005C6, 0x000005C5, 0x000400CF, 0x0000000C, 0x000005C7, 0x000005C6, 0x0003003E, +0x000005C4, 0x000005C7, 0x00050041, 0x0000000D, 0x000005C9, 0x0000056A, 0x00000208, 0x0004003D, +0x0000000C, 0x000005CA, 0x000005C9, 0x000400D0, 0x0000000C, 0x000005CB, 0x000005CA, 0x0003003E, +0x000005C8, 0x000005CB, 0x0004003D, 0x0000000C, 0x000005CD, 0x000005C4, 0x0004003D, 0x0000000C, +0x000005CE, 0x000005C4, 0x00050094, 0x00000006, 0x000005CF, 0x000005CD, 0x000005CE, 0x0004003D, +0x0000000C, 0x000005D0, 0x000005C8, 0x0004003D, 0x0000000C, 0x000005D1, 0x000005C8, 0x00050094, +0x00000006, 0x000005D2, 0x000005D0, 0x000005D1, 0x00050081, 0x00000006, 0x000005D3, 0x000005CF, +0x000005D2, 0x0003003E, 0x000005CC, 0x000005D3, 0x0004003D, 0x00000006, 0x000005D5, 0x000005CC, +0x00050085, 0x00000006, 0x000005D6, 0x000005D5, 0x000000D3, 0x0007000C, 0x00000006, 0x000005D8, +0x00000001, 0x00000025, 0x000005D6, 0x000005D7, 0x0003003E, 0x000005D4, 0x000005D8, 0x0004003D, +0x00000006, 0x000005DA, 0x000005C0, 0x0004003D, 0x00000006, 0x000005DB, 0x000005D4, 0x00050081, +0x00000006, 0x000005DC, 0x000005DA, 0x000005DB, 0x0003003E, 0x000005DD, 0x000005DC, 0x00050039, +0x00000006, 0x000005DE, 0x00000019, 0x000005DD, 0x0003003E, 0x000005D9, 0x000005DE, 0x0004003D, +0x00000006, 0x000005DF, 0x000005D9, 0x0006000C, 0x00000006, 0x000005E0, 0x00000001, 0x0000001F, +0x000005DF, 0x00050041, 0x00000007, 0x000005E1, 0x0000056A, 0x0000020E, 0x0003003E, 0x000005E1, +0x000005E0, 0x00050041, 0x00000007, 0x000005E2, 0x0000056A, 0x0000020E, 0x0004003D, 0x00000006, +0x000005E3, 0x000005E2, 0x0008000C, 0x00000006, 0x000005E5, 0x00000001, 0x0000002B, 0x000005E3, +0x000005E4, 0x000000D3, 0x00050041, 0x00000007, 0x000005E6, 0x0000056A, 0x0000020E, 0x0003003E, +0x000005E6, 0x000005E5, 0x00050041, 0x0000059F, 0x000005E8, 0x000001FC, 0x0000020E, 0x0004003D, +0x00000012, 0x000005E9, 0x000005E8, 0x0008004F, 0x0000000C, 0x000005EA, 0x000005E9, 0x000005E9, +0x00000000, 0x00000001, 0x00000002, 0x0003003E, 0x000005E7, 0x000005EA, 0x00050041, 0x000001E8, +0x000005EB, 0x000002AC, 0x000001DE, 0x0004003D, 0x00000012, 0x000005EC, 0x000005EB, 0x0008004F, +0x0000000C, 0x000005ED, 0x000005EC, 0x000005EC, 0x00000000, 0x00000001, 0x00000002, 0x0004003D, +0x0000000C, 0x000005EE, 0x000005E7, 0x00050083, 0x0000000C, 0x000005EF, 0x000005ED, 0x000005EE, +0x0006000C, 0x0000000C, 0x000005F0, 0x00000001, 0x00000045, 0x000005EF, 0x00050041, 0x0000000D, +0x000005F1, 0x0000056A, 0x000002D1, 0x0003003E, 0x000005F1, 0x000005F0, 0x00050041, 0x0000000D, +0x000005F2, 0x0000056A, 0x00000208, 0x0004003D, 0x0000000C, 0x000005F3, 0x000005F2, 0x00050041, +0x0000000D, 0x000005F4, 0x0000056A, 0x000002D1, 0x0004003D, 0x0000000C, 0x000005F5, 0x000005F4, +0x00050094, 0x00000006, 0x000005F6, 0x000005F3, 0x000005F5, 0x0007000C, 0x00000006, 0x000005F7, +0x00000001, 0x00000028, 0x000005F6, 0x0000018D, 0x00050041, 0x00000007, 0x000005F8, 0x0000056A, +0x00000258, 0x0003003E, 0x000005F8, 0x000005F7, 0x0004003D, 0x000001F5, 0x000005FA, 0x000005F9, +0x00050041, 0x00000007, 0x000005FB, 0x0000056A, 0x00000258, 0x0004003D, 0x00000006, 0x000005FC, +0x000005FB, 0x00050041, 0x00000007, 0x000005FD, 0x0000056A, 0x000003E6, 0x0004003D, 0x00000006, +0x000005FE, 0x000005FD, 0x00050050, 0x0000007D, 0x000005FF, 0x000005FC, 0x000005FE, 0x00050057, +0x00000012, 0x00000600, 0x000005FA, 0x000005FF, 0x0007004F, 0x0000007D, 0x00000601, 0x00000600, +0x00000600, 0x00000000, 0x00000001, 0x00050041, 0x0000007E, 0x00000602, 0x0000056A, 0x0000030C, +0x0003003E, 0x00000602, 0x00000601, 0x00050041, 0x00000007, 0x00000605, 0x0000056A, 0x0000025E, +0x0004003D, 0x00000006, 0x00000606, 0x00000605, 0x0003003E, 0x00000604, 0x00000606, 0x00050039, +0x00000006, 0x00000607, 0x00000054, 0x00000604, 0x0003003E, 0x00000603, 0x00000607, 0x00050041, +0x00000013, 0x00000609, 0x0000056A, 0x000001E7, 0x0004003D, 0x00000012, 0x0000060A, 0x00000609, +0x00050041, 0x00000007, 0x0000060C, 0x0000056A, 0x000001FD, 0x0004003D, 0x00000006, 0x0000060D, +0x0000060C, 0x0003003E, 0x0000060B, 0x0000060D, 0x0004003D, 0x00000006, 0x0000060F, 0x00000603, +0x0003003E, 0x0000060E, 0x0000060F, 0x00070039, 0x0000000C, 0x00000610, 0x00000051, 0x0000060A, +0x0000060B, 0x0000060E, 0x0003003E, 0x00000608, 0x00000610, 0x0004003D, 0x0000000C, 0x00000611, +0x00000608, 0x00050041, 0x0000000D, 0x00000612, 0x0000056A, 0x00000242, 0x0003003E, 0x00000612, +0x00000611, 0x00050041, 0x0000000D, 0x00000613, 0x0000056A, 0x00000242, 0x0004003D, 0x0000000C, +0x00000614, 0x00000613, 0x00060041, 0x00000007, 0x00000616, 0x0000056A, 0x0000030C, 0x00000501, +0x0004003D, 0x00000006, 0x00000617, 0x00000616, 0x0007000C, 0x00000006, 0x00000618, 0x00000001, +0x00000028, 0x00000615, 0x00000617, 0x00050088, 0x00000006, 0x00000619, 0x000000D3, 0x00000618, +0x00050083, 0x00000006, 0x0000061A, 0x00000619, 0x000000D3, 0x0005008E, 0x0000000C, 0x0000061B, +0x00000614, 0x0000061A, 0x00060050, 0x0000000C, 0x0000061C, 0x000000D3, 0x000000D3, 0x000000D3, +0x00050081, 0x0000000C, 0x0000061D, 0x0000061C, 0x0000061B, 0x00050041, 0x0000000D, 0x0000061E, +0x0000056A, 0x000003D5, 0x0003003E, 0x0000061E, 0x0000061D, 0x00050041, 0x00000013, 0x0000061F, +0x0000056A, 0x000001E7, 0x0004003D, 0x00000012, 0x00000620, 0x0000061F, 0x00050041, 0x00000007, +0x00000622, 0x0000056A, 0x000001FD, 0x0004003D, 0x00000006, 0x00000623, 0x00000622, 0x0003003E, +0x00000621, 0x00000623, 0x00060039, 0x0000000C, 0x00000624, 0x0000004B, 0x00000620, 0x00000621, +0x00060041, 0x00000007, 0x00000625, 0x0000056A, 0x000001E7, 0x0000023C, 0x00050051, 0x00000006, +0x00000626, 0x00000624, 0x00000000, 0x0003003E, 0x00000625, 0x00000626, 0x00060041, 0x00000007, +0x00000627, 0x0000056A, 0x000001E7, 0x00000501, 0x00050051, 0x00000006, 0x00000628, 0x00000624, +0x00000001, 0x0003003E, 0x00000627, 0x00000628, 0x00060041, 0x00000007, 0x00000629, 0x0000056A, +0x000001E7, 0x000002EA, 0x00050051, 0x00000006, 0x0000062A, 0x00000624, 0x00000002, 0x0003003E, +0x00000629, 0x0000062A, 0x00050041, 0x000001DF, 0x0000062C, 0x000002AC, 0x000002D1, 0x0004003D, +0x00000006, 0x0000062D, 0x0000062C, 0x0003003E, 0x0000062B, 0x0000062D, 0x00050041, 0x000001DF, +0x0000062F, 0x000002AC, 0x00000258, 0x0004003D, 0x00000006, 0x00000630, 0x0000062F, 0x0003003E, +0x0000062E, 0x00000630, 0x00050041, 0x000002FC, 0x00000632, 0x000002AC, 0x0000020E, 0x0004003D, +0x000002A6, 0x00000633, 0x00000632, 0x0004003D, 0x0000000C, 0x00000634, 0x000005E7, 0x00050051, +0x00000006, 0x00000635, 0x00000634, 0x00000000, 0x00050051, 0x00000006, 0x00000636, 0x00000634, +0x00000001, 0x00050051, 0x00000006, 0x00000637, 0x00000634, 0x00000002, 0x00070050, 0x00000012, +0x00000638, 0x00000635, 0x00000636, 0x00000637, 0x000000D3, 0x00050091, 0x00000012, 0x00000639, +0x00000633, 0x00000638, 0x0003003E, 0x00000631, 0x00000639, 0x0004003D, 0x00000012, 0x0000063B, +0x00000631, 0x0006000C, 0x00000006, 0x0000063C, 0x00000001, 0x00000042, 0x0000063B, 0x0003003E, +0x0000063A, 0x0000063C, 0x0004003D, 0x00000006, 0x0000063D, 0x0000063A, 0x0004003D, 0x00000006, +0x0000063E, 0x0000062B, 0x0004003D, 0x00000006, 0x0000063F, 0x0000062E, 0x00050083, 0x00000006, +0x00000640, 0x0000063E, 0x0000063F, 0x00050083, 0x00000006, 0x00000641, 0x0000063D, 0x00000640, +0x0003003E, 0x000000D2, 0x00000641, 0x0004003D, 0x00000006, 0x00000642, 0x0000062E, 0x0004003D, +0x00000006, 0x00000643, 0x000000D2, 0x00050088, 0x00000006, 0x00000644, 0x00000643, 0x00000642, +0x0003003E, 0x000000D2, 0x00000644, 0x0004003D, 0x00000006, 0x00000645, 0x000000D2, 0x00050083, +0x00000006, 0x00000646, 0x000000D3, 0x00000645, 0x0008000C, 0x00000006, 0x00000647, 0x00000001, +0x0000002B, 0x00000646, 0x000000F6, 0x000000D3, 0x0003003E, 0x000000D2, 0x00000647, 0x00050041, +0x00000007, 0x00000649, 0x0000056A, 0x00000258, 0x0004003D, 0x00000006, 0x0000064A, 0x00000649, +0x00050085, 0x00000006, 0x0000064B, 0x0000012E, 0x0000064A, 0x00050041, 0x0000000D, 0x0000064C, +0x0000056A, 0x00000208, 0x0004003D, 0x0000000C, 0x0000064D, 0x0000064C, 0x0005008E, 0x0000000C, +0x0000064E, 0x0000064D, 0x0000064B, 0x00050041, 0x0000000D, 0x0000064F, 0x0000056A, 0x000002D1, +0x0004003D, 0x0000000C, 0x00000650, 0x0000064F, 0x00050083, 0x0000000C, 0x00000651, 0x0000064E, +0x00000650, 0x0003003E, 0x00000648, 0x00000651, 0x00050041, 0x0000000D, 0x00000654, 0x0000056A, +0x00000242, 0x0004003D, 0x0000000C, 0x00000655, 0x00000654, 0x0003003E, 0x00000653, 0x00000655, +0x0004003D, 0x0000000C, 0x00000657, 0x000005E7, 0x0003003E, 0x00000656, 0x00000657, 0x0004003D, +0x000000A9, 0x00000659, 0x0000056A, 0x0003003E, 0x00000658, 0x00000659, 0x00070039, 0x0000000C, +0x0000065A, 0x000000CA, 0x00000653, 0x00000656, 0x00000658, 0x0003003E, 0x00000652, 0x0000065A, +0x00050041, 0x0000000D, 0x0000065D, 0x0000056A, 0x00000242, 0x0004003D, 0x0000000C, 0x0000065E, +0x0000065D, 0x0003003E, 0x0000065C, 0x0000065E, 0x0004003D, 0x0000000C, 0x00000660, 0x00000648, +0x0003003E, 0x0000065F, 0x00000660, 0x0004003D, 0x000000A9, 0x00000662, 0x0000056A, 0x0003003E, +0x00000661, 0x00000662, 0x00070039, 0x0000000C, 0x00000663, 0x000000CF, 0x0000065C, 0x0000065F, +0x00000661, 0x0003003E, 0x0000065B, 0x00000663, 0x0004003D, 0x0000000C, 0x00000665, 0x00000652, +0x0004003D, 0x0000000C, 0x00000666, 0x0000065B, 0x00050081, 0x0000000C, 0x00000667, 0x00000665, +0x00000666, 0x00050041, 0x0000000D, 0x00000668, 0x0000056A, 0x000001DE, 0x0004003D, 0x0000000C, +0x00000669, 0x00000668, 0x00050081, 0x0000000C, 0x0000066A, 0x00000667, 0x00000669, 0x0003003E, +0x00000664, 0x0000066A, 0x0004003D, 0x0000000C, 0x0000066D, 0x00000664, 0x00050051, 0x00000006, +0x0000066E, 0x0000066D, 0x00000000, 0x00050051, 0x00000006, 0x0000066F, 0x0000066D, 0x00000001, +0x00050051, 0x00000006, 0x00000670, 0x0000066D, 0x00000002, 0x00070050, 0x00000012, 0x00000671, +0x0000066E, 0x0000066F, 0x00000670, 0x000000D3, 0x0003003E, 0x0000066C, 0x00000671, 0x00050041, +0x0000030D, 0x00000673, 0x000002AC, 0x00000672, 0x0004003D, 0x00000083, 0x00000674, 0x00000673, +0x000500AD, 0x000001E3, 0x00000675, 0x00000674, 0x000001E7, 0x000300F7, 0x00000677, 0x00000000, +0x000400FA, 0x00000675, 0x00000676, 0x00000677, 0x000200F8, 0x00000676, 0x00050041, 0x0000030D, +0x00000678, 0x000002AC, 0x00000672, 0x0004003D, 0x00000083, 0x00000679, 0x00000678, 0x000300F7, +0x00000681, 0x00000000, 0x001100FB, 0x00000679, 0x00000681, 0x00000001, 0x0000067A, 0x00000002, +0x0000067B, 0x00000003, 0x0000067C, 0x00000004, 0x0000067D, 0x00000005, 0x0000067E, 0x00000006, +0x0000067F, 0x00000007, 0x00000680, 0x000200F8, 0x0000067A, 0x00050041, 0x00000013, 0x00000682, +0x0000056A, 0x000001E7, 0x0004003D, 0x00000012, 0x00000683, 0x00000682, 0x0003003E, 0x0000066C, +0x00000683, 0x000200F9, 0x00000681, 0x000200F8, 0x0000067B, 0x00050041, 0x00000007, 0x00000685, +0x0000056A, 0x000001FD, 0x0004003D, 0x00000006, 0x00000686, 0x00000685, 0x00060050, 0x0000000C, +0x00000687, 0x00000686, 0x00000686, 0x00000686, 0x00050051, 0x00000006, 0x00000688, 0x00000687, +0x00000000, 0x00050051, 0x00000006, 0x00000689, 0x00000687, 0x00000001, 0x00050051, 0x00000006, +0x0000068A, 0x00000687, 0x00000002, 0x00070050, 0x00000012, 0x0000068B, 0x00000688, 0x00000689, +0x0000068A, 0x000000D3, 0x0003003E, 0x0000066C, 0x0000068B, 0x000200F9, 0x00000681, 0x000200F8, +0x0000067C, 0x00050041, 0x00000007, 0x0000068D, 0x0000056A, 0x000003E6, 0x0004003D, 0x00000006, +0x0000068E, 0x0000068D, 0x00060050, 0x0000000C, 0x0000068F, 0x0000068E, 0x0000068E, 0x0000068E, +0x00050051, 0x00000006, 0x00000690, 0x0000068F, 0x00000000, 0x00050051, 0x00000006, 0x00000691, +0x0000068F, 0x00000001, 0x00050051, 0x00000006, 0x00000692, 0x0000068F, 0x00000002, 0x00070050, +0x00000012, 0x00000693, 0x00000690, 0x00000691, 0x00000692, 0x000000D3, 0x0003003E, 0x0000066C, +0x00000693, 0x000200F9, 0x00000681, 0x000200F8, 0x0000067D, 0x00050041, 0x00000007, 0x00000695, +0x0000056A, 0x00000226, 0x0004003D, 0x00000006, 0x00000696, 0x00000695, 0x00060050, 0x0000000C, +0x00000697, 0x00000696, 0x00000696, 0x00000696, 0x00050051, 0x00000006, 0x00000698, 0x00000697, +0x00000000, 0x00050051, 0x00000006, 0x00000699, 0x00000697, 0x00000001, 0x00050051, 0x00000006, +0x0000069A, 0x00000697, 0x00000002, 0x00070050, 0x00000012, 0x0000069B, 0x00000698, 0x00000699, +0x0000069A, 0x000000D3, 0x0003003E, 0x0000066C, 0x0000069B, 0x000200F9, 0x00000681, 0x000200F8, +0x0000067E, 0x00050041, 0x0000000D, 0x0000069D, 0x0000056A, 0x000001DE, 0x0004003D, 0x0000000C, +0x0000069E, 0x0000069D, 0x00050051, 0x00000006, 0x0000069F, 0x0000069E, 0x00000000, 0x00050051, +0x00000006, 0x000006A0, 0x0000069E, 0x00000001, 0x00050051, 0x00000006, 0x000006A1, 0x0000069E, +0x00000002, 0x00070050, 0x00000012, 0x000006A2, 0x0000069F, 0x000006A0, 0x000006A1, 0x000000D3, +0x0003003E, 0x0000066C, 0x000006A2, 0x000200F9, 0x00000681, 0x000200F8, 0x0000067F, 0x00050041, +0x0000000D, 0x000006A4, 0x0000056A, 0x00000208, 0x0004003D, 0x0000000C, 0x000006A5, 0x000006A4, +0x00050051, 0x00000006, 0x000006A6, 0x000006A5, 0x00000000, 0x00050051, 0x00000006, 0x000006A7, +0x000006A5, 0x00000001, 0x00050051, 0x00000006, 0x000006A8, 0x000006A5, 0x00000002, 0x00070050, +0x00000012, 0x000006A9, 0x000006A6, 0x000006A7, 0x000006A8, 0x000000D3, 0x0003003E, 0x0000066C, +0x000006A9, 0x000200F9, 0x00000681, 0x000200F8, 0x00000680, 0x0004003D, 0x0000000C, 0x000006AD, +0x000005E7, 0x0003003E, 0x000006AC, 0x000006AD, 0x00050039, 0x00000083, 0x000006AE, 0x000000A0, +0x000006AC, 0x0003003E, 0x000006AB, 0x000006AE, 0x0004003D, 0x00000083, 0x000006AF, 0x000006AB, +0x000300F7, 0x000006B4, 0x00000000, 0x000B00FB, 0x000006AF, 0x000006B4, 0x00000000, 0x000006B0, +0x00000001, 0x000006B1, 0x00000002, 0x000006B2, 0x00000003, 0x000006B3, 0x000200F8, 0x000006B0, +0x0004003D, 0x00000012, 0x000006B5, 0x0000066C, 0x00050085, 0x00000012, 0x000006B9, 0x000006B5, +0x000006B8, 0x0003003E, 0x0000066C, 0x000006B9, 0x000200F9, 0x000006B4, 0x000200F8, 0x000006B1, +0x0004003D, 0x00000012, 0x000006BB, 0x0000066C, 0x00050085, 0x00000012, 0x000006BD, 0x000006BB, +0x000006BC, 0x0003003E, 0x0000066C, 0x000006BD, 0x000200F9, 0x000006B4, 0x000200F8, 0x000006B2, +0x0004003D, 0x00000012, 0x000006BF, 0x0000066C, 0x00050085, 0x00000012, 0x000006C1, 0x000006BF, +0x000006C0, 0x0003003E, 0x0000066C, 0x000006C1, 0x000200F9, 0x000006B4, 0x000200F8, 0x000006B3, +0x0004003D, 0x00000012, 0x000006C3, 0x0000066C, 0x00050085, 0x00000012, 0x000006C5, 0x000006C3, +0x000006C4, 0x0003003E, 0x0000066C, 0x000006C5, 0x000200F9, 0x000006B4, 0x000200F8, 0x000006B4, +0x000200F9, 0x00000681, 0x000200F8, 0x00000681, 0x000200F9, 0x00000677, 0x000200F8, 0x00000677, +0x000100FD, 0x00010038, 0x00050036, 0x00000006, 0x0000000A, 0x00000000, 0x00000008, 0x00030037, +0x00000007, 0x00000009, 0x000200F8, 0x0000000B, 0x0004003B, 0x00000007, 0x000000D6, 0x00000007, +0x0004003D, 0x00000006, 0x000000D7, 0x00000009, 0x0004003D, 0x00000006, 0x000000D8, 0x00000009, +0x00050085, 0x00000006, 0x000000D9, 0x000000D7, 0x000000D8, 0x0003003E, 0x000000D6, 0x000000D9, +0x0004003D, 0x00000006, 0x000000DA, 0x000000D6, 0x0004003D, 0x00000006, 0x000000DB, 0x000000D6, +0x00050085, 0x00000006, 0x000000DC, 0x000000DA, 0x000000DB, 0x0004003D, 0x00000006, 0x000000DD, +0x00000009, 0x00050085, 0x00000006, 0x000000DE, 0x000000DC, 0x000000DD, 0x000200FE, 0x000000DE, +0x00010038, 0x00050036, 0x0000000C, 0x00000010, 0x00000000, 0x0000000E, 0x00030037, 0x0000000D, +0x0000000F, 0x000200F8, 0x00000011, 0x0004003D, 0x0000000C, 0x000000E1, 0x0000000F, 0x0007000C, +0x0000000C, 0x000000E4, 0x00000001, 0x0000001A, 0x000000E1, 0x000000E3, 0x000200FE, 0x000000E4, +0x00010038, 0x00050036, 0x00000012, 0x00000016, 0x00000000, 0x00000014, 0x00030037, 0x00000013, +0x00000015, 0x000200F8, 0x00000017, 0x0004003B, 0x0000000D, 0x000000E7, 0x00000007, 0x0004003D, +0x00000012, 0x000000E8, 0x00000015, 0x0008004F, 0x0000000C, 0x000000E9, 0x000000E8, 0x000000E8, +0x00000000, 0x00000001, 0x00000002, 0x0003003E, 0x000000E7, 0x000000E9, 0x00050039, 0x0000000C, +0x000000EA, 0x00000010, 0x000000E7, 0x00050041, 0x00000007, 0x000000ED, 0x00000015, 0x000000EC, +0x0004003D, 0x00000006, 0x000000EE, 0x000000ED, 0x00050051, 0x00000006, 0x000000EF, 0x000000EA, +0x00000000, 0x00050051, 0x00000006, 0x000000F0, 0x000000EA, 0x00000001, 0x00050051, 0x00000006, +0x000000F1, 0x000000EA, 0x00000002, 0x00070050, 0x00000012, 0x000000F2, 0x000000EF, 0x000000F0, +0x000000F1, 0x000000EE, 0x000200FE, 0x000000F2, 0x00010038, 0x00050036, 0x00000006, 0x00000019, +0x00000000, 0x00000008, 0x00030037, 0x00000007, 0x00000018, 0x000200F8, 0x0000001A, 0x0004003D, +0x00000006, 0x000000F5, 0x00000018, 0x0008000C, 0x00000006, 0x000000F7, 0x00000001, 0x0000002B, +0x000000F5, 0x000000F6, 0x000000D3, 0x000200FE, 0x000000F7, 0x00010038, 0x00050036, 0x00000006, +0x00000020, 0x00000000, 0x0000001B, 0x00030037, 0x00000007, 0x0000001C, 0x00030037, 0x00000007, +0x0000001D, 0x00030037, 0x0000000C, 0x0000001E, 0x00030037, 0x0000000C, 0x0000001F, 0x000200F8, +0x00000021, 0x0004003B, 0x0000000D, 0x000000FA, 0x00000007, 0x0004003B, 0x00000007, 0x000000FC, +0x00000007, 0x0004003B, 0x00000007, 0x00000100, 0x00000007, 0x0004003B, 0x00000007, 0x0000010A, +0x00000007, 0x0007000C, 0x0000000C, 0x000000FB, 0x00000001, 0x00000044, 0x0000001E, 0x0000001F, +0x0003003E, 0x000000FA, 0x000000FB, 0x0004003D, 0x00000006, 0x000000FD, 0x0000001D, 0x0004003D, +0x00000006, 0x000000FE, 0x0000001C, 0x00050085, 0x00000006, 0x000000FF, 0x000000FD, 0x000000FE, +0x0003003E, 0x000000FC, 0x000000FF, 0x0004003D, 0x00000006, 0x00000101, 0x0000001C, 0x0004003D, +0x0000000C, 0x00000102, 0x000000FA, 0x0004003D, 0x0000000C, 0x00000103, 0x000000FA, 0x00050094, +0x00000006, 0x00000104, 0x00000102, 0x00000103, 0x0004003D, 0x00000006, 0x00000105, 0x000000FC, +0x0004003D, 0x00000006, 0x00000106, 0x000000FC, 0x00050085, 0x00000006, 0x00000107, 0x00000105, +0x00000106, 0x00050081, 0x00000006, 0x00000108, 0x00000104, 0x00000107, 0x00050088, 0x00000006, +0x00000109, 0x00000101, 0x00000108, 0x0003003E, 0x00000100, 0x00000109, 0x0004003D, 0x00000006, +0x0000010B, 0x00000100, 0x0004003D, 0x00000006, 0x0000010C, 0x00000100, 0x00050085, 0x00000006, +0x0000010D, 0x0000010B, 0x0000010C, 0x00050085, 0x00000006, 0x0000010F, 0x0000010D, 0x0000010E, +0x0003003E, 0x0000010A, 0x0000010F, 0x0004003D, 0x00000006, 0x00000110, 0x0000010A, 0x0007000C, +0x00000006, 0x00000112, 0x00000001, 0x00000025, 0x00000110, 0x00000111, 0x000200FE, 0x00000112, +0x00010038, 0x00050036, 0x0000000C, 0x00000026, 0x00000000, 0x00000022, 0x00030037, 0x0000000C, +0x00000023, 0x00030037, 0x00000007, 0x00000024, 0x00030037, 0x00000007, 0x00000025, 0x000200F8, +0x00000027, 0x0004003B, 0x00000007, 0x0000011A, 0x00000007, 0x0004003D, 0x00000006, 0x00000115, +0x00000024, 0x00060050, 0x0000000C, 0x00000116, 0x00000115, 0x00000115, 0x00000115, 0x00050083, +0x0000000C, 0x00000117, 0x00000116, 0x00000023, 0x0004003D, 0x00000006, 0x00000118, 0x00000025, +0x00050083, 0x00000006, 0x00000119, 0x000000D3, 0x00000118, 0x0003003E, 0x0000011A, 0x00000119, +0x00050039, 0x00000006, 0x0000011B, 0x0000000A, 0x0000011A, 0x0005008E, 0x0000000C, 0x0000011C, +0x00000117, 0x0000011B, 0x00050081, 0x0000000C, 0x0000011D, 0x00000023, 0x0000011C, 0x000200FE, +0x0000011D, 0x00010038, 0x00050036, 0x00000006, 0x0000002C, 0x00000000, 0x00000028, 0x00030037, +0x00000007, 0x00000029, 0x00030037, 0x00000007, 0x0000002A, 0x00030037, 0x00000007, 0x0000002B, +0x000200F8, 0x0000002D, 0x0004003D, 0x00000006, 0x00000120, 0x0000002A, 0x0004003D, 0x00000006, +0x00000121, 0x0000002B, 0x0004003D, 0x00000006, 0x00000122, 0x0000002A, 0x00050083, 0x00000006, +0x00000123, 0x00000121, 0x00000122, 0x0004003D, 0x00000006, 0x00000124, 0x00000029, 0x00050083, +0x00000006, 0x00000125, 0x000000D3, 0x00000124, 0x0007000C, 0x00000006, 0x00000127, 0x00000001, +0x0000001A, 0x00000125, 0x00000126, 0x00050085, 0x00000006, 0x00000128, 0x00000123, 0x00000127, +0x00050081, 0x00000006, 0x00000129, 0x00000120, 0x00000128, 0x000200FE, 0x00000129, 0x00010038, +0x00050036, 0x00000006, 0x00000033, 0x00000000, 0x0000002E, 0x00030037, 0x00000007, 0x0000002F, +0x00030037, 0x00000007, 0x00000030, 0x00030037, 0x00000007, 0x00000031, 0x00030037, 0x00000007, +0x00000032, 0x000200F8, 0x00000034, 0x0004003B, 0x00000007, 0x0000012C, 0x00000007, 0x0004003B, +0x00000007, 0x00000136, 0x00000007, 0x0004003B, 0x00000007, 0x00000137, 0x00000007, 0x0004003B, +0x00000007, 0x00000138, 0x00000007, 0x0004003B, 0x00000007, 0x0000013A, 0x00000007, 0x0004003B, +0x00000007, 0x0000013D, 0x00000007, 0x0004003B, 0x00000007, 0x0000013E, 0x00000007, 0x0004003B, +0x00000007, 0x0000013F, 0x00000007, 0x0004003B, 0x00000007, 0x00000141, 0x00000007, 0x0004003D, +0x00000006, 0x0000012F, 0x0000002F, 0x00050085, 0x00000006, 0x00000130, 0x0000012E, 0x0000012F, +0x0004003D, 0x00000006, 0x00000131, 0x00000032, 0x00050085, 0x00000006, 0x00000132, 0x00000130, +0x00000131, 0x0004003D, 0x00000006, 0x00000133, 0x00000032, 0x00050085, 0x00000006, 0x00000134, +0x00000132, 0x00000133, 0x00050081, 0x00000006, 0x00000135, 0x0000012D, 0x00000134, 0x0003003E, +0x0000012C, 0x00000135, 0x0003003E, 0x00000137, 0x000000D3, 0x0004003D, 0x00000006, 0x00000139, +0x0000012C, 0x0003003E, 0x00000138, 0x00000139, 0x0004003D, 0x00000006, 0x0000013B, 0x00000031, +0x0003003E, 0x0000013A, 0x0000013B, 0x00070039, 0x00000006, 0x0000013C, 0x0000002C, 0x00000137, +0x00000138, 0x0000013A, 0x0003003E, 0x00000136, 0x0000013C, 0x0003003E, 0x0000013E, 0x000000D3, +0x0004003D, 0x00000006, 0x00000140, 0x0000012C, 0x0003003E, 0x0000013F, 0x00000140, 0x0004003D, +0x00000006, 0x00000142, 0x00000030, 0x0003003E, 0x00000141, 0x00000142, 0x00070039, 0x00000006, +0x00000143, 0x0000002C, 0x0000013E, 0x0000013F, 0x00000141, 0x0003003E, 0x0000013D, 0x00000143, +0x0004003D, 0x00000006, 0x00000144, 0x00000136, 0x0004003D, 0x00000006, 0x00000145, 0x0000013D, +0x00050085, 0x00000006, 0x00000146, 0x00000144, 0x00000145, 0x00050085, 0x00000006, 0x00000147, +0x00000146, 0x0000010E, 0x000200FE, 0x00000147, 0x00010038, 0x00050036, 0x00000006, 0x00000038, +0x00000000, 0x00000028, 0x00030037, 0x00000007, 0x00000035, 0x00030037, 0x00000007, 0x00000036, +0x00030037, 0x00000007, 0x00000037, 0x000200F8, 0x00000039, 0x0004003B, 0x00000007, 0x0000014A, +0x00000007, 0x0004003B, 0x00000007, 0x0000014E, 0x00000007, 0x0004003B, 0x00000007, 0x0000015C, +0x00000007, 0x0004003D, 0x00000006, 0x0000014B, 0x00000037, 0x0004003D, 0x00000006, 0x0000014C, +0x00000037, 0x00050085, 0x00000006, 0x0000014D, 0x0000014B, 0x0000014C, 0x0003003E, 0x0000014A, +0x0000014D, 0x0004003D, 0x00000006, 0x0000014F, 0x00000035, 0x0004003D, 0x00000006, 0x00000150, +0x00000036, 0x0004007F, 0x00000006, 0x00000151, 0x00000150, 0x0004003D, 0x00000006, 0x00000152, +0x0000014A, 0x00050085, 0x00000006, 0x00000153, 0x00000151, 0x00000152, 0x0004003D, 0x00000006, +0x00000154, 0x00000036, 0x00050081, 0x00000006, 0x00000155, 0x00000153, 0x00000154, 0x0004003D, +0x00000006, 0x00000156, 0x00000036, 0x00050085, 0x00000006, 0x00000157, 0x00000155, 0x00000156, +0x0004003D, 0x00000006, 0x00000158, 0x0000014A, 0x00050081, 0x00000006, 0x00000159, 0x00000157, +0x00000158, 0x0006000C, 0x00000006, 0x0000015A, 0x00000001, 0x0000001F, 0x00000159, 0x00050085, +0x00000006, 0x0000015B, 0x0000014F, 0x0000015A, 0x0003003E, 0x0000014E, 0x0000015B, 0x0004003D, +0x00000006, 0x0000015D, 0x00000036, 0x0004003D, 0x00000006, 0x0000015E, 0x00000035, 0x0004007F, +0x00000006, 0x0000015F, 0x0000015E, 0x0004003D, 0x00000006, 0x00000160, 0x0000014A, 0x00050085, +0x00000006, 0x00000161, 0x0000015F, 0x00000160, 0x0004003D, 0x00000006, 0x00000162, 0x00000035, +0x00050081, 0x00000006, 0x00000163, 0x00000161, 0x00000162, 0x0004003D, 0x00000006, 0x00000164, +0x00000035, 0x00050085, 0x00000006, 0x00000165, 0x00000163, 0x00000164, 0x0004003D, 0x00000006, +0x00000166, 0x0000014A, 0x00050081, 0x00000006, 0x00000167, 0x00000165, 0x00000166, 0x0006000C, +0x00000006, 0x00000168, 0x00000001, 0x0000001F, 0x00000167, 0x00050085, 0x00000006, 0x00000169, +0x0000015D, 0x00000168, 0x0003003E, 0x0000015C, 0x00000169, 0x0004003D, 0x00000006, 0x0000016A, +0x0000015C, 0x0004003D, 0x00000006, 0x0000016B, 0x0000014E, 0x00050081, 0x00000006, 0x0000016C, +0x0000016A, 0x0000016B, 0x00050088, 0x00000006, 0x0000016D, 0x0000012D, 0x0000016C, 0x000200FE, +0x0000016D, 0x00010038, 0x00050036, 0x00000006, 0x0000003D, 0x00000000, 0x0000003A, 0x00030037, +0x00000007, 0x0000003B, 0x00030037, 0x00000007, 0x0000003C, 0x000200F8, 0x0000003E, 0x0004003B, +0x00000007, 0x00000170, 0x00000007, 0x0004003B, 0x00000007, 0x00000176, 0x00000007, 0x0004003B, +0x00000007, 0x0000017A, 0x00000007, 0x0004003D, 0x00000006, 0x00000171, 0x0000003C, 0x0007000C, +0x00000006, 0x00000173, 0x00000001, 0x00000025, 0x00000171, 0x00000172, 0x00050083, 0x00000006, +0x00000174, 0x000000D3, 0x00000173, 0x0006000C, 0x00000006, 0x00000175, 0x00000001, 0x00000020, +0x00000174, 0x0003003E, 0x00000170, 0x00000175, 0x0004003D, 0x00000006, 0x00000177, 0x0000003B, +0x0004003D, 0x00000006, 0x00000178, 0x00000170, 0x00050085, 0x00000006, 0x00000179, 0x00000177, +0x00000178, 0x0003003E, 0x0000017A, 0x00000179, 0x00050039, 0x00000006, 0x0000017B, 0x00000019, +0x0000017A, 0x0003003E, 0x00000176, 0x0000017B, 0x0004003D, 0x00000006, 0x0000017C, 0x00000176, +0x0004003D, 0x00000006, 0x0000017D, 0x00000176, 0x00050085, 0x00000006, 0x0000017E, 0x0000017C, +0x0000017D, 0x000200FE, 0x0000017E, 0x00010038, 0x00050036, 0x00000006, 0x00000043, 0x00000000, +0x0000002E, 0x00030037, 0x00000007, 0x0000003F, 0x00030037, 0x00000007, 0x00000040, 0x00030037, +0x00000007, 0x00000041, 0x00030037, 0x00000007, 0x00000042, 0x000200F8, 0x00000044, 0x0004003B, +0x00000007, 0x00000181, 0x00000007, 0x0004003B, 0x00000007, 0x00000183, 0x00000007, 0x0004003B, +0x00000007, 0x00000185, 0x00000007, 0x0004003B, 0x00000007, 0x00000187, 0x00000007, 0x0004003D, +0x00000006, 0x00000182, 0x0000003F, 0x0003003E, 0x00000181, 0x00000182, 0x0004003D, 0x00000006, +0x00000184, 0x00000040, 0x0003003E, 0x00000183, 0x00000184, 0x0004003D, 0x00000006, 0x00000186, +0x00000041, 0x0003003E, 0x00000185, 0x00000186, 0x0004003D, 0x00000006, 0x00000188, 0x00000042, +0x0003003E, 0x00000187, 0x00000188, 0x00080039, 0x00000006, 0x00000189, 0x00000033, 0x00000181, +0x00000183, 0x00000185, 0x00000187, 0x000200FE, 0x00000189, 0x00010038, 0x00050036, 0x00000006, +0x00000046, 0x00000000, 0x00000008, 0x00030037, 0x00000007, 0x00000045, 0x000200F8, 0x00000047, +0x0004003D, 0x00000006, 0x0000018C, 0x00000045, 0x0007000C, 0x00000006, 0x0000018E, 0x00000001, +0x00000028, 0x0000018C, 0x0000018D, 0x000200FE, 0x0000018E, 0x00010038, 0x00050036, 0x0000000C, +0x0000004B, 0x00000000, 0x00000048, 0x00030037, 0x00000012, 0x00000049, 0x00030037, 0x00000007, +0x0000004A, 0x000200F8, 0x0000004C, 0x0008004F, 0x0000000C, 0x00000191, 0x00000049, 0x00000049, +0x00000000, 0x00000001, 0x00000002, 0x0004003D, 0x00000006, 0x00000192, 0x0000004A, 0x00050083, +0x00000006, 0x00000193, 0x000000D3, 0x00000192, 0x0005008E, 0x0000000C, 0x00000194, 0x00000191, +0x00000193, 0x000200FE, 0x00000194, 0x00010038, 0x00050036, 0x0000000C, 0x00000051, 0x00000000, +0x0000004D, 0x00030037, 0x00000012, 0x0000004E, 0x00030037, 0x00000007, 0x0000004F, 0x00030037, +0x00000007, 0x00000050, 0x000200F8, 0x00000052, 0x0008004F, 0x0000000C, 0x00000197, 0x0000004E, +0x0000004E, 0x00000000, 0x00000001, 0x00000002, 0x0004003D, 0x00000006, 0x00000198, 0x0000004F, +0x0005008E, 0x0000000C, 0x00000199, 0x00000197, 0x00000198, 0x0004003D, 0x00000006, 0x0000019A, +0x00000050, 0x0004003D, 0x00000006, 0x0000019B, 0x0000004F, 0x00050083, 0x00000006, 0x0000019C, +0x000000D3, 0x0000019B, 0x00050085, 0x00000006, 0x0000019D, 0x0000019A, 0x0000019C, 0x00060050, +0x0000000C, 0x0000019E, 0x0000019D, 0x0000019D, 0x0000019D, 0x00050081, 0x0000000C, 0x0000019F, +0x00000199, 0x0000019E, 0x000200FE, 0x0000019F, 0x00010038, 0x00050036, 0x00000006, 0x00000054, +0x00000000, 0x00000008, 0x00030037, 0x00000007, 0x00000053, 0x000200F8, 0x00000055, 0x0004003D, +0x00000006, 0x000001A3, 0x00000053, 0x00050085, 0x00000006, 0x000001A4, 0x000001A2, 0x000001A3, +0x0004003D, 0x00000006, 0x000001A5, 0x00000053, 0x00050085, 0x00000006, 0x000001A6, 0x000001A4, +0x000001A5, 0x000200FE, 0x000001A6, 0x00010038, 0x00050036, 0x00000006, 0x00000057, 0x00000000, +0x00000008, 0x00030037, 0x00000007, 0x00000056, 0x000200F8, 0x00000058, 0x0004003D, 0x00000006, +0x000001A9, 0x00000056, 0x0004003D, 0x00000006, 0x000001AA, 0x00000056, 0x00050085, 0x00000006, +0x000001AB, 0x000001A9, 0x000001AA, 0x000200FE, 0x000001AB, 0x00010038, 0x00050036, 0x00000006, +0x0000005D, 0x00000000, 0x0000001B, 0x00030037, 0x00000007, 0x00000059, 0x00030037, 0x00000007, +0x0000005A, 0x00030037, 0x0000000C, 0x0000005B, 0x00030037, 0x0000000C, 0x0000005C, 0x000200F8, +0x0000005E, 0x0004003B, 0x00000007, 0x000001AE, 0x00000007, 0x0004003B, 0x00000007, 0x000001B0, +0x00000007, 0x0004003D, 0x00000006, 0x000001AF, 0x00000059, 0x0003003E, 0x000001AE, 0x000001AF, +0x0004003D, 0x00000006, 0x000001B1, 0x0000005A, 0x0003003E, 0x000001B0, 0x000001B1, 0x00080039, +0x00000006, 0x000001B2, 0x00000020, 0x000001AE, 0x000001B0, 0x0000005C, 0x0000005B, 0x000200FE, +0x000001B2, 0x00010038, 0x00050036, 0x00000006, 0x00000062, 0x00000000, 0x00000028, 0x00030037, +0x00000007, 0x0000005F, 0x00030037, 0x00000007, 0x00000060, 0x00030037, 0x00000007, 0x00000061, +0x000200F8, 0x00000063, 0x0004003B, 0x00000007, 0x000001B5, 0x00000007, 0x0004003B, 0x00000007, +0x000001B7, 0x00000007, 0x0004003B, 0x00000007, 0x000001B9, 0x00000007, 0x0004003D, 0x00000006, +0x000001B6, 0x0000005F, 0x0003003E, 0x000001B5, 0x000001B6, 0x0004003D, 0x00000006, 0x000001B8, +0x00000060, 0x0003003E, 0x000001B7, 0x000001B8, 0x0004003D, 0x00000006, 0x000001BA, 0x00000061, +0x0003003E, 0x000001B9, 0x000001BA, 0x00070039, 0x00000006, 0x000001BB, 0x00000038, 0x000001B5, +0x000001B7, 0x000001B9, 0x000200FE, 0x000001BB, 0x00010038, 0x00050036, 0x0000000C, 0x00000067, +0x00000000, 0x00000064, 0x00030037, 0x0000000C, 0x00000065, 0x00030037, 0x00000007, 0x00000066, +0x000200F8, 0x00000068, 0x0004003B, 0x00000007, 0x000001BE, 0x00000007, 0x0004003B, 0x00000007, +0x000001C2, 0x00000007, 0x0004003B, 0x00000007, 0x000001C4, 0x00000007, 0x0004003B, 0x00000007, +0x000001C6, 0x00000007, 0x00050094, 0x00000006, 0x000001C1, 0x00000065, 0x000001C0, 0x0003003E, +0x000001C2, 0x000001C1, 0x00050039, 0x00000006, 0x000001C3, 0x00000019, 0x000001C2, 0x0003003E, +0x000001BE, 0x000001C3, 0x0004003D, 0x00000006, 0x000001C5, 0x000001BE, 0x0003003E, 0x000001C4, +0x000001C5, 0x0004003D, 0x00000006, 0x000001C7, 0x00000066, 0x0003003E, 0x000001C6, 0x000001C7, +0x00070039, 0x0000000C, 0x000001C8, 0x00000026, 0x00000065, 0x000001C4, 0x000001C6, 0x000200FE, +0x000001C8, 0x00010038, 0x00050036, 0x0000000C, 0x0000006D, 0x00000000, 0x00000069, 0x00030037, +0x0000000D, 0x0000006A, 0x00030037, 0x00000007, 0x0000006B, 0x00030037, 0x00000007, 0x0000006C, +0x000200F8, 0x0000006E, 0x0004003D, 0x0000000C, 0x000001CB, 0x0000006A, 0x0004003D, 0x00000006, +0x000001CC, 0x0000006C, 0x00050083, 0x00000006, 0x000001CD, 0x000000D3, 0x000001CC, 0x00060050, +0x0000000C, 0x000001CE, 0x000001CD, 0x000001CD, 0x000001CD, 0x0004003D, 0x0000000C, 0x000001CF, +0x0000006A, 0x0007000C, 0x0000000C, 0x000001D0, 0x00000001, 0x00000028, 0x000001CE, 0x000001CF, +0x0004003D, 0x0000000C, 0x000001D1, 0x0000006A, 0x00050083, 0x0000000C, 0x000001D2, 0x000001D0, +0x000001D1, 0x0004003D, 0x00000006, 0x000001D3, 0x0000006B, 0x00050083, 0x00000006, 0x000001D4, +0x000000D3, 0x000001D3, 0x0007000C, 0x00000006, 0x000001D5, 0x00000001, 0x00000028, 0x000001D4, +0x000000F6, 0x0007000C, 0x00000006, 0x000001D6, 0x00000001, 0x0000001A, 0x000001D5, 0x00000126, +0x0005008E, 0x0000000C, 0x000001D7, 0x000001D2, 0x000001D6, 0x00050081, 0x0000000C, 0x000001D8, +0x000001CB, 0x000001D7, 0x000200FE, 0x000001D8, 0x00010038, 0x00050036, 0x00000012, 0x00000070, +0x00000000, 0x0000006F, 0x000200F8, 0x00000071, 0x0004003B, 0x00000013, 0x00000202, 0x00000007, +0x00050041, 0x000001DF, 0x000001E0, 0x000001DD, 0x000001DE, 0x0004003D, 0x00000006, 0x000001E1, +0x000001E0, 0x000500B8, 0x000001E3, 0x000001E4, 0x000001E1, 0x000001E2, 0x000300F7, 0x000001E6, +0x00000000, 0x000400FA, 0x000001E4, 0x000001E5, 0x000001E6, 0x000200F8, 0x000001E5, 0x00050041, +0x000001E8, 0x000001E9, 0x000001DD, 0x000001E7, 0x0004003D, 0x00000012, 0x000001EA, 0x000001E9, +0x000200FE, 0x000001EA, 0x000200F8, 0x000001E6, 0x00050041, 0x000001DF, 0x000001EC, 0x000001DD, +0x000001DE, 0x0004003D, 0x00000006, 0x000001ED, 0x000001EC, 0x00050083, 0x00000006, 0x000001EE, +0x000000D3, 0x000001ED, 0x00050041, 0x000001E8, 0x000001EF, 0x000001DD, 0x000001E7, 0x0004003D, +0x00000012, 0x000001F0, 0x000001EF, 0x0005008E, 0x00000012, 0x000001F1, 0x000001F0, 0x000001EE, +0x00050041, 0x000001DF, 0x000001F2, 0x000001DD, 0x000001DE, 0x0004003D, 0x00000006, 0x000001F3, +0x000001F2, 0x0004003D, 0x000001F5, 0x000001F8, 0x000001F7, 0x00050041, 0x000001FE, 0x000001FF, +0x000001FC, 0x000001FD, 0x0004003D, 0x0000007D, 0x00000200, 0x000001FF, 0x00050057, 0x00000012, +0x00000201, 0x000001F8, 0x00000200, 0x0003003E, 0x00000202, 0x00000201, 0x00050039, 0x00000012, +0x00000203, 0x00000016, 0x00000202, 0x0005008E, 0x00000012, 0x00000204, 0x00000203, 0x000001F3, +0x00050081, 0x00000012, 0x00000205, 0x000001F1, 0x00000204, 0x000200FE, 0x00000205, 0x00010038, +0x00050036, 0x0000000C, 0x00000073, 0x00000000, 0x00000072, 0x000200F8, 0x00000074, 0x00050041, +0x000001DF, 0x00000209, 0x000001DD, 0x00000208, 0x0004003D, 0x00000006, 0x0000020A, 0x00000209, +0x000500B8, 0x000001E3, 0x0000020B, 0x0000020A, 0x000001E2, 0x000300F7, 0x0000020D, 0x00000000, +0x000400FA, 0x0000020B, 0x0000020C, 0x0000020D, 0x000200F8, 0x0000020C, 0x00050041, 0x000001DF, +0x0000020F, 0x000001DD, 0x0000020E, 0x0004003D, 0x00000006, 0x00000210, 0x0000020F, 0x00060050, +0x0000000C, 0x00000211, 0x00000210, 0x00000210, 0x00000210, 0x000200FE, 0x00000211, 0x000200F8, +0x0000020D, 0x00050041, 0x000001DF, 0x00000213, 0x000001DD, 0x00000208, 0x0004003D, 0x00000006, +0x00000214, 0x00000213, 0x00050083, 0x00000006, 0x00000215, 0x000000D3, 0x00000214, 0x00050041, +0x000001DF, 0x00000216, 0x000001DD, 0x0000020E, 0x0004003D, 0x00000006, 0x00000217, 0x00000216, +0x00050085, 0x00000006, 0x00000218, 0x00000215, 0x00000217, 0x00050041, 0x000001DF, 0x00000219, +0x000001DD, 0x00000208, 0x0004003D, 0x00000006, 0x0000021A, 0x00000219, 0x0004003D, 0x000001F5, +0x0000021C, 0x0000021B, 0x00050041, 0x000001FE, 0x0000021D, 0x000001FC, 0x000001FD, 0x0004003D, +0x0000007D, 0x0000021E, 0x0000021D, 0x00050057, 0x00000012, 0x0000021F, 0x0000021C, 0x0000021E, +0x0008004F, 0x0000000C, 0x00000220, 0x0000021F, 0x0000021F, 0x00000000, 0x00000001, 0x00000002, +0x0005008E, 0x0000000C, 0x00000221, 0x00000220, 0x0000021A, 0x00060050, 0x0000000C, 0x00000222, +0x00000218, 0x00000218, 0x00000218, 0x00050081, 0x0000000C, 0x00000223, 0x00000222, 0x00000221, +0x000200FE, 0x00000223, 0x00010038, 0x00050036, 0x00000006, 0x00000076, 0x00000000, 0x00000075, +0x000200F8, 0x00000077, 0x00050041, 0x000001DF, 0x00000227, 0x000001DD, 0x00000226, 0x0004003D, +0x00000006, 0x00000228, 0x00000227, 0x000500B8, 0x000001E3, 0x00000229, 0x00000228, 0x000001E2, +0x000300F7, 0x0000022B, 0x00000000, 0x000400FA, 0x00000229, 0x0000022A, 0x0000022B, 0x000200F8, +0x0000022A, 0x00050041, 0x000001DF, 0x0000022C, 0x000001DD, 0x000001FD, 0x0004003D, 0x00000006, +0x0000022D, 0x0000022C, 0x000200FE, 0x0000022D, 0x000200F8, 0x0000022B, 0x00050041, 0x000001DF, +0x0000022F, 0x000001DD, 0x00000226, 0x0004003D, 0x00000006, 0x00000230, 0x0000022F, 0x00050083, +0x00000006, 0x00000231, 0x000000D3, 0x00000230, 0x00050041, 0x000001DF, 0x00000232, 0x000001DD, +0x000001FD, 0x0004003D, 0x00000006, 0x00000233, 0x00000232, 0x00050085, 0x00000006, 0x00000234, +0x00000231, 0x00000233, 0x00050041, 0x000001DF, 0x00000235, 0x000001DD, 0x00000226, 0x0004003D, +0x00000006, 0x00000236, 0x00000235, 0x0004003D, 0x000001F5, 0x00000238, 0x00000237, 0x00050041, +0x000001FE, 0x00000239, 0x000001FC, 0x000001FD, 0x0004003D, 0x0000007D, 0x0000023A, 0x00000239, +0x00050057, 0x00000012, 0x0000023B, 0x00000238, 0x0000023A, 0x00050051, 0x00000006, 0x0000023D, +0x0000023B, 0x00000000, 0x00050085, 0x00000006, 0x0000023E, 0x00000236, 0x0000023D, 0x00050081, +0x00000006, 0x0000023F, 0x00000234, 0x0000023E, 0x000200FE, 0x0000023F, 0x00010038, 0x00050036, +0x00000006, 0x00000078, 0x00000000, 0x00000075, 0x000200F8, 0x00000079, 0x00050041, 0x000001DF, +0x00000243, 0x000001DD, 0x00000242, 0x0004003D, 0x00000006, 0x00000244, 0x00000243, 0x000500B8, +0x000001E3, 0x00000245, 0x00000244, 0x000001E2, 0x000300F7, 0x00000247, 0x00000000, 0x000400FA, +0x00000245, 0x00000246, 0x00000247, 0x000200F8, 0x00000246, 0x000200FE, 0x000000D3, 0x000200F8, +0x00000247, 0x00050041, 0x000001DF, 0x00000249, 0x000001DD, 0x00000242, 0x0004003D, 0x00000006, +0x0000024A, 0x00000249, 0x00050083, 0x00000006, 0x0000024B, 0x000000D3, 0x0000024A, 0x00050041, +0x000001DF, 0x0000024C, 0x000001DD, 0x00000242, 0x0004003D, 0x00000006, 0x0000024D, 0x0000024C, +0x0004003D, 0x000001F5, 0x0000024F, 0x0000024E, 0x00050041, 0x000001FE, 0x00000250, 0x000001FC, +0x000001FD, 0x0004003D, 0x0000007D, 0x00000251, 0x00000250, 0x00050057, 0x00000012, 0x00000252, +0x0000024F, 0x00000251, 0x00050051, 0x00000006, 0x00000253, 0x00000252, 0x00000000, 0x00050085, +0x00000006, 0x00000254, 0x0000024D, 0x00000253, 0x00050081, 0x00000006, 0x00000255, 0x0000024B, +0x00000254, 0x000200FE, 0x00000255, 0x00010038, 0x00050036, 0x0000000C, 0x0000007B, 0x00000000, +0x0000000E, 0x00030037, 0x0000000D, 0x0000007A, 0x000200F8, 0x0000007C, 0x0004003B, 0x0000000D, +0x0000026F, 0x00000007, 0x00050041, 0x000001DF, 0x00000259, 0x000001DD, 0x00000258, 0x0004003D, +0x00000006, 0x0000025A, 0x00000259, 0x000500B8, 0x000001E3, 0x0000025B, 0x0000025A, 0x000001E2, +0x000300F7, 0x0000025D, 0x00000000, 0x000400FA, 0x0000025B, 0x0000025C, 0x0000025D, 0x000200F8, +0x0000025C, 0x00050041, 0x000001DF, 0x0000025F, 0x000001DD, 0x0000025E, 0x0004003D, 0x00000006, +0x00000260, 0x0000025F, 0x0004003D, 0x0000000C, 0x00000261, 0x0000007A, 0x0005008E, 0x0000000C, +0x00000262, 0x00000261, 0x00000260, 0x000200FE, 0x00000262, 0x000200F8, 0x0000025D, 0x00050041, +0x000001DF, 0x00000264, 0x000001DD, 0x0000025E, 0x0004003D, 0x00000006, 0x00000265, 0x00000264, +0x0004003D, 0x0000000C, 0x00000266, 0x0000007A, 0x0005008E, 0x0000000C, 0x00000267, 0x00000266, +0x00000265, 0x00050041, 0x000001DF, 0x00000268, 0x000001DD, 0x00000258, 0x0004003D, 0x00000006, +0x00000269, 0x00000268, 0x0004003D, 0x000001F5, 0x0000026B, 0x0000026A, 0x00050041, 0x000001FE, +0x0000026C, 0x000001FC, 0x000001FD, 0x0004003D, 0x0000007D, 0x0000026D, 0x0000026C, 0x00050057, +0x00000012, 0x0000026E, 0x0000026B, 0x0000026D, 0x0008004F, 0x0000000C, 0x00000270, 0x0000026E, +0x0000026E, 0x00000000, 0x00000001, 0x00000002, 0x0003003E, 0x0000026F, 0x00000270, 0x00050039, +0x0000000C, 0x00000271, 0x00000010, 0x0000026F, 0x0005008E, 0x0000000C, 0x00000272, 0x00000271, +0x00000269, 0x00050081, 0x0000000C, 0x00000273, 0x00000267, 0x00000272, 0x000200FE, 0x00000273, +0x00010038, 0x00050036, 0x00000006, 0x00000081, 0x00000000, 0x0000007F, 0x00030037, 0x0000007E, +0x00000080, 0x000200F8, 0x00000082, 0x0004003D, 0x0000007D, 0x00000276, 0x00000080, 0x00050094, +0x00000006, 0x0000027A, 0x00000276, 0x00000279, 0x0006000C, 0x00000006, 0x0000027B, 0x00000001, +0x0000000D, 0x0000027A, 0x00050085, 0x00000006, 0x0000027D, 0x0000027B, 0x0000027C, 0x0006000C, +0x00000006, 0x0000027E, 0x00000001, 0x0000000A, 0x0000027D, 0x000200FE, 0x0000027E, 0x00010038, +0x00050036, 0x0000007D, 0x00000089, 0x00000000, 0x00000085, 0x00030037, 0x00000084, 0x00000086, +0x00030037, 0x00000084, 0x00000087, 0x00030037, 0x00000007, 0x00000088, 0x000200F8, 0x0000008A, +0x0004003B, 0x00000007, 0x00000281, 0x00000007, 0x0004003B, 0x00000007, 0x00000283, 0x00000007, +0x0004003B, 0x00000007, 0x0000028C, 0x00000007, 0x0004003B, 0x00000007, 0x00000293, 0x00000007, +0x0004003B, 0x00000007, 0x00000296, 0x00000007, 0x0003003E, 0x00000281, 0x00000282, 0x0004003D, +0x00000083, 0x00000284, 0x00000086, 0x0004006F, 0x00000006, 0x00000285, 0x00000284, 0x00050081, +0x00000006, 0x00000286, 0x00000285, 0x0000012D, 0x0006000C, 0x00000006, 0x00000287, 0x00000001, +0x0000001F, 0x00000286, 0x0004003D, 0x00000083, 0x00000288, 0x00000087, 0x0004006F, 0x00000006, +0x00000289, 0x00000288, 0x0006000C, 0x00000006, 0x0000028A, 0x00000001, 0x0000001F, 0x00000289, +0x00050088, 0x00000006, 0x0000028B, 0x00000287, 0x0000028A, 0x0003003E, 0x00000283, 0x0000028B, +0x0004003D, 0x00000083, 0x0000028D, 0x00000086, 0x0004006F, 0x00000006, 0x0000028E, 0x0000028D, +0x0004003D, 0x00000006, 0x0000028F, 0x00000281, 0x00050085, 0x00000006, 0x00000290, 0x0000028E, +0x0000028F, 0x0004003D, 0x00000006, 0x00000291, 0x00000088, 0x00050081, 0x00000006, 0x00000292, +0x00000290, 0x00000291, 0x0003003E, 0x0000028C, 0x00000292, 0x0004003D, 0x00000006, 0x00000294, +0x0000028C, 0x0006000C, 0x00000006, 0x00000295, 0x00000001, 0x0000000D, 0x00000294, 0x0003003E, +0x00000293, 0x00000295, 0x0004003D, 0x00000006, 0x00000297, 0x0000028C, 0x0006000C, 0x00000006, +0x00000298, 0x00000001, 0x0000000E, 0x00000297, 0x0003003E, 0x00000296, 0x00000298, 0x0004003D, +0x00000006, 0x00000299, 0x00000283, 0x0004003D, 0x00000006, 0x0000029A, 0x00000296, 0x00050085, +0x00000006, 0x0000029B, 0x00000299, 0x0000029A, 0x0004003D, 0x00000006, 0x0000029C, 0x00000283, +0x0004003D, 0x00000006, 0x0000029D, 0x00000293, 0x00050085, 0x00000006, 0x0000029E, 0x0000029C, +0x0000029D, 0x00050050, 0x0000007D, 0x0000029F, 0x0000029B, 0x0000029E, 0x000200FE, 0x0000029F, +0x00010038, 0x00050036, 0x00000006, 0x0000008F, 0x00000000, 0x0000008B, 0x00030037, 0x0000000D, +0x0000008C, 0x00030037, 0x0000000D, 0x0000008D, 0x00030037, 0x00000084, 0x0000008E, 0x000200F8, +0x00000090, 0x0004003B, 0x00000007, 0x000002A2, 0x00000007, 0x0004003B, 0x00000007, 0x000002B0, +0x00000007, 0x00050041, 0x000001DF, 0x000002AE, 0x000002AC, 0x000002AD, 0x0004003D, 0x00000006, +0x000002AF, 0x000002AE, 0x0003003E, 0x000002A2, 0x000002AF, 0x0004003D, 0x00000006, 0x000002B1, +0x000002A2, 0x0004003D, 0x0000000C, 0x000002B2, 0x0000008D, 0x0004003D, 0x0000000C, 0x000002B3, +0x0000008C, 0x00050094, 0x00000006, 0x000002B4, 0x000002B2, 0x000002B3, 0x00050083, 0x00000006, +0x000002B5, 0x000000D3, 0x000002B4, 0x00050085, 0x00000006, 0x000002B6, 0x000002B1, 0x000002B5, +0x0004003D, 0x00000006, 0x000002B7, 0x000002A2, 0x0007000C, 0x00000006, 0x000002B8, 0x00000001, +0x00000028, 0x000002B6, 0x000002B7, 0x0003003E, 0x000002B0, 0x000002B8, 0x0004003D, 0x00000006, +0x000002B9, 0x000002B0, 0x000200FE, 0x000002B9, 0x00010038, 0x00050036, 0x00000006, 0x0000009C, +0x00000000, 0x00000094, 0x00030037, 0x00000093, 0x00000095, 0x00030037, 0x00000013, 0x00000096, +0x00030037, 0x00000007, 0x00000097, 0x00030037, 0x0000000D, 0x00000098, 0x00030037, 0x0000000D, +0x00000099, 0x00030037, 0x0000000D, 0x0000009A, 0x00030037, 0x00000084, 0x0000009B, 0x000200F8, +0x0000009D, 0x0004003B, 0x00000007, 0x000002BC, 0x00000007, 0x0004003B, 0x0000000D, 0x000002BD, +0x00000007, 0x0004003B, 0x0000000D, 0x000002BF, 0x00000007, 0x0004003B, 0x00000084, 0x000002C1, +0x00000007, 0x0004003B, 0x00000007, 0x000002C4, 0x00000007, 0x0004003B, 0x00000007, 0x000002C5, +0x00000007, 0x0004003B, 0x0000007E, 0x000002C6, 0x00000007, 0x0004003B, 0x00000084, 0x000002CA, +0x00000007, 0x0004003B, 0x0000007E, 0x000002D3, 0x00000007, 0x0004003B, 0x00000084, 0x000002D4, +0x00000007, 0x0004003B, 0x00000084, 0x000002D6, 0x00000007, 0x0004003B, 0x00000007, 0x000002D7, +0x00000007, 0x0004003B, 0x00000007, 0x000002DD, 0x00000007, 0x0004003D, 0x0000000C, 0x000002BE, +0x00000098, 0x0003003E, 0x000002BD, 0x000002BE, 0x0004003D, 0x0000000C, 0x000002C0, 0x00000099, +0x0003003E, 0x000002BF, 0x000002C0, 0x0004003D, 0x00000083, 0x000002C2, 0x0000009B, 0x0003003E, +0x000002C1, 0x000002C2, 0x00070039, 0x00000006, 0x000002C3, 0x0000008F, 0x000002BD, 0x000002BF, +0x000002C1, 0x0003003E, 0x000002BC, 0x000002C3, 0x0003003E, 0x000002C4, 0x000000F6, 0x0004003D, +0x0000000C, 0x000002C7, 0x0000009A, 0x0007004F, 0x0000007D, 0x000002C8, 0x000002C7, 0x000002C7, +0x00000000, 0x00000001, 0x0003003E, 0x000002C6, 0x000002C8, 0x00050039, 0x00000006, 0x000002C9, +0x00000081, 0x000002C6, 0x0003003E, 0x000002C5, 0x000002C9, 0x0003003E, 0x000002CA, 0x000001E7, +0x000200F9, 0x000002CB, 0x000200F8, 0x000002CB, 0x000400F6, 0x000002CD, 0x000002CE, 0x00000000, +0x000200F9, 0x000002CF, 0x000200F8, 0x000002CF, 0x0004003D, 0x00000083, 0x000002D0, 0x000002CA, +0x000500B1, 0x000001E3, 0x000002D2, 0x000002D0, 0x000002D1, 0x000400FA, 0x000002D2, 0x000002CC, +0x000002CD, 0x000200F8, 0x000002CC, 0x0004003D, 0x00000083, 0x000002D5, 0x000002CA, 0x0003003E, +0x000002D4, 0x000002D5, 0x0003003E, 0x000002D6, 0x000002D1, 0x0004003D, 0x00000006, 0x000002D8, +0x000002C5, 0x0003003E, 0x000002D7, 0x000002D8, 0x00070039, 0x0000007D, 0x000002D9, 0x00000089, +0x000002D4, 0x000002D6, 0x000002D7, 0x00050050, 0x0000007D, 0x000002DB, 0x000002DA, 0x000002DA, +0x00050088, 0x0000007D, 0x000002DC, 0x000002D9, 0x000002DB, 0x0003003E, 0x000002D3, 0x000002DC, +0x0004003D, 0x00000092, 0x000002DE, 0x00000095, 0x0004003D, 0x00000012, 0x000002DF, 0x00000096, +0x0007004F, 0x0000007D, 0x000002E0, 0x000002DF, 0x000002DF, 0x00000000, 0x00000001, 0x0004003D, +0x0000007D, 0x000002E1, 0x000002D3, 0x00050081, 0x0000007D, 0x000002E2, 0x000002E0, 0x000002E1, +0x0004003D, 0x00000083, 0x000002E3, 0x0000009B, 0x0004006F, 0x00000006, 0x000002E4, 0x000002E3, +0x00050051, 0x00000006, 0x000002E5, 0x000002E2, 0x00000000, 0x00050051, 0x00000006, 0x000002E6, +0x000002E2, 0x00000001, 0x00060050, 0x0000000C, 0x000002E7, 0x000002E5, 0x000002E6, 0x000002E4, +0x00050057, 0x00000012, 0x000002E8, 0x000002DE, 0x000002E7, 0x00050051, 0x00000006, 0x000002E9, +0x000002E8, 0x00000000, 0x0003003E, 0x000002DD, 0x000002E9, 0x00050041, 0x00000007, 0x000002EB, +0x00000096, 0x000002EA, 0x0004003D, 0x00000006, 0x000002EC, 0x000002EB, 0x0004003D, 0x00000006, +0x000002ED, 0x000002BC, 0x00050083, 0x00000006, 0x000002EE, 0x000002EC, 0x000002ED, 0x0004003D, +0x00000006, 0x000002EF, 0x000002DD, 0x0007000C, 0x00000006, 0x000002F0, 0x00000001, 0x00000030, +0x000002EE, 0x000002EF, 0x0004003D, 0x00000006, 0x000002F1, 0x000002C4, 0x00050081, 0x00000006, +0x000002F2, 0x000002F1, 0x000002F0, 0x0003003E, 0x000002C4, 0x000002F2, 0x000200F9, 0x000002CE, +0x000200F8, 0x000002CE, 0x0004003D, 0x00000083, 0x000002F3, 0x000002CA, 0x00050080, 0x00000083, +0x000002F4, 0x000002F3, 0x000001FD, 0x0003003E, 0x000002CA, 0x000002F4, 0x000200F9, 0x000002CB, +0x000200F8, 0x000002CD, 0x0004003D, 0x00000006, 0x000002F5, 0x000002C4, 0x00050088, 0x00000006, +0x000002F7, 0x000002F5, 0x000002F6, 0x000200FE, 0x000002F7, 0x00010038, 0x00050036, 0x00000083, +0x000000A0, 0x00000000, 0x0000009E, 0x00030037, 0x0000000D, 0x0000009F, 0x000200F8, 0x000000A1, +0x0004003B, 0x00000084, 0x000002FA, 0x00000007, 0x0004003B, 0x00000013, 0x000002FB, 0x00000007, +0x0004003B, 0x00000084, 0x00000305, 0x00000007, 0x0003003E, 0x000002FA, 0x000001E7, 0x00050041, +0x000002FC, 0x000002FD, 0x000002AC, 0x0000020E, 0x0004003D, 0x000002A6, 0x000002FE, 0x000002FD, +0x0004003D, 0x0000000C, 0x000002FF, 0x0000009F, 0x00050051, 0x00000006, 0x00000300, 0x000002FF, +0x00000000, 0x00050051, 0x00000006, 0x00000301, 0x000002FF, 0x00000001, 0x00050051, 0x00000006, +0x00000302, 0x000002FF, 0x00000002, 0x00070050, 0x00000012, 0x00000303, 0x00000300, 0x00000301, +0x00000302, 0x000000D3, 0x00050091, 0x00000012, 0x00000304, 0x000002FE, 0x00000303, 0x0003003E, +0x000002FB, 0x00000304, 0x0003003E, 0x00000305, 0x000001E7, 0x000200F9, 0x00000306, 0x000200F8, +0x00000306, 0x000400F6, 0x00000308, 0x00000309, 0x00000000, 0x000200F9, 0x0000030A, 0x000200F8, +0x0000030A, 0x0004003D, 0x00000083, 0x0000030B, 0x00000305, 0x00050041, 0x0000030D, 0x0000030E, +0x000002AC, 0x0000030C, 0x0004003D, 0x00000083, 0x0000030F, 0x0000030E, 0x00050082, 0x00000083, +0x00000310, 0x0000030F, 0x000001FD, 0x000500B1, 0x000001E3, 0x00000311, 0x0000030B, 0x00000310, +0x000400FA, 0x00000311, 0x00000307, 0x00000308, 0x000200F8, 0x00000307, 0x00050041, 0x00000007, +0x00000312, 0x000002FB, 0x000002EA, 0x0004003D, 0x00000006, 0x00000313, 0x00000312, 0x0004003D, +0x00000083, 0x00000314, 0x00000305, 0x00070041, 0x000001DF, 0x00000315, 0x000002AC, 0x00000208, +0x00000314, 0x0000023C, 0x0004003D, 0x00000006, 0x00000316, 0x00000315, 0x000500B8, 0x000001E3, +0x00000317, 0x00000313, 0x00000316, 0x000300F7, 0x00000319, 0x00000000, 0x000400FA, 0x00000317, +0x00000318, 0x00000319, 0x000200F8, 0x00000318, 0x0004003D, 0x00000083, 0x0000031A, 0x00000305, +0x00050080, 0x00000083, 0x0000031B, 0x0000031A, 0x000001FD, 0x0003003E, 0x000002FA, 0x0000031B, +0x000200F9, 0x00000319, 0x000200F8, 0x00000319, 0x000200F9, 0x00000309, 0x000200F8, 0x00000309, +0x0004003D, 0x00000083, 0x0000031C, 0x00000305, 0x00050080, 0x00000083, 0x0000031D, 0x0000031C, +0x000001FD, 0x0003003E, 0x00000305, 0x0000031D, 0x000200F9, 0x00000306, 0x000200F8, 0x00000308, +0x0004003D, 0x00000083, 0x0000031E, 0x000002FA, 0x000200FE, 0x0000031E, 0x00010038, 0x00050036, +0x00000006, 0x000000A7, 0x00000000, 0x000000A2, 0x00030037, 0x0000000D, 0x000000A3, 0x00030037, +0x00000084, 0x000000A4, 0x00030037, 0x0000000D, 0x000000A5, 0x00030037, 0x0000000D, 0x000000A6, +0x000200F8, 0x000000A8, 0x0004003B, 0x00000013, 0x00000321, 0x00000007, 0x0004003B, 0x00000007, +0x00000333, 0x00000007, 0x0004003B, 0x00000007, 0x00000335, 0x00000007, 0x0004003B, 0x00000013, +0x00000340, 0x00000007, 0x0004003B, 0x00000007, 0x00000349, 0x00000007, 0x0004003B, 0x00000013, +0x0000034B, 0x00000007, 0x0004003B, 0x00000007, 0x0000034D, 0x00000007, 0x0004003B, 0x0000000D, +0x0000034F, 0x00000007, 0x0004003B, 0x0000000D, 0x00000351, 0x00000007, 0x0004003B, 0x0000000D, +0x00000353, 0x00000007, 0x0004003B, 0x00000084, 0x00000355, 0x00000007, 0x0004003B, 0x00000007, +0x00000358, 0x00000007, 0x0004003B, 0x00000084, 0x00000365, 0x00000007, 0x0004003B, 0x00000007, +0x0000037F, 0x00000007, 0x0004003B, 0x00000013, 0x00000380, 0x00000007, 0x0004003B, 0x00000007, +0x00000382, 0x00000007, 0x0004003B, 0x0000000D, 0x00000384, 0x00000007, 0x0004003B, 0x0000000D, +0x00000386, 0x00000007, 0x0004003B, 0x0000000D, 0x00000388, 0x00000007, 0x0004003B, 0x00000084, +0x0000038A, 0x00000007, 0x00050041, 0x000002FC, 0x00000322, 0x000002AC, 0x0000025E, 0x0004003D, +0x000002A6, 0x00000323, 0x00000322, 0x0004003D, 0x00000083, 0x00000324, 0x000000A4, 0x00060041, +0x000002FC, 0x00000325, 0x000002AC, 0x000001FD, 0x00000324, 0x0004003D, 0x000002A6, 0x00000326, +0x00000325, 0x00050092, 0x000002A6, 0x00000327, 0x00000323, 0x00000326, 0x0004003D, 0x0000000C, +0x00000328, 0x000000A3, 0x00050051, 0x00000006, 0x00000329, 0x00000328, 0x00000000, 0x00050051, +0x00000006, 0x0000032A, 0x00000328, 0x00000001, 0x00050051, 0x00000006, 0x0000032B, 0x00000328, +0x00000002, 0x00070050, 0x00000012, 0x0000032C, 0x00000329, 0x0000032A, 0x0000032B, 0x000000D3, +0x00050091, 0x00000012, 0x0000032D, 0x00000327, 0x0000032C, 0x0003003E, 0x00000321, 0x0000032D, +0x0004003D, 0x00000012, 0x0000032E, 0x00000321, 0x00050041, 0x00000007, 0x0000032F, 0x00000321, +0x000000EC, 0x0004003D, 0x00000006, 0x00000330, 0x0000032F, 0x00050088, 0x00000006, 0x00000331, +0x000000D3, 0x00000330, 0x0005008E, 0x00000012, 0x00000332, 0x0000032E, 0x00000331, 0x0003003E, +0x00000321, 0x00000332, 0x0003003E, 0x00000333, 0x00000334, 0x00050041, 0x000001DF, 0x00000336, +0x000002AC, 0x00000226, 0x0004003D, 0x00000006, 0x00000337, 0x00000336, 0x0004003D, 0x00000006, +0x00000338, 0x00000333, 0x00050085, 0x00000006, 0x00000339, 0x00000337, 0x00000338, 0x00050041, +0x00000007, 0x0000033A, 0x00000321, 0x000002EA, 0x0004003D, 0x00000006, 0x0000033B, 0x0000033A, +0x00050088, 0x00000006, 0x0000033C, 0x00000339, 0x0000033B, 0x0003003E, 0x00000335, 0x0000033C, +0x0004003D, 0x00000006, 0x0000033D, 0x00000335, 0x0007000C, 0x00000006, 0x0000033F, 0x00000001, +0x00000025, 0x0000033D, 0x0000033E, 0x0003003E, 0x00000335, 0x0000033F, 0x00050041, 0x000002FC, +0x00000341, 0x000002AC, 0x0000020E, 0x0004003D, 0x000002A6, 0x00000342, 0x00000341, 0x0004003D, +0x0000000C, 0x00000343, 0x000000A3, 0x00050051, 0x00000006, 0x00000344, 0x00000343, 0x00000000, +0x00050051, 0x00000006, 0x00000345, 0x00000343, 0x00000001, 0x00050051, 0x00000006, 0x00000346, +0x00000343, 0x00000002, 0x00070050, 0x00000012, 0x00000347, 0x00000344, 0x00000345, 0x00000346, +0x000000D3, 0x00050091, 0x00000012, 0x00000348, 0x00000342, 0x00000347, 0x0003003E, 0x00000340, +0x00000348, 0x0003003E, 0x00000349, 0x000000D3, 0x0004003D, 0x00000012, 0x0000034C, 0x00000321, +0x0003003E, 0x0000034B, 0x0000034C, 0x0004003D, 0x00000006, 0x0000034E, 0x00000335, 0x0003003E, +0x0000034D, 0x0000034E, 0x0004003D, 0x0000000C, 0x00000350, 0x000000A5, 0x0003003E, 0x0000034F, +0x00000350, 0x0004003D, 0x0000000C, 0x00000352, 0x000000A6, 0x0003003E, 0x00000351, 0x00000352, +0x0004003D, 0x0000000C, 0x00000354, 0x000000A3, 0x0003003E, 0x00000353, 0x00000354, 0x0004003D, +0x00000083, 0x00000356, 0x000000A4, 0x0003003E, 0x00000355, 0x00000356, 0x000B0039, 0x00000006, +0x00000357, 0x0000009C, 0x0000034A, 0x0000034B, 0x0000034D, 0x0000034F, 0x00000351, 0x00000353, +0x00000355, 0x0003003E, 0x00000349, 0x00000357, 0x0004003D, 0x00000083, 0x00000359, 0x000000A4, +0x00070041, 0x000001DF, 0x0000035A, 0x000002AC, 0x00000208, 0x00000359, 0x0000023C, 0x0004003D, +0x00000006, 0x0000035B, 0x0000035A, 0x00050041, 0x000001DF, 0x0000035C, 0x000002AC, 0x00000242, +0x0004003D, 0x00000006, 0x0000035D, 0x0000035C, 0x00050081, 0x00000006, 0x0000035E, 0x0000035B, +0x0000035D, 0x0004003D, 0x00000083, 0x0000035F, 0x000000A4, 0x00070041, 0x000001DF, 0x00000360, +0x000002AC, 0x00000208, 0x0000035F, 0x0000023C, 0x0004003D, 0x00000006, 0x00000361, 0x00000360, +0x00050041, 0x00000007, 0x00000362, 0x00000340, 0x000002EA, 0x0004003D, 0x00000006, 0x00000363, +0x00000362, 0x0008000C, 0x00000006, 0x00000364, 0x00000001, 0x00000031, 0x0000035E, 0x00000361, +0x00000363, 0x0003003E, 0x00000358, 0x00000364, 0x0004003D, 0x00000083, 0x00000366, 0x000000A4, +0x00050080, 0x00000083, 0x00000367, 0x00000366, 0x000001FD, 0x0003003E, 0x00000365, 0x00000367, +0x0004003D, 0x00000006, 0x00000368, 0x00000358, 0x000500BA, 0x000001E3, 0x00000369, 0x00000368, +0x000000F6, 0x000300F7, 0x0000036B, 0x00000000, 0x000400FA, 0x00000369, 0x0000036A, 0x0000036B, +0x000200F8, 0x0000036A, 0x0004003D, 0x00000083, 0x0000036C, 0x00000365, 0x00050041, 0x0000030D, +0x0000036D, 0x000002AC, 0x0000030C, 0x0004003D, 0x00000083, 0x0000036E, 0x0000036D, 0x000500B1, +0x000001E3, 0x0000036F, 0x0000036C, 0x0000036E, 0x000200F9, 0x0000036B, 0x000200F8, 0x0000036B, +0x000700F5, 0x000001E3, 0x00000370, 0x00000369, 0x000000A8, 0x0000036F, 0x0000036A, 0x000300F7, +0x00000372, 0x00000000, 0x000400FA, 0x00000370, 0x00000371, 0x00000372, 0x000200F8, 0x00000371, +0x00050041, 0x000002FC, 0x00000373, 0x000002AC, 0x0000025E, 0x0004003D, 0x000002A6, 0x00000374, +0x00000373, 0x0004003D, 0x00000083, 0x00000375, 0x00000365, 0x00060041, 0x000002FC, 0x00000376, +0x000002AC, 0x000001FD, 0x00000375, 0x0004003D, 0x000002A6, 0x00000377, 0x00000376, 0x00050092, +0x000002A6, 0x00000378, 0x00000374, 0x00000377, 0x0004003D, 0x0000000C, 0x00000379, 0x000000A3, +0x00050051, 0x00000006, 0x0000037A, 0x00000379, 0x00000000, 0x00050051, 0x00000006, 0x0000037B, +0x00000379, 0x00000001, 0x00050051, 0x00000006, 0x0000037C, 0x00000379, 0x00000002, 0x00070050, +0x00000012, 0x0000037D, 0x0000037A, 0x0000037B, 0x0000037C, 0x000000D3, 0x00050091, 0x00000012, +0x0000037E, 0x00000378, 0x0000037D, 0x0003003E, 0x00000321, 0x0000037E, 0x0004003D, 0x00000012, +0x00000381, 0x00000321, 0x0003003E, 0x00000380, 0x00000381, 0x0004003D, 0x00000006, 0x00000383, +0x00000335, 0x0003003E, 0x00000382, 0x00000383, 0x0004003D, 0x0000000C, 0x00000385, 0x000000A5, +0x0003003E, 0x00000384, 0x00000385, 0x0004003D, 0x0000000C, 0x00000387, 0x000000A6, 0x0003003E, +0x00000386, 0x00000387, 0x0004003D, 0x0000000C, 0x00000389, 0x000000A3, 0x0003003E, 0x00000388, +0x00000389, 0x0004003D, 0x00000083, 0x0000038B, 0x00000365, 0x0003003E, 0x0000038A, 0x0000038B, +0x000B0039, 0x00000006, 0x0000038C, 0x0000009C, 0x0000034A, 0x00000380, 0x00000382, 0x00000384, +0x00000386, 0x00000388, 0x0000038A, 0x0003003E, 0x0000037F, 0x0000038C, 0x0004003D, 0x00000006, +0x0000038D, 0x00000349, 0x0004003D, 0x00000006, 0x0000038E, 0x0000037F, 0x0004003D, 0x00000006, +0x0000038F, 0x00000358, 0x0008000C, 0x00000006, 0x00000390, 0x00000001, 0x0000002E, 0x0000038D, +0x0000038E, 0x0000038F, 0x0003003E, 0x00000349, 0x00000390, 0x000200F9, 0x00000372, 0x000200F8, +0x00000372, 0x0004003D, 0x00000006, 0x00000391, 0x00000349, 0x00050083, 0x00000006, 0x00000392, +0x000000D3, 0x00000391, 0x0004003D, 0x00000006, 0x00000393, 0x000000D2, 0x00050085, 0x00000006, +0x00000394, 0x00000392, 0x00000393, 0x00050083, 0x00000006, 0x00000395, 0x000000D3, 0x00000394, +0x000200FE, 0x00000395, 0x00010038, 0x00050036, 0x0000000C, 0x000000B3, 0x00000000, 0x000000AB, +0x00030037, 0x000000A9, 0x000000AC, 0x00030037, 0x000000AA, 0x000000AD, 0x00030037, 0x0000000C, +0x000000AE, 0x00030037, 0x00000007, 0x000000AF, 0x00030037, 0x00000007, 0x000000B0, 0x00030037, +0x00000007, 0x000000B1, 0x00030037, 0x00000007, 0x000000B2, 0x000200F8, 0x000000B4, 0x0004003B, +0x00000007, 0x00000398, 0x00000007, 0x0004003B, 0x00000007, 0x0000039A, 0x00000007, 0x0004003B, +0x00000007, 0x0000039C, 0x00000007, 0x0004003B, 0x00000007, 0x0000039F, 0x00000007, 0x0004003B, +0x00000007, 0x000003A0, 0x00000007, 0x0004003B, 0x00000007, 0x000003A2, 0x00000007, 0x0004003B, +0x00000007, 0x000003A4, 0x00000007, 0x0004003B, 0x0000000D, 0x000003A7, 0x00000007, 0x0004003B, +0x00000007, 0x000003A9, 0x00000007, 0x00050051, 0x0000000C, 0x00000399, 0x000000AC, 0x00000006, +0x00050051, 0x00000006, 0x0000039B, 0x000000AC, 0x00000002, 0x0003003E, 0x0000039A, 0x0000039B, +0x0004003D, 0x00000006, 0x0000039D, 0x000000B1, 0x0003003E, 0x0000039C, 0x0000039D, 0x00080039, +0x00000006, 0x0000039E, 0x0000005D, 0x0000039A, 0x0000039C, 0x00000399, 0x000000AE, 0x0003003E, +0x00000398, 0x0000039E, 0x00050051, 0x00000006, 0x000003A1, 0x000000AC, 0x00000002, 0x0003003E, +0x000003A0, 0x000003A1, 0x0004003D, 0x00000006, 0x000003A3, 0x000000AF, 0x0003003E, 0x000003A2, +0x000003A3, 0x0004003D, 0x00000006, 0x000003A5, 0x000000B0, 0x0003003E, 0x000003A4, 0x000003A5, +0x00070039, 0x00000006, 0x000003A6, 0x00000062, 0x000003A0, 0x000003A2, 0x000003A4, 0x0003003E, +0x0000039F, 0x000003A6, 0x00050051, 0x0000000C, 0x000003A8, 0x000000AC, 0x0000000A, 0x0004003D, +0x00000006, 0x000003AA, 0x000000B2, 0x0003003E, 0x000003A9, 0x000003AA, 0x00060039, 0x0000000C, +0x000003AB, 0x00000067, 0x000003A8, 0x000003A9, 0x0003003E, 0x000003A7, 0x000003AB, 0x0004003D, +0x00000006, 0x000003AC, 0x00000398, 0x0004003D, 0x00000006, 0x000003AD, 0x0000039F, 0x00050085, +0x00000006, 0x000003AE, 0x000003AC, 0x000003AD, 0x0004003D, 0x0000000C, 0x000003AF, 0x000003A7, +0x0005008E, 0x0000000C, 0x000003B0, 0x000003AF, 0x000003AE, 0x000200FE, 0x000003B0, 0x00010038, +0x00050036, 0x0000000C, 0x000000BA, 0x00000000, 0x000000B5, 0x00030037, 0x000000A9, 0x000000B6, +0x00030037, 0x00000007, 0x000000B7, 0x00030037, 0x00000007, 0x000000B8, 0x00030037, 0x00000007, +0x000000B9, 0x000200F8, 0x000000BB, 0x0004003B, 0x00000007, 0x000003B5, 0x00000007, 0x0004003B, +0x00000007, 0x000003B7, 0x00000007, 0x0004003B, 0x00000007, 0x000003B9, 0x00000007, 0x0004003B, +0x00000007, 0x000003BB, 0x00000007, 0x00050051, 0x00000012, 0x000003B3, 0x000000B6, 0x00000000, +0x0008004F, 0x0000000C, 0x000003B4, 0x000003B3, 0x000003B3, 0x00000000, 0x00000001, 0x00000002, +0x00050051, 0x00000006, 0x000003B6, 0x000000B6, 0x00000002, 0x0003003E, 0x000003B5, 0x000003B6, +0x0004003D, 0x00000006, 0x000003B8, 0x000000B7, 0x0003003E, 0x000003B7, 0x000003B8, 0x0004003D, +0x00000006, 0x000003BA, 0x000000B8, 0x0003003E, 0x000003B9, 0x000003BA, 0x0004003D, 0x00000006, +0x000003BC, 0x000000B9, 0x0003003E, 0x000003BB, 0x000003BC, 0x00080039, 0x00000006, 0x000003BD, +0x00000043, 0x000003B5, 0x000003B7, 0x000003B9, 0x000003BB, 0x0005008E, 0x0000000C, 0x000003BE, +0x000003B4, 0x000003BD, 0x000200FE, 0x000003BE, 0x00010038, 0x00050036, 0x0000000C, 0x000000C3, +0x00000000, 0x000000AB, 0x00030037, 0x000000A9, 0x000000BC, 0x00030037, 0x000000AA, 0x000000BD, +0x00030037, 0x0000000C, 0x000000BE, 0x00030037, 0x00000007, 0x000000BF, 0x00030037, 0x00000007, +0x000000C0, 0x00030037, 0x00000007, 0x000000C1, 0x00030037, 0x00000007, 0x000000C2, 0x000200F8, +0x000000C4, 0x0004003B, 0x00000007, 0x000003C1, 0x00000007, 0x0004003B, 0x00000007, 0x000003C3, +0x00000007, 0x0004003B, 0x00000007, 0x000003C5, 0x00000007, 0x0004003B, 0x00000007, 0x000003C7, +0x00000007, 0x0004003D, 0x00000006, 0x000003C2, 0x000000BF, 0x0003003E, 0x000003C1, 0x000003C2, +0x0004003D, 0x00000006, 0x000003C4, 0x000000C0, 0x0003003E, 0x000003C3, 0x000003C4, 0x0004003D, +0x00000006, 0x000003C6, 0x000000C1, 0x0003003E, 0x000003C5, 0x000003C6, 0x0004003D, 0x00000006, +0x000003C8, 0x000000C2, 0x0003003E, 0x000003C7, 0x000003C8, 0x000B0039, 0x0000000C, 0x000003C9, +0x000000B3, 0x000000BC, 0x000000BD, 0x000000BE, 0x000003C1, 0x000003C3, 0x000003C5, 0x000003C7, +0x000200FE, 0x000003C9, 0x00010038, 0x00050036, 0x0000000C, 0x000000CA, 0x00000000, 0x000000C6, +0x00030037, 0x0000000D, 0x000000C7, 0x00030037, 0x0000000D, 0x000000C8, 0x00030037, 0x000000C5, +0x000000C9, 0x000200F8, 0x000000CB, 0x0004003B, 0x0000000D, 0x000003CC, 0x00000007, 0x0004003B, +0x00000084, 0x000003CE, 0x00000007, 0x0004003B, 0x000003D9, 0x000003DA, 0x00000007, 0x0004003B, +0x00000007, 0x000003EE, 0x00000007, 0x0004003B, 0x0000000D, 0x000003F4, 0x00000007, 0x0004003B, +0x00000007, 0x000003FA, 0x00000007, 0x0004003B, 0x00000007, 0x000003FF, 0x00000007, 0x0004003B, +0x00000007, 0x00000406, 0x00000007, 0x0004003B, 0x0000000D, 0x0000041F, 0x00000007, 0x0004003B, +0x00000007, 0x00000425, 0x00000007, 0x0004003B, 0x00000007, 0x00000429, 0x00000007, 0x0004003B, +0x00000007, 0x0000042E, 0x00000007, 0x0004003B, 0x00000007, 0x00000434, 0x00000007, 0x0004003B, +0x00000007, 0x0000043A, 0x00000007, 0x0004003B, 0x00000084, 0x0000044B, 0x00000007, 0x0004003B, +0x0000000D, 0x0000044C, 0x00000007, 0x0004003B, 0x0000000D, 0x00000455, 0x00000007, 0x0004003B, +0x00000084, 0x00000457, 0x00000007, 0x0004003B, 0x0000000D, 0x00000459, 0x00000007, 0x0004003B, +0x0000000D, 0x0000045D, 0x00000007, 0x0004003B, 0x0000000D, 0x00000462, 0x00000007, 0x0004003B, +0x0000000D, 0x00000466, 0x00000007, 0x0004003B, 0x0000000D, 0x0000046D, 0x00000007, 0x0004003B, +0x00000007, 0x00000473, 0x00000007, 0x0004003B, 0x00000007, 0x00000478, 0x00000007, 0x0004003B, +0x0000000D, 0x0000047A, 0x00000007, 0x0004003B, 0x00000007, 0x00000480, 0x00000007, 0x0004003B, +0x00000007, 0x00000486, 0x00000007, 0x0004003B, 0x00000007, 0x00000488, 0x00000007, 0x0004003B, +0x00000007, 0x0000048A, 0x00000007, 0x0004003B, 0x00000007, 0x0000048B, 0x00000007, 0x0004003B, +0x00000007, 0x0000048E, 0x00000007, 0x0004003B, 0x00000007, 0x00000493, 0x00000007, 0x0004003B, +0x00000007, 0x00000495, 0x00000007, 0x0004003B, 0x00000007, 0x00000499, 0x00000007, 0x0004003B, +0x0000000D, 0x0000049B, 0x00000007, 0x0004003B, 0x00000007, 0x0000049D, 0x00000007, 0x0004003B, +0x00000007, 0x0000049F, 0x00000007, 0x0004003B, 0x00000007, 0x000004A1, 0x00000007, 0x0004003B, +0x0000000D, 0x000004A4, 0x00000007, 0x0004003B, 0x00000007, 0x000004A8, 0x00000007, 0x0004003B, +0x00000007, 0x000004AA, 0x00000007, 0x0004003B, 0x00000007, 0x000004AC, 0x00000007, 0x0004003B, +0x00000007, 0x000004AE, 0x00000007, 0x0004003B, 0x0000000D, 0x000004B1, 0x00000007, 0x0004003B, +0x00000007, 0x000004BB, 0x00000007, 0x0004003B, 0x00000007, 0x000004BD, 0x00000007, 0x0003003E, +0x000003CC, 0x000003CD, 0x0003003E, 0x000003CE, 0x000001E7, 0x000200F9, 0x000003CF, 0x000200F8, +0x000003CF, 0x000400F6, 0x000003D1, 0x000003D2, 0x00000000, 0x000200F9, 0x000003D3, 0x000200F8, +0x000003D3, 0x0004003D, 0x00000083, 0x000003D4, 0x000003CE, 0x00050041, 0x0000030D, 0x000003D6, +0x000002AC, 0x000003D5, 0x0004003D, 0x00000083, 0x000003D7, 0x000003D6, 0x000500B1, 0x000001E3, +0x000003D8, 0x000003D4, 0x000003D7, 0x000400FA, 0x000003D8, 0x000003D0, 0x000003D1, 0x000200F8, +0x000003D0, 0x0004003D, 0x00000083, 0x000003DB, 0x000003CE, 0x00060041, 0x000003DC, 0x000003DD, +0x000002AC, 0x000001E7, 0x000003DB, 0x0004003D, 0x000002A3, 0x000003DE, 0x000003DD, 0x00050051, +0x00000012, 0x000003DF, 0x000003DE, 0x00000000, 0x00050041, 0x00000013, 0x000003E0, 0x000003DA, +0x000001E7, 0x0003003E, 0x000003E0, 0x000003DF, 0x00050051, 0x00000012, 0x000003E1, 0x000003DE, +0x00000001, 0x00050041, 0x00000013, 0x000003E2, 0x000003DA, 0x000001FD, 0x0003003E, 0x000003E2, +0x000003E1, 0x00050051, 0x00000012, 0x000003E3, 0x000003DE, 0x00000002, 0x00050041, 0x00000013, +0x000003E4, 0x000003DA, 0x0000020E, 0x0003003E, 0x000003E4, 0x000003E3, 0x00050051, 0x00000006, +0x000003E5, 0x000003DE, 0x00000003, 0x00050041, 0x00000007, 0x000003E7, 0x000003DA, 0x000003E6, +0x0003003E, 0x000003E7, 0x000003E5, 0x00050051, 0x00000006, 0x000003E8, 0x000003DE, 0x00000004, +0x00050041, 0x00000007, 0x000003E9, 0x000003DA, 0x0000025E, 0x0003003E, 0x000003E9, 0x000003E8, +0x00050051, 0x00000006, 0x000003EA, 0x000003DE, 0x00000005, 0x00050041, 0x00000007, 0x000003EB, +0x000003DA, 0x000001DE, 0x0003003E, 0x000003EB, 0x000003EA, 0x00050051, 0x00000006, 0x000003EC, +0x000003DE, 0x00000006, 0x00050041, 0x00000007, 0x000003ED, 0x000003DA, 0x00000208, 0x0003003E, +0x000003ED, 0x000003EC, 0x0003003E, 0x000003EE, 0x000000F6, 0x00050041, 0x00000007, 0x000003EF, +0x000003DA, 0x000001DE, 0x0004003D, 0x00000006, 0x000003F0, 0x000003EF, 0x000500B4, 0x000001E3, +0x000003F1, 0x000003F0, 0x0000012E, 0x000300F7, 0x000003F3, 0x00000000, 0x000400FA, 0x000003F1, +0x000003F2, 0x00000419, 0x000200F8, 0x000003F2, 0x00050041, 0x00000013, 0x000003F5, 0x000003DA, +0x000001FD, 0x0004003D, 0x00000012, 0x000003F6, 0x000003F5, 0x0008004F, 0x0000000C, 0x000003F7, +0x000003F6, 0x000003F6, 0x00000000, 0x00000001, 0x00000002, 0x0004003D, 0x0000000C, 0x000003F8, +0x000000C8, 0x00050083, 0x0000000C, 0x000003F9, 0x000003F7, 0x000003F8, 0x0003003E, 0x000003F4, +0x000003F9, 0x0004003D, 0x0000000C, 0x000003FB, 0x000003F4, 0x0006000C, 0x00000006, 0x000003FC, +0x00000001, 0x00000042, 0x000003FB, 0x0003003E, 0x000003FA, 0x000003FC, 0x0004003D, 0x0000000C, +0x000003FD, 0x000003F4, 0x0006000C, 0x0000000C, 0x000003FE, 0x00000001, 0x00000045, 0x000003FD, +0x0003003E, 0x000003F4, 0x000003FE, 0x00050041, 0x00000007, 0x00000400, 0x000003DA, 0x0000025E, +0x0004003D, 0x00000006, 0x00000401, 0x00000400, 0x0004003D, 0x00000006, 0x00000402, 0x000003FA, +0x0007000C, 0x00000006, 0x00000403, 0x00000001, 0x0000001A, 0x00000402, 0x0000012E, 0x00050081, +0x00000006, 0x00000404, 0x00000403, 0x000000D3, 0x00050088, 0x00000006, 0x00000405, 0x00000401, +0x00000404, 0x0003003E, 0x000003FF, 0x00000405, 0x0004003D, 0x00000006, 0x00000407, 0x000003FA, +0x0004003D, 0x00000006, 0x00000408, 0x000003FA, 0x00050085, 0x00000006, 0x00000409, 0x00000407, +0x00000408, 0x00050041, 0x00000007, 0x0000040A, 0x000003DA, 0x0000025E, 0x0004003D, 0x00000006, +0x0000040B, 0x0000040A, 0x00050041, 0x00000007, 0x0000040C, 0x000003DA, 0x0000025E, 0x0004003D, +0x00000006, 0x0000040D, 0x0000040C, 0x00050085, 0x00000006, 0x0000040E, 0x0000040B, 0x0000040D, +0x00050088, 0x00000006, 0x0000040F, 0x00000409, 0x0000040E, 0x00050083, 0x00000006, 0x00000410, +0x000000D3, 0x0000040F, 0x0008000C, 0x00000006, 0x00000411, 0x00000001, 0x0000002B, 0x00000410, +0x000000F6, 0x000000D3, 0x0003003E, 0x00000406, 0x00000411, 0x0004003D, 0x00000006, 0x00000412, +0x00000406, 0x0003003E, 0x000003EE, 0x00000412, 0x0004003D, 0x0000000C, 0x00000413, 0x000003F4, +0x00050051, 0x00000006, 0x00000414, 0x00000413, 0x00000000, 0x00050051, 0x00000006, 0x00000415, +0x00000413, 0x00000001, 0x00050051, 0x00000006, 0x00000416, 0x00000413, 0x00000002, 0x00070050, +0x00000012, 0x00000417, 0x00000414, 0x00000415, 0x00000416, 0x000000D3, 0x00050041, 0x00000013, +0x00000418, 0x000003DA, 0x0000020E, 0x0003003E, 0x00000418, 0x00000417, 0x000200F9, 0x000003F3, +0x000200F8, 0x00000419, 0x00050041, 0x00000007, 0x0000041A, 0x000003DA, 0x000001DE, 0x0004003D, +0x00000006, 0x0000041B, 0x0000041A, 0x000500B4, 0x000001E3, 0x0000041C, 0x0000041B, 0x000000D3, +0x000300F7, 0x0000041E, 0x00000000, 0x000400FA, 0x0000041C, 0x0000041D, 0x0000044A, 0x000200F8, +0x0000041D, 0x00050041, 0x00000013, 0x00000420, 0x000003DA, 0x000001FD, 0x0004003D, 0x00000012, +0x00000421, 0x00000420, 0x0008004F, 0x0000000C, 0x00000422, 0x00000421, 0x00000421, 0x00000000, +0x00000001, 0x00000002, 0x0004003D, 0x0000000C, 0x00000423, 0x000000C8, 0x00050083, 0x0000000C, +0x00000424, 0x00000422, 0x00000423, 0x0003003E, 0x0000041F, 0x00000424, 0x00050041, 0x00000007, +0x00000426, 0x000003DA, 0x00000208, 0x0004003D, 0x00000006, 0x00000427, 0x00000426, 0x00050083, +0x00000006, 0x00000428, 0x000000D3, 0x00000427, 0x0003003E, 0x00000425, 0x00000428, 0x0004003D, +0x0000000C, 0x0000042A, 0x0000041F, 0x0006000C, 0x00000006, 0x0000042B, 0x00000001, 0x00000042, +0x0000042A, 0x0003003E, 0x00000429, 0x0000042B, 0x0004003D, 0x0000000C, 0x0000042C, 0x0000041F, +0x0006000C, 0x0000000C, 0x0000042D, 0x00000001, 0x00000045, 0x0000042C, 0x0003003E, 0x0000041F, +0x0000042D, 0x0004003D, 0x0000000C, 0x0000042F, 0x0000041F, 0x00050041, 0x00000013, 0x00000430, +0x000003DA, 0x0000020E, 0x0004003D, 0x00000012, 0x00000431, 0x00000430, 0x0008004F, 0x0000000C, +0x00000432, 0x00000431, 0x00000431, 0x00000000, 0x00000001, 0x00000002, 0x00050094, 0x00000006, +0x00000433, 0x0000042F, 0x00000432, 0x0003003E, 0x0000042E, 0x00000433, 0x0004003D, 0x00000006, +0x00000435, 0x00000425, 0x0004003D, 0x00000006, 0x00000436, 0x00000425, 0x00050085, 0x00000006, +0x00000438, 0x00000436, 0x00000437, 0x00050083, 0x00000006, 0x00000439, 0x00000435, 0x00000438, +0x0003003E, 0x00000434, 0x00000439, 0x0004003D, 0x00000006, 0x0000043B, 0x0000042E, 0x0004003D, +0x00000006, 0x0000043C, 0x00000425, 0x00050083, 0x00000006, 0x0000043D, 0x0000043B, 0x0000043C, +0x0004003D, 0x00000006, 0x0000043E, 0x00000434, 0x00050088, 0x00000006, 0x0000043F, 0x0000043D, +0x0000043E, 0x0003003E, 0x0000043A, 0x0000043F, 0x00050041, 0x00000007, 0x00000440, 0x000003DA, +0x0000025E, 0x0004003D, 0x00000006, 0x00000441, 0x00000440, 0x0004003D, 0x00000006, 0x00000442, +0x00000429, 0x0007000C, 0x00000006, 0x00000443, 0x00000001, 0x0000001A, 0x00000442, 0x0000012E, +0x00050081, 0x00000006, 0x00000444, 0x00000443, 0x000000D3, 0x00050088, 0x00000006, 0x00000445, +0x00000441, 0x00000444, 0x0004003D, 0x00000006, 0x00000446, 0x0000043A, 0x00050085, 0x00000006, +0x00000447, 0x00000446, 0x00000445, 0x0003003E, 0x0000043A, 0x00000447, 0x0004003D, 0x00000006, +0x00000448, 0x0000043A, 0x0008000C, 0x00000006, 0x00000449, 0x00000001, 0x0000002B, 0x00000448, +0x000000F6, 0x000000D3, 0x0003003E, 0x000003EE, 0x00000449, 0x000200F9, 0x0000041E, 0x000200F8, +0x0000044A, 0x0004003D, 0x0000000C, 0x0000044D, 0x000000C8, 0x0003003E, 0x0000044C, 0x0000044D, +0x00050039, 0x00000083, 0x0000044E, 0x000000A0, 0x0000044C, 0x0003003E, 0x0000044B, 0x0000044E, +0x00050041, 0x0000030D, 0x00000450, 0x000002AC, 0x0000044F, 0x0004003D, 0x00000083, 0x00000451, +0x00000450, 0x000500AD, 0x000001E3, 0x00000452, 0x00000451, 0x000001E7, 0x000300F7, 0x00000454, +0x00000000, 0x000400FA, 0x00000452, 0x00000453, 0x00000461, 0x000200F8, 0x00000453, 0x0004003D, +0x0000000C, 0x00000456, 0x000000C8, 0x0003003E, 0x00000455, 0x00000456, 0x0004003D, 0x00000083, +0x00000458, 0x0000044B, 0x0003003E, 0x00000457, 0x00000458, 0x00050041, 0x00000013, 0x0000045A, +0x000003DA, 0x0000020E, 0x0004003D, 0x00000012, 0x0000045B, 0x0000045A, 0x0008004F, 0x0000000C, +0x0000045C, 0x0000045B, 0x0000045B, 0x00000000, 0x00000001, 0x00000002, 0x0003003E, 0x00000459, +0x0000045C, 0x00050041, 0x0000000D, 0x0000045E, 0x000000C9, 0x00000208, 0x0004003D, 0x0000000C, +0x0000045F, 0x0000045E, 0x0003003E, 0x0000045D, 0x0000045F, 0x00080039, 0x00000006, 0x00000460, +0x000000A7, 0x00000455, 0x00000457, 0x00000459, 0x0000045D, 0x0003003E, 0x000003EE, 0x00000460, +0x000200F9, 0x00000454, 0x000200F8, 0x00000461, 0x0003003E, 0x000003EE, 0x000000D3, 0x000200F9, +0x00000454, 0x000200F8, 0x00000454, 0x000200F9, 0x0000041E, 0x000200F8, 0x0000041E, 0x000200F9, +0x000003F3, 0x000200F8, 0x000003F3, 0x00050041, 0x00000013, 0x00000463, 0x000003DA, 0x0000020E, +0x0004003D, 0x00000012, 0x00000464, 0x00000463, 0x0008004F, 0x0000000C, 0x00000465, 0x00000464, +0x00000464, 0x00000000, 0x00000001, 0x00000002, 0x0003003E, 0x00000462, 0x00000465, 0x00050041, +0x00000013, 0x00000467, 0x000003DA, 0x000001E7, 0x0004003D, 0x00000012, 0x00000468, 0x00000467, +0x0008004F, 0x0000000C, 0x00000469, 0x00000468, 0x00000468, 0x00000000, 0x00000001, 0x00000002, +0x00050041, 0x00000007, 0x0000046A, 0x000003DA, 0x000003E6, 0x0004003D, 0x00000006, 0x0000046B, +0x0000046A, 0x0005008E, 0x0000000C, 0x0000046C, 0x00000469, 0x0000046B, 0x0003003E, 0x00000466, +0x0000046C, 0x0004003D, 0x0000000C, 0x0000046E, 0x00000462, 0x00050041, 0x0000000D, 0x0000046F, +0x000000C9, 0x000002D1, 0x0004003D, 0x0000000C, 0x00000470, 0x0000046F, 0x00050081, 0x0000000C, +0x00000471, 0x0000046E, 0x00000470, 0x0006000C, 0x0000000C, 0x00000472, 0x00000001, 0x00000045, +0x00000471, 0x0003003E, 0x0000046D, 0x00000472, 0x00050041, 0x0000000D, 0x00000474, 0x000000C9, +0x00000208, 0x0004003D, 0x0000000C, 0x00000475, 0x00000474, 0x0004003D, 0x0000000C, 0x00000476, +0x00000462, 0x00050094, 0x00000006, 0x00000477, 0x00000475, 0x00000476, 0x0003003E, 0x00000478, +0x00000477, 0x00050039, 0x00000006, 0x00000479, 0x00000019, 0x00000478, 0x0003003E, 0x00000473, +0x00000479, 0x00050041, 0x0000000D, 0x0000047B, 0x000000C9, 0x000002D1, 0x0004003D, 0x0000000C, +0x0000047C, 0x0000047B, 0x0004003D, 0x0000000C, 0x0000047D, 0x00000462, 0x00050081, 0x0000000C, +0x0000047E, 0x0000047C, 0x0000047D, 0x0006000C, 0x0000000C, 0x0000047F, 0x00000001, 0x00000045, +0x0000047E, 0x0003003E, 0x0000047A, 0x0000047F, 0x00050041, 0x0000000D, 0x00000481, 0x000000C9, +0x00000208, 0x0004003D, 0x0000000C, 0x00000482, 0x00000481, 0x00050041, 0x0000000D, 0x00000483, +0x000000C9, 0x000002D1, 0x0004003D, 0x0000000C, 0x00000484, 0x00000483, 0x00050094, 0x00000006, +0x00000485, 0x00000482, 0x00000484, 0x0003003E, 0x00000486, 0x00000485, 0x00050039, 0x00000006, +0x00000487, 0x00000046, 0x00000486, 0x0003003E, 0x00000480, 0x00000487, 0x0004003D, 0x00000006, +0x00000489, 0x00000480, 0x0003003E, 0x00000488, 0x00000489, 0x0004003D, 0x00000006, 0x0000048C, +0x00000473, 0x0003003E, 0x0000048B, 0x0000048C, 0x00050039, 0x00000006, 0x0000048D, 0x00000019, +0x0000048B, 0x0003003E, 0x0000048A, 0x0000048D, 0x00050041, 0x0000000D, 0x0000048F, 0x000000C9, +0x00000208, 0x0004003D, 0x0000000C, 0x00000490, 0x0000048F, 0x0004003D, 0x0000000C, 0x00000491, +0x0000047A, 0x00050094, 0x00000006, 0x00000492, 0x00000490, 0x00000491, 0x0003003E, 0x00000493, +0x00000492, 0x00050039, 0x00000006, 0x00000494, 0x00000019, 0x00000493, 0x0003003E, 0x0000048E, +0x00000494, 0x0004003D, 0x0000000C, 0x00000496, 0x00000462, 0x0004003D, 0x0000000C, 0x00000497, +0x0000047A, 0x00050094, 0x00000006, 0x00000498, 0x00000496, 0x00000497, 0x0003003E, 0x00000499, +0x00000498, 0x00050039, 0x00000006, 0x0000049A, 0x00000019, 0x00000499, 0x0003003E, 0x00000495, +0x0000049A, 0x0004003D, 0x000000A9, 0x0000049C, 0x000000C9, 0x0004003D, 0x00000006, 0x0000049E, +0x00000488, 0x0003003E, 0x0000049D, 0x0000049E, 0x0004003D, 0x00000006, 0x000004A0, 0x0000048A, +0x0003003E, 0x0000049F, 0x000004A0, 0x0004003D, 0x00000006, 0x000004A2, 0x00000495, 0x0003003E, +0x000004A1, 0x000004A2, 0x00080039, 0x0000000C, 0x000004A3, 0x000000BA, 0x0000049C, 0x0000049D, +0x0000049F, 0x000004A1, 0x0003003E, 0x0000049B, 0x000004A3, 0x0004003D, 0x000000A9, 0x000004A5, +0x000000C9, 0x0004003D, 0x000000AA, 0x000004A6, 0x000003DA, 0x0004003D, 0x0000000C, 0x000004A7, +0x0000047A, 0x0004003D, 0x00000006, 0x000004A9, 0x00000488, 0x0003003E, 0x000004A8, 0x000004A9, +0x0004003D, 0x00000006, 0x000004AB, 0x0000048A, 0x0003003E, 0x000004AA, 0x000004AB, 0x0004003D, +0x00000006, 0x000004AD, 0x0000048E, 0x0003003E, 0x000004AC, 0x000004AD, 0x0004003D, 0x00000006, +0x000004AF, 0x00000495, 0x0003003E, 0x000004AE, 0x000004AF, 0x000B0039, 0x0000000C, 0x000004B0, +0x000000C3, 0x000004A5, 0x000004A6, 0x000004A7, 0x000004A8, 0x000004AA, 0x000004AC, 0x000004AE, +0x0003003E, 0x000004A4, 0x000004B0, 0x0004003D, 0x0000000C, 0x000004B2, 0x0000049B, 0x0004003D, +0x0000000C, 0x000004B3, 0x000004A4, 0x00050081, 0x0000000C, 0x000004B4, 0x000004B2, 0x000004B3, +0x0003003E, 0x000004B1, 0x000004B4, 0x0004003D, 0x0000000C, 0x000004B5, 0x000004B1, 0x0004003D, +0x0000000C, 0x000004B6, 0x00000466, 0x00050085, 0x0000000C, 0x000004B7, 0x000004B5, 0x000004B6, +0x0004003D, 0x00000006, 0x000004B8, 0x000003EE, 0x0004003D, 0x00000006, 0x000004B9, 0x0000048A, +0x00050085, 0x00000006, 0x000004BA, 0x000004B8, 0x000004B9, 0x0004003D, 0x00000006, 0x000004BC, +0x0000048A, 0x0003003E, 0x000004BB, 0x000004BC, 0x00050041, 0x00000007, 0x000004BE, 0x000000C9, +0x00000226, 0x0004003D, 0x00000006, 0x000004BF, 0x000004BE, 0x0003003E, 0x000004BD, 0x000004BF, +0x00060039, 0x00000006, 0x000004C0, 0x0000003D, 0x000004BB, 0x000004BD, 0x00050085, 0x00000006, +0x000004C1, 0x000004BA, 0x000004C0, 0x0005008E, 0x0000000C, 0x000004C2, 0x000004B7, 0x000004C1, +0x0004003D, 0x0000000C, 0x000004C3, 0x000003CC, 0x00050081, 0x0000000C, 0x000004C4, 0x000004C3, +0x000004C2, 0x0003003E, 0x000003CC, 0x000004C4, 0x000200F9, 0x000003D2, 0x000200F8, 0x000003D2, +0x0004003D, 0x00000083, 0x000004C5, 0x000003CE, 0x00050080, 0x00000083, 0x000004C6, 0x000004C5, +0x000001FD, 0x0003003E, 0x000003CE, 0x000004C6, 0x000200F9, 0x000003CF, 0x000200F8, 0x000003D1, +0x0004003D, 0x0000000C, 0x000004C7, 0x000003CC, 0x000200FE, 0x000004C7, 0x00010038, 0x00050036, +0x0000000C, 0x000000CF, 0x00000000, 0x000000C6, 0x00030037, 0x0000000D, 0x000000CC, 0x00030037, +0x0000000D, 0x000000CD, 0x00030037, 0x000000C5, 0x000000CE, 0x000200F8, 0x000000D0, 0x0004003B, +0x0000000D, 0x000004CA, 0x00000007, 0x0004003B, 0x0000000D, 0x000004D4, 0x00000007, 0x0004003B, +0x0000000D, 0x000004D5, 0x00000007, 0x0004003B, 0x00000007, 0x000004D7, 0x00000007, 0x0004003B, +0x00000007, 0x000004DA, 0x00000007, 0x0004003B, 0x0000000D, 0x000004DE, 0x00000007, 0x0004003B, +0x0000000D, 0x000004E6, 0x00000007, 0x0004003B, 0x00000084, 0x000004EC, 0x00000007, 0x0004003B, +0x0000000D, 0x000004F0, 0x00000007, 0x0004003B, 0x0000000D, 0x000004FB, 0x00000007, 0x0004003D, +0x000004CC, 0x000004CF, 0x000004CE, 0x00050041, 0x0000000D, 0x000004D0, 0x000000CE, 0x00000208, +0x0004003D, 0x0000000C, 0x000004D1, 0x000004D0, 0x00050057, 0x00000012, 0x000004D2, 0x000004CF, +0x000004D1, 0x0008004F, 0x0000000C, 0x000004D3, 0x000004D2, 0x000004D2, 0x00000000, 0x00000001, +0x00000002, 0x0003003E, 0x000004CA, 0x000004D3, 0x0004003D, 0x0000000C, 0x000004D6, 0x000000CC, +0x0003003E, 0x000004D5, 0x000004D6, 0x00050041, 0x00000007, 0x000004D8, 0x000000CE, 0x00000258, +0x0004003D, 0x00000006, 0x000004D9, 0x000004D8, 0x0003003E, 0x000004D7, 0x000004D9, 0x00050041, +0x00000007, 0x000004DB, 0x000000CE, 0x0000020E, 0x0004003D, 0x00000006, 0x000004DC, 0x000004DB, +0x0003003E, 0x000004DA, 0x000004DC, 0x00070039, 0x0000000C, 0x000004DD, 0x0000006D, 0x000004D5, +0x000004D7, 0x000004DA, 0x0003003E, 0x000004D4, 0x000004DD, 0x0004003D, 0x0000000C, 0x000004DF, +0x000004D4, 0x00060050, 0x0000000C, 0x000004E0, 0x000000D3, 0x000000D3, 0x000000D3, 0x00050083, +0x0000000C, 0x000004E1, 0x000004E0, 0x000004DF, 0x00050041, 0x00000007, 0x000004E2, 0x000000CE, +0x000001FD, 0x0004003D, 0x00000006, 0x000004E3, 0x000004E2, 0x00050083, 0x00000006, 0x000004E4, +0x000000D3, 0x000004E3, 0x0005008E, 0x0000000C, 0x000004E5, 0x000004E1, 0x000004E4, 0x0003003E, +0x000004DE, 0x000004E5, 0x00050041, 0x00000013, 0x000004E7, 0x000000CE, 0x000001E7, 0x0004003D, +0x00000012, 0x000004E8, 0x000004E7, 0x0008004F, 0x0000000C, 0x000004E9, 0x000004E8, 0x000004E8, +0x00000000, 0x00000001, 0x00000002, 0x0004003D, 0x0000000C, 0x000004EA, 0x000004CA, 0x00050085, +0x0000000C, 0x000004EB, 0x000004E9, 0x000004EA, 0x0003003E, 0x000004E6, 0x000004EB, 0x00050041, +0x0000030D, 0x000004EE, 0x000002AC, 0x000004ED, 0x0004003D, 0x00000083, 0x000004EF, 0x000004EE, +0x0003003E, 0x000004EC, 0x000004EF, 0x0004003D, 0x000004CC, 0x000004F2, 0x000004F1, 0x0004003D, +0x0000000C, 0x000004F3, 0x000000CD, 0x00050041, 0x00000007, 0x000004F4, 0x000000CE, 0x000003E6, +0x0004003D, 0x00000006, 0x000004F5, 0x000004F4, 0x0004003D, 0x00000083, 0x000004F6, 0x000004EC, +0x0004006F, 0x00000006, 0x000004F7, 0x000004F6, 0x00050085, 0x00000006, 0x000004F8, 0x000004F5, +0x000004F7, 0x00070058, 0x00000012, 0x000004F9, 0x000004F2, 0x000004F3, 0x00000002, 0x000004F8, +0x0008004F, 0x0000000C, 0x000004FA, 0x000004F9, 0x000004F9, 0x00000000, 0x00000001, 0x00000002, +0x0003003E, 0x000004F0, 0x000004FA, 0x0004003D, 0x0000000C, 0x000004FC, 0x000004F0, 0x0004003D, +0x0000000C, 0x000004FD, 0x000004D4, 0x00060041, 0x00000007, 0x000004FE, 0x000000CE, 0x0000030C, +0x0000023C, 0x0004003D, 0x00000006, 0x000004FF, 0x000004FE, 0x0005008E, 0x0000000C, 0x00000500, +0x000004FD, 0x000004FF, 0x00060041, 0x00000007, 0x00000502, 0x000000CE, 0x0000030C, 0x00000501, +0x0004003D, 0x00000006, 0x00000503, 0x00000502, 0x00060050, 0x0000000C, 0x00000504, 0x00000503, +0x00000503, 0x00000503, 0x00050081, 0x0000000C, 0x00000505, 0x00000500, 0x00000504, 0x00050085, +0x0000000C, 0x00000506, 0x000004FC, 0x00000505, 0x0003003E, 0x000004FB, 0x00000506, 0x0004003D, +0x0000000C, 0x00000507, 0x000004DE, 0x0004003D, 0x0000000C, 0x00000508, 0x000004E6, 0x00050085, +0x0000000C, 0x00000509, 0x00000507, 0x00000508, 0x0004003D, 0x0000000C, 0x0000050A, 0x000004FB, +0x00050081, 0x0000000C, 0x0000050B, 0x00000509, 0x0000050A, 0x000200FE, 0x0000050B, 0x00010038, + }; \ No newline at end of file diff --git a/Lumos/Assets/Shaders/ForwardPBR.frag b/Lumos/Assets/Shaders/ForwardPBR.frag index f88a7f98e..757a44886 100644 --- a/Lumos/Assets/Shaders/ForwardPBR.frag +++ b/Lumos/Assets/Shaders/ForwardPBR.frag @@ -556,6 +556,8 @@ void main() material.Roughness = sqrt(filteredRoughness2); } + material.Roughness = clamp(material.Roughness, MIN_ROUGHNESS, 1.0); + vec3 wsPos = VertexOutput.Position.xyz; material.View = normalize(ubo.cameraPosition.xyz - wsPos); material.NDotV = max(dot(material.Normal, material.View), 1e-4); diff --git a/Lumos/Assets/Shaders/PBR.glslh b/Lumos/Assets/Shaders/PBR.glslh index e40726e68..f6ab3d57e 100644 --- a/Lumos/Assets/Shaders/PBR.glslh +++ b/Lumos/Assets/Shaders/PBR.glslh @@ -163,7 +163,7 @@ float distribution(float roughness, float NoH, const vec3 h, const vec3 normal) float visibility(float roughness, float NoV, float NoL) { #if QUALITY_LOW - return V_SmithGGXCorrelated_Fast(roughness, NoV, NoL); + return V_SmithGGXCorrelatedFast(roughness, NoV, NoL); #else return V_SmithGGXCorrelated(roughness, NoV, NoL); #endif @@ -171,7 +171,7 @@ float visibility(float roughness, float NoV, float NoL) { vec3 fresnel(const vec3 f0, float LoH) { #if QUALITY_LOW - return F_Schlick(f0, LoH); // f90 = 1.0 + return F_Schlick(LoH, f0); // f90 = 1.0 #else float f90 = saturate(dot(f0, vec3(50.0 * 0.33))); return F_Schlick(f0, f90, LoH); diff --git a/Lumos/External/spdlog/.clang-format b/Lumos/External/spdlog/.clang-format new file mode 100644 index 000000000..222faea47 --- /dev/null +++ b/Lumos/External/spdlog/.clang-format @@ -0,0 +1,109 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -4 +AlignAfterOpenBracket: DontAlign +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: true +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: true +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 140 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + - Regex: '.*' + Priority: 1 +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: false +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: false +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 8 +UseTab: Never +IndentPPDirectives: AfterHash +... + diff --git a/Lumos/External/spdlog/.clang-tidy b/Lumos/External/spdlog/.clang-tidy new file mode 100644 index 000000000..34239d6b1 --- /dev/null +++ b/Lumos/External/spdlog/.clang-tidy @@ -0,0 +1,54 @@ +Checks: 'cppcoreguidelines-*, +performance-*, +modernize-*, +google-*, +misc-* +cert-*, +readability-*, +clang-analyzer-*, +-performance-unnecessary-value-param, +-modernize-use-trailing-return-type, +-google-runtime-references, +-misc-non-private-member-variables-in-classes, +-readability-braces-around-statements, +-google-readability-braces-around-statements, +-cppcoreguidelines-avoid-magic-numbers, +-readability-magic-numbers, +-readability-magic-numbers, +-cppcoreguidelines-pro-type-vararg, +-cppcoreguidelines-pro-bounds-pointer-arithmetic, +-cppcoreguidelines-avoid-c-arrays, +-modernize-avoid-c-arrays, +-cppcoreguidelines-pro-bounds-array-to-pointer-decay, +-readability-named-parameter, +-cert-env33-c +' + + +WarningsAsErrors: '' +HeaderFilterRegex: '*spdlog/[^f].*' +AnalyzeTemporaryDtors: false +FormatStyle: none + +CheckOptions: + - key: google-readability-braces-around-statements.ShortStatementLines + value: '1' + - key: google-readability-function-size.StatementThreshold + value: '800' + - key: google-readability-namespace-comments.ShortNamespaceLines + value: '10' + - key: google-readability-namespace-comments.SpacesBeforeComments + value: '2' + - key: modernize-loop-convert.MaxCopySize + value: '16' + - key: modernize-loop-convert.MinConfidence + value: reasonable + - key: modernize-loop-convert.NamingStyle + value: CamelCase + - key: modernize-pass-by-value.IncludeStyle + value: llvm + - key: modernize-replace-auto-ptr.IncludeStyle + value: llvm + - key: modernize-use-nullptr.NullMacros + value: 'NULL' + diff --git a/Lumos/External/spdlog/CMakeLists.txt b/Lumos/External/spdlog/CMakeLists.txt new file mode 100644 index 000000000..6556144b5 --- /dev/null +++ b/Lumos/External/spdlog/CMakeLists.txt @@ -0,0 +1,360 @@ +# Copyright(c) 2019 spdlog authors Distributed under the MIT License (http://opensource.org/licenses/MIT) + +cmake_minimum_required(VERSION 3.10...3.21) + +# --------------------------------------------------------------------------------------- +# Start spdlog project +# --------------------------------------------------------------------------------------- +include(cmake/utils.cmake) +include(cmake/ide.cmake) + +spdlog_extract_version() + +project(spdlog VERSION ${SPDLOG_VERSION} LANGUAGES CXX) +message(STATUS "Build spdlog: ${SPDLOG_VERSION}") + +include(GNUInstallDirs) + +# --------------------------------------------------------------------------------------- +# Set default build to release +# --------------------------------------------------------------------------------------- +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose Release or Debug" FORCE) +endif() + +# --------------------------------------------------------------------------------------- +# Compiler config +# --------------------------------------------------------------------------------------- +if(SPDLOG_USE_STD_FORMAT) + set(CMAKE_CXX_STANDARD 20) + set(CMAKE_CXX_STANDARD_REQUIRED ON) +elseif(NOT CMAKE_CXX_STANDARD) + set(CMAKE_CXX_STANDARD 11) + set(CMAKE_CXX_STANDARD_REQUIRED ON) +endif() + +# make sure __cplusplus is defined when using msvc and enable parallel build +if(MSVC) + string(APPEND CMAKE_CXX_FLAGS " /Zc:__cplusplus /MP") +endif() + +set(CMAKE_CXX_EXTENSIONS OFF) + +if(CMAKE_SYSTEM_NAME MATCHES "CYGWIN" OR CMAKE_SYSTEM_NAME MATCHES "MSYS") + set(CMAKE_CXX_EXTENSIONS ON) +endif() + +# --------------------------------------------------------------------------------------- +# Set SPDLOG_MASTER_PROJECT to ON if we are building spdlog +# --------------------------------------------------------------------------------------- +# Check if spdlog is being used directly or via add_subdirectory, but allow overriding +if(NOT DEFINED SPDLOG_MASTER_PROJECT) + if(CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) + set(SPDLOG_MASTER_PROJECT ON) + else() + set(SPDLOG_MASTER_PROJECT OFF) + endif() +endif() + +option(SPDLOG_BUILD_ALL "Build all artifacts" OFF) + +# build shared option +option(SPDLOG_BUILD_SHARED "Build shared library" OFF) + +# precompiled headers option +option(SPDLOG_ENABLE_PCH "Build static or shared library using precompiled header to speed up compilation time" OFF) + +# build position independent code +option(SPDLOG_BUILD_PIC "Build position independent code (-fPIC)" OFF) + +# example options +option(SPDLOG_BUILD_EXAMPLE "Build example" ${SPDLOG_MASTER_PROJECT}) +option(SPDLOG_BUILD_EXAMPLE_HO "Build header only example" OFF) + +# testing options +option(SPDLOG_BUILD_TESTS "Build tests" OFF) +option(SPDLOG_BUILD_TESTS_HO "Build tests using the header only version" OFF) + +# bench options +option(SPDLOG_BUILD_BENCH "Build benchmarks (Requires https://github.com/google/benchmark.git to be installed)" OFF) + +# sanitizer options +option(SPDLOG_SANITIZE_ADDRESS "Enable address sanitizer in tests" OFF) + +# warning options +option(SPDLOG_BUILD_WARNINGS "Enable compiler warnings" OFF) + +# install options +option(SPDLOG_SYSTEM_INCLUDES "Include as system headers (skip for clang-tidy)." OFF) +option(SPDLOG_INSTALL "Generate the install target" ${SPDLOG_MASTER_PROJECT}) +option(SPDLOG_USE_STD_FORMAT "Use std::format instead of fmt library." OFF) +option(SPDLOG_FMT_EXTERNAL "Use external fmt library instead of bundled" OFF) +option(SPDLOG_FMT_EXTERNAL_HO "Use external fmt header-only library instead of bundled" OFF) +option(SPDLOG_NO_EXCEPTIONS "Compile with -fno-exceptions. Call abort() on any spdlog exceptions" OFF) + +if(SPDLOG_FMT_EXTERNAL AND SPDLOG_FMT_EXTERNAL_HO) + message(FATAL_ERROR "SPDLOG_FMT_EXTERNAL and SPDLOG_FMT_EXTERNAL_HO are mutually exclusive") +endif() + +if(SPDLOG_USE_STD_FORMAT AND SPDLOG_FMT_EXTERNAL_HO) + message(FATAL_ERROR "SPDLOG_USE_STD_FORMAT and SPDLOG_FMT_EXTERNAL_HO are mutually exclusive") +endif() + +if(SPDLOG_USE_STD_FORMAT AND SPDLOG_FMT_EXTERNAL) + message(FATAL_ERROR "SPDLOG_USE_STD_FORMAT and SPDLOG_FMT_EXTERNAL are mutually exclusive") +endif() + +# misc tweakme options +if(WIN32) + option(SPDLOG_WCHAR_SUPPORT "Support wchar api" OFF) + option(SPDLOG_WCHAR_FILENAMES "Support wchar filenames" OFF) +else() + set(SPDLOG_WCHAR_SUPPORT OFF CACHE BOOL "non supported option" FORCE) + set(SPDLOG_WCHAR_FILENAMES OFF CACHE BOOL "non supported option" FORCE) +endif() + +if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") + option(SPDLOG_CLOCK_COARSE "Use CLOCK_REALTIME_COARSE instead of the regular clock," OFF) +else() + set(SPDLOG_CLOCK_COARSE OFF CACHE BOOL "non supported option" FORCE) +endif() + +option(SPDLOG_PREVENT_CHILD_FD "Prevent from child processes to inherit log file descriptors" OFF) +option(SPDLOG_NO_THREAD_ID "prevent spdlog from querying the thread id on each log call if thread id is not needed" OFF) +option(SPDLOG_NO_TLS "prevent spdlog from using thread local storage" OFF) +option( + SPDLOG_NO_ATOMIC_LEVELS + "prevent spdlog from using of std::atomic log levels (use only if your code never modifies log levels concurrently" + OFF) +option(SPDLOG_DISABLE_DEFAULT_LOGGER "Disable default logger creation" OFF) + +# clang-tidy +if(${CMAKE_VERSION} VERSION_GREATER "3.5") + option(SPDLOG_TIDY "run clang-tidy" OFF) +endif() + +if(SPDLOG_TIDY) + set(CMAKE_CXX_CLANG_TIDY "clang-tidy") + set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + message(STATUS "Enabled clang-tidy") +endif() + +if(SPDLOG_BUILD_PIC) + set(CMAKE_POSITION_INDEPENDENT_CODE ON) +endif() + +find_package(Threads REQUIRED) +message(STATUS "Build type: " ${CMAKE_BUILD_TYPE}) +# --------------------------------------------------------------------------------------- +# Static/Shared library +# --------------------------------------------------------------------------------------- +set(SPDLOG_SRCS src/spdlog.cpp src/stdout_sinks.cpp src/color_sinks.cpp src/file_sinks.cpp src/async.cpp src/cfg.cpp) + +if(NOT SPDLOG_USE_STD_FORMAT AND NOT SPDLOG_FMT_EXTERNAL AND NOT SPDLOG_FMT_EXTERNAL_HO) + list(APPEND SPDLOG_SRCS src/bundled_fmtlib_format.cpp) +endif() + +if(SPDLOG_BUILD_SHARED OR BUILD_SHARED_LIBS) + if(WIN32) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.rc.in ${CMAKE_CURRENT_BINARY_DIR}/version.rc @ONLY) + list(APPEND SPDLOG_SRCS ${CMAKE_CURRENT_BINARY_DIR}/version.rc) + endif() + add_library(spdlog SHARED ${SPDLOG_SRCS} ${SPDLOG_ALL_HEADERS}) + target_compile_definitions(spdlog PUBLIC SPDLOG_SHARED_LIB) + if(MSVC) + target_compile_options(spdlog PUBLIC $<$,$>>:/wd4251 + /wd4275>) + endif() + if(NOT SPDLOG_USE_STD_FORMAT AND NOT SPDLOG_FMT_EXTERNAL AND NOT SPDLOG_FMT_EXTERNAL_HO) + target_compile_definitions(spdlog PRIVATE FMT_EXPORT PUBLIC FMT_SHARED) + endif() +else() + add_library(spdlog STATIC ${SPDLOG_SRCS} ${SPDLOG_ALL_HEADERS}) +endif() + +add_library(spdlog::spdlog ALIAS spdlog) + +set(SPDLOG_INCLUDES_LEVEL "") +if(SPDLOG_SYSTEM_INCLUDES) + set(SPDLOG_INCLUDES_LEVEL "SYSTEM") +endif() + +target_compile_definitions(spdlog PUBLIC SPDLOG_COMPILED_LIB) +target_include_directories(spdlog ${SPDLOG_INCLUDES_LEVEL} PUBLIC "$" + "$") +target_link_libraries(spdlog PUBLIC Threads::Threads) +spdlog_enable_warnings(spdlog) + +set_target_properties(spdlog PROPERTIES VERSION ${SPDLOG_VERSION} SOVERSION + ${SPDLOG_VERSION_MAJOR}.${SPDLOG_VERSION_MINOR}) +set_target_properties(spdlog PROPERTIES DEBUG_POSTFIX d) + +if(COMMAND target_precompile_headers AND SPDLOG_ENABLE_PCH) + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/pch.h.in ${PROJECT_BINARY_DIR}/spdlog_pch.h @ONLY) + target_precompile_headers(spdlog PRIVATE ${PROJECT_BINARY_DIR}/spdlog_pch.h) +endif() + +# --------------------------------------------------------------------------------------- +# Header only version +# --------------------------------------------------------------------------------------- +add_library(spdlog_header_only INTERFACE) +add_library(spdlog::spdlog_header_only ALIAS spdlog_header_only) + +target_include_directories( + spdlog_header_only ${SPDLOG_INCLUDES_LEVEL} INTERFACE "$" + "$") +target_link_libraries(spdlog_header_only INTERFACE Threads::Threads) + +# --------------------------------------------------------------------------------------- +# Use fmt package if using external fmt +# --------------------------------------------------------------------------------------- +if(SPDLOG_FMT_EXTERNAL OR SPDLOG_FMT_EXTERNAL_HO) + if(NOT TARGET fmt::fmt) + find_package(fmt CONFIG REQUIRED) + endif() + target_compile_definitions(spdlog PUBLIC SPDLOG_FMT_EXTERNAL) + target_compile_definitions(spdlog_header_only INTERFACE SPDLOG_FMT_EXTERNAL) + + # use external fmt-header-nly + if(SPDLOG_FMT_EXTERNAL_HO) + target_link_libraries(spdlog PUBLIC fmt::fmt-header-only) + target_link_libraries(spdlog_header_only INTERFACE fmt::fmt-header-only) + else() # use external compile fmt + target_link_libraries(spdlog PUBLIC fmt::fmt) + target_link_libraries(spdlog_header_only INTERFACE fmt::fmt) + endif() + + set(PKG_CONFIG_REQUIRES fmt) # add dependency to pkg-config +endif() + +# --------------------------------------------------------------------------------------- +# Add required libraries for Android CMake build +# --------------------------------------------------------------------------------------- +if(ANDROID) + target_link_libraries(spdlog PUBLIC log) + target_link_libraries(spdlog_header_only INTERFACE log) +endif() + +# --------------------------------------------------------------------------------------- +# Misc definitions according to tweak options +# --------------------------------------------------------------------------------------- +set(SPDLOG_WCHAR_TO_UTF8_SUPPORT ${SPDLOG_WCHAR_SUPPORT}) +foreach( + SPDLOG_OPTION + SPDLOG_WCHAR_TO_UTF8_SUPPORT + SPDLOG_WCHAR_FILENAMES + SPDLOG_NO_EXCEPTIONS + SPDLOG_CLOCK_COARSE + SPDLOG_PREVENT_CHILD_FD + SPDLOG_NO_THREAD_ID + SPDLOG_NO_TLS + SPDLOG_NO_ATOMIC_LEVELS + SPDLOG_DISABLE_DEFAULT_LOGGER + SPDLOG_USE_STD_FORMAT) + if(${SPDLOG_OPTION}) + target_compile_definitions(spdlog PUBLIC ${SPDLOG_OPTION}) + target_compile_definitions(spdlog_header_only INTERFACE ${SPDLOG_OPTION}) + endif() +endforeach() + +# --------------------------------------------------------------------------------------- +# If exceptions are disabled, disable them in the bundled fmt as well +# --------------------------------------------------------------------------------------- +if(SPDLOG_NO_EXCEPTIONS) + if(NOT SPDLOG_FMT_EXTERNAL AND NOT SPDLOG_FMT_EXTERNAL_HO) + target_compile_definitions(spdlog PUBLIC FMT_EXCEPTIONS=0) + endif() + if(NOT MSVC) + target_compile_options(spdlog PRIVATE -fno-exceptions) + else() + target_compile_options(spdlog PRIVATE /EHsc) + endif() +endif() +# --------------------------------------------------------------------------------------- +# Build binaries +# --------------------------------------------------------------------------------------- +if(SPDLOG_BUILD_EXAMPLE OR SPDLOG_BUILD_EXAMPLE_HO OR SPDLOG_BUILD_ALL) + message(STATUS "Generating example(s)") + add_subdirectory(example) + spdlog_enable_warnings(example) + if(SPDLOG_BUILD_EXAMPLE_HO) + spdlog_enable_warnings(example_header_only) + endif() +endif() + +if(SPDLOG_BUILD_TESTS OR SPDLOG_BUILD_TESTS_HO OR SPDLOG_BUILD_ALL) + message(STATUS "Generating tests") + enable_testing() + add_subdirectory(tests) +endif() + +if(SPDLOG_BUILD_BENCH OR SPDLOG_BUILD_ALL) + message(STATUS "Generating benchmarks") + add_subdirectory(bench) +endif() + +# --------------------------------------------------------------------------------------- +# Install +# --------------------------------------------------------------------------------------- +if(SPDLOG_INSTALL) + message(STATUS "Generating install") + set(project_config_in "${CMAKE_CURRENT_LIST_DIR}/cmake/spdlogConfig.cmake.in") + set(project_config_out "${CMAKE_CURRENT_BINARY_DIR}/spdlogConfig.cmake") + set(config_targets_file "spdlogConfigTargets.cmake") + set(version_config_file "${CMAKE_CURRENT_BINARY_DIR}/spdlogConfigVersion.cmake") + set(export_dest_dir "${CMAKE_INSTALL_LIBDIR}/cmake/spdlog") + set(pkgconfig_install_dir "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + set(pkg_config "${CMAKE_BINARY_DIR}/${PROJECT_NAME}.pc") + + # --------------------------------------------------------------------------------------- + # Include files + # --------------------------------------------------------------------------------------- + install(DIRECTORY include/ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" PATTERN "fmt/bundled" EXCLUDE) + install( + TARGETS spdlog spdlog_header_only + EXPORT spdlog + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) + + if(NOT SPDLOG_USE_STD_FORMAT AND NOT SPDLOG_FMT_EXTERNAL AND NOT SPDLOG_FMT_EXTERNAL_HO) + install(DIRECTORY include/${PROJECT_NAME}/fmt/bundled/ + DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME}/fmt/bundled/") + endif() + + # --------------------------------------------------------------------------------------- + # Install pkg-config file + # --------------------------------------------------------------------------------------- + if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}") + set(PKG_CONFIG_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}") + else() + set(PKG_CONFIG_INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}") + endif() + if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}") + set(PKG_CONFIG_LIBDIR "${CMAKE_INSTALL_LIBDIR}") + else() + set(PKG_CONFIG_LIBDIR "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}") + endif() + get_target_property(PKG_CONFIG_DEFINES spdlog INTERFACE_COMPILE_DEFINITIONS) + string(REPLACE ";" " -D" PKG_CONFIG_DEFINES "${PKG_CONFIG_DEFINES}") + string(CONCAT PKG_CONFIG_DEFINES "-D" "${PKG_CONFIG_DEFINES}") + configure_file("cmake/${PROJECT_NAME}.pc.in" "${pkg_config}" @ONLY) + install(FILES "${pkg_config}" DESTINATION "${pkgconfig_install_dir}") + + # --------------------------------------------------------------------------------------- + # Install CMake config files + # --------------------------------------------------------------------------------------- + export(TARGETS spdlog NAMESPACE spdlog:: FILE "${CMAKE_CURRENT_BINARY_DIR}/${config_targets_file}") + install(EXPORT spdlog DESTINATION ${export_dest_dir} NAMESPACE spdlog:: FILE ${config_targets_file}) + + include(CMakePackageConfigHelpers) + configure_package_config_file("${project_config_in}" "${project_config_out}" INSTALL_DESTINATION ${export_dest_dir}) + + write_basic_package_version_file("${version_config_file}" COMPATIBILITY SameMajorVersion) + install(FILES "${project_config_out}" "${version_config_file}" DESTINATION "${export_dest_dir}") + + # --------------------------------------------------------------------------------------- + # Support creation of installable packages + # --------------------------------------------------------------------------------------- + include(cmake/spdlogCPack.cmake) +endif() diff --git a/Lumos/External/spdlog/INSTALL b/Lumos/External/spdlog/INSTALL new file mode 100644 index 000000000..20a9b4c40 --- /dev/null +++ b/Lumos/External/spdlog/INSTALL @@ -0,0 +1,24 @@ +Header only version: +================================================================== +Just copy the files to your build tree and use a C++11 compiler. +Or use CMake: + add_executable(example_header_only example.cpp) + target_link_libraries(example_header_only spdlog::spdlog_header_only) + + +Compiled library version: +================================================================== +CMake: + add_executable(example example.cpp) + target_link_libraries(example spdlog::spdlog) + +Or copy files src/*.cpp to your build tree and pass the -DSPDLOG_COMPILED_LIB to the compiler. + +Tested on: +gcc 4.8.1 and above +clang 3.5 +Visual Studio 2013 + + + + diff --git a/Lumos/External/spdlog/README.md b/Lumos/External/spdlog/README.md index a37938c59..6ce32fb60 100644 --- a/Lumos/External/spdlog/README.md +++ b/Lumos/External/spdlog/README.md @@ -1,59 +1,61 @@ # spdlog -Very fast, header-only/compiled, C++ logging library. [![Build Status](https://travis-ci.com/gabime/spdlog.svg?branch=v1.x)](https://travis-ci.com/gabime/spdlog)  [![Build status](https://ci.appveyor.com/api/projects/status/d2jnxclg20vd0o50?svg=true)](https://ci.appveyor.com/project/gabime/spdlog) [![Release](https://img.shields.io/github/release/gabime/spdlog.svg)](https://github.com/gabime/spdlog/releases/latest) +Very fast, header-only/compiled, C++ logging library. [![ci](https://github.com/gabime/spdlog/actions/workflows/ci.yml/badge.svg)](https://github.com/gabime/spdlog/actions/workflows/ci.yml)  [![Build status](https://ci.appveyor.com/api/projects/status/d2jnxclg20vd0o50?svg=true&branch=v1.x)](https://ci.appveyor.com/project/gabime/spdlog) [![Release](https://img.shields.io/github/release/gabime/spdlog.svg)](https://github.com/gabime/spdlog/releases/latest) -## Install -#### Header only version -Copy the source [folder](https://github.com/gabime/spdlog/tree/v1.x/include/spdlog) to your build tree and use a C++11 compiler. +## Install +#### Header-only version +Copy the include [folder](https://github.com/gabime/spdlog/tree/v1.x/include/spdlog) to your build tree and use a C++11 compiler. -#### Static lib version (recommended - much faster compile times) +#### Compiled version (recommended - much faster compile times) ```console $ git clone https://github.com/gabime/spdlog.git $ cd spdlog && mkdir build && cd build $ cmake .. && make -j ``` - - see example [CMakeLists.txt](https://github.com/gabime/spdlog/blob/v1.x/example/CMakeLists.txt) on how to use. + +see example [CMakeLists.txt](https://github.com/gabime/spdlog/blob/v1.x/example/CMakeLists.txt) on how to use. ## Platforms - * Linux, FreeBSD, OpenBSD, Solaris, AIX - * Windows (msvc 2013+, cygwin) - * macOS (clang 3.5+) - * Android +* Linux, FreeBSD, OpenBSD, Solaris, AIX +* Windows (msvc 2013+, cygwin) +* macOS (clang 3.5+) +* Android ## Package managers: +* Debian: `sudo apt install libspdlog-dev` * Homebrew: `brew install spdlog` * MacPorts: `sudo port install spdlog` -* FreeBSD: `cd /usr/ports/devel/spdlog/ && make install clean` +* FreeBSD: `pkg install spdlog` * Fedora: `dnf install spdlog` * Gentoo: `emerge dev-libs/spdlog` * Arch Linux: `pacman -S spdlog` +* openSUSE: `sudo zypper in spdlog-devel` * vcpkg: `vcpkg install spdlog` * conan: `spdlog/[>=1.4.1]` * conda: `conda install -c conda-forge spdlog` * build2: ```depends: spdlog ^1.8.2``` - ## Features * Very fast (see [benchmarks](#benchmarks) below). * Headers only or compiled -* Feature rich formatting, using the excellent [fmt](https://github.com/fmtlib/fmt) library. +* Feature-rich formatting, using the excellent [fmt](https://github.com/fmtlib/fmt) library. * Asynchronous mode (optional) * [Custom](https://github.com/gabime/spdlog/wiki/3.-Custom-formatting) formatting. * Multi/Single threaded loggers. * Various log targets: - * Rotating log files. - * Daily log files. - * Console logging (colors supported). - * syslog. - * Windows event log. - * Windows debugger (```OutputDebugString(..)```). - * Easily [extendable](https://github.com/gabime/spdlog/wiki/4.-Sinks#implementing-your-own-sink) with custom log targets. -* Log filtering - log levels can be modified in runtime as well as in compile time. -* Support for loading log levels from argv or from environment var. -* [Backtrace](#backtrace-support) support - store debug messages in a ring buffer and display later on demand. - + * Rotating log files. + * Daily log files. + * Console logging (colors supported). + * syslog. + * Windows event log. + * Windows debugger (```OutputDebugString(..)```). + * Log to Qt widgets ([example](#log-to-qt-with-nice-colors)). + * Easily [extendable](https://github.com/gabime/spdlog/wiki/4.-Sinks#implementing-your-own-sink) with custom log targets. +* Log filtering - log levels can be modified at runtime as well as compile time. +* Support for loading log levels from argv or environment var. +* [Backtrace](#backtrace-support) support - store debug messages in a ring buffer and display them later on demand. + ## Usage samples #### Basic usage @@ -91,7 +93,7 @@ int main() #include "spdlog/sinks/stdout_color_sinks.h" void stdout_example() { - // create color multi threaded logger + // create a color multi-threaded logger auto console = spdlog::stdout_color_mt("console"); auto err_logger = spdlog::stderr_color_mt("stderr"); spdlog::get("console")->info("loggers can be retrieved from a global registry using the spdlog::get(logger_name)"); @@ -120,7 +122,7 @@ void basic_logfile_example() #include "spdlog/sinks/rotating_file_sink.h" void rotating_example() { - // Create a file rotating logger with 5mb size max and 3 rotated files + // Create a file rotating logger with 5 MB size max and 3 rotated files auto max_size = 1048576 * 5; auto max_files = 3; auto logger = spdlog::rotating_logger_mt("some_logger_name", "logs/rotating.txt", max_size, max_files); @@ -134,7 +136,7 @@ void rotating_example() #include "spdlog/sinks/daily_file_sink.h" void daily_example() { - // Create a daily logger - a new file is created every day on 2:30am + // Create a daily logger - a new file is created every day at 2:30 am auto logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30); } @@ -144,10 +146,10 @@ void daily_example() #### Backtrace support ```c++ // Debug messages can be stored in a ring buffer instead of being logged immediately. -// This is useful in order to display debug logs only when really nededed (e.g. when error happens). -// When needed, call dump_backtrace() to see them. +// This is useful to display debug logs only when needed (e.g. when an error happens). +// When needed, call dump_backtrace() to dump them to your log. -spdlog::enable_backtrace(32); // Store the latest 32 messages in a buffer. Older messages will be dropped. +spdlog::enable_backtrace(32); // Store the latest 32 messages in a buffer. // or my_logger->enable_backtrace(32).. for(int i = 0; i < 100; i++) { @@ -155,7 +157,6 @@ for(int i = 0; i < 100; i++) } // e.g. if some error happened: spdlog::dump_backtrace(); // log them now! show the last 32 messages - // or my_logger->dump_backtrace(32).. ``` @@ -163,7 +164,7 @@ spdlog::dump_backtrace(); // log them now! show the last 32 messages #### Periodic flush ```c++ // periodically flush all *registered* loggers every 3 seconds: -// warning: only use if all your loggers are thread safe ("_mt" loggers) +// warning: only use if all your loggers are thread-safe ("_mt" loggers) spdlog::flush_every(std::chrono::seconds(3)); ``` @@ -191,7 +192,7 @@ void stopwatch_example() // {:X} - print in uppercase. // {:s} - don't separate each byte with space. // {:p} - don't print the position on each line start. -// {:n} - don't split the output to lines. +// {:n} - don't split the output into lines. // {:a} - show ASCII if :n is not set. #include "spdlog/fmt/bin_to_hex.h" @@ -211,11 +212,11 @@ void binary_example() ``` --- -#### Logger with multi sinks - each with different format and log level +#### Logger with multi sinks - each with a different format and log level ```c++ -// create logger with 2 targets with different log levels and formats. -// the console will show only warnings or errors, while the file will log all. +// create a logger with 2 targets, with different log levels and formats. +// The console will show only warnings or errors, while the file will log all. void multi_sink_example() { auto console_sink = std::make_shared(); @@ -232,6 +233,27 @@ void multi_sink_example() } ``` +--- +#### User-defined callbacks about log events +```c++ + +// create a logger with a lambda function callback, the callback will be called +// each time something is logged to the logger +void callback_example() +{ + auto callback_sink = std::make_shared([](const spdlog::details::log_msg &msg) { + // for example you can be notified by sending an email to yourself + }); + callback_sink->set_level(spdlog::level::err); + + auto console_sink = std::make_shared(); + spdlog::logger logger("custom_callback_logger", {console_sink, callback_sink}); + + logger.info("some info log"); + logger.error("critical issue"); // will notify you +} +``` + --- #### Asynchronous logging ```c++ @@ -249,7 +271,7 @@ void async_example() ``` --- -#### Asynchronous logger with multi sinks +#### Asynchronous logger with multi sinks ```c++ #include "spdlog/sinks/stdout_color_sinks.h" #include "spdlog/sinks/rotating_file_sink.h" @@ -266,29 +288,26 @@ void multi_sink_example2() ``` --- -#### User defined types +#### User-defined types ```c++ -// user defined types logging by implementing operator<< -#include "spdlog/fmt/ostr.h" // must be included -struct my_type +template<> +struct fmt::formatter : fmt::formatter { - int i; - template - friend OStream &operator<<(OStream &os, const my_type &c) + auto format(my_type my, format_context &ctx) const -> decltype(ctx.out()) { - return os << "[my_type i=" << c.i << "]"; + return format_to(ctx.out(), "[my_type i={}]", my.i); } }; void user_defined_example() { - spdlog::get("console")->info("user defined type: {}", my_type{14}); + spdlog::info("user defined type: {}", my_type(14)); } ``` --- -#### User defined flags in the log pattern +#### User-defined flags in the log pattern ```c++ // Log patterns can contain custom flags. // the following example will add new flag '%*' - which will be bound to a instance. @@ -330,7 +349,7 @@ void err_handler_example() ``` --- -#### syslog +#### syslog ```c++ #include "spdlog/sinks/syslog_sink.h" void syslog_example() @@ -341,7 +360,7 @@ void syslog_example() } ``` --- -#### Android example +#### Android example ```c++ #include "spdlog/sinks/android_sink.h" void android_example() @@ -353,14 +372,14 @@ void android_example() ``` --- -#### Load log levels from env variable or from argv +#### Load log levels from the env variable or argv ```c++ #include "spdlog/cfg/env.h" int main (int argc, char *argv[]) { spdlog::cfg::load_env_levels(); - // or from command line: + // or from the command line: // ./example SPDLOG_LEVEL=info,mylogger=trace // #include "spdlog/cfg/argv.h" // for loading levels from argv // spdlog::cfg::load_argv_levels(argc, argv); @@ -373,6 +392,51 @@ $ export SPDLOG_LEVEL=info,mylogger=trace $ ./example ``` + +--- +#### Log file open/close event handlers +```c++ +// You can get callbacks from spdlog before/after a log file has been opened or closed. +// This is useful for cleanup procedures or for adding something to the start/end of the log file. +void file_events_example() +{ + // pass the spdlog::file_event_handlers to file sinks for open/close log file notifications + spdlog::file_event_handlers handlers; + handlers.before_open = [](spdlog::filename_t filename) { spdlog::info("Before opening {}", filename); }; + handlers.after_open = [](spdlog::filename_t filename, std::FILE *fstream) { fputs("After opening\n", fstream); }; + handlers.before_close = [](spdlog::filename_t filename, std::FILE *fstream) { fputs("Before closing\n", fstream); }; + handlers.after_close = [](spdlog::filename_t filename) { spdlog::info("After closing {}", filename); }; + auto my_logger = spdlog::basic_logger_st("some_logger", "logs/events-sample.txt", true, handlers); +} +``` + +--- +#### Replace the Default Logger +```c++ +void replace_default_logger_example() +{ + auto new_logger = spdlog::basic_logger_mt("new_default_logger", "logs/new-default-log.txt", true); + spdlog::set_default_logger(new_logger); + spdlog::info("new logger log message"); +} +``` + +--- +#### Log to Qt with nice colors +```c++ +#include "spdlog/spdlog.h" +#include "spdlog/sinks/qt_sinks.h" +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) +{ + setMinimumSize(640, 480); + auto log_widget = new QTextEdit(this); + setCentralWidget(log_widget); + int max_lines = 500; // keep the text widget to max 500 lines. remove old lines if needed. + auto logger = spdlog::qt_color_logger_mt("qt_logger", log_widget, max_lines); + logger->info("Some info message"); +} +``` + --- ## Benchmarks diff --git a/Lumos/External/spdlog/appveyor.yml b/Lumos/External/spdlog/appveyor.yml new file mode 100644 index 000000000..f2757f30c --- /dev/null +++ b/Lumos/External/spdlog/appveyor.yml @@ -0,0 +1,89 @@ +version: 1.0.{build} +image: Visual Studio 2017 +environment: + matrix: + - GENERATOR: '"Visual Studio 15 2017 Win64"' + BUILD_TYPE: Debug + BUILD_SHARED: 'OFF' + FATAL_ERRORS: 'OFF' + WCHAR: 'ON' + WCHAR_FILES: 'OFF' + BUILD_EXAMPLE: 'ON' + USE_STD_FORMAT: 'OFF' + CXX_STANDARD: 11 + - GENERATOR: '"Visual Studio 15 2017 Win64"' + BUILD_TYPE: Release + BUILD_SHARED: 'OFF' + FATAL_ERRORS: 'OFF' + WCHAR: 'OFF' + WCHAR_FILES: 'OFF' + BUILD_EXAMPLE: 'ON' + USE_STD_FORMAT: 'OFF' + CXX_STANDARD: 11 + - GENERATOR: '"Visual Studio 15 2017 Win64"' + BUILD_TYPE: Release + BUILD_SHARED: 'ON' + FATAL_ERRORS: 'OFF' + WCHAR: 'OFF' + WCHAR_FILES: 'OFF' + BUILD_EXAMPLE: 'ON' + USE_STD_FORMAT: 'OFF' + CXX_STANDARD: 11 + - GENERATOR: '"Visual Studio 15 2017 Win64"' + BUILD_TYPE: Release + BUILD_SHARED: 'ON' + FATAL_ERRORS: 'OFF' + WCHAR: 'ON' + WCHAR_FILES: 'ON' + BUILD_EXAMPLE: 'OFF' + USE_STD_FORMAT: 'OFF' + CXX_STANDARD: 11 + - GENERATOR: '"Visual Studio 16 2019" -A x64' + BUILD_TYPE: Release + BUILD_SHARED: 'ON' + FATAL_ERRORS: 'ON' + WCHAR: 'OFF' + WCHAR_FILES: 'OFF' + BUILD_EXAMPLE: 'OFF' + USE_STD_FORMAT: 'OFF' + CXX_STANDARD: 17 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2019 + - GENERATOR: '"Visual Studio 17 2022" -A x64' + BUILD_TYPE: Release + BUILD_SHARED: 'ON' + FATAL_ERRORS: 'ON' + WCHAR: 'OFF' + WCHAR_FILES: 'OFF' + BUILD_EXAMPLE: 'OFF' + USE_STD_FORMAT: 'ON' + CXX_STANDARD: 20 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 + - GENERATOR: '"Visual Studio 17 2022" -A x64' + BUILD_TYPE: Release + BUILD_SHARED: 'ON' + FATAL_ERRORS: 'ON' + WCHAR: 'ON' + WCHAR_FILES: 'ON' + BUILD_EXAMPLE: 'OFF' + USE_STD_FORMAT: 'ON' + CXX_STANDARD: 20 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2022 +build_script: + - cmd: >- + set + + mkdir build + + cd build + + set PATH=%PATH%;C:\Program Files\Git\usr\bin + + cmake -G %GENERATOR% -D CMAKE_BUILD_TYPE=%BUILD_TYPE% -D BUILD_SHARED_LIBS=%BUILD_SHARED% -D SPDLOG_WCHAR_SUPPORT=%WCHAR% -D SPDLOG_WCHAR_FILENAMES=%WCHAR_FILES% -D SPDLOG_BUILD_EXAMPLE=%BUILD_EXAMPLE% -D SPDLOG_BUILD_EXAMPLE_HO=%BUILD_EXAMPLE% -D SPDLOG_BUILD_TESTS=ON -D SPDLOG_BUILD_TESTS_HO=OFF -D SPDLOG_BUILD_WARNINGS=%FATAL_ERRORS% -D SPDLOG_USE_STD_FORMAT=%USE_STD_FORMAT% -D CMAKE_CXX_STANDARD=%CXX_STANDARD% .. + + cmake --build . --config %BUILD_TYPE% + +before_test: + - set PATH=%PATH%;C:\projects\spdlog\build\_deps\catch2-build\src\%BUILD_TYPE%;C:\projects\spdlog\build\%BUILD_TYPE% + +test_script: + - C:\projects\spdlog\build\tests\%BUILD_TYPE%\spdlog-utests.exe diff --git a/Lumos/External/spdlog/bench/CMakeLists.txt b/Lumos/External/spdlog/bench/CMakeLists.txt new file mode 100644 index 000000000..8003886a6 --- /dev/null +++ b/Lumos/External/spdlog/bench/CMakeLists.txt @@ -0,0 +1,41 @@ +# Copyright(c) 2019 spdlog authors Distributed under the MIT License (http://opensource.org/licenses/MIT) + +cmake_minimum_required(VERSION 3.10) +project(spdlog_bench CXX) + +if(NOT TARGET spdlog) + # Stand-alone build + find_package(spdlog CONFIG REQUIRED) +endif() + +find_package(Threads REQUIRED) +find_package(benchmark CONFIG) +if(NOT benchmark_FOUND) + message(STATUS "Using CMake Version ${CMAKE_VERSION}") + if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.11.0") + # User can fetch googlebenchmark + message(STATUS "Downloading GoogleBenchmark") + include(FetchContent) + + # disable tests + set(BENCHMARK_ENABLE_TESTING OFF CACHE INTERNAL "") + # Do not build and run googlebenchmark tests + FetchContent_Declare(googlebenchmark GIT_REPOSITORY https://github.com/google/benchmark.git GIT_TAG v1.6.0) + FetchContent_MakeAvailable(googlebenchmark) + else() + message(FATAL_ERROR "GoogleBenchmark is missing. Use CMake >= 3.11 or download it") + endif() +endif() + +add_executable(bench bench.cpp) +spdlog_enable_warnings(bench) +target_link_libraries(bench PRIVATE spdlog::spdlog) + +add_executable(async_bench async_bench.cpp) +target_link_libraries(async_bench PRIVATE spdlog::spdlog) + +add_executable(latency latency.cpp) +target_link_libraries(latency PRIVATE benchmark::benchmark spdlog::spdlog) + +add_executable(formatter-bench formatter-bench.cpp) +target_link_libraries(formatter-bench PRIVATE benchmark::benchmark spdlog::spdlog) diff --git a/Lumos/External/spdlog/bench/async_bench.cpp b/Lumos/External/spdlog/bench/async_bench.cpp new file mode 100644 index 000000000..cf4d9754d --- /dev/null +++ b/Lumos/External/spdlog/bench/async_bench.cpp @@ -0,0 +1,186 @@ +// +// Copyright(c) 2015 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +// +// bench.cpp : spdlog benchmarks +// +#include "spdlog/spdlog.h" +#include "spdlog/async.h" +#include "spdlog/sinks/basic_file_sink.h" + +#if defined(SPDLOG_USE_STD_FORMAT) +# include +#elif defined(SPDLOG_FMT_EXTERNAL) +# include +#else +# include "spdlog/fmt/bundled/format.h" +#endif + +#include "utils.h" +#include +#include +#include +#include +#include + +using namespace std; +using namespace std::chrono; +using namespace spdlog; +using namespace spdlog::sinks; +using namespace utils; + +void bench_mt(int howmany, std::shared_ptr log, int thread_count); + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4996) // disable fopen warning under msvc +#endif // _MSC_VER + +int count_lines(const char *filename) +{ + int counter = 0; + auto *infile = fopen(filename, "r"); + int ch; + while (EOF != (ch = getc(infile))) + { + if ('\n' == ch) + counter++; + } + fclose(infile); + + return counter; +} + +void verify_file(const char *filename, int expected_count) +{ + spdlog::info("Verifying {} to contain {} line..", filename, expected_count); + auto count = count_lines(filename); + if (count != expected_count) + { + spdlog::error("Test failed. {} has {} lines instead of {}", filename, count, expected_count); + exit(1); + } + spdlog::info("Line count OK ({})\n", count); +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif + +int main(int argc, char *argv[]) +{ + + int howmany = 1000000; + int queue_size = std::min(howmany + 2, 8192); + int threads = 10; + int iters = 3; + + try + { + spdlog::set_pattern("[%^%l%$] %v"); + if (argc == 1) + { + spdlog::info("Usage: {} ", argv[0]); + return 0; + } + + if (argc > 1) + howmany = atoi(argv[1]); + if (argc > 2) + threads = atoi(argv[2]); + if (argc > 3) + { + queue_size = atoi(argv[3]); + if (queue_size > 500000) + { + spdlog::error("Max queue size allowed: 500,000"); + exit(1); + } + } + + if (argc > 4) + iters = atoi(argv[4]); + + auto slot_size = sizeof(spdlog::details::async_msg); + spdlog::info("-------------------------------------------------"); + spdlog::info("Messages : {:L}", howmany); + spdlog::info("Threads : {:L}", threads); + spdlog::info("Queue : {:L} slots", queue_size); + spdlog::info("Queue memory : {:L} x {:L} = {:L} KB ", queue_size, slot_size, (queue_size * slot_size) / 1024); + spdlog::info("Total iters : {:L}", iters); + spdlog::info("-------------------------------------------------"); + + const char *filename = "logs/basic_async.log"; + spdlog::info(""); + spdlog::info("*********************************"); + spdlog::info("Queue Overflow Policy: block"); + spdlog::info("*********************************"); + for (int i = 0; i < iters; i++) + { + auto tp = std::make_shared(queue_size, 1); + auto file_sink = std::make_shared(filename, true); + auto logger = std::make_shared("async_logger", std::move(file_sink), std::move(tp), async_overflow_policy::block); + bench_mt(howmany, std::move(logger), threads); + // verify_file(filename, howmany); + } + + spdlog::info(""); + spdlog::info("*********************************"); + spdlog::info("Queue Overflow Policy: overrun"); + spdlog::info("*********************************"); + // do same test but discard oldest if queue is full instead of blocking + filename = "logs/basic_async-overrun.log"; + for (int i = 0; i < iters; i++) + { + auto tp = std::make_shared(queue_size, 1); + auto file_sink = std::make_shared(filename, true); + auto logger = + std::make_shared("async_logger", std::move(file_sink), std::move(tp), async_overflow_policy::overrun_oldest); + bench_mt(howmany, std::move(logger), threads); + } + spdlog::shutdown(); + } + catch (std::exception &ex) + { + std::cerr << "Error: " << ex.what() << std::endl; + perror("Last error"); + return 1; + } + return 0; +} + +void thread_fun(std::shared_ptr logger, int howmany) +{ + for (int i = 0; i < howmany; i++) + { + logger->info("Hello logger: msg number {}", i); + } +} + +void bench_mt(int howmany, std::shared_ptr logger, int thread_count) +{ + using std::chrono::high_resolution_clock; + vector threads; + auto start = high_resolution_clock::now(); + + int msgs_per_thread = howmany / thread_count; + int msgs_per_thread_mod = howmany % thread_count; + for (int t = 0; t < thread_count; ++t) + { + if (t == 0 && msgs_per_thread_mod) + threads.push_back(std::thread(thread_fun, logger, msgs_per_thread + msgs_per_thread_mod)); + else + threads.push_back(std::thread(thread_fun, logger, msgs_per_thread)); + } + + for (auto &t : threads) + { + t.join(); + }; + + auto delta = high_resolution_clock::now() - start; + auto delta_d = duration_cast>(delta).count(); + spdlog::info("Elapsed: {} secs\t {:L}/sec", delta_d, int(howmany / delta_d)); +} diff --git a/Lumos/External/spdlog/bench/bench.cpp b/Lumos/External/spdlog/bench/bench.cpp new file mode 100644 index 000000000..ae47f047c --- /dev/null +++ b/Lumos/External/spdlog/bench/bench.cpp @@ -0,0 +1,248 @@ +// +// Copyright(c) 2015 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +// +// bench.cpp : spdlog benchmarks +// +#include "spdlog/spdlog.h" +#include "spdlog/sinks/basic_file_sink.h" +#include "spdlog/sinks/daily_file_sink.h" +#include "spdlog/sinks/null_sink.h" +#include "spdlog/sinks/rotating_file_sink.h" + +#if defined(SPDLOG_USE_STD_FORMAT) +# include +#elif defined(SPDLOG_FMT_EXTERNAL) +# include +#else +# include "spdlog/fmt/bundled/format.h" +#endif + +#include "utils.h" +#include +#include // EXIT_FAILURE +#include +#include +#include + +void bench(int howmany, std::shared_ptr log); +void bench_mt(int howmany, std::shared_ptr log, size_t thread_count); + +// void bench_default_api(int howmany, std::shared_ptr log); +// void bench_c_string(int howmany, std::shared_ptr log); + +static const size_t file_size = 30 * 1024 * 1024; +static const size_t rotating_files = 5; +static const int max_threads = 1000; + +void bench_threaded_logging(size_t threads, int iters) +{ + spdlog::info("**************************************************************"); + spdlog::info(spdlog::fmt_lib::format(std::locale("en_US.UTF-8"), "Multi threaded: {:L} threads, {:L} messages", threads, iters)); + spdlog::info("**************************************************************"); + + auto basic_mt = spdlog::basic_logger_mt("basic_mt", "logs/basic_mt.log", true); + bench_mt(iters, std::move(basic_mt), threads); + auto basic_mt_tracing = spdlog::basic_logger_mt("basic_mt/backtrace-on", "logs/basic_mt.log", true); + basic_mt_tracing->enable_backtrace(32); + bench_mt(iters, std::move(basic_mt_tracing), threads); + + spdlog::info(""); + auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "logs/rotating_mt.log", file_size, rotating_files); + bench_mt(iters, std::move(rotating_mt), threads); + auto rotating_mt_tracing = spdlog::rotating_logger_mt("rotating_mt/backtrace-on", "logs/rotating_mt.log", file_size, rotating_files); + rotating_mt_tracing->enable_backtrace(32); + bench_mt(iters, std::move(rotating_mt_tracing), threads); + + spdlog::info(""); + auto daily_mt = spdlog::daily_logger_mt("daily_mt", "logs/daily_mt.log"); + bench_mt(iters, std::move(daily_mt), threads); + auto daily_mt_tracing = spdlog::daily_logger_mt("daily_mt/backtrace-on", "logs/daily_mt.log"); + daily_mt_tracing->enable_backtrace(32); + bench_mt(iters, std::move(daily_mt_tracing), threads); + + spdlog::info(""); + auto empty_logger = std::make_shared("level-off"); + empty_logger->set_level(spdlog::level::off); + bench(iters, empty_logger); + auto empty_logger_tracing = std::make_shared("level-off/backtrace-on"); + empty_logger_tracing->set_level(spdlog::level::off); + empty_logger_tracing->enable_backtrace(32); + bench(iters, empty_logger_tracing); +} + +void bench_single_threaded(int iters) +{ + spdlog::info("**************************************************************"); + spdlog::info(spdlog::fmt_lib::format(std::locale("en_US.UTF-8"), "Single threaded: {} messages", iters)); + spdlog::info("**************************************************************"); + + auto basic_st = spdlog::basic_logger_st("basic_st", "logs/basic_st.log", true); + bench(iters, std::move(basic_st)); + + auto basic_st_tracing = spdlog::basic_logger_st("basic_st/backtrace-on", "logs/basic_st.log", true); + bench(iters, std::move(basic_st_tracing)); + + spdlog::info(""); + auto rotating_st = spdlog::rotating_logger_st("rotating_st", "logs/rotating_st.log", file_size, rotating_files); + bench(iters, std::move(rotating_st)); + auto rotating_st_tracing = spdlog::rotating_logger_st("rotating_st/backtrace-on", "logs/rotating_st.log", file_size, rotating_files); + rotating_st_tracing->enable_backtrace(32); + bench(iters, std::move(rotating_st_tracing)); + + spdlog::info(""); + auto daily_st = spdlog::daily_logger_st("daily_st", "logs/daily_st.log"); + bench(iters, std::move(daily_st)); + auto daily_st_tracing = spdlog::daily_logger_st("daily_st/backtrace-on", "logs/daily_st.log"); + daily_st_tracing->enable_backtrace(32); + bench(iters, std::move(daily_st_tracing)); + + spdlog::info(""); + auto empty_logger = std::make_shared("level-off"); + empty_logger->set_level(spdlog::level::off); + bench(iters, empty_logger); + + auto empty_logger_tracing = std::make_shared("level-off/backtrace-on"); + empty_logger_tracing->set_level(spdlog::level::off); + empty_logger_tracing->enable_backtrace(32); + bench(iters, empty_logger_tracing); +} + +int main(int argc, char *argv[]) +{ + spdlog::set_automatic_registration(false); + spdlog::default_logger()->set_pattern("[%^%l%$] %v"); + int iters = 250000; + size_t threads = 4; + try + { + + if (argc > 1) + { + iters = std::stoi(argv[1]); + } + if (argc > 2) + { + threads = std::stoul(argv[2]); + } + + if (threads > max_threads) + { + throw std::runtime_error(spdlog::fmt_lib::format("Number of threads exceeds maximum({})", max_threads)); + } + + bench_single_threaded(iters); + bench_threaded_logging(1, iters); + bench_threaded_logging(threads, iters); + } + catch (std::exception &ex) + { + spdlog::error(ex.what()); + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} + +void bench(int howmany, std::shared_ptr log) +{ + using std::chrono::duration; + using std::chrono::duration_cast; + using std::chrono::high_resolution_clock; + + auto start = high_resolution_clock::now(); + for (auto i = 0; i < howmany; ++i) + { + log->info("Hello logger: msg number {}", i); + } + + auto delta = high_resolution_clock::now() - start; + auto delta_d = duration_cast>(delta).count(); + + spdlog::info(spdlog::fmt_lib::format( + std::locale("en_US.UTF-8"), "{:<30} Elapsed: {:0.2f} secs {:>16L}/sec", log->name(), delta_d, int(howmany / delta_d))); + spdlog::drop(log->name()); +} + +void bench_mt(int howmany, std::shared_ptr log, size_t thread_count) +{ + using std::chrono::duration; + using std::chrono::duration_cast; + using std::chrono::high_resolution_clock; + + std::vector threads; + threads.reserve(thread_count); + auto start = high_resolution_clock::now(); + for (size_t t = 0; t < thread_count; ++t) + { + threads.emplace_back([&]() { + for (int j = 0; j < howmany / static_cast(thread_count); j++) + { + log->info("Hello logger: msg number {}", j); + } + }); + } + + for (auto &t : threads) + { + t.join(); + }; + + auto delta = high_resolution_clock::now() - start; + auto delta_d = duration_cast>(delta).count(); + spdlog::info(spdlog::fmt_lib::format( + std::locale("en_US.UTF-8"), "{:<30} Elapsed: {:0.2f} secs {:>16L}/sec", log->name(), delta_d, int(howmany / delta_d))); + spdlog::drop(log->name()); +} + +/* +void bench_default_api(int howmany, std::shared_ptr log) +{ + using std::chrono::high_resolution_clock; + using std::chrono::duration; + using std::chrono::duration_cast; + + auto orig_default = spdlog::default_logger(); + spdlog::set_default_logger(log); + auto start = high_resolution_clock::now(); + for (auto i = 0; i < howmany; ++i) + { + spdlog::info("Hello logger: msg number {}", i); + } + + auto delta = high_resolution_clock::now() - start; + auto delta_d = duration_cast>(delta).count(); + spdlog::drop(log->name()); + spdlog::set_default_logger(std::move(orig_default)); + spdlog::info("{:<30} Elapsed: {:0.2f} secs {:>16}/sec", log->name(), delta_d, int(howmany / delta_d)); +} + +void bench_c_string(int howmany, std::shared_ptr log) +{ + using std::chrono::high_resolution_clock; + using std::chrono::duration; + using std::chrono::duration_cast; + + const char *msg = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pharetra metus cursus " + "lacus placerat congue. Nulla egestas, mauris a tincidunt tempus, enim lectus volutpat mi, eu consequat sem " + "libero nec massa. In dapibus ipsum a diam rhoncus gravida. Etiam non dapibus eros. Donec fringilla dui sed " + "augue pretium, nec scelerisque est maximus. Nullam convallis, sem nec blandit maximus, nisi turpis ornare " + "nisl, sit amet volutpat neque massa eu odio. Maecenas malesuada quam ex, posuere congue nibh turpis duis."; + + auto orig_default = spdlog::default_logger(); + spdlog::set_default_logger(log); + auto start = high_resolution_clock::now(); + for (auto i = 0; i < howmany; ++i) + { + spdlog::log(spdlog::level::info, msg); + } + + auto delta = high_resolution_clock::now() - start; + auto delta_d = duration_cast>(delta).count(); + spdlog::drop(log->name()); + spdlog::set_default_logger(std::move(orig_default)); + spdlog::info("{:<30} Elapsed: {:0.2f} secs {:>16}/sec", log->name(), delta_d, int(howmany / delta_d)); +} + +*/ \ No newline at end of file diff --git a/Lumos/External/spdlog/bench/formatter-bench.cpp b/Lumos/External/spdlog/bench/formatter-bench.cpp new file mode 100644 index 000000000..1454c6bb8 --- /dev/null +++ b/Lumos/External/spdlog/bench/formatter-bench.cpp @@ -0,0 +1,80 @@ +// +// Copyright(c) 2018 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +#include "benchmark/benchmark.h" + +#include "spdlog/spdlog.h" +#include "spdlog/pattern_formatter.h" + +void bench_formatter(benchmark::State &state, std::string pattern) +{ + auto formatter = spdlog::details::make_unique(pattern); + spdlog::memory_buf_t dest; + std::string logger_name = "logger-name"; + const char *text = "Hello. This is some message with length of 80 "; + + spdlog::source_loc source_loc{"a/b/c/d/myfile.cpp", 123, "some_func()"}; + spdlog::details::log_msg msg(source_loc, logger_name, spdlog::level::info, text); + + for (auto _ : state) + { + dest.clear(); + formatter->format(msg, dest); + benchmark::DoNotOptimize(dest); + } +} + +void bench_formatters() +{ + // basic patterns(single flag) + std::string all_flags = "+vtPnlLaAbBcCYDmdHIMSefFprRTXzEisg@luioO%"; + std::vector basic_patterns; + for (auto &flag : all_flags) + { + auto pattern = std::string("%") + flag; + benchmark::RegisterBenchmark(pattern.c_str(), &bench_formatter, pattern); + + // pattern = std::string("%16") + flag; + // benchmark::RegisterBenchmark(pattern.c_str(), &bench_formatter, pattern); + // + // // bench center padding + // pattern = std::string("%=16") + flag; + // benchmark::RegisterBenchmark(pattern.c_str(), &bench_formatter, pattern); + } + + // complex patterns + std::vector patterns = { + "[%D %X] [%l] [%n] %v", + "[%Y-%m-%d %H:%M:%S.%e] [%l] [%n] %v", + "[%Y-%m-%d %H:%M:%S.%e] [%l] [%n] [%t] %v", + }; + for (auto &pattern : patterns) + { + benchmark::RegisterBenchmark(pattern.c_str(), &bench_formatter, pattern)->Iterations(2500000); + } +} + +int main(int argc, char *argv[]) +{ + + spdlog::set_pattern("[%^%l%$] %v"); + if (argc != 2) + { + spdlog::error("Usage: {} (or \"all\" to bench all)", argv[0]); + exit(1); + } + + std::string pattern = argv[1]; + if (pattern == "all") + { + bench_formatters(); + } + else + { + benchmark::RegisterBenchmark(pattern.c_str(), &bench_formatter, pattern); + } + benchmark::Initialize(&argc, argv); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/Lumos/External/spdlog/bench/latency.cpp b/Lumos/External/spdlog/bench/latency.cpp new file mode 100644 index 000000000..8f002ee12 --- /dev/null +++ b/Lumos/External/spdlog/bench/latency.cpp @@ -0,0 +1,189 @@ +// +// Copyright(c) 2018 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +// +// latency.cpp : spdlog latency benchmarks +// + +#include "benchmark/benchmark.h" + +#include "spdlog/spdlog.h" +#include "spdlog/async.h" +#include "spdlog/sinks/basic_file_sink.h" +#include "spdlog/sinks/daily_file_sink.h" +#include "spdlog/sinks/null_sink.h" +#include "spdlog/sinks/rotating_file_sink.h" + +void bench_c_string(benchmark::State &state, std::shared_ptr logger) +{ + const char *msg = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pharetra metus cursus " + "lacus placerat congue. Nulla egestas, mauris a tincidunt tempus, enim lectus volutpat mi, eu consequat sem " + "libero nec massa. In dapibus ipsum a diam rhoncus gravida. Etiam non dapibus eros. Donec fringilla dui sed " + "augue pretium, nec scelerisque est maximus. Nullam convallis, sem nec blandit maximus, nisi turpis ornare " + "nisl, sit amet volutpat neque massa eu odio. Maecenas malesuada quam ex, posuere congue nibh turpis duis."; + + for (auto _ : state) + { + logger->info(msg); + } +} + +void bench_logger(benchmark::State &state, std::shared_ptr logger) +{ + int i = 0; + for (auto _ : state) + { + logger->info("Hello logger: msg number {}...............", ++i); + } +} +void bench_global_logger(benchmark::State &state, std::shared_ptr logger) +{ + spdlog::set_default_logger(std::move(logger)); + int i = 0; + for (auto _ : state) + { + spdlog::info("Hello logger: msg number {}...............", ++i); + } +} + +void bench_disabled_macro(benchmark::State &state, std::shared_ptr logger) +{ + int i = 0; + benchmark::DoNotOptimize(i); // prevent unused warnings + benchmark::DoNotOptimize(logger); // prevent unused warnings + for (auto _ : state) + { + SPDLOG_LOGGER_DEBUG(logger, "Hello logger: msg number {}...............", i++); + } +} + +void bench_disabled_macro_global_logger(benchmark::State &state, std::shared_ptr logger) +{ + spdlog::set_default_logger(std::move(logger)); + int i = 0; + benchmark::DoNotOptimize(i); // prevent unused warnings + benchmark::DoNotOptimize(logger); // prevent unused warnings + for (auto _ : state) + { + SPDLOG_DEBUG("Hello logger: msg number {}...............", i++); + } +} + +#ifdef __linux__ +void bench_dev_null() +{ + auto dev_null_st = spdlog::basic_logger_st("/dev/null_st", "/dev/null"); + benchmark::RegisterBenchmark("/dev/null_st", bench_logger, std::move(dev_null_st))->UseRealTime(); + spdlog::drop("/dev/null_st"); + + auto dev_null_mt = spdlog::basic_logger_mt("/dev/null_mt", "/dev/null"); + benchmark::RegisterBenchmark("/dev/null_mt", bench_logger, std::move(dev_null_mt))->UseRealTime(); + spdlog::drop("/dev/null_mt"); +} +#endif // __linux__ + +int main(int argc, char *argv[]) +{ + using spdlog::sinks::null_sink_mt; + using spdlog::sinks::null_sink_st; + + size_t file_size = 30 * 1024 * 1024; + size_t rotating_files = 5; + int n_threads = benchmark::CPUInfo::Get().num_cpus; + + auto full_bench = argc > 1 && std::string(argv[1]) == "full"; + + // disabled loggers + auto disabled_logger = std::make_shared("bench", std::make_shared()); + disabled_logger->set_level(spdlog::level::off); + benchmark::RegisterBenchmark("disabled-at-compile-time", bench_disabled_macro, disabled_logger); + benchmark::RegisterBenchmark("disabled-at-compile-time (global logger)", bench_disabled_macro_global_logger, disabled_logger); + benchmark::RegisterBenchmark("disabled-at-runtime", bench_logger, disabled_logger); + benchmark::RegisterBenchmark("disabled-at-runtime (global logger)", bench_global_logger, disabled_logger); + // with backtrace of 64 + auto tracing_disabled_logger = std::make_shared("bench", std::make_shared()); + tracing_disabled_logger->enable_backtrace(64); + benchmark::RegisterBenchmark("disabled-at-runtime/backtrace", bench_logger, tracing_disabled_logger); + + auto null_logger_st = std::make_shared("bench", std::make_shared()); + benchmark::RegisterBenchmark("null_sink_st (500_bytes c_str)", bench_c_string, std::move(null_logger_st)); + benchmark::RegisterBenchmark("null_sink_st", bench_logger, null_logger_st); + benchmark::RegisterBenchmark("null_sink_st (global logger)", bench_global_logger, null_logger_st); + // with backtrace of 64 + auto tracing_null_logger_st = std::make_shared("bench", std::make_shared()); + tracing_null_logger_st->enable_backtrace(64); + benchmark::RegisterBenchmark("null_sink_st/backtrace", bench_logger, tracing_null_logger_st); + +#ifdef __linux + bench_dev_null(); +#endif // __linux__ + + if (full_bench) + { + // basic_st + auto basic_st = spdlog::basic_logger_st("basic_st", "latency_logs/basic_st.log", true); + benchmark::RegisterBenchmark("basic_st", bench_logger, std::move(basic_st))->UseRealTime(); + spdlog::drop("basic_st"); + // with backtrace of 64 + auto tracing_basic_st = spdlog::basic_logger_st("tracing_basic_st", "latency_logs/tracing_basic_st.log", true); + tracing_basic_st->enable_backtrace(64); + benchmark::RegisterBenchmark("basic_st/backtrace", bench_logger, std::move(tracing_basic_st))->UseRealTime(); + spdlog::drop("tracing_basic_st"); + + // rotating st + auto rotating_st = spdlog::rotating_logger_st("rotating_st", "latency_logs/rotating_st.log", file_size, rotating_files); + benchmark::RegisterBenchmark("rotating_st", bench_logger, std::move(rotating_st))->UseRealTime(); + spdlog::drop("rotating_st"); + // with backtrace of 64 + auto tracing_rotating_st = + spdlog::rotating_logger_st("tracing_rotating_st", "latency_logs/tracing_rotating_st.log", file_size, rotating_files); + benchmark::RegisterBenchmark("rotating_st/backtrace", bench_logger, std::move(tracing_rotating_st))->UseRealTime(); + spdlog::drop("tracing_rotating_st"); + + // daily st + auto daily_st = spdlog::daily_logger_mt("daily_st", "latency_logs/daily_st.log"); + benchmark::RegisterBenchmark("daily_st", bench_logger, std::move(daily_st))->UseRealTime(); + spdlog::drop("daily_st"); + auto tracing_daily_st = spdlog::daily_logger_mt("tracing_daily_st", "latency_logs/daily_st.log"); + benchmark::RegisterBenchmark("daily_st/backtrace", bench_logger, std::move(tracing_daily_st))->UseRealTime(); + spdlog::drop("tracing_daily_st"); + + // + // Multi threaded bench, 10 loggers using same logger concurrently + // + auto null_logger_mt = std::make_shared("bench", std::make_shared()); + benchmark::RegisterBenchmark("null_sink_mt", bench_logger, null_logger_mt)->Threads(n_threads)->UseRealTime(); + + // basic_mt + auto basic_mt = spdlog::basic_logger_mt("basic_mt", "latency_logs/basic_mt.log", true); + benchmark::RegisterBenchmark("basic_mt", bench_logger, std::move(basic_mt))->Threads(n_threads)->UseRealTime(); + spdlog::drop("basic_mt"); + + // rotating mt + auto rotating_mt = spdlog::rotating_logger_mt("rotating_mt", "latency_logs/rotating_mt.log", file_size, rotating_files); + benchmark::RegisterBenchmark("rotating_mt", bench_logger, std::move(rotating_mt))->Threads(n_threads)->UseRealTime(); + spdlog::drop("rotating_mt"); + + // daily mt + auto daily_mt = spdlog::daily_logger_mt("daily_mt", "latency_logs/daily_mt.log"); + benchmark::RegisterBenchmark("daily_mt", bench_logger, std::move(daily_mt))->Threads(n_threads)->UseRealTime(); + spdlog::drop("daily_mt"); + } + + // async + auto queue_size = 1024 * 1024 * 3; + auto tp = std::make_shared(queue_size, 1); + auto async_logger = std::make_shared( + "async_logger", std::make_shared(), std::move(tp), spdlog::async_overflow_policy::overrun_oldest); + benchmark::RegisterBenchmark("async_logger", bench_logger, async_logger)->Threads(n_threads)->UseRealTime(); + + auto async_logger_tracing = std::make_shared( + "async_logger_tracing", std::make_shared(), std::move(tp), spdlog::async_overflow_policy::overrun_oldest); + async_logger_tracing->enable_backtrace(32); + benchmark::RegisterBenchmark("async_logger/tracing", bench_logger, async_logger_tracing)->Threads(n_threads)->UseRealTime(); + + benchmark::Initialize(&argc, argv); + benchmark::RunSpecifiedBenchmarks(); +} diff --git a/Lumos/External/spdlog/bench/utils.h b/Lumos/External/spdlog/bench/utils.h new file mode 100644 index 000000000..916101283 --- /dev/null +++ b/Lumos/External/spdlog/bench/utils.h @@ -0,0 +1,34 @@ +// +// Copyright(c) 2015 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +#pragma once + +#include +#include +#include + +namespace utils { + +template +inline std::string format(const T &value) +{ + static std::locale loc(""); + std::stringstream ss; + ss.imbue(loc); + ss << value; + return ss.str(); +} + +template<> +inline std::string format(const double &value) +{ + static std::locale loc(""); + std::stringstream ss; + ss.imbue(loc); + ss << std::fixed << std::setprecision(1) << value; + return ss.str(); +} + +} // namespace utils diff --git a/Lumos/External/spdlog/cmake/ide.cmake b/Lumos/External/spdlog/cmake/ide.cmake new file mode 100644 index 000000000..a0656a5e8 --- /dev/null +++ b/Lumos/External/spdlog/cmake/ide.cmake @@ -0,0 +1,18 @@ +# --------------------------------------------------------------------------------------- +# IDE support for headers +# --------------------------------------------------------------------------------------- +set(SPDLOG_HEADERS_DIR "${CMAKE_CURRENT_LIST_DIR}/../include") + +file(GLOB SPDLOG_TOP_HEADERS "${SPDLOG_HEADERS_DIR}/spdlog/*.h") +file(GLOB SPDLOG_DETAILS_HEADERS "${SPDLOG_HEADERS_DIR}/spdlog/details/*.h") +file(GLOB SPDLOG_SINKS_HEADERS "${SPDLOG_HEADERS_DIR}/spdlog/sinks/*.h") +file(GLOB SPDLOG_FMT_HEADERS "${SPDLOG_HEADERS_DIR}/spdlog/fmt/*.h") +file(GLOB SPDLOG_FMT_BUNDELED_HEADERS "${SPDLOG_HEADERS_DIR}/spdlog/fmt/bundled/*.h") +set(SPDLOG_ALL_HEADERS ${SPDLOG_TOP_HEADERS} ${SPDLOG_DETAILS_HEADERS} ${SPDLOG_SINKS_HEADERS} ${SPDLOG_FMT_HEADERS} + ${SPDLOG_FMT_BUNDELED_HEADERS}) + +source_group("Header Files\\spdlog" FILES ${SPDLOG_TOP_HEADERS}) +source_group("Header Files\\spdlog\\details" FILES ${SPDLOG_DETAILS_HEADERS}) +source_group("Header Files\\spdlog\\sinks" FILES ${SPDLOG_SINKS_HEADERS}) +source_group("Header Files\\spdlog\\fmt" FILES ${SPDLOG_FMT_HEADERS}) +source_group("Header Files\\spdlog\\fmt\\bundled\\" FILES ${SPDLOG_FMT_BUNDELED_HEADERS}) diff --git a/Lumos/External/spdlog/cmake/pch.h.in b/Lumos/External/spdlog/cmake/pch.h.in new file mode 100644 index 000000000..a5f941507 --- /dev/null +++ b/Lumos/External/spdlog/cmake/pch.h.in @@ -0,0 +1,258 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#pragma once + +// details/pattern_formatter-inl.h +// fmt/bin_to_hex.h +// fmt/bundled/format-inl.h +#include + +// details/file_helper-inl.h +// details/os-inl.h +// fmt/bundled/core.h +// fmt/bundled/posix.h +// logger-inl.h +// sinks/daily_file_sink.h +// sinks/stdout_sinks.h +#include + +// details/os-inl.h +// fmt/bundled/posix.h +#include + +// details/os-inl.h +// details/pattern_formatter-inl.h +// fmt/bundled/core.h +// fmt/bundled/format-inl.h +#include + +// details/os-inl.h +// details/os.h +// details/pattern_formatter-inl.h +// details/pattern_formatter.h +// fmt/bundled/chrono.h +// sinks/daily_file_sink.h +// sinks/rotating_file_sink-inl.h +#include + +// fmt/bundled/format-inl.h +#include + +// fmt/bundled/format-inl.h +#include + +// fmt/bundled/format-inl.h +// fmt/bundled/format.h +#include + +// fmt/bundled/format-inl.h +#include + +// details/file_helper-inl.h +// fmt/bundled/format.h +// fmt/bundled/posix.h +// sinks/rotating_file_sink-inl.h +#include + +// details/circular_q.h +// details/thread_pool-inl.h +// fmt/bundled/format-inl.h +#include + +// async_logger-inl.h +// cfg/helpers-inl.h +// log_levels.h +// common.h +// details/file_helper-inl.h +// details/log_msg.h +// details/os-inl.h +// details/pattern_formatter-inl.h +// details/pattern_formatter.h +// details/registry-inl.h +// details/registry.h +// details/tcp_client-windows.h +// details/tcp_client.h +// fmt/bundled/core.h +// sinks/android_sink.h +// sinks/ansicolor_sink.h +// sinks/basic_file_sink.h +// sinks/daily_file_sink.h +// sinks/dup_filter_sink.h +// sinks/msvc_sink.h +// sinks/ringbuffer_sink.h +// sinks/rotating_file_sink-inl.h +// sinks/rotating_file_sink.h +// sinks/syslog_sink.h +// sinks/tcp_sink.h +// sinks/win_eventlog_sink.h +// sinks/wincolor_sink.h +// spdlog.h: +#include + +// cfg/helpers-inl.h +// fmt/bundled/chrono.h +#include + +// fmt/bundled/ostream.h +// sinks/ostream_sink.h +#include + +// cfg/log_levels.h +// details/registry-inl.h +// details/registry.h +#include + +// details/circular_q.h +// details/pattern_formatter-inl.h +// details/pattern_formatter.h +// details/thread_pool.h +// fmt/bundled/compile.h +// logger.h +// sinks/dist_sink.h +// sinks/ringbuffer_sink.h +// sinks/win_eventlog_sink.h +#include + +// details/os-inl.h +// details/pattern_formatter-inl.h +// sinks/ansicolor_sink.h +// sinks/syslog_sink.h +// sinks/systemd_sink.h +// sinks/wincolor_sink.h +#include + +// details/file_helper-inl.h +// details/file_helper.h +// sinks/rotating_file_sink-inl.h +#include + +// details/os-inl.h +// fmt/bundled/format.h +// fmt/bundled/printf.h +#include + +// common.h +// details/backtracer.h +// details/null_mutex.h +#include + +// common.h +// details/backtracer.h +// details/null_mutex.h +#include + +// common.h +#include + +// common.h +#include + +// common.h +// details/fmt_helper.h +// fmt/bundled/core.h +// fmt/bundled/ranges.h +#include + +// cfg/helpers-inl.h +// details/null_mutex.h +// details/pattern_formatter-inl.h +#include + +// async.h +// async_logger-inl.h +// common.h +// details/pattern_formatter-inl.h +// details/pattern_formatter.h +// details/registry-inl.h +// details/registry.h +// details/thread_pool.h +// fmt/bundled/format.h +// sinks/ansicolor_sink.h +// sinks/base_sink-inl.h +// sinks/dist_sink.h +// sinks/stdout_sinks-inl.h +// sinks/wincolor_sink.h +// spdlog.h +#include + +// async.h +// common.h +// details/backtracer.h +// details/periodic_worker.h +// details/registry-inl.h +// details/registry.h +// details/thread_pool.h +// sinks/tcp_sink.h +// spdlog.h +#include + +// details/mpmc_blocking_q.h +// details/periodic_worker.h +#include + +// details/os-inl.h +// fmt/bundled/format.h +// fmt/bundled/printf.h +// sinks/dist_sink.h +#include + +// common.h +// details/file_helper-inl.h +// details/fmt_helper.h +// details/os-inl.h +// details/pattern_formatter-inl.h +// details/pattern_formatter.h +// details/periodic_worker.h +// details/registry-inl.h +// details/registry.h +// details/thread_pool.h +// fmt/bundled/chrono.h +// sinks/android_sink.h +// sinks/daily_file_sink.h +// sinks/dup_filter_sink.h +// sinks/rotating_file_sink-inl.h +// sinks/rotating_file_sink.h +// sinks/tcp_sink.h +// spdlog.h +#include + +// details/file_helper-inl.h +// details/os-inl.h +// details/pattern_formatter-inl.h +// details/periodic_worker.h +// details/thread_pool.h +// sinks/android_sink.h +#include + +// async.h +// details/backtracer.h +// details/console_globals.h +// details/mpmc_blocking_q.h +// details/pattern_formatter-inl.h +// details/periodic_worker.h +// details/registry.h +// sinks/android_sink.h +// sinks/ansicolor_sink.h +// sinks/basic_file_sink.h +// sinks/daily_file_sink.h +// sinks/dist_sink.h +// sinks/dup_filter_sink.h +// sinks/msvc_sink.h +// sinks/null_sink.h +// sinks/ostream_sink.h +// sinks/ringbuffer_sink.h +// sinks/rotating_file_sink-inl.h +// sinks/rotating_file_sink.h +// sinks/tcp_sink.h +// sinks/win_eventlog_sink.h +// sinks/wincolor_sink.h +// +// color_sinks.cpp +// file_sinks.cpp +// spdlog.cpp +// stdout_sinks.cpp +#include + +// spdlog +#include \ No newline at end of file diff --git a/Lumos/External/spdlog/cmake/spdlog.pc.in b/Lumos/External/spdlog/cmake/spdlog.pc.in new file mode 100644 index 000000000..ffab5d6f8 --- /dev/null +++ b/Lumos/External/spdlog/cmake/spdlog.pc.in @@ -0,0 +1,13 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +includedir=@PKG_CONFIG_INCLUDEDIR@ +libdir=@PKG_CONFIG_LIBDIR@ + +Name: lib@PROJECT_NAME@ +Description: Fast C++ logging library. +URL: https://github.com/gabime/@PROJECT_NAME@ +Version: @SPDLOG_VERSION@ +CFlags: -I${includedir} @PKG_CONFIG_DEFINES@ +Libs: -L${libdir} -lspdlog -pthread +Requires: @PKG_CONFIG_REQUIRES@ + diff --git a/Lumos/External/spdlog/cmake/spdlogConfig.cmake.in b/Lumos/External/spdlog/cmake/spdlogConfig.cmake.in new file mode 100644 index 000000000..d8a3ac164 --- /dev/null +++ b/Lumos/External/spdlog/cmake/spdlogConfig.cmake.in @@ -0,0 +1,20 @@ +# Copyright(c) 2019 spdlog authors +# Distributed under the MIT License (http://opensource.org/licenses/MIT) + +@PACKAGE_INIT@ + +find_package(Threads REQUIRED) + +set(SPDLOG_FMT_EXTERNAL @SPDLOG_FMT_EXTERNAL@) +set(SPDLOG_FMT_EXTERNAL_HO @SPDLOG_FMT_EXTERNAL_HO@) +set(config_targets_file @config_targets_file@) + +if(SPDLOG_FMT_EXTERNAL OR SPDLOG_FMT_EXTERNAL_HO) + include(CMakeFindDependencyMacro) + find_dependency(fmt CONFIG) +endif() + + +include("${CMAKE_CURRENT_LIST_DIR}/${config_targets_file}") + +check_required_components(spdlog) diff --git a/Lumos/External/spdlog/cmake/utils.cmake b/Lumos/External/spdlog/cmake/utils.cmake new file mode 100644 index 000000000..85fcd80f7 --- /dev/null +++ b/Lumos/External/spdlog/cmake/utils.cmake @@ -0,0 +1,62 @@ +# Get spdlog version from include/spdlog/version.h and put it in SPDLOG_VERSION +function(spdlog_extract_version) + file(READ "${CMAKE_CURRENT_LIST_DIR}/include/spdlog/version.h" file_contents) + string(REGEX MATCH "SPDLOG_VER_MAJOR ([0-9]+)" _ "${file_contents}") + if(NOT CMAKE_MATCH_COUNT EQUAL 1) + message(FATAL_ERROR "Could not extract major version number from spdlog/version.h") + endif() + set(ver_major ${CMAKE_MATCH_1}) + + string(REGEX MATCH "SPDLOG_VER_MINOR ([0-9]+)" _ "${file_contents}") + if(NOT CMAKE_MATCH_COUNT EQUAL 1) + message(FATAL_ERROR "Could not extract minor version number from spdlog/version.h") + endif() + + set(ver_minor ${CMAKE_MATCH_1}) + string(REGEX MATCH "SPDLOG_VER_PATCH ([0-9]+)" _ "${file_contents}") + if(NOT CMAKE_MATCH_COUNT EQUAL 1) + message(FATAL_ERROR "Could not extract patch version number from spdlog/version.h") + endif() + set(ver_patch ${CMAKE_MATCH_1}) + + set(SPDLOG_VERSION_MAJOR ${ver_major} PARENT_SCOPE) + set(SPDLOG_VERSION_MINOR ${ver_minor} PARENT_SCOPE) + set(SPDLOG_VERSION_PATCH ${ver_patch} PARENT_SCOPE) + set(SPDLOG_VERSION "${ver_major}.${ver_minor}.${ver_patch}" PARENT_SCOPE) +endfunction() + +# Turn on warnings on the given target +function(spdlog_enable_warnings target_name) + if(SPDLOG_BUILD_WARNINGS) + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + list(APPEND MSVC_OPTIONS "/W3") + if(MSVC_VERSION GREATER 1900) # Allow non fatal security warnings for msvc 2015 + list(APPEND MSVC_OPTIONS "/WX") + endif() + endif() + + target_compile_options( + ${target_name} + PRIVATE $<$,$,$>: + -Wall + -Wextra + -Wconversion + -pedantic + -Werror + -Wfatal-errors> + $<$:${MSVC_OPTIONS}>) + endif() +endfunction() + +# Enable address sanitizer (gcc/clang only) +function(spdlog_enable_sanitizer target_name) + if(NOT CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") + message(FATAL_ERROR "Sanitizer supported only for gcc/clang") + endif() + message(STATUS "Address sanitizer enabled") + target_compile_options(${target_name} PRIVATE -fsanitize=address,undefined) + target_compile_options(${target_name} PRIVATE -fno-sanitize=signed-integer-overflow) + target_compile_options(${target_name} PRIVATE -fno-sanitize-recover=all) + target_compile_options(${target_name} PRIVATE -fno-omit-frame-pointer) + target_link_libraries(${target_name} PRIVATE -fsanitize=address,undefined -fuse-ld=gold) +endfunction() diff --git a/Lumos/External/spdlog/cmake/version.rc.in b/Lumos/External/spdlog/cmake/version.rc.in new file mode 100644 index 000000000..a86c13853 --- /dev/null +++ b/Lumos/External/spdlog/cmake/version.rc.in @@ -0,0 +1,42 @@ +#define APSTUDIO_READONLY_SYMBOLS +#include +#undef APSTUDIO_READONLY_SYMBOLS + +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US + + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @SPDLOG_VERSION_MAJOR@,@SPDLOG_VERSION_MINOR@,@SPDLOG_VERSION_PATCH@,0 + PRODUCTVERSION @SPDLOG_VERSION_MAJOR@,@SPDLOG_VERSION_MINOR@,@SPDLOG_VERSION_PATCH@,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "FileDescription", "spdlog dll\0" + VALUE "FileVersion", "@SPDLOG_VERSION@.0\0" + VALUE "InternalName", "spdlog.dll\0" + VALUE "LegalCopyright", "Copyright (C) spdlog\0" + VALUE "ProductName", "spdlog\0" + VALUE "ProductVersion", "@SPDLOG_VERSION@.0\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + + + + diff --git a/Lumos/External/spdlog/example/CMakeLists.txt b/Lumos/External/spdlog/example/CMakeLists.txt new file mode 100644 index 000000000..a7863493c --- /dev/null +++ b/Lumos/External/spdlog/example/CMakeLists.txt @@ -0,0 +1,23 @@ +# Copyright(c) 2019 spdlog authors Distributed under the MIT License (http://opensource.org/licenses/MIT) + +cmake_minimum_required(VERSION 3.10) +project(spdlog_examples CXX) + +if(NOT TARGET spdlog) + # Stand-alone build + find_package(spdlog REQUIRED) +endif() + +# --------------------------------------------------------------------------------------- +# Example of using pre-compiled library +# --------------------------------------------------------------------------------------- +add_executable(example example.cpp) +target_link_libraries(example PRIVATE spdlog::spdlog $<$:ws2_32>) + +# --------------------------------------------------------------------------------------- +# Example of using header-only library +# --------------------------------------------------------------------------------------- +if(SPDLOG_BUILD_EXAMPLE_HO) + add_executable(example_header_only example.cpp) + target_link_libraries(example_header_only PRIVATE spdlog::spdlog_header_only) +endif() diff --git a/Lumos/External/spdlog/example/example.cpp b/Lumos/External/spdlog/example/example.cpp new file mode 100644 index 000000000..d6609ed51 --- /dev/null +++ b/Lumos/External/spdlog/example/example.cpp @@ -0,0 +1,398 @@ +// +// Copyright(c) 2015 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +// spdlog usage example + +#include +#include + +void load_levels_example(); +void stdout_logger_example(); +void basic_example(); +void rotating_example(); +void daily_example(); +void callback_example(); +void async_example(); +void binary_example(); +void vector_example(); +void stopwatch_example(); +void trace_example(); +void multi_sink_example(); +void user_defined_example(); +void err_handler_example(); +void syslog_example(); +void udp_example(); +void custom_flags_example(); +void file_events_example(); +void replace_default_logger_example(); + +#include "spdlog/spdlog.h" +#include "spdlog/cfg/env.h" // support for loading levels from the environment variable +#include "spdlog/fmt/ostr.h" // support for user defined types + + +int main(int, char *[]) +{ + // Log levels can be loaded from argv/env using "SPDLOG_LEVEL" + load_levels_example(); + + spdlog::info("Welcome to spdlog version {}.{}.{} !", SPDLOG_VER_MAJOR, SPDLOG_VER_MINOR, SPDLOG_VER_PATCH); + + spdlog::warn("Easy padding in numbers like {:08d}", 12); + spdlog::critical("Support for int: {0:d}; hex: {0:x}; oct: {0:o}; bin: {0:b}", 42); + spdlog::info("Support for floats {:03.2f}", 1.23456); + spdlog::info("Positional args are {1} {0}..", "too", "supported"); + spdlog::info("{:>8} aligned, {:<8} aligned", "right", "left"); + + // Runtime log levels + spdlog::set_level(spdlog::level::info); // Set global log level to info + spdlog::debug("This message should not be displayed!"); + spdlog::set_level(spdlog::level::trace); // Set specific logger's log level + spdlog::debug("This message should be displayed.."); + + // Customize msg format for all loggers + spdlog::set_pattern("[%H:%M:%S %z] [%^%L%$] [thread %t] %v"); + spdlog::info("This an info message with custom format"); + spdlog::set_pattern("%+"); // back to default format + spdlog::set_level(spdlog::level::info); + + // Backtrace support + // Loggers can store in a ring buffer all messages (including debug/trace) for later inspection. + // When needed, call dump_backtrace() to see what happened: + spdlog::enable_backtrace(10); // create ring buffer with capacity of 10 messages + for (int i = 0; i < 100; i++) + { + spdlog::debug("Backtrace message {}", i); // not logged.. + } + // e.g. if some error happened: + spdlog::dump_backtrace(); // log them now! + + try + { + stdout_logger_example(); + basic_example(); + rotating_example(); + daily_example(); + callback_example(); + async_example(); + binary_example(); + vector_example(); + multi_sink_example(); + user_defined_example(); + err_handler_example(); + trace_example(); + stopwatch_example(); + udp_example(); + custom_flags_example(); + file_events_example(); + replace_default_logger_example(); + + // Flush all *registered* loggers using a worker thread every 3 seconds. + // note: registered loggers *must* be thread safe for this to work correctly! + spdlog::flush_every(std::chrono::seconds(3)); + + // Apply some function on all registered loggers + spdlog::apply_all([&](std::shared_ptr l) { l->info("End of example."); }); + + // Release all spdlog resources, and drop all loggers in the registry. + // This is optional (only mandatory if using windows + async log). + spdlog::shutdown(); + } + + // Exceptions will only be thrown upon failed logger or sink construction (not during logging). + catch (const spdlog::spdlog_ex &ex) + { + std::printf("Log initialization failed: %s\n", ex.what()); + return 1; + } +} + +#include "spdlog/sinks/stdout_color_sinks.h" +// or #include "spdlog/sinks/stdout_sinks.h" if no colors needed. +void stdout_logger_example() +{ + // Create color multi threaded logger. + auto console = spdlog::stdout_color_mt("console"); + // or for stderr: + // auto console = spdlog::stderr_color_mt("error-logger"); +} + +#include "spdlog/sinks/basic_file_sink.h" +void basic_example() +{ + // Create basic file logger (not rotated). + auto my_logger = spdlog::basic_logger_mt("file_logger", "logs/basic-log.txt", true); +} + +#include "spdlog/sinks/rotating_file_sink.h" +void rotating_example() +{ + // Create a file rotating logger with 5mb size max and 3 rotated files. + auto rotating_logger = spdlog::rotating_logger_mt("some_logger_name", "logs/rotating.txt", 1048576 * 5, 3); +} + +#include "spdlog/sinks/daily_file_sink.h" +void daily_example() +{ + // Create a daily logger - a new file is created every day on 2:30am. + auto daily_logger = spdlog::daily_logger_mt("daily_logger", "logs/daily.txt", 2, 30); +} + +#include "spdlog/sinks/callback_sink.h" +void callback_example() +{ + // Create the logger + auto logger = spdlog::callback_logger_mt("custom_callback_logger", [](const spdlog::details::log_msg & /*msg*/) { + // do what you need to do with msg + }); +} + +#include "spdlog/cfg/env.h" +void load_levels_example() +{ + // Set the log level to "info" and mylogger to "trace": + // SPDLOG_LEVEL=info,mylogger=trace && ./example + spdlog::cfg::load_env_levels(); + // or from command line: + // ./example SPDLOG_LEVEL=info,mylogger=trace + // #include "spdlog/cfg/argv.h" // for loading levels from argv + // spdlog::cfg::load_argv_levels(args, argv); +} + +#include "spdlog/async.h" +void async_example() +{ + // Default thread pool settings can be modified *before* creating the async logger: + // spdlog::init_thread_pool(32768, 1); // queue with max 32k items 1 backing thread. + auto async_file = spdlog::basic_logger_mt("async_file_logger", "logs/async_log.txt"); + // alternatively: + // auto async_file = spdlog::create_async("async_file_logger", "logs/async_log.txt"); + + for (int i = 1; i < 101; ++i) + { + async_file->info("Async message #{}", i); + } +} + +// Log binary data as hex. +// Many types of std::container types can be used. +// Iterator ranges are supported too. +// Format flags: +// {:X} - print in uppercase. +// {:s} - don't separate each byte with space. +// {:p} - don't print the position on each line start. +// {:n} - don't split the output to lines. + +#if !defined SPDLOG_USE_STD_FORMAT || defined(_MSC_VER) +#include "spdlog/fmt/bin_to_hex.h" +void binary_example() +{ + std::vector buf(80); + for (int i = 0; i < 80; i++) + { + buf.push_back(static_cast(i & 0xff)); + } + spdlog::info("Binary example: {}", spdlog::to_hex(buf)); + spdlog::info("Another binary example:{:n}", spdlog::to_hex(std::begin(buf), std::begin(buf) + 10)); + // more examples: + // logger->info("uppercase: {:X}", spdlog::to_hex(buf)); + // logger->info("uppercase, no delimiters: {:Xs}", spdlog::to_hex(buf)); + // logger->info("uppercase, no delimiters, no position info: {:Xsp}", spdlog::to_hex(buf)); + // logger->info("hexdump style: {:a}", spdlog::to_hex(buf)); + // logger->info("hexdump style, 20 chars per line {:a}", spdlog::to_hex(buf, 20)); +} +#else +void binary_example() { + // not supported with std::format yet +} +#endif + +// Log a vector of numbers +#ifndef SPDLOG_USE_STD_FORMAT +# include "spdlog/fmt/ranges.h" +void vector_example() +{ + std::vector vec = {1, 2, 3}; + spdlog::info("Vector example: {}", vec); +} + +#else +void vector_example() {} +#endif + +// ! DSPDLOG_USE_STD_FORMAT + +// Compile time log levels. +// define SPDLOG_ACTIVE_LEVEL to required level (e.g. SPDLOG_LEVEL_TRACE) +void trace_example() +{ + // trace from default logger + SPDLOG_TRACE("Some trace message.. {} ,{}", 1, 3.23); + // debug from default logger + SPDLOG_DEBUG("Some debug message.. {} ,{}", 1, 3.23); + + // trace from logger object + auto logger = spdlog::get("file_logger"); + SPDLOG_LOGGER_TRACE(logger, "another trace message"); +} + +// stopwatch example +#include "spdlog/stopwatch.h" +#include +void stopwatch_example() +{ + spdlog::stopwatch sw; + std::this_thread::sleep_for(std::chrono::milliseconds(123)); + spdlog::info("Stopwatch: {} seconds", sw); +} + +#include "spdlog/sinks/udp_sink.h" +void udp_example() +{ + spdlog::sinks::udp_sink_config cfg("127.0.0.1", 11091); + auto my_logger = spdlog::udp_logger_mt("udplog", cfg); + my_logger->set_level(spdlog::level::debug); + my_logger->info("hello world"); +} + +// A logger with multiple sinks (stdout and file) - each with a different format and log level. +void multi_sink_example() +{ + auto console_sink = std::make_shared(); + console_sink->set_level(spdlog::level::warn); + console_sink->set_pattern("[multi_sink_example] [%^%l%$] %v"); + + auto file_sink = std::make_shared("logs/multisink.txt", true); + file_sink->set_level(spdlog::level::trace); + + spdlog::logger logger("multi_sink", {console_sink, file_sink}); + logger.set_level(spdlog::level::debug); + logger.warn("this should appear in both console and file"); + logger.info("this message should not appear in the console, only in the file"); +} + +// User defined types logging +struct my_type +{ + int i = 0; + explicit my_type(int i) + : i(i){}; +}; + +#ifndef SPDLOG_USE_STD_FORMAT // when using fmtlib +template<> +struct fmt::formatter : fmt::formatter +{ + auto format(my_type my, format_context &ctx) -> decltype(ctx.out()) + { + return fmt::format_to(ctx.out(), "[my_type i={}]", my.i); + } +}; + +#else // when using std::format +template<> +struct std::formatter : std::formatter +{ + auto format(my_type my, format_context &ctx) const -> decltype(ctx.out()) + { + return format_to(ctx.out(), "[my_type i={}]", my.i); + } +}; +#endif + +void user_defined_example() +{ + spdlog::info("user defined type: {}", my_type(14)); +} + +// Custom error handler. Will be triggered on log failure. +void err_handler_example() +{ + // can be set globally or per logger(logger->set_error_handler(..)) + spdlog::set_error_handler([](const std::string &msg) { printf("*** Custom log error handler: %s ***\n", msg.c_str()); }); +} + +// syslog example (linux/osx/freebsd) +#ifndef _WIN32 +# include "spdlog/sinks/syslog_sink.h" +void syslog_example() +{ + std::string ident = "spdlog-example"; + auto syslog_logger = spdlog::syslog_logger_mt("syslog", ident, LOG_PID); + syslog_logger->warn("This is warning that will end up in syslog."); +} +#endif + +// Android example. +#if defined(__ANDROID__) +# include "spdlog/sinks/android_sink.h" +void android_example() +{ + std::string tag = "spdlog-android"; + auto android_logger = spdlog::android_logger_mt("android", tag); + android_logger->critical("Use \"adb shell logcat\" to view this message."); +} +#endif + +// Log patterns can contain custom flags. +// this will add custom flag '%*' which will be bound to a instance +#include "spdlog/pattern_formatter.h" +class my_formatter_flag : public spdlog::custom_flag_formatter +{ +public: + void format(const spdlog::details::log_msg &, const std::tm &, spdlog::memory_buf_t &dest) override + { + std::string some_txt = "custom-flag"; + dest.append(some_txt.data(), some_txt.data() + some_txt.size()); + } + + std::unique_ptr clone() const override + { + return spdlog::details::make_unique(); + } +}; + +void custom_flags_example() +{ + + using spdlog::details::make_unique; // for pre c++14 + auto formatter = make_unique(); + formatter->add_flag('*').set_pattern("[%n] [%*] [%^%l%$] %v"); + // set the new formatter using spdlog::set_formatter(formatter) or logger->set_formatter(formatter) + // spdlog::set_formatter(std::move(formatter)); +} + +void file_events_example() +{ + // pass the spdlog::file_event_handlers to file sinks for open/close log file notifications + spdlog::file_event_handlers handlers; + handlers.before_open = [](spdlog::filename_t filename) { spdlog::info("Before opening {}", filename); }; + handlers.after_open = [](spdlog::filename_t filename, std::FILE *fstream) { + spdlog::info("After opening {}", filename); + fputs("After opening\n", fstream); + }; + handlers.before_close = [](spdlog::filename_t filename, std::FILE *fstream) { + spdlog::info("Before closing {}", filename); + fputs("Before closing\n", fstream); + }; + handlers.after_close = [](spdlog::filename_t filename) { spdlog::info("After closing {}", filename); }; + auto file_sink = std::make_shared("logs/events-sample.txt", true, handlers); + spdlog::logger my_logger("some_logger", file_sink); + my_logger.info("Some log line"); +} + +void replace_default_logger_example() +{ + // store the old logger so we don't break other examples. + auto old_logger = spdlog::default_logger(); + + auto new_logger = spdlog::basic_logger_mt("new_default_logger", "logs/new-default-log.txt", true); + spdlog::set_default_logger(new_logger); + spdlog::set_level(spdlog::level::info); + spdlog::debug("This message should not be displayed!"); + spdlog::set_level(spdlog::level::trace); + spdlog::debug("This message should be displayed.."); + + spdlog::set_default_logger(old_logger); +} diff --git a/Lumos/External/spdlog/include/spdlog/async.h b/Lumos/External/spdlog/include/spdlog/async.h index 6406822c5..94f9f6d94 100644 --- a/Lumos/External/spdlog/include/spdlog/async.h +++ b/Lumos/External/spdlog/include/spdlog/async.h @@ -73,16 +73,22 @@ inline std::shared_ptr create_async_nb(std::string logger_name, } // set global thread pool. -inline void init_thread_pool(size_t q_size, size_t thread_count, std::function on_thread_start) +inline void init_thread_pool( + size_t q_size, size_t thread_count, std::function on_thread_start, std::function on_thread_stop) { - auto tp = std::make_shared(q_size, thread_count, on_thread_start); + auto tp = std::make_shared(q_size, thread_count, on_thread_start, on_thread_stop); details::registry::instance().set_tp(std::move(tp)); } -// set global thread pool. +inline void init_thread_pool(size_t q_size, size_t thread_count, std::function on_thread_start) +{ + init_thread_pool(q_size, thread_count, on_thread_start, [] {}); +} + inline void init_thread_pool(size_t q_size, size_t thread_count) { - init_thread_pool(q_size, thread_count, [] {}); + init_thread_pool( + q_size, thread_count, [] {}, [] {}); } // get the global thread pool. diff --git a/Lumos/External/spdlog/include/spdlog/async_logger-inl.h b/Lumos/External/spdlog/include/spdlog/async_logger-inl.h index 6fac8fc9f..4de8382a6 100644 --- a/Lumos/External/spdlog/include/spdlog/async_logger-inl.h +++ b/Lumos/External/spdlog/include/spdlog/async_logger-inl.h @@ -24,29 +24,27 @@ SPDLOG_INLINE spdlog::async_logger::async_logger( {} // send the log message to the thread pool -SPDLOG_INLINE void spdlog::async_logger::sink_it_(const details::log_msg &msg) +SPDLOG_INLINE void spdlog::async_logger::sink_it_(const details::log_msg &msg){ + SPDLOG_TRY{if (auto pool_ptr = thread_pool_.lock()){pool_ptr->post_log(shared_from_this(), msg, overflow_policy_); +} +else { - if (auto pool_ptr = thread_pool_.lock()) - { - pool_ptr->post_log(shared_from_this(), msg, overflow_policy_); - } - else - { - throw_spdlog_ex("async log: thread pool doesn't exist anymore"); - } + throw_spdlog_ex("async log: thread pool doesn't exist anymore"); +} +} +SPDLOG_LOGGER_CATCH(msg.source) } // send flush request to the thread pool -SPDLOG_INLINE void spdlog::async_logger::flush_() +SPDLOG_INLINE void spdlog::async_logger::flush_(){ + SPDLOG_TRY{if (auto pool_ptr = thread_pool_.lock()){pool_ptr->post_flush(shared_from_this(), overflow_policy_); +} +else { - if (auto pool_ptr = thread_pool_.lock()) - { - pool_ptr->post_flush(shared_from_this(), overflow_policy_); - } - else - { - throw_spdlog_ex("async flush: thread pool doesn't exist anymore"); - } + throw_spdlog_ex("async flush: thread pool doesn't exist anymore"); +} +} +SPDLOG_LOGGER_CATCH(source_loc()) } // @@ -62,7 +60,7 @@ SPDLOG_INLINE void spdlog::async_logger::backend_sink_it_(const details::log_msg { sink->log(msg); } - SPDLOG_LOGGER_CATCH() + SPDLOG_LOGGER_CATCH(msg.source) } } @@ -80,7 +78,7 @@ SPDLOG_INLINE void spdlog::async_logger::backend_flush_() { sink->flush(); } - SPDLOG_LOGGER_CATCH() + SPDLOG_LOGGER_CATCH(source_loc()) } } diff --git a/Lumos/External/spdlog/include/spdlog/common-inl.h b/Lumos/External/spdlog/include/spdlog/common-inl.h index f83476563..728f98317 100644 --- a/Lumos/External/spdlog/include/spdlog/common-inl.h +++ b/Lumos/External/spdlog/include/spdlog/common-inl.h @@ -55,9 +55,13 @@ SPDLOG_INLINE spdlog_ex::spdlog_ex(std::string msg) SPDLOG_INLINE spdlog_ex::spdlog_ex(const std::string &msg, int last_errno) { +#ifdef SPDLOG_USE_STD_FORMAT + msg_ = std::system_error(std::error_code(last_errno, std::generic_category()), msg).what(); +#else memory_buf_t outbuf; fmt::format_system_error(outbuf, last_errno, msg.c_str()); msg_ = fmt::to_string(outbuf); +#endif } SPDLOG_INLINE const char *spdlog_ex::what() const SPDLOG_NOEXCEPT diff --git a/Lumos/External/spdlog/include/spdlog/common.h b/Lumos/External/spdlog/include/spdlog/common.h index d64348931..0a262eb2c 100644 --- a/Lumos/External/spdlog/include/spdlog/common.h +++ b/Lumos/External/spdlog/include/spdlog/common.h @@ -14,16 +14,30 @@ #include #include #include +#include + +#ifdef SPDLOG_USE_STD_FORMAT +# include +# if __cpp_lib_format >= 202207L +# include +# else +# include +# endif +#endif #ifdef SPDLOG_COMPILED_LIB # undef SPDLOG_HEADER_ONLY -# if defined(_WIN32) && defined(SPDLOG_SHARED_LIB) -# ifdef spdlog_EXPORTS -# define SPDLOG_API __declspec(dllexport) -# else -# define SPDLOG_API __declspec(dllimport) +# if defined(SPDLOG_SHARED_LIB) +# if defined(_WIN32) +# ifdef spdlog_EXPORTS +# define SPDLOG_API __declspec(dllexport) +# else // !spdlog_EXPORTS +# define SPDLOG_API __declspec(dllimport) +# endif +# else // !defined(_WIN32) +# define SPDLOG_API __attribute__((visibility("default"))) # endif -# else // !defined(_WIN32) || !defined(SPDLOG_SHARED_LIB) +# else // !defined(SPDLOG_SHARED_LIB) # define SPDLOG_API # endif # define SPDLOG_INLINE @@ -35,23 +49,30 @@ #include -// backward compatibility with fmt versions older than 8 -#if FMT_VERSION >= 80000 +#if !defined(SPDLOG_USE_STD_FORMAT) && FMT_VERSION >= 80000 // backward compatibility with fmt versions older than 8 # define SPDLOG_FMT_RUNTIME(format_string) fmt::runtime(format_string) +# define SPDLOG_FMT_STRING(format_string) FMT_STRING(format_string) # if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) # include # endif #else # define SPDLOG_FMT_RUNTIME(format_string) format_string +# define SPDLOG_FMT_STRING(format_string) format_string #endif -// visual studio upto 2013 does not support noexcept nor constexpr +// visual studio up to 2013 does not support noexcept nor constexpr #if defined(_MSC_VER) && (_MSC_VER < 1900) # define SPDLOG_NOEXCEPT _NOEXCEPT # define SPDLOG_CONSTEXPR +# define SPDLOG_CONSTEXPR_FUNC inline #else # define SPDLOG_NOEXCEPT noexcept # define SPDLOG_CONSTEXPR constexpr +# if __cplusplus >= 201402L +# define SPDLOG_CONSTEXPR_FUNC constexpr +# else +# define SPDLOG_CONSTEXPR_FUNC inline +# endif #endif #if defined(__GNUC__) || defined(__clang__) @@ -86,7 +107,8 @@ # define SPDLOG_TRY try # define SPDLOG_THROW(ex) throw(ex) # define SPDLOG_CATCH_STD \ - catch (const std::exception &) {} + catch (const std::exception &) \ + {} #endif namespace spdlog { @@ -111,24 +133,82 @@ using log_clock = std::chrono::system_clock; using sink_ptr = std::shared_ptr; using sinks_init_list = std::initializer_list; using err_handler = std::function; +#ifdef SPDLOG_USE_STD_FORMAT +namespace fmt_lib = std; + +using string_view_t = std::string_view; +using memory_buf_t = std::string; + +template +# if __cpp_lib_format >= 202207L +using format_string_t = std::format_string; +# else +using format_string_t = std::string_view; +# endif + +template +struct is_convertible_to_basic_format_string : std::integral_constant>::value> +{}; + +# if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) +using wstring_view_t = std::wstring_view; +using wmemory_buf_t = std::wstring; + +template +# if __cpp_lib_format >= 202207L +using wformat_string_t = std::wformat_string; +# else +using wformat_string_t = std::wstring_view; +# endif +# endif +# define SPDLOG_BUF_TO_STRING(x) x +#else // use fmt lib instead of std::format +namespace fmt_lib = fmt; + using string_view_t = fmt::basic_string_view; -using wstring_view_t = fmt::basic_string_view; using memory_buf_t = fmt::basic_memory_buffer; + +template +using format_string_t = fmt::format_string; + +template +using remove_cvref_t = typename std::remove_cv::type>::type; + +template +# if FMT_VERSION >= 90101 +using fmt_runtime_string = fmt::runtime_format_string; +# else +using fmt_runtime_string = fmt::basic_runtime; +# endif + +// clang doesn't like SFINAE disabled constructor in std::is_convertible<> so have to repeat the condition from basic_format_string here, +// in addition, fmt::basic_runtime is only convertible to basic_format_string but not basic_string_view +template +struct is_convertible_to_basic_format_string + : std::integral_constant>::value || std::is_same, fmt_runtime_string>::value> +{}; + +# if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) +using wstring_view_t = fmt::basic_string_view; using wmemory_buf_t = fmt::basic_memory_buffer; +template +using wformat_string_t = fmt::wformat_string; +# endif +# define SPDLOG_BUF_TO_STRING(x) fmt::to_string(x) +#endif + #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT # ifndef _WIN32 # error SPDLOG_WCHAR_TO_UTF8_SUPPORT only supported on windows -# else -template -struct is_convertible_to_wstring_view : std::is_convertible -{}; # endif // _WIN32 -#else -template -struct is_convertible_to_wstring_view : std::false_type +#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT + +template +struct is_convertible_to_any_format_string : std::integral_constant::value || + is_convertible_to_basic_format_string::value> {}; -#endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT #if defined(SPDLOG_NO_ATOMIC_LEVELS) using level_t = details::null_atomic_int; @@ -150,7 +230,7 @@ using level_t = std::atomic; // Log level enum namespace level { -enum level_enum +enum level_enum : int { trace = SPDLOG_LEVEL_TRACE, debug = SPDLOG_LEVEL_DEBUG, @@ -162,13 +242,13 @@ enum level_enum n_levels }; -#define SPDLOG_LEVEL_NAME_TRACE string_view_t("trace", 5) -#define SPDLOG_LEVEL_NAME_DEBUG string_view_t("debug", 5) -#define SPDLOG_LEVEL_NAME_INFO string_view_t("info", 4) -#define SPDLOG_LEVEL_NAME_WARNING string_view_t("warning", 7) -#define SPDLOG_LEVEL_NAME_ERROR string_view_t("error", 5) -#define SPDLOG_LEVEL_NAME_CRITICAL string_view_t("critical", 8) -#define SPDLOG_LEVEL_NAME_OFF string_view_t("off", 3) +#define SPDLOG_LEVEL_NAME_TRACE spdlog::string_view_t("trace", 5) +#define SPDLOG_LEVEL_NAME_DEBUG spdlog::string_view_t("debug", 5) +#define SPDLOG_LEVEL_NAME_INFO spdlog::string_view_t("info", 4) +#define SPDLOG_LEVEL_NAME_WARNING spdlog::string_view_t("warning", 7) +#define SPDLOG_LEVEL_NAME_ERROR spdlog::string_view_t("error", 5) +#define SPDLOG_LEVEL_NAME_CRITICAL spdlog::string_view_t("critical", 8) +#define SPDLOG_LEVEL_NAME_OFF spdlog::string_view_t("off", 3) #if !defined(SPDLOG_LEVEL_NAMES) # define SPDLOG_LEVEL_NAMES \ @@ -247,12 +327,70 @@ struct source_loc const char *funcname{nullptr}; }; +struct file_event_handlers +{ + file_event_handlers() + : before_open(nullptr) + , after_open(nullptr) + , before_close(nullptr) + , after_close(nullptr) + {} + + std::function before_open; + std::function after_open; + std::function before_close; + std::function after_close; +}; + namespace details { + +// to_string_view + +SPDLOG_CONSTEXPR_FUNC spdlog::string_view_t to_string_view(const memory_buf_t &buf) SPDLOG_NOEXCEPT +{ + return spdlog::string_view_t{buf.data(), buf.size()}; +} + +SPDLOG_CONSTEXPR_FUNC spdlog::string_view_t to_string_view(spdlog::string_view_t str) SPDLOG_NOEXCEPT +{ + return str; +} + +#if defined(SPDLOG_WCHAR_FILENAMES) || defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) +SPDLOG_CONSTEXPR_FUNC spdlog::wstring_view_t to_string_view(const wmemory_buf_t &buf) SPDLOG_NOEXCEPT +{ + return spdlog::wstring_view_t{buf.data(), buf.size()}; +} + +SPDLOG_CONSTEXPR_FUNC spdlog::wstring_view_t to_string_view(spdlog::wstring_view_t str) SPDLOG_NOEXCEPT +{ + return str; +} +#endif + +#ifndef SPDLOG_USE_STD_FORMAT +template +inline fmt::basic_string_view to_string_view(fmt::basic_format_string fmt) +{ + return fmt; +} +#elif __cpp_lib_format >= 202207L +template +SPDLOG_CONSTEXPR_FUNC std::basic_string_view to_string_view(std::basic_format_string fmt) SPDLOG_NOEXCEPT +{ + return fmt.get(); +} +#endif + // make_unique support for pre c++14 #if __cplusplus >= 201402L // C++14 and beyond +using std::enable_if_t; using std::make_unique; #else +template +using enable_if_t = typename std::enable_if::type; + template std::unique_ptr make_unique(Args &&...args) { @@ -260,6 +398,20 @@ std::unique_ptr make_unique(Args &&...args) return std::unique_ptr(new T(std::forward(args)...)); } #endif + +// to avoid useless casts (see https://github.com/nlohmann/json/issues/2893#issuecomment-889152324) +template::value, int> = 0> +constexpr T conditional_static_cast(U value) +{ + return static_cast(value); +} + +template::value, int> = 0> +constexpr T conditional_static_cast(U value) +{ + return value; +} + } // namespace details } // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/details/backtracer-inl.h b/Lumos/External/spdlog/include/spdlog/details/backtracer-inl.h index 2621c8f7d..40eba4086 100644 --- a/Lumos/External/spdlog/include/spdlog/details/backtracer-inl.h +++ b/Lumos/External/spdlog/include/spdlog/details/backtracer-inl.h @@ -54,6 +54,12 @@ SPDLOG_INLINE void backtracer::push_back(const log_msg &msg) messages_.push_back(log_msg_buffer{msg}); } +SPDLOG_INLINE bool backtracer::empty() const +{ + std::lock_guard lock{mutex_}; + return messages_.empty(); +} + // pop all items in the q and apply the given fun on each of them. SPDLOG_INLINE void backtracer::foreach_pop(std::function fun) { diff --git a/Lumos/External/spdlog/include/spdlog/details/backtracer.h b/Lumos/External/spdlog/include/spdlog/details/backtracer.h index b336ee776..13785d856 100644 --- a/Lumos/External/spdlog/include/spdlog/details/backtracer.h +++ b/Lumos/External/spdlog/include/spdlog/details/backtracer.h @@ -32,6 +32,7 @@ class SPDLOG_API backtracer void disable(); bool enabled() const; void push_back(const log_msg &msg); + bool empty() const; // pop all items in the q and apply the given fun on each of them. void foreach_pop(std::function fun); diff --git a/Lumos/External/spdlog/include/spdlog/details/circular_q.h b/Lumos/External/spdlog/include/spdlog/details/circular_q.h index 1f2712e7e..e4fd5fd4a 100644 --- a/Lumos/External/spdlog/include/spdlog/details/circular_q.h +++ b/Lumos/External/spdlog/include/spdlog/details/circular_q.h @@ -121,6 +121,11 @@ class circular_q return overrun_counter_; } + void reset_overrun_counter() + { + overrun_counter_ = 0; + } + private: // copy from other&& and reset it to disabled state void copy_moveable(circular_q &&other) SPDLOG_NOEXCEPT diff --git a/Lumos/External/spdlog/include/spdlog/details/file_helper-inl.h b/Lumos/External/spdlog/include/spdlog/details/file_helper-inl.h index ac7021a9f..74c89a873 100644 --- a/Lumos/External/spdlog/include/spdlog/details/file_helper-inl.h +++ b/Lumos/External/spdlog/include/spdlog/details/file_helper-inl.h @@ -20,6 +20,10 @@ namespace spdlog { namespace details { +SPDLOG_INLINE file_helper::file_helper(const file_event_handlers &event_handlers) + : event_handlers_(event_handlers) +{} + SPDLOG_INLINE file_helper::~file_helper() { close(); @@ -33,6 +37,10 @@ SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate) auto *mode = SPDLOG_FILENAME_T("ab"); auto *trunc_mode = SPDLOG_FILENAME_T("wb"); + if (event_handlers_.before_open) + { + event_handlers_.before_open(filename_); + } for (int tries = 0; tries < open_tries_; ++tries) { // create containing folder if not exists already. @@ -52,6 +60,10 @@ SPDLOG_INLINE void file_helper::open(const filename_t &fname, bool truncate) } if (!os::fopen_s(&fd_, fname, mode)) { + if (event_handlers_.after_open) + { + event_handlers_.after_open(filename_, fd_); + } return; } @@ -72,15 +84,36 @@ SPDLOG_INLINE void file_helper::reopen(bool truncate) SPDLOG_INLINE void file_helper::flush() { - std::fflush(fd_); + if (std::fflush(fd_) != 0) + { + throw_spdlog_ex("Failed flush to file " + os::filename_to_str(filename_), errno); + } +} + +SPDLOG_INLINE void file_helper::sync() +{ + if (!os::fsync(fd_)) + { + throw_spdlog_ex("Failed to fsync file " + os::filename_to_str(filename_), errno); + } } SPDLOG_INLINE void file_helper::close() { if (fd_ != nullptr) { + if (event_handlers_.before_close) + { + event_handlers_.before_close(filename_, fd_); + } + std::fclose(fd_); fd_ = nullptr; + + if (event_handlers_.after_close) + { + event_handlers_.after_close(filename_); + } } } diff --git a/Lumos/External/spdlog/include/spdlog/details/file_helper.h b/Lumos/External/spdlog/include/spdlog/details/file_helper.h index cfccaed2a..f42a5eb1c 100644 --- a/Lumos/External/spdlog/include/spdlog/details/file_helper.h +++ b/Lumos/External/spdlog/include/spdlog/details/file_helper.h @@ -16,7 +16,8 @@ namespace details { class SPDLOG_API file_helper { public: - explicit file_helper() = default; + file_helper() = default; + explicit file_helper(const file_event_handlers &event_handlers); file_helper(const file_helper &) = delete; file_helper &operator=(const file_helper &) = delete; @@ -25,6 +26,7 @@ class SPDLOG_API file_helper void open(const filename_t &fname, bool truncate = false); void reopen(bool truncate); void flush(); + void sync(); void close(); void write(const memory_buf_t &buf); size_t size() const; @@ -50,6 +52,7 @@ class SPDLOG_API file_helper const unsigned int open_interval_ = 10; std::FILE *fd_{nullptr}; filename_t filename_; + file_event_handlers event_handlers_; }; } // namespace details } // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/details/fmt_helper.h b/Lumos/External/spdlog/include/spdlog/details/fmt_helper.h index dcbee10ae..d98671808 100644 --- a/Lumos/External/spdlog/include/spdlog/details/fmt_helper.h +++ b/Lumos/External/spdlog/include/spdlog/details/fmt_helper.h @@ -8,42 +8,89 @@ #include #include +#ifdef SPDLOG_USE_STD_FORMAT +# include +# include +#endif + // Some fmt helpers to efficiently format and pad ints and strings namespace spdlog { namespace details { namespace fmt_helper { -inline spdlog::string_view_t to_string_view(const memory_buf_t &buf) SPDLOG_NOEXCEPT -{ - return spdlog::string_view_t{buf.data(), buf.size()}; -} - inline void append_string_view(spdlog::string_view_t view, memory_buf_t &dest) { auto *buf_ptr = view.data(); dest.append(buf_ptr, buf_ptr + view.size()); } +#ifdef SPDLOG_USE_STD_FORMAT +template +inline void append_int(T n, memory_buf_t &dest) +{ + // Buffer should be large enough to hold all digits (digits10 + 1) and a sign + SPDLOG_CONSTEXPR const auto BUF_SIZE = std::numeric_limits::digits10 + 2; + char buf[BUF_SIZE]; + + auto [ptr, ec] = std::to_chars(buf, buf + BUF_SIZE, n, 10); + if (ec == std::errc()) + { + dest.append(buf, ptr); + } + else + { + throw_spdlog_ex("Failed to format int", static_cast(ec)); + } +} +#else template inline void append_int(T n, memory_buf_t &dest) { fmt::format_int i(n); dest.append(i.data(), i.data() + i.size()); } +#endif + +template +SPDLOG_CONSTEXPR_FUNC unsigned int count_digits_fallback(T n) +{ + // taken from fmt: https://github.com/fmtlib/fmt/blob/8.0.1/include/fmt/format.h#L899-L912 + unsigned int count = 1; + for (;;) + { + // Integer division is slow so do it for a group of four digits instead + // of for every digit. The idea comes from the talk by Alexandrescu + // "Three Optimization Tips for C++". See speed-test for a comparison. + if (n < 10) + return count; + if (n < 100) + return count + 1; + if (n < 1000) + return count + 2; + if (n < 10000) + return count + 3; + n /= 10000u; + count += 4; + } +} template inline unsigned int count_digits(T n) { using count_type = typename std::conditional<(sizeof(T) > sizeof(uint32_t)), uint64_t, uint32_t>::type; +#ifdef SPDLOG_USE_STD_FORMAT + return count_digits_fallback(static_cast(n)); +#else return static_cast(fmt:: // fmt 7.0.0 renamed the internal namespace to detail. // See: https://github.com/fmtlib/fmt/issues/1538 -#if FMT_VERSION < 70000 +# if FMT_VERSION < 70000 internal -#else +# else detail -#endif +# endif ::count_digits(static_cast(n))); +#endif } inline void pad2(int n, memory_buf_t &dest) @@ -55,7 +102,7 @@ inline void pad2(int n, memory_buf_t &dest) } else // unlikely, but just in case, let fmt deal with it { - fmt::format_to(std::back_inserter(dest), "{:02}", n); + fmt_lib::format_to(std::back_inserter(dest), SPDLOG_FMT_STRING("{:02}"), n); } } diff --git a/Lumos/External/spdlog/include/spdlog/details/mpmc_blocking_q.h b/Lumos/External/spdlog/include/spdlog/details/mpmc_blocking_q.h index 5c3cca76b..101ea8c05 100644 --- a/Lumos/External/spdlog/include/spdlog/details/mpmc_blocking_q.h +++ b/Lumos/External/spdlog/include/spdlog/details/mpmc_blocking_q.h @@ -49,7 +49,7 @@ class mpmc_blocking_queue push_cv_.notify_one(); } - // try to dequeue item. if no item found. wait upto timeout and try again + // dequeue with a timeout. // Return true, if succeeded dequeue item, false otherwise bool dequeue_for(T &popped_item, std::chrono::milliseconds wait_duration) { @@ -66,6 +66,18 @@ class mpmc_blocking_queue return true; } + // blocking dequeue without a timeout. + void dequeue(T &popped_item) + { + { + std::unique_lock lock(queue_mutex_); + push_cv_.wait(lock, [this] { return !this->q_.empty(); }); + popped_item = std::move(q_.front()); + q_.pop_front(); + } + pop_cv_.notify_one(); + } + #else // apparently mingw deadlocks if the mutex is released before cv.notify_one(), // so release the mutex at the very end each function. @@ -87,7 +99,7 @@ class mpmc_blocking_queue push_cv_.notify_one(); } - // try to dequeue item. if no item found. wait upto timeout and try again + // dequeue with a timeout. // Return true, if succeeded dequeue item, false otherwise bool dequeue_for(T &popped_item, std::chrono::milliseconds wait_duration) { @@ -102,6 +114,16 @@ class mpmc_blocking_queue return true; } + // blocking dequeue without a timeout. + void dequeue(T &popped_item) + { + std::unique_lock lock(queue_mutex_); + push_cv_.wait(lock, [this] { return !this->q_.empty(); }); + popped_item = std::move(q_.front()); + q_.pop_front(); + pop_cv_.notify_one(); + } + #endif size_t overrun_counter() @@ -116,6 +138,12 @@ class mpmc_blocking_queue return q_.size(); } + void reset_overrun_counter() + { + std::unique_lock lock(queue_mutex_); + q_.reset_overrun_counter(); + } + private: std::mutex queue_mutex_; std::condition_variable push_cv_; diff --git a/Lumos/External/spdlog/include/spdlog/details/null_mutex.h b/Lumos/External/spdlog/include/spdlog/details/null_mutex.h index 83533d4fe..6550a7bf6 100644 --- a/Lumos/External/spdlog/include/spdlog/details/null_mutex.h +++ b/Lumos/External/spdlog/include/spdlog/details/null_mutex.h @@ -13,10 +13,6 @@ struct null_mutex { void lock() const {} void unlock() const {} - bool try_lock() const - { - return true; - } }; struct null_atomic_int diff --git a/Lumos/External/spdlog/include/spdlog/details/os-inl.h b/Lumos/External/spdlog/include/spdlog/details/os-inl.h index 4602782c8..ea8864eae 100644 --- a/Lumos/External/spdlog/include/spdlog/details/os-inl.h +++ b/Lumos/External/spdlog/include/spdlog/details/os-inl.h @@ -23,9 +23,10 @@ #ifdef _WIN32 -# include // _get_osfhandle and _isatty support -# include // _get_pid support +# include // for _get_osfhandle, _isatty, _fileno +# include // for _get_pid # include +# include // for FlushFileBuffers # ifdef __MINGW32__ # include @@ -33,6 +34,7 @@ # if defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES) # include +# include # endif # include // for _mkdir/_wmkdir @@ -46,7 +48,7 @@ # include //Use gettid() syscall under linux to get thread id # elif defined(_AIX) -# include // for pthread_getthreadid_np +# include // for pthread_getthrds_np # elif defined(__DragonFly__) || defined(__FreeBSD__) # include // for pthread_getthreadid_np @@ -60,6 +62,10 @@ #endif // unix +#if defined __APPLE__ +# include +#endif + #ifndef __has_feature // Clang - feature checking macros. # define __has_feature(x) 0 // Compatibility with non-clang compilers. #endif @@ -145,7 +151,7 @@ SPDLOG_INLINE bool fopen_s(FILE **fp, const filename_t &filename, const filename const int fd = ::open((filename.c_str()), O_CREAT | O_WRONLY | O_CLOEXEC | mode_flag, mode_t(0644)); if (fd == -1) { - return false; + return true; } *fp = ::fdopen(fd, mode.c_str()); if (*fp == nullptr) @@ -230,14 +236,14 @@ SPDLOG_INLINE size_t filesize(FILE *f) # endif #else // unix -// OpenBSD doesn't compile with :: before the fileno(..) -# if defined(__OpenBSD__) +// OpenBSD and AIX doesn't compile with :: before the fileno(..) +# if defined(__OpenBSD__) || defined(_AIX) int fd = fileno(f); # else int fd = ::fileno(f); # endif -// 64 bits(but not in osx or cygwin, where fstat64 is deprecated) -# if (defined(__linux__) || defined(__sun) || defined(_AIX)) && (defined(__LP64__) || defined(_LP64)) +// 64 bits(but not in osx, linux/musl or cygwin, where fstat64 is deprecated) +# if ((defined(__linux__) && defined(__GLIBC__)) || defined(__sun) || defined(_AIX)) && (defined(__LP64__) || defined(_LP64)) struct stat64 st; if (::fstat64(fd, &st) == 0) { @@ -286,7 +292,8 @@ SPDLOG_INLINE int utc_minutes_offset(const std::tm &tm) return offset; #else -# if defined(sun) || defined(__sun) || defined(_AIX) || (!defined(_BSD_SOURCE) && !defined(_GNU_SOURCE)) +# if defined(sun) || defined(__sun) || defined(_AIX) || (defined(__NEWLIB__) && !defined(__TM_GMTOFF)) || \ + (!defined(_BSD_SOURCE) && !defined(_GNU_SOURCE)) // 'tm_gmtoff' field is BSD extension and it's missing on SunOS/Solaris struct helper { @@ -305,7 +312,7 @@ SPDLOG_INLINE int utc_minutes_offset(const std::tm &tm) ((local_year / 100 >> 2) - (gmt_year / 100 >> 2)) // + difference in years * 365 */ - + (long int)(local_year - gmt_year) * 365); + + static_cast(local_year - gmt_year) * 365); long int hours = (24 * days) + (localtm.tm_hour - gmtm.tm_hour); long int mins = (60 * hours) + (localtm.tm_min - gmtm.tm_min); @@ -336,7 +343,14 @@ SPDLOG_INLINE size_t _thread_id() SPDLOG_NOEXCEPT # define SYS_gettid __NR_gettid # endif return static_cast(::syscall(SYS_gettid)); -#elif defined(_AIX) || defined(__DragonFly__) || defined(__FreeBSD__) +#elif defined(_AIX) + struct __pthrdsinfo buf; + int reg_size = 0; + pthread_t pt = pthread_self(); + int retval = pthread_getthrds_np(&pt, PTHRDSINFO_QUERY_TID, &buf, sizeof(buf), NULL, ®_size); + int tid = (!retval) ? buf.__pi_tid : 0; + return static_cast(tid); +#elif defined(__DragonFly__) || defined(__FreeBSD__) return static_cast(::pthread_getthreadid_np()); #elif defined(__NetBSD__) return static_cast(::_lwp_self()); @@ -346,7 +360,22 @@ SPDLOG_INLINE size_t _thread_id() SPDLOG_NOEXCEPT return static_cast(::thr_self()); #elif __APPLE__ uint64_t tid; + // There is no pthread_threadid_np prior to 10.6, and it is not supported on any PPC, + // including 10.6.8 Rosetta. __POWERPC__ is Apple-specific define encompassing ppc and ppc64. +# if (MAC_OS_X_VERSION_MAX_ALLOWED < 1060) || defined(__POWERPC__) + tid = pthread_mach_thread_np(pthread_self()); +# elif MAC_OS_X_VERSION_MIN_REQUIRED < 1060 + if (&pthread_threadid_np) + { + pthread_threadid_np(nullptr, &tid); + } + else + { + tid = pthread_mach_thread_np(pthread_self()); + } +# else pthread_threadid_np(nullptr, &tid); +# endif return static_cast(tid); #else // Default to standard C++11 (other Unix) return static_cast(std::hash()(std::this_thread::get_id())); @@ -381,7 +410,7 @@ SPDLOG_INLINE std::string filename_to_str(const filename_t &filename) { memory_buf_t buf; wstr_to_utf8buf(filename, buf); - return fmt::to_string(buf); + return SPDLOG_BUF_TO_STRING(buf); } #else SPDLOG_INLINE std::string filename_to_str(const filename_t &filename) @@ -394,9 +423,9 @@ SPDLOG_INLINE int pid() SPDLOG_NOEXCEPT { #ifdef _WIN32 - return static_cast(::GetCurrentProcessId()); + return conditional_static_cast(::GetCurrentProcessId()); #else - return static_cast(::getpid()); + return conditional_static_cast(::getpid()); #endif } @@ -476,7 +505,7 @@ SPDLOG_INLINE void wstr_to_utf8buf(wstring_view_t wstr, memory_buf_t &target) } } - throw_spdlog_ex(fmt::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError())); + throw_spdlog_ex(fmt_lib::format("WideCharToMultiByte failed. Last error: {}", ::GetLastError())); } SPDLOG_INLINE void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target) @@ -493,25 +522,21 @@ SPDLOG_INLINE void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target) return; } - int result_size = static_cast(target.capacity()); - if (str_size + 1 > result_size) - { - result_size = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.data(), str_size, NULL, 0); - } + // find the size to allocate for the result buffer + int result_size = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.data(), str_size, NULL, 0); if (result_size > 0) { target.resize(result_size); result_size = ::MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, str.data(), str_size, target.data(), result_size); - if (result_size > 0) { - target.resize(result_size); + assert(result_size == target.size()); return; } } - throw_spdlog_ex(fmt::format("MultiByteToWideChar failed. Last error: {}", ::GetLastError())); + throw_spdlog_ex(fmt_lib::format("MultiByteToWideChar failed. Last error: {}", ::GetLastError())); } #endif // (defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) || defined(SPDLOG_WCHAR_FILENAMES)) && defined(_WIN32) @@ -531,7 +556,7 @@ static SPDLOG_INLINE bool mkdir_(const filename_t &path) // create the given directory - and all directories leading to it // return true on success or if the directory already exists -SPDLOG_INLINE bool create_dir(filename_t path) +SPDLOG_INLINE bool create_dir(const filename_t &path) { if (path_exists(path)) { @@ -570,7 +595,7 @@ SPDLOG_INLINE bool create_dir(filename_t path) // "abc/" => "abc" // "abc" => "" // "abc///" => "abc//" -SPDLOG_INLINE filename_t dir_name(filename_t path) +SPDLOG_INLINE filename_t dir_name(const filename_t &path) { auto pos = path.find_last_of(folder_seps_filename); return pos != filename_t::npos ? path.substr(0, pos) : filename_t{}; @@ -594,6 +619,17 @@ std::string SPDLOG_INLINE getenv(const char *field) #endif } +// Do fsync by FILE handlerpointer +// Return true on success +SPDLOG_INLINE bool fsync(FILE *fp) +{ +#ifdef _WIN32 + return FlushFileBuffers(reinterpret_cast(_get_osfhandle(_fileno(fp)))) != 0; +#else + return ::fsync(fileno(fp)) == 0; +#endif +} + } // namespace os } // namespace details } // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/details/os.h b/Lumos/External/spdlog/include/spdlog/details/os.h index 2b2ffa1d2..37b008745 100644 --- a/Lumos/External/spdlog/include/spdlog/details/os.h +++ b/Lumos/External/spdlog/include/spdlog/details/os.h @@ -99,16 +99,20 @@ SPDLOG_API void utf8_to_wstrbuf(string_view_t str, wmemory_buf_t &target); // "abc/" => "abc" // "abc" => "" // "abc///" => "abc//" -SPDLOG_API filename_t dir_name(filename_t path); +SPDLOG_API filename_t dir_name(const filename_t &path); // Create a dir from the given path. // Return true if succeeded or if this dir already exists. -SPDLOG_API bool create_dir(filename_t path); +SPDLOG_API bool create_dir(const filename_t &path); // non thread safe, cross platform getenv/getenv_s // return empty string if field not found SPDLOG_API std::string getenv(const char *field); +// Do fsync by FILE objectpointer. +// Return true on success. +SPDLOG_API bool fsync(FILE *fp); + } // namespace os } // namespace details } // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/details/periodic_worker-inl.h b/Lumos/External/spdlog/include/spdlog/details/periodic_worker-inl.h index d4abbda31..520a2b339 100644 --- a/Lumos/External/spdlog/include/spdlog/details/periodic_worker-inl.h +++ b/Lumos/External/spdlog/include/spdlog/details/periodic_worker-inl.h @@ -10,27 +10,6 @@ namespace spdlog { namespace details { -SPDLOG_INLINE periodic_worker::periodic_worker(const std::function &callback_fun, std::chrono::seconds interval) -{ - active_ = (interval > std::chrono::seconds::zero()); - if (!active_) - { - return; - } - - worker_thread_ = std::thread([this, callback_fun, interval]() { - for (;;) - { - std::unique_lock lock(this->mutex_); - if (this->cv_.wait_for(lock, interval, [this] { return !this->active_; })) - { - return; // active_ == false, so exit this thread - } - callback_fun(); - } - }); -} - // stop the worker thread and join it SPDLOG_INLINE periodic_worker::~periodic_worker() { diff --git a/Lumos/External/spdlog/include/spdlog/details/periodic_worker.h b/Lumos/External/spdlog/include/spdlog/details/periodic_worker.h index a300218d6..d7d69b28c 100644 --- a/Lumos/External/spdlog/include/spdlog/details/periodic_worker.h +++ b/Lumos/External/spdlog/include/spdlog/details/periodic_worker.h @@ -20,7 +20,27 @@ namespace details { class SPDLOG_API periodic_worker { public: - periodic_worker(const std::function &callback_fun, std::chrono::seconds interval); + template + periodic_worker(const std::function &callback_fun, std::chrono::duration interval) + { + active_ = (interval > std::chrono::duration::zero()); + if (!active_) + { + return; + } + + worker_thread_ = std::thread([this, callback_fun, interval]() { + for (;;) + { + std::unique_lock lock(this->mutex_); + if (this->cv_.wait_for(lock, interval, [this] { return !this->active_; })) + { + return; // active_ == false, so exit this thread + } + callback_fun(); + } + }); + } periodic_worker(const periodic_worker &) = delete; periodic_worker &operator=(const periodic_worker &) = delete; // stop the worker thread and join it diff --git a/Lumos/External/spdlog/include/spdlog/details/registry-inl.h b/Lumos/External/spdlog/include/spdlog/details/registry-inl.h index c55b5eea8..cb1fe84ff 100644 --- a/Lumos/External/spdlog/include/spdlog/details/registry-inl.h +++ b/Lumos/External/spdlog/include/spdlog/details/registry-inl.h @@ -188,13 +188,6 @@ SPDLOG_INLINE void registry::flush_on(level::level_enum log_level) flush_level_ = log_level; } -SPDLOG_INLINE void registry::flush_every(std::chrono::seconds interval) -{ - std::lock_guard lock(flusher_mutex_); - auto clbk = [this]() { this->flush_all(); }; - periodic_flusher_ = details::make_unique(clbk, interval); -} - SPDLOG_INLINE void registry::set_error_handler(err_handler handler) { std::lock_guard lock(logger_map_mutex_); @@ -226,8 +219,9 @@ SPDLOG_INLINE void registry::flush_all() SPDLOG_INLINE void registry::drop(const std::string &logger_name) { std::lock_guard lock(logger_map_mutex_); + auto is_default_logger = default_logger_ && default_logger_->name() == logger_name; loggers_.erase(logger_name); - if (default_logger_ && default_logger_->name() == logger_name) + if (is_default_logger) { default_logger_.reset(); } @@ -294,6 +288,14 @@ SPDLOG_INLINE registry ®istry::instance() return s_instance; } +SPDLOG_INLINE void registry::apply_logger_env_levels(std::shared_ptr new_logger) +{ + std::lock_guard lock(logger_map_mutex_); + auto it = log_levels_.find(new_logger->name()); + auto new_level = it != log_levels_.end() ? it->second : global_log_level_; + new_logger->set_level(new_level); +} + SPDLOG_INLINE void registry::throw_if_exists_(const std::string &logger_name) { if (loggers_.find(logger_name) != loggers_.end()) diff --git a/Lumos/External/spdlog/include/spdlog/details/registry.h b/Lumos/External/spdlog/include/spdlog/details/registry.h index 97473ea33..4666fa296 100644 --- a/Lumos/External/spdlog/include/spdlog/details/registry.h +++ b/Lumos/External/spdlog/include/spdlog/details/registry.h @@ -9,6 +9,7 @@ // This class is thread safe #include +#include #include #include @@ -22,7 +23,6 @@ class logger; namespace details { class thread_pool; -class periodic_worker; class SPDLOG_API registry { @@ -61,7 +61,13 @@ class SPDLOG_API registry void flush_on(level::level_enum log_level); - void flush_every(std::chrono::seconds interval); + template + void flush_every(std::chrono::duration interval) + { + std::lock_guard lock(flusher_mutex_); + auto clbk = [this]() { this->flush_all(); }; + periodic_flusher_ = details::make_unique(clbk, interval); + } void set_error_handler(err_handler handler); @@ -85,6 +91,8 @@ class SPDLOG_API registry static registry &instance(); + void apply_logger_env_levels(std::shared_ptr new_logger); + private: registry(); ~registry(); diff --git a/Lumos/External/spdlog/include/spdlog/details/tcp_client-windows.h b/Lumos/External/spdlog/include/spdlog/details/tcp_client-windows.h index 95c0d22e8..968b25702 100644 --- a/Lumos/External/spdlog/include/spdlog/details/tcp_client-windows.h +++ b/Lumos/External/spdlog/include/spdlog/details/tcp_client-windows.h @@ -25,20 +25,6 @@ class tcp_client { SOCKET socket_ = INVALID_SOCKET; - static bool winsock_initialized_() - { - SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (s == INVALID_SOCKET) - { - return false; - } - else - { - closesocket(s); - return true; - } - } - static void init_winsock_() { WSADATA wsaData; @@ -52,13 +38,24 @@ class tcp_client static void throw_winsock_error_(const std::string &msg, int last_error) { char buf[512]; - ::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_error, + ::FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, (sizeof(buf) / sizeof(char)), NULL); - throw_spdlog_ex(fmt::format("tcp_sink - {}: {}", msg, buf)); + throw_spdlog_ex(fmt_lib::format("tcp_sink - {}: {}", msg, buf)); } public: + tcp_client() + { + init_winsock_(); + } + + ~tcp_client() + { + close(); + ::WSACleanup(); + } + bool is_connected() const { return socket_ != INVALID_SOCKET; @@ -68,7 +65,6 @@ class tcp_client { ::closesocket(socket_); socket_ = INVALID_SOCKET; - WSACleanup(); } SOCKET fd() const @@ -76,20 +72,9 @@ class tcp_client return socket_; } - ~tcp_client() - { - close(); - } - // try to connect or throw on failure void connect(const std::string &host, int port) { - // initialize winsock if needed - if (!winsock_initialized_()) - { - init_winsock_(); - } - if (is_connected()) { close(); @@ -98,7 +83,7 @@ class tcp_client {}; ZeroMemory(&hints, sizeof(hints)); - hints.ai_family = AF_INET; // IPv4 + hints.ai_family = AF_UNSPEC; // To work with IPv4, IPv6, and so on hints.ai_socktype = SOCK_STREAM; // TCP hints.ai_flags = AI_NUMERICSERV; // port passed as as numeric value hints.ai_protocol = 0; diff --git a/Lumos/External/spdlog/include/spdlog/details/tcp_client.h b/Lumos/External/spdlog/include/spdlog/details/tcp_client.h index 706d75994..8b11dfd24 100644 --- a/Lumos/External/spdlog/include/spdlog/details/tcp_client.h +++ b/Lumos/External/spdlog/include/spdlog/details/tcp_client.h @@ -16,6 +16,7 @@ #include #include #include +#include #include @@ -57,7 +58,7 @@ class tcp_client struct addrinfo hints {}; memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = AF_INET; // IPv4 + hints.ai_family = AF_UNSPEC; // To work with IPv4, IPv6, and so on hints.ai_socktype = SOCK_STREAM; // TCP hints.ai_flags = AI_NUMERICSERV; // port passed as as numeric value hints.ai_protocol = 0; @@ -67,8 +68,7 @@ class tcp_client auto rv = ::getaddrinfo(host.c_str(), port_str.c_str(), &hints, &addrinfo_result); if (rv != 0) { - auto msg = fmt::format("::getaddrinfo failed: {}", gai_strerror(rv)); - throw_spdlog_ex(msg); + throw_spdlog_ex(fmt_lib::format("::getaddrinfo failed: {}", gai_strerror(rv))); } // Try each address until we successfully connect(2). @@ -111,7 +111,7 @@ class tcp_client #endif #if !defined(SO_NOSIGPIPE) && !defined(MSG_NOSIGNAL) -# error "tcp_sink would raise SIGPIPE since niether SO_NOSIGPIPE nor MSG_NOSIGNAL are available" +# error "tcp_sink would raise SIGPIPE since neither SO_NOSIGPIPE nor MSG_NOSIGNAL are available" #endif } diff --git a/Lumos/External/spdlog/include/spdlog/details/thread_pool-inl.h b/Lumos/External/spdlog/include/spdlog/details/thread_pool-inl.h index deee37661..dbd424ff0 100644 --- a/Lumos/External/spdlog/include/spdlog/details/thread_pool-inl.h +++ b/Lumos/External/spdlog/include/spdlog/details/thread_pool-inl.h @@ -13,7 +13,8 @@ namespace spdlog { namespace details { -SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, size_t threads_n, std::function on_thread_start) +SPDLOG_INLINE thread_pool::thread_pool( + size_t q_max_items, size_t threads_n, std::function on_thread_start, std::function on_thread_stop) : q_(q_max_items) { if (threads_n == 0 || threads_n > 1000) @@ -23,15 +24,21 @@ SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, size_t threads_n, std } for (size_t i = 0; i < threads_n; i++) { - threads_.emplace_back([this, on_thread_start] { + threads_.emplace_back([this, on_thread_start, on_thread_stop] { on_thread_start(); this->thread_pool::worker_loop_(); + on_thread_stop(); }); } } +SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, size_t threads_n, std::function on_thread_start) + : thread_pool(q_max_items, threads_n, on_thread_start, [] {}) +{} + SPDLOG_INLINE thread_pool::thread_pool(size_t q_max_items, size_t threads_n) - : thread_pool(q_max_items, threads_n, [] {}) + : thread_pool( + q_max_items, threads_n, [] {}, [] {}) {} // message all threads to terminate gracefully join them @@ -68,6 +75,11 @@ size_t SPDLOG_INLINE thread_pool::overrun_counter() return q_.overrun_counter(); } +void SPDLOG_INLINE thread_pool::reset_overrun_counter() +{ + q_.reset_overrun_counter(); +} + size_t SPDLOG_INLINE thread_pool::queue_size() { return q_.size(); @@ -96,11 +108,7 @@ void SPDLOG_INLINE thread_pool::worker_loop_() bool SPDLOG_INLINE thread_pool::process_next_msg_() { async_msg incoming_async_msg; - bool dequeued = q_.dequeue_for(incoming_async_msg, std::chrono::seconds(10)); - if (!dequeued) - { - return true; - } + q_.dequeue(incoming_async_msg); switch (incoming_async_msg.msg_type) { diff --git a/Lumos/External/spdlog/include/spdlog/details/thread_pool.h b/Lumos/External/spdlog/include/spdlog/details/thread_pool.h index aa3cef2bc..52c569b80 100644 --- a/Lumos/External/spdlog/include/spdlog/details/thread_pool.h +++ b/Lumos/External/spdlog/include/spdlog/details/thread_pool.h @@ -27,7 +27,6 @@ enum class async_msg_type terminate }; -#include // Async msg to move to/from the queue // Movable only. should never be copied struct async_msg : log_msg_buffer @@ -85,10 +84,11 @@ class SPDLOG_API thread_pool using item_type = async_msg; using q_type = details::mpmc_blocking_queue; + thread_pool(size_t q_max_items, size_t threads_n, std::function on_thread_start, std::function on_thread_stop); thread_pool(size_t q_max_items, size_t threads_n, std::function on_thread_start); thread_pool(size_t q_max_items, size_t threads_n); - // message all threads to terminate gracefully join them + // message all threads to terminate gracefully and join them ~thread_pool(); thread_pool(const thread_pool &) = delete; @@ -97,6 +97,7 @@ class SPDLOG_API thread_pool void post_log(async_logger_ptr &&worker_ptr, const details::log_msg &msg, async_overflow_policy overflow_policy); void post_flush(async_logger_ptr &&worker_ptr, async_overflow_policy overflow_policy); size_t overrun_counter(); + void reset_overrun_counter(); size_t queue_size(); private: diff --git a/Lumos/External/spdlog/include/spdlog/details/udp_client-windows.h b/Lumos/External/spdlog/include/spdlog/details/udp_client-windows.h new file mode 100644 index 000000000..10894ee6a --- /dev/null +++ b/Lumos/External/spdlog/include/spdlog/details/udp_client-windows.h @@ -0,0 +1,113 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#pragma once + +// Helper RAII over winsock udp client socket. +// Will throw on construction if socket creation failed. + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma comment(lib, "Ws2_32.lib") +# pragma comment(lib, "Mswsock.lib") +# pragma comment(lib, "AdvApi32.lib") +#endif + +namespace spdlog { +namespace details { +class udp_client +{ + static constexpr int TX_BUFFER_SIZE = 1024 * 10; + SOCKET socket_ = INVALID_SOCKET; + sockaddr_in addr_ = {}; + + static void init_winsock_() + { + WSADATA wsaData; + auto rv = ::WSAStartup(MAKEWORD(2, 2), &wsaData); + if (rv != 0) + { + throw_winsock_error_("WSAStartup failed", ::WSAGetLastError()); + } + } + + static void throw_winsock_error_(const std::string &msg, int last_error) + { + char buf[512]; + ::FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), buf, (sizeof(buf) / sizeof(char)), NULL); + + throw_spdlog_ex(fmt_lib::format("udp_sink - {}: {}", msg, buf)); + } + + void cleanup_() + { + if (socket_ != INVALID_SOCKET) + { + ::closesocket(socket_); + } + socket_ = INVALID_SOCKET; + ::WSACleanup(); + } + +public: + udp_client(const std::string &host, uint16_t port) + { + init_winsock_(); + + addr_.sin_family = PF_INET; + addr_.sin_port = htons(port); + addr_.sin_addr.s_addr = INADDR_ANY; + if (InetPtonA(PF_INET, host.c_str(), &addr_.sin_addr.s_addr) != 1) + { + int last_error = ::WSAGetLastError(); + ::WSACleanup(); + throw_winsock_error_("error: Invalid address!", last_error); + } + + socket_ = ::socket(PF_INET, SOCK_DGRAM, 0); + if (socket_ == INVALID_SOCKET) + { + int last_error = ::WSAGetLastError(); + ::WSACleanup(); + throw_winsock_error_("error: Create Socket failed", last_error); + } + + int option_value = TX_BUFFER_SIZE; + if (::setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&option_value), sizeof(option_value)) < 0) + { + int last_error = ::WSAGetLastError(); + cleanup_(); + throw_winsock_error_("error: setsockopt(SO_SNDBUF) Failed!", last_error); + } + } + + ~udp_client() + { + cleanup_(); + } + + SOCKET fd() const + { + return socket_; + } + + void send(const char *data, size_t n_bytes) + { + socklen_t tolen = sizeof(struct sockaddr); + if (::sendto(socket_, data, static_cast(n_bytes), 0, (struct sockaddr *)&addr_, tolen) == -1) + { + throw_spdlog_ex("sendto(2) failed", errno); + } + } +}; +} // namespace details +} // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/details/udp_client.h b/Lumos/External/spdlog/include/spdlog/details/udp_client.h new file mode 100644 index 000000000..e8c2cccf3 --- /dev/null +++ b/Lumos/External/spdlog/include/spdlog/details/udp_client.h @@ -0,0 +1,94 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#pragma once + +// Helper RAII over unix udp client socket. +// Will throw on construction if the socket creation failed. + +#ifdef _WIN32 +# error "include udp_client-windows.h instead" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace spdlog { +namespace details { + +class udp_client +{ + static constexpr int TX_BUFFER_SIZE = 1024 * 10; + int socket_ = -1; + struct sockaddr_in sockAddr_; + + void cleanup_() + { + if (socket_ != -1) + { + ::close(socket_); + socket_ = -1; + } + } + +public: + udp_client(const std::string &host, uint16_t port) + { + socket_ = ::socket(PF_INET, SOCK_DGRAM, 0); + if (socket_ < 0) + { + throw_spdlog_ex("error: Create Socket Failed!"); + } + + int option_value = TX_BUFFER_SIZE; + if (::setsockopt(socket_, SOL_SOCKET, SO_SNDBUF, reinterpret_cast(&option_value), sizeof(option_value)) < 0) + { + cleanup_(); + throw_spdlog_ex("error: setsockopt(SO_SNDBUF) Failed!"); + } + + sockAddr_.sin_family = AF_INET; + sockAddr_.sin_port = htons(port); + + if (::inet_aton(host.c_str(), &sockAddr_.sin_addr) == 0) + { + cleanup_(); + throw_spdlog_ex("error: Invalid address!"); + } + + ::memset(sockAddr_.sin_zero, 0x00, sizeof(sockAddr_.sin_zero)); + } + + ~udp_client() + { + cleanup_(); + } + + int fd() const + { + return socket_; + } + + // Send exactly n_bytes of the given data. + // On error close the connection and throw. + void send(const char *data, size_t n_bytes) + { + ssize_t toslen = 0; + socklen_t tolen = sizeof(struct sockaddr); + if ((toslen = ::sendto(socket_, data, n_bytes, 0, (struct sockaddr *)&sockAddr_, tolen)) == -1) + { + throw_spdlog_ex("sendto(2) failed", errno); + } + } +}; +} // namespace details +} // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bin_to_hex.h b/Lumos/External/spdlog/include/spdlog/fmt/bin_to_hex.h index 45bc8f7d8..3bf003d47 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/bin_to_hex.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/bin_to_hex.h @@ -6,10 +6,21 @@ #pragma once #include +#include + +#if defined(__has_include) +# if __has_include() +# include +# endif +#endif + +#if __cpp_lib_span >= 202002L +# include +#endif // // Support for logging binary data as hex -// format flags, any combination of the followng: +// format flags, any combination of the following: // {:X} - print in uppercase. // {:s} - don't separate each byte with space. // {:p} - don't print the position on each line start. @@ -38,11 +49,12 @@ class dump_info , size_per_line_(size_per_line) {} - It begin() const + // do not use begin() and end() to avoid collision with fmt/ranges + It get_begin() const { return begin_; } - It end() const + It get_end() const { return end_; } @@ -66,6 +78,20 @@ inline details::dump_info to_hex(const Conta return details::dump_info(std::begin(container), std::end(container), size_per_line); } +#if __cpp_lib_span >= 202002L + +template +inline details::dump_info::iterator> to_hex( + const std::span &container, size_t size_per_line = 32) +{ + using Container = std::span; + static_assert(sizeof(typename Container::value_type) == 1, "sizeof(Container::value_type) != 1"); + using Iter = typename Container::iterator; + return details::dump_info(std::begin(container), std::end(container), size_per_line); +} + +#endif + // create dump_info from ranges template inline details::dump_info to_hex(const It range_begin, const It range_end, size_t size_per_line = 32) @@ -75,10 +101,16 @@ inline details::dump_info to_hex(const It range_begin, const It range_end, s } // namespace spdlog -namespace fmt { +namespace +#ifdef SPDLOG_USE_STD_FORMAT + std +#else + fmt +#endif +{ template -struct formatter> +struct formatter, char> { const char delimiter = ' '; bool put_newlines = true; @@ -89,7 +121,7 @@ struct formatter> // parse the format string flags template - auto parse(ParseContext &ctx) -> decltype(ctx.begin()) + SPDLOG_CONSTEXPR_FUNC auto parse(ParseContext &ctx) -> decltype(ctx.begin()) { auto it = ctx.begin(); while (it != ctx.end() && *it != '}') @@ -124,27 +156,27 @@ struct formatter> // format the given bytes range as hex template - auto format(const spdlog::details::dump_info &the_range, FormatContext &ctx) -> decltype(ctx.out()) + auto format(const spdlog::details::dump_info &the_range, FormatContext &ctx) const -> decltype(ctx.out()) { SPDLOG_CONSTEXPR const char *hex_upper = "0123456789ABCDEF"; SPDLOG_CONSTEXPR const char *hex_lower = "0123456789abcdef"; const char *hex_chars = use_uppercase ? hex_upper : hex_lower; -#if FMT_VERSION < 60000 +#if !defined(SPDLOG_USE_STD_FORMAT) && FMT_VERSION < 60000 auto inserter = ctx.begin(); #else auto inserter = ctx.out(); #endif int size_per_line = static_cast(the_range.size_per_line()); - auto start_of_line = the_range.begin(); - for (auto i = the_range.begin(); i != the_range.end(); i++) + auto start_of_line = the_range.get_begin(); + for (auto i = the_range.get_begin(); i != the_range.get_end(); i++) { auto ch = static_cast(*i); - if (put_newlines && (i == the_range.begin() || i - start_of_line >= size_per_line)) + if (put_newlines && (i == the_range.get_begin() || i - start_of_line >= size_per_line)) { - if (show_ascii && i != the_range.begin()) + if (show_ascii && i != the_range.get_begin()) { *inserter++ = delimiter; *inserter++ = delimiter; @@ -155,7 +187,7 @@ struct formatter> } } - put_newline(inserter, static_cast(i - the_range.begin())); + put_newline(inserter, static_cast(i - the_range.get_begin())); // put first byte without delimiter in front of it *inserter++ = hex_chars[(ch >> 4) & 0x0f]; @@ -164,7 +196,7 @@ struct formatter> continue; } - if (put_delimiters) + if (put_delimiters && i != the_range.get_begin()) { *inserter++ = delimiter; } @@ -174,9 +206,9 @@ struct formatter> } if (show_ascii) // add ascii to last line { - if (the_range.end() - the_range.begin() > size_per_line) + if (the_range.get_end() - the_range.get_begin() > size_per_line) { - auto blank_num = size_per_line - (the_range.end() - start_of_line); + auto blank_num = size_per_line - (the_range.get_end() - start_of_line); while (blank_num-- > 0) { *inserter++ = delimiter; @@ -189,7 +221,7 @@ struct formatter> } *inserter++ = delimiter; *inserter++ = delimiter; - for (auto j = start_of_line; j != the_range.end(); j++) + for (auto j = start_of_line; j != the_range.get_end(); j++) { auto pc = static_cast(*j); *inserter++ = std::isprint(pc) ? static_cast(*j) : '.'; @@ -200,7 +232,7 @@ struct formatter> // put newline(and position header) template - void put_newline(It inserter, std::size_t pos) + void put_newline(It inserter, std::size_t pos) const { #ifdef _WIN32 *inserter++ = '\r'; @@ -209,8 +241,8 @@ struct formatter> if (put_positions) { - fmt::format_to(inserter, "{:04X}: ", pos); + spdlog::fmt_lib::format_to(inserter, SPDLOG_FMT_STRING("{:04X}: "), pos); } } }; -} // namespace fmt +} // namespace std diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bundled/args.h b/Lumos/External/spdlog/include/spdlog/fmt/bundled/args.h index 562e8ab11..a3966d140 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/bundled/args.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/bundled/args.h @@ -95,10 +95,10 @@ class dynamic_format_arg_store }; template - using stored_type = conditional_t::value && - !has_formatter::value && - !detail::is_reference_wrapper::value, - std::basic_string, T>; + using stored_type = conditional_t< + std::is_convertible>::value && + !detail::is_reference_wrapper::value, + std::basic_string, T>; // Storage of basic_format_arg must be contiguous. std::vector> data_; @@ -143,6 +143,8 @@ class dynamic_format_arg_store } public: + constexpr dynamic_format_arg_store() = default; + /** \rst Adds an argument into the dynamic store for later passing to a formatting diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bundled/chrono.h b/Lumos/External/spdlog/include/spdlog/fmt/bundled/chrono.h index c024fd710..b112f76e9 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/bundled/chrono.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/bundled/chrono.h @@ -10,14 +10,32 @@ #include #include +#include // std::isfinite +#include // std::memcpy #include +#include #include -#include +#include +#include #include "format.h" FMT_BEGIN_NAMESPACE +// Enable tzset. +#ifndef FMT_USE_TZSET +// UWP doesn't provide _tzset. +# if FMT_HAS_INCLUDE("winapifamily.h") +# include +# endif +# if defined(_WIN32) && (!defined(WINAPI_FAMILY) || \ + (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)) +# define FMT_USE_TZSET 1 +# else +# define FMT_USE_TZSET 0 +# endif +#endif + // Enable safe chrono durations, unless explicitly disabled. #ifndef FMT_SAFE_DURATION_CAST # define FMT_SAFE_DURATION_CAST 1 @@ -44,7 +62,7 @@ FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) { static_assert(T::is_integer, "To must be integral"); // A and B are both signed, or both unsigned. - if (F::digits <= T::digits) { + if (detail::const_check(F::digits <= T::digits)) { // From fits in To without any problem. } else { // From does not always fit in To, resort to a dynamic check. @@ -79,14 +97,15 @@ FMT_CONSTEXPR To lossless_integral_conversion(const From from, int& ec) { return {}; } // From is positive. Can it always fit in To? - if (F::digits > T::digits && + if (detail::const_check(F::digits > T::digits) && from > static_cast(detail::max_value())) { ec = 1; return {}; } } - if (!F::is_signed && T::is_signed && F::digits >= T::digits && + if (detail::const_check(!F::is_signed && T::is_signed && + F::digits >= T::digits) && from > static_cast(detail::max_value())) { ec = 1; return {}; @@ -184,7 +203,7 @@ To safe_duration_cast(std::chrono::duration from, } const auto min1 = (std::numeric_limits::min)() / Factor::num; - if (count < min1) { + if (!std::is_unsigned::value && count < min1) { ec = 1; return {}; } @@ -243,7 +262,7 @@ To safe_duration_cast(std::chrono::duration from, } // multiply with Factor::num without overflow or underflow - if (Factor::num != 1) { + if (detail::const_check(Factor::num != 1)) { constexpr auto max1 = detail::max_value() / static_cast(Factor::num); if (count > max1) { @@ -260,7 +279,7 @@ To safe_duration_cast(std::chrono::duration from, } // this can't go wrong, right? den>0 is checked earlier. - if (Factor::den != 1) { + if (detail::const_check(Factor::den != 1)) { using common_t = typename std::common_type::type; count /= static_cast(Factor::den); } @@ -288,74 +307,138 @@ inline null<> localtime_s(...) { return null<>(); } inline null<> gmtime_r(...) { return null<>(); } inline null<> gmtime_s(...) { return null<>(); } -inline auto do_write(const std::tm& time, const std::locale& loc, char format, - char modifier) -> std::string { - auto&& os = std::ostringstream(); - os.imbue(loc); - using iterator = std::ostreambuf_iterator; - const auto& facet = std::use_facet>(loc); - auto end = facet.put(os, os, ' ', &time, format, modifier); - if (end.failed()) FMT_THROW(format_error("failed to format time")); - auto str = os.str(); - if (!detail::is_utf8() || loc == std::locale::classic()) return str; - // char16_t and char32_t codecvts are broken in MSVC (linkage errors) and - // gcc-4. -#if FMT_MSC_VER != 0 || \ - (defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_DUAL_ABI)) - // The _GLIBCXX_USE_DUAL_ABI macro is always defined in libstdc++ from gcc-5 - // and newer. - using code_unit = wchar_t; +inline const std::locale& get_classic_locale() { + static const auto& locale = std::locale::classic(); + return locale; +} + +template struct codecvt_result { + static constexpr const size_t max_size = 32; + CodeUnit buf[max_size]; + CodeUnit* end; +}; +template +constexpr const size_t codecvt_result::max_size; + +template +void write_codecvt(codecvt_result& out, string_view in_buf, + const std::locale& loc) { +#if FMT_CLANG_VERSION +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wdeprecated" + auto& f = std::use_facet>(loc); +# pragma clang diagnostic pop #else - using code_unit = char32_t; + auto& f = std::use_facet>(loc); #endif - auto& f = std::use_facet>(loc); auto mb = std::mbstate_t(); const char* from_next = nullptr; - code_unit* to_next = nullptr; - constexpr size_t buf_size = 32; - code_unit buf[buf_size] = {}; - auto result = f.in(mb, str.data(), str.data() + str.size(), from_next, buf, - buf + buf_size, to_next); + auto result = f.in(mb, in_buf.begin(), in_buf.end(), from_next, + std::begin(out.buf), std::end(out.buf), out.end); if (result != std::codecvt_base::ok) FMT_THROW(format_error("failed to format time")); - str.clear(); - for (code_unit* p = buf; p != to_next; ++p) { - uint32_t c = static_cast(*p); - if (sizeof(code_unit) == 2 && c >= 0xd800 && c <= 0xdfff) { - // surrogate pair - ++p; - if (p == to_next || (c & 0xfc00) != 0xd800 || (*p & 0xfc00) != 0xdc00) { +} + +template +auto write_encoded_tm_str(OutputIt out, string_view in, const std::locale& loc) + -> OutputIt { + if (detail::is_utf8() && loc != get_classic_locale()) { + // char16_t and char32_t codecvts are broken in MSVC (linkage errors) and + // gcc-4. +#if FMT_MSC_VERSION != 0 || \ + (defined(__GLIBCXX__) && !defined(_GLIBCXX_USE_DUAL_ABI)) + // The _GLIBCXX_USE_DUAL_ABI macro is always defined in libstdc++ from gcc-5 + // and newer. + using code_unit = wchar_t; +#else + using code_unit = char32_t; +#endif + + using unit_t = codecvt_result; + unit_t unit; + write_codecvt(unit, in, loc); + // In UTF-8 is used one to four one-byte code units. + auto&& buf = basic_memory_buffer(); + for (code_unit* p = unit.buf; p != unit.end; ++p) { + uint32_t c = static_cast(*p); + if (sizeof(code_unit) == 2 && c >= 0xd800 && c <= 0xdfff) { + // surrogate pair + ++p; + if (p == unit.end || (c & 0xfc00) != 0xd800 || + (*p & 0xfc00) != 0xdc00) { + FMT_THROW(format_error("failed to format time")); + } + c = (c << 10) + static_cast(*p) - 0x35fdc00; + } + if (c < 0x80) { + buf.push_back(static_cast(c)); + } else if (c < 0x800) { + buf.push_back(static_cast(0xc0 | (c >> 6))); + buf.push_back(static_cast(0x80 | (c & 0x3f))); + } else if ((c >= 0x800 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xffff)) { + buf.push_back(static_cast(0xe0 | (c >> 12))); + buf.push_back(static_cast(0x80 | ((c & 0xfff) >> 6))); + buf.push_back(static_cast(0x80 | (c & 0x3f))); + } else if (c >= 0x10000 && c <= 0x10ffff) { + buf.push_back(static_cast(0xf0 | (c >> 18))); + buf.push_back(static_cast(0x80 | ((c & 0x3ffff) >> 12))); + buf.push_back(static_cast(0x80 | ((c & 0xfff) >> 6))); + buf.push_back(static_cast(0x80 | (c & 0x3f))); + } else { FMT_THROW(format_error("failed to format time")); } - c = (c << 10) + static_cast(*p) - 0x35fdc00; - } - if (c < 0x80) { - str.push_back(static_cast(c)); - } else if (c < 0x800) { - str.push_back(static_cast(0xc0 | (c >> 6))); - str.push_back(static_cast(0x80 | (c & 0x3f))); - } else if ((c >= 0x800 && c <= 0xd7ff) || (c >= 0xe000 && c <= 0xffff)) { - str.push_back(static_cast(0xe0 | (c >> 12))); - str.push_back(static_cast(0x80 | ((c & 0xfff) >> 6))); - str.push_back(static_cast(0x80 | (c & 0x3f))); - } else if (c >= 0x10000 && c <= 0x10ffff) { - str.push_back(static_cast(0xf0 | (c >> 18))); - str.push_back(static_cast(0x80 | ((c & 0x3ffff) >> 12))); - str.push_back(static_cast(0x80 | ((c & 0xfff) >> 6))); - str.push_back(static_cast(0x80 | (c & 0x3f))); - } else { - FMT_THROW(format_error("failed to format time")); } + return copy_str(buf.data(), buf.data() + buf.size(), out); } - return str; + return copy_str(in.data(), in.data() + in.size(), out); } -template +template ::value)> +auto write_tm_str(OutputIt out, string_view sv, const std::locale& loc) + -> OutputIt { + codecvt_result unit; + write_codecvt(unit, sv, loc); + return copy_str(unit.buf, unit.end, out); +} + +template ::value)> +auto write_tm_str(OutputIt out, string_view sv, const std::locale& loc) + -> OutputIt { + return write_encoded_tm_str(out, sv, loc); +} + +template +inline void do_write(buffer& buf, const std::tm& time, + const std::locale& loc, char format, char modifier) { + auto&& format_buf = formatbuf>(buf); + auto&& os = std::basic_ostream(&format_buf); + os.imbue(loc); + using iterator = std::ostreambuf_iterator; + const auto& facet = std::use_facet>(loc); + auto end = facet.put(os, os, Char(' '), &time, format, modifier); + if (end.failed()) FMT_THROW(format_error("failed to format time")); +} + +template ::value)> +auto write(OutputIt out, const std::tm& time, const std::locale& loc, + char format, char modifier = 0) -> OutputIt { + auto&& buf = get_buffer(out); + do_write(buf, time, loc, format, modifier); + return buf.out(); +} + +template ::value)> auto write(OutputIt out, const std::tm& time, const std::locale& loc, char format, char modifier = 0) -> OutputIt { - auto str = do_write(time, loc, format, modifier); - return std::copy(str.begin(), str.end(), out); + auto&& buf = basic_memory_buffer(); + do_write(buf, time, loc, format, modifier); + return write_encoded_tm_str(out, string_view(buf.data(), buf.size()), loc); } + } // namespace detail FMT_MODULE_EXPORT_BEGIN @@ -386,7 +469,7 @@ inline std::tm localtime(std::time_t time) { bool fallback(int res) { return res == 0; } -#if !FMT_MSC_VER +#if !FMT_MSC_VERSION bool fallback(detail::null<>) { using namespace fmt::detail; std::tm* tm = std::localtime(&time_); @@ -432,7 +515,7 @@ inline std::tm gmtime(std::time_t time) { bool fallback(int res) { return res == 0; } -#if !FMT_MSC_VER +#if !FMT_MSC_VERSION bool fallback(detail::null<>) { std::tm* tm = std::gmtime(&time_); if (tm) tm_ = *tm; @@ -453,102 +536,39 @@ inline std::tm gmtime( FMT_BEGIN_DETAIL_NAMESPACE -inline size_t strftime(char* str, size_t count, const char* format, - const std::tm* time) { - // Assign to a pointer to suppress GCCs -Wformat-nonliteral - // First assign the nullptr to suppress -Wsuggest-attribute=format - std::size_t (*strftime)(char*, std::size_t, const char*, const std::tm*) = - nullptr; - strftime = std::strftime; - return strftime(str, count, format, time); -} - -inline size_t strftime(wchar_t* str, size_t count, const wchar_t* format, - const std::tm* time) { - // See above - std::size_t (*wcsftime)(wchar_t*, std::size_t, const wchar_t*, - const std::tm*) = nullptr; - wcsftime = std::wcsftime; - return wcsftime(str, count, format, time); -} - -FMT_END_DETAIL_NAMESPACE - -template -struct formatter, - Char> : formatter { - FMT_CONSTEXPR formatter() { - this->specs = {default_specs, sizeof(default_specs) / sizeof(Char)}; - } - - template - FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - auto it = ctx.begin(); - if (it != ctx.end() && *it == ':') ++it; - auto end = it; - while (end != ctx.end() && *end != '}') ++end; - if (end != it) this->specs = {it, detail::to_unsigned(end - it)}; - return end; - } - - template - auto format(std::chrono::time_point val, - FormatContext& ctx) -> decltype(ctx.out()) { - std::tm time = localtime(val); - return formatter::format(time, ctx); - } - - static constexpr Char default_specs[] = {'%', 'Y', '-', '%', 'm', '-', - '%', 'd', ' ', '%', 'H', ':', - '%', 'M', ':', '%', 'S'}; -}; - -template -constexpr Char - formatter, - Char>::default_specs[]; - -template struct formatter { - template - FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - auto it = ctx.begin(); - if (it != ctx.end() && *it == ':') ++it; - auto end = it; - while (end != ctx.end() && *end != '}') ++end; - specs = {it, detail::to_unsigned(end - it)}; - return end; - } - - template - auto format(const std::tm& tm, FormatContext& ctx) const - -> decltype(ctx.out()) { - basic_memory_buffer tm_format; - tm_format.append(specs.begin(), specs.end()); - // By appending an extra space we can distinguish an empty result that - // indicates insufficient buffer size from a guaranteed non-empty result - // https://github.com/fmtlib/fmt/issues/2238 - tm_format.push_back(' '); - tm_format.push_back('\0'); - basic_memory_buffer buf; - size_t start = buf.size(); - for (;;) { - size_t size = buf.capacity() - start; - size_t count = detail::strftime(&buf[start], size, &tm_format[0], &tm); - if (count != 0) { - buf.resize(start + count); - break; - } - const size_t MIN_GROWTH = 10; - buf.reserve(buf.capacity() + (size > MIN_GROWTH ? size : MIN_GROWTH)); - } - // Remove the extra space. - return std::copy(buf.begin(), buf.end() - 1, ctx.out()); +// Writes two-digit numbers a, b and c separated by sep to buf. +// The method by Pavel Novikov based on +// https://johnnylee-sde.github.io/Fast-unsigned-integer-to-time-string/. +inline void write_digit2_separated(char* buf, unsigned a, unsigned b, + unsigned c, char sep) { + unsigned long long digits = + a | (b << 24) | (static_cast(c) << 48); + // Convert each value to BCD. + // We have x = a * 10 + b and we want to convert it to BCD y = a * 16 + b. + // The difference is + // y - x = a * 6 + // a can be found from x: + // a = floor(x / 10) + // then + // y = x + a * 6 = x + floor(x / 10) * 6 + // floor(x / 10) is (x * 205) >> 11 (needs 16 bits). + digits += (((digits * 205) >> 11) & 0x000f00000f00000f) * 6; + // Put low nibbles to high bytes and high nibbles to low bytes. + digits = ((digits & 0x00f00000f00000f0) >> 4) | + ((digits & 0x000f00000f00000f) << 8); + auto usep = static_cast(sep); + // Add ASCII '0' to each digit byte and insert separators. + digits |= 0x3030003030003030 | (usep << 16) | (usep << 40); + + constexpr const size_t len = 8; + if (const_check(is_big_endian())) { + char tmp[len]; + std::memcpy(tmp, &digits, len); + std::reverse_copy(tmp, tmp + len, buf); + } else { + std::memcpy(buf, &digits, len); } - - basic_string_view specs; -}; - -FMT_BEGIN_DETAIL_NAMESPACE +} template FMT_CONSTEXPR inline const char* get_units() { if (std::is_same::value) return "as"; @@ -610,6 +630,22 @@ FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin, handler.on_text(tab, tab + 1); break; } + // Year: + case 'Y': + handler.on_year(numeric_system::standard); + break; + case 'y': + handler.on_short_year(numeric_system::standard); + break; + case 'C': + handler.on_century(numeric_system::standard); + break; + case 'G': + handler.on_iso_week_based_year(); + break; + case 'g': + handler.on_iso_week_based_short_year(); + break; // Day of the week: case 'a': handler.on_abbr_weekday(); @@ -625,11 +661,34 @@ FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin, break; // Month: case 'b': + case 'h': handler.on_abbr_month(); break; case 'B': handler.on_full_month(); break; + case 'm': + handler.on_dec_month(numeric_system::standard); + break; + // Day of the year/month: + case 'U': + handler.on_dec0_week_of_year(numeric_system::standard); + break; + case 'W': + handler.on_dec1_week_of_year(numeric_system::standard); + break; + case 'V': + handler.on_iso_week_of_year(numeric_system::standard); + break; + case 'j': + handler.on_day_of_year(); + break; + case 'd': + handler.on_day_of_month(numeric_system::standard); + break; + case 'e': + handler.on_day_of_month_space(numeric_system::standard); + break; // Hour, minute, second: case 'H': handler.on_24_hour(numeric_system::standard); @@ -688,6 +747,15 @@ FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin, if (ptr == end) FMT_THROW(format_error("invalid format")); c = *ptr++; switch (c) { + case 'Y': + handler.on_year(numeric_system::alternative); + break; + case 'y': + handler.on_offset_year(); + break; + case 'C': + handler.on_century(numeric_system::alternative); + break; case 'c': handler.on_datetime(numeric_system::alternative); break; @@ -706,6 +774,27 @@ FMT_CONSTEXPR const Char* parse_chrono_format(const Char* begin, if (ptr == end) FMT_THROW(format_error("invalid format")); c = *ptr++; switch (c) { + case 'y': + handler.on_short_year(numeric_system::alternative); + break; + case 'm': + handler.on_dec_month(numeric_system::alternative); + break; + case 'U': + handler.on_dec0_week_of_year(numeric_system::alternative); + break; + case 'W': + handler.on_dec1_week_of_year(numeric_system::alternative); + break; + case 'V': + handler.on_iso_week_of_year(numeric_system::alternative); + break; + case 'd': + handler.on_day_of_month(numeric_system::alternative); + break; + case 'e': + handler.on_day_of_month_space(numeric_system::alternative); + break; case 'w': handler.on_dec0_weekday(numeric_system::alternative); break; @@ -741,12 +830,25 @@ template struct null_chrono_spec_handler { FMT_CONSTEXPR void unsupported() { static_cast(this)->unsupported(); } + FMT_CONSTEXPR void on_year(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_short_year(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_offset_year() { unsupported(); } + FMT_CONSTEXPR void on_century(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_iso_week_based_year() { unsupported(); } + FMT_CONSTEXPR void on_iso_week_based_short_year() { unsupported(); } FMT_CONSTEXPR void on_abbr_weekday() { unsupported(); } FMT_CONSTEXPR void on_full_weekday() { unsupported(); } FMT_CONSTEXPR void on_dec0_weekday(numeric_system) { unsupported(); } FMT_CONSTEXPR void on_dec1_weekday(numeric_system) { unsupported(); } FMT_CONSTEXPR void on_abbr_month() { unsupported(); } FMT_CONSTEXPR void on_full_month() { unsupported(); } + FMT_CONSTEXPR void on_dec_month(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_dec0_week_of_year(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_dec1_week_of_year(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_iso_week_of_year(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_day_of_year() { unsupported(); } + FMT_CONSTEXPR void on_day_of_month(numeric_system) { unsupported(); } + FMT_CONSTEXPR void on_day_of_month_space(numeric_system) { unsupported(); } FMT_CONSTEXPR void on_24_hour(numeric_system) { unsupported(); } FMT_CONSTEXPR void on_12_hour(numeric_system) { unsupported(); } FMT_CONSTEXPR void on_minute(numeric_system) { unsupported(); } @@ -766,6 +868,509 @@ template struct null_chrono_spec_handler { FMT_CONSTEXPR void on_tz_name() { unsupported(); } }; +struct tm_format_checker : null_chrono_spec_handler { + FMT_NORETURN void unsupported() { FMT_THROW(format_error("no format")); } + + template + FMT_CONSTEXPR void on_text(const Char*, const Char*) {} + FMT_CONSTEXPR void on_year(numeric_system) {} + FMT_CONSTEXPR void on_short_year(numeric_system) {} + FMT_CONSTEXPR void on_offset_year() {} + FMT_CONSTEXPR void on_century(numeric_system) {} + FMT_CONSTEXPR void on_iso_week_based_year() {} + FMT_CONSTEXPR void on_iso_week_based_short_year() {} + FMT_CONSTEXPR void on_abbr_weekday() {} + FMT_CONSTEXPR void on_full_weekday() {} + FMT_CONSTEXPR void on_dec0_weekday(numeric_system) {} + FMT_CONSTEXPR void on_dec1_weekday(numeric_system) {} + FMT_CONSTEXPR void on_abbr_month() {} + FMT_CONSTEXPR void on_full_month() {} + FMT_CONSTEXPR void on_dec_month(numeric_system) {} + FMT_CONSTEXPR void on_dec0_week_of_year(numeric_system) {} + FMT_CONSTEXPR void on_dec1_week_of_year(numeric_system) {} + FMT_CONSTEXPR void on_iso_week_of_year(numeric_system) {} + FMT_CONSTEXPR void on_day_of_year() {} + FMT_CONSTEXPR void on_day_of_month(numeric_system) {} + FMT_CONSTEXPR void on_day_of_month_space(numeric_system) {} + FMT_CONSTEXPR void on_24_hour(numeric_system) {} + FMT_CONSTEXPR void on_12_hour(numeric_system) {} + FMT_CONSTEXPR void on_minute(numeric_system) {} + FMT_CONSTEXPR void on_second(numeric_system) {} + FMT_CONSTEXPR void on_datetime(numeric_system) {} + FMT_CONSTEXPR void on_loc_date(numeric_system) {} + FMT_CONSTEXPR void on_loc_time(numeric_system) {} + FMT_CONSTEXPR void on_us_date() {} + FMT_CONSTEXPR void on_iso_date() {} + FMT_CONSTEXPR void on_12_hour_time() {} + FMT_CONSTEXPR void on_24_hour_time() {} + FMT_CONSTEXPR void on_iso_time() {} + FMT_CONSTEXPR void on_am_pm() {} + FMT_CONSTEXPR void on_utc_offset() {} + FMT_CONSTEXPR void on_tz_name() {} +}; + +inline const char* tm_wday_full_name(int wday) { + static constexpr const char* full_name_list[] = { + "Sunday", "Monday", "Tuesday", "Wednesday", + "Thursday", "Friday", "Saturday"}; + return wday >= 0 && wday <= 6 ? full_name_list[wday] : "?"; +} +inline const char* tm_wday_short_name(int wday) { + static constexpr const char* short_name_list[] = {"Sun", "Mon", "Tue", "Wed", + "Thu", "Fri", "Sat"}; + return wday >= 0 && wday <= 6 ? short_name_list[wday] : "???"; +} + +inline const char* tm_mon_full_name(int mon) { + static constexpr const char* full_name_list[] = { + "January", "February", "March", "April", "May", "June", + "July", "August", "September", "October", "November", "December"}; + return mon >= 0 && mon <= 11 ? full_name_list[mon] : "?"; +} +inline const char* tm_mon_short_name(int mon) { + static constexpr const char* short_name_list[] = { + "Jan", "Feb", "Mar", "Apr", "May", "Jun", + "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", + }; + return mon >= 0 && mon <= 11 ? short_name_list[mon] : "???"; +} + +template +struct has_member_data_tm_gmtoff : std::false_type {}; +template +struct has_member_data_tm_gmtoff> + : std::true_type {}; + +template +struct has_member_data_tm_zone : std::false_type {}; +template +struct has_member_data_tm_zone> + : std::true_type {}; + +#if FMT_USE_TZSET +inline void tzset_once() { + static bool init = []() -> bool { + _tzset(); + return true; + }(); + ignore_unused(init); +} +#endif + +template class tm_writer { + private: + static constexpr int days_per_week = 7; + + const std::locale& loc_; + const bool is_classic_; + OutputIt out_; + const std::tm& tm_; + + auto tm_sec() const noexcept -> int { + FMT_ASSERT(tm_.tm_sec >= 0 && tm_.tm_sec <= 61, ""); + return tm_.tm_sec; + } + auto tm_min() const noexcept -> int { + FMT_ASSERT(tm_.tm_min >= 0 && tm_.tm_min <= 59, ""); + return tm_.tm_min; + } + auto tm_hour() const noexcept -> int { + FMT_ASSERT(tm_.tm_hour >= 0 && tm_.tm_hour <= 23, ""); + return tm_.tm_hour; + } + auto tm_mday() const noexcept -> int { + FMT_ASSERT(tm_.tm_mday >= 1 && tm_.tm_mday <= 31, ""); + return tm_.tm_mday; + } + auto tm_mon() const noexcept -> int { + FMT_ASSERT(tm_.tm_mon >= 0 && tm_.tm_mon <= 11, ""); + return tm_.tm_mon; + } + auto tm_year() const noexcept -> long long { return 1900ll + tm_.tm_year; } + auto tm_wday() const noexcept -> int { + FMT_ASSERT(tm_.tm_wday >= 0 && tm_.tm_wday <= 6, ""); + return tm_.tm_wday; + } + auto tm_yday() const noexcept -> int { + FMT_ASSERT(tm_.tm_yday >= 0 && tm_.tm_yday <= 365, ""); + return tm_.tm_yday; + } + + auto tm_hour12() const noexcept -> int { + const auto h = tm_hour(); + const auto z = h < 12 ? h : h - 12; + return z == 0 ? 12 : z; + } + + // POSIX and the C Standard are unclear or inconsistent about what %C and %y + // do if the year is negative or exceeds 9999. Use the convention that %C + // concatenated with %y yields the same output as %Y, and that %Y contains at + // least 4 characters, with more only if necessary. + auto split_year_lower(long long year) const noexcept -> int { + auto l = year % 100; + if (l < 0) l = -l; // l in [0, 99] + return static_cast(l); + } + + // Algorithm: + // https://en.wikipedia.org/wiki/ISO_week_date#Calculating_the_week_number_from_a_month_and_day_of_the_month_or_ordinal_date + auto iso_year_weeks(long long curr_year) const noexcept -> int { + const auto prev_year = curr_year - 1; + const auto curr_p = + (curr_year + curr_year / 4 - curr_year / 100 + curr_year / 400) % + days_per_week; + const auto prev_p = + (prev_year + prev_year / 4 - prev_year / 100 + prev_year / 400) % + days_per_week; + return 52 + ((curr_p == 4 || prev_p == 3) ? 1 : 0); + } + auto iso_week_num(int tm_yday, int tm_wday) const noexcept -> int { + return (tm_yday + 11 - (tm_wday == 0 ? days_per_week : tm_wday)) / + days_per_week; + } + auto tm_iso_week_year() const noexcept -> long long { + const auto year = tm_year(); + const auto w = iso_week_num(tm_yday(), tm_wday()); + if (w < 1) return year - 1; + if (w > iso_year_weeks(year)) return year + 1; + return year; + } + auto tm_iso_week_of_year() const noexcept -> int { + const auto year = tm_year(); + const auto w = iso_week_num(tm_yday(), tm_wday()); + if (w < 1) return iso_year_weeks(year - 1); + if (w > iso_year_weeks(year)) return 1; + return w; + } + + void write1(int value) { + *out_++ = static_cast('0' + to_unsigned(value) % 10); + } + void write2(int value) { + const char* d = digits2(to_unsigned(value) % 100); + *out_++ = *d++; + *out_++ = *d; + } + + void write_year_extended(long long year) { + // At least 4 characters. + int width = 4; + if (year < 0) { + *out_++ = '-'; + year = 0 - year; + --width; + } + uint32_or_64_or_128_t n = to_unsigned(year); + const int num_digits = count_digits(n); + if (width > num_digits) out_ = std::fill_n(out_, width - num_digits, '0'); + out_ = format_decimal(out_, n, num_digits).end; + } + void write_year(long long year) { + if (year >= 0 && year < 10000) { + write2(static_cast(year / 100)); + write2(static_cast(year % 100)); + } else { + write_year_extended(year); + } + } + + void write_utc_offset(long offset) { + if (offset < 0) { + *out_++ = '-'; + offset = -offset; + } else { + *out_++ = '+'; + } + offset /= 60; + write2(static_cast(offset / 60)); + write2(static_cast(offset % 60)); + } + template ::value)> + void format_utc_offset_impl(const T& tm) { + write_utc_offset(tm.tm_gmtoff); + } + template ::value)> + void format_utc_offset_impl(const T& tm) { +#if defined(_WIN32) && defined(_UCRT) +# if FMT_USE_TZSET + tzset_once(); +# endif + long offset = 0; + _get_timezone(&offset); + if (tm.tm_isdst) { + long dstbias = 0; + _get_dstbias(&dstbias); + offset += dstbias; + } + write_utc_offset(-offset); +#else + ignore_unused(tm); + format_localized('z'); +#endif + } + + template ::value)> + void format_tz_name_impl(const T& tm) { + if (is_classic_) + out_ = write_tm_str(out_, tm.tm_zone, loc_); + else + format_localized('Z'); + } + template ::value)> + void format_tz_name_impl(const T&) { + format_localized('Z'); + } + + void format_localized(char format, char modifier = 0) { + out_ = write(out_, tm_, loc_, format, modifier); + } + + public: + tm_writer(const std::locale& loc, OutputIt out, const std::tm& tm) + : loc_(loc), + is_classic_(loc_ == get_classic_locale()), + out_(out), + tm_(tm) {} + + OutputIt out() const { return out_; } + + FMT_CONSTEXPR void on_text(const Char* begin, const Char* end) { + out_ = copy_str(begin, end, out_); + } + + void on_abbr_weekday() { + if (is_classic_) + out_ = write(out_, tm_wday_short_name(tm_wday())); + else + format_localized('a'); + } + void on_full_weekday() { + if (is_classic_) + out_ = write(out_, tm_wday_full_name(tm_wday())); + else + format_localized('A'); + } + void on_dec0_weekday(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) return write1(tm_wday()); + format_localized('w', 'O'); + } + void on_dec1_weekday(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) { + auto wday = tm_wday(); + write1(wday == 0 ? days_per_week : wday); + } else { + format_localized('u', 'O'); + } + } + + void on_abbr_month() { + if (is_classic_) + out_ = write(out_, tm_mon_short_name(tm_mon())); + else + format_localized('b'); + } + void on_full_month() { + if (is_classic_) + out_ = write(out_, tm_mon_full_name(tm_mon())); + else + format_localized('B'); + } + + void on_datetime(numeric_system ns) { + if (is_classic_) { + on_abbr_weekday(); + *out_++ = ' '; + on_abbr_month(); + *out_++ = ' '; + on_day_of_month_space(numeric_system::standard); + *out_++ = ' '; + on_iso_time(); + *out_++ = ' '; + on_year(numeric_system::standard); + } else { + format_localized('c', ns == numeric_system::standard ? '\0' : 'E'); + } + } + void on_loc_date(numeric_system ns) { + if (is_classic_) + on_us_date(); + else + format_localized('x', ns == numeric_system::standard ? '\0' : 'E'); + } + void on_loc_time(numeric_system ns) { + if (is_classic_) + on_iso_time(); + else + format_localized('X', ns == numeric_system::standard ? '\0' : 'E'); + } + void on_us_date() { + char buf[8]; + write_digit2_separated(buf, to_unsigned(tm_mon() + 1), + to_unsigned(tm_mday()), + to_unsigned(split_year_lower(tm_year())), '/'); + out_ = copy_str(std::begin(buf), std::end(buf), out_); + } + void on_iso_date() { + auto year = tm_year(); + char buf[10]; + size_t offset = 0; + if (year >= 0 && year < 10000) { + copy2(buf, digits2(static_cast(year / 100))); + } else { + offset = 4; + write_year_extended(year); + year = 0; + } + write_digit2_separated(buf + 2, static_cast(year % 100), + to_unsigned(tm_mon() + 1), to_unsigned(tm_mday()), + '-'); + out_ = copy_str(std::begin(buf) + offset, std::end(buf), out_); + } + + void on_utc_offset() { format_utc_offset_impl(tm_); } + void on_tz_name() { format_tz_name_impl(tm_); } + + void on_year(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) + return write_year(tm_year()); + format_localized('Y', 'E'); + } + void on_short_year(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) + return write2(split_year_lower(tm_year())); + format_localized('y', 'O'); + } + void on_offset_year() { + if (is_classic_) return write2(split_year_lower(tm_year())); + format_localized('y', 'E'); + } + + void on_century(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) { + auto year = tm_year(); + auto upper = year / 100; + if (year >= -99 && year < 0) { + // Zero upper on negative year. + *out_++ = '-'; + *out_++ = '0'; + } else if (upper >= 0 && upper < 100) { + write2(static_cast(upper)); + } else { + out_ = write(out_, upper); + } + } else { + format_localized('C', 'E'); + } + } + + void on_dec_month(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) + return write2(tm_mon() + 1); + format_localized('m', 'O'); + } + + void on_dec0_week_of_year(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) + return write2((tm_yday() + days_per_week - tm_wday()) / days_per_week); + format_localized('U', 'O'); + } + void on_dec1_week_of_year(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) { + auto wday = tm_wday(); + write2((tm_yday() + days_per_week - + (wday == 0 ? (days_per_week - 1) : (wday - 1))) / + days_per_week); + } else { + format_localized('W', 'O'); + } + } + void on_iso_week_of_year(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) + return write2(tm_iso_week_of_year()); + format_localized('V', 'O'); + } + + void on_iso_week_based_year() { write_year(tm_iso_week_year()); } + void on_iso_week_based_short_year() { + write2(split_year_lower(tm_iso_week_year())); + } + + void on_day_of_year() { + auto yday = tm_yday() + 1; + write1(yday / 100); + write2(yday % 100); + } + void on_day_of_month(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) return write2(tm_mday()); + format_localized('d', 'O'); + } + void on_day_of_month_space(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) { + auto mday = to_unsigned(tm_mday()) % 100; + const char* d2 = digits2(mday); + *out_++ = mday < 10 ? ' ' : d2[0]; + *out_++ = d2[1]; + } else { + format_localized('e', 'O'); + } + } + + void on_24_hour(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) return write2(tm_hour()); + format_localized('H', 'O'); + } + void on_12_hour(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) + return write2(tm_hour12()); + format_localized('I', 'O'); + } + void on_minute(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) return write2(tm_min()); + format_localized('M', 'O'); + } + void on_second(numeric_system ns) { + if (is_classic_ || ns == numeric_system::standard) return write2(tm_sec()); + format_localized('S', 'O'); + } + + void on_12_hour_time() { + if (is_classic_) { + char buf[8]; + write_digit2_separated(buf, to_unsigned(tm_hour12()), + to_unsigned(tm_min()), to_unsigned(tm_sec()), ':'); + out_ = copy_str(std::begin(buf), std::end(buf), out_); + *out_++ = ' '; + on_am_pm(); + } else { + format_localized('r'); + } + } + void on_24_hour_time() { + write2(tm_hour()); + *out_++ = ':'; + write2(tm_min()); + } + void on_iso_time() { + char buf[8]; + write_digit2_separated(buf, to_unsigned(tm_hour()), to_unsigned(tm_min()), + to_unsigned(tm_sec()), ':'); + out_ = copy_str(std::begin(buf), std::end(buf), out_); + } + + void on_am_pm() { + if (is_classic_) { + *out_++ = tm_hour() < 12 ? 'A' : 'P'; + *out_++ = 'M'; + } else { + format_localized('p'); + } + } + + // These apply to chrono durations but not tm. + void on_duration_value() {} + void on_duration_unit() {} +}; + struct chrono_format_checker : null_chrono_spec_handler { FMT_NORETURN void unsupported() { FMT_THROW(format_error("no date")); } @@ -783,39 +1388,25 @@ struct chrono_format_checker : null_chrono_spec_handler { FMT_CONSTEXPR void on_duration_unit() {} }; -template ::value)> -inline bool isnan(T) { - return false; -} -template ::value)> -inline bool isnan(T value) { - return std::isnan(value); -} - template ::value)> inline bool isfinite(T) { return true; } -template ::value)> -inline bool isfinite(T value) { - return std::isfinite(value); -} -// Converts value to int and checks that it's in the range [0, upper). -template ::value)> -inline int to_nonnegative_int(T value, int upper) { - FMT_ASSERT(value >= 0 && to_unsigned(value) <= to_unsigned(upper), +// Converts value to Int and checks that it's in the range [0, upper). +template ::value)> +inline Int to_nonnegative_int(T value, Int upper) { + FMT_ASSERT(std::is_unsigned::value || + (value >= 0 && to_unsigned(value) <= to_unsigned(upper)), "invalid value"); (void)upper; - return static_cast(value); + return static_cast(value); } -template ::value)> -inline int to_nonnegative_int(T value, int upper) { - FMT_ASSERT( - std::isnan(value) || (value >= 0 && value <= static_cast(upper)), - "invalid value"); - (void)upper; - return static_cast(value); +template ::value)> +inline Int to_nonnegative_int(T value, Int upper) { + if (value < 0 || value > static_cast(upper)) + FMT_THROW(format_error("invalid value")); + return static_cast(value); } template ::value)> @@ -872,15 +1463,45 @@ inline std::chrono::duration get_milliseconds( #endif } -template ::value)> -inline std::chrono::duration get_milliseconds( +// Counts the number of fractional digits in the range [0, 18] according to the +// C++20 spec. If more than 18 fractional digits are required then returns 6 for +// microseconds precision. +template () / 10)> +struct count_fractional_digits { + static constexpr int value = + Num % Den == 0 ? N : count_fractional_digits::value; +}; + +// Base case that doesn't instantiate any more templates +// in order to avoid overflow. +template +struct count_fractional_digits { + static constexpr int value = (Num % Den == 0) ? N : 6; +}; + +constexpr long long pow10(std::uint32_t n) { + return n == 0 ? 1 : 10 * pow10(n - 1); +} + +template ::is_signed)> +constexpr std::chrono::duration abs( std::chrono::duration d) { - using common_type = typename std::common_type::type; - auto ms = mod(d.count() * static_cast(Period::num) / - static_cast(Period::den) * 1000, - 1000); - return std::chrono::duration(static_cast(ms)); + // We need to compare the duration using the count() method directly + // due to a compiler bug in clang-11 regarding the spaceship operator, + // when -Wzero-as-null-pointer-constant is enabled. + // In clang-12 the bug has been fixed. See + // https://bugs.llvm.org/show_bug.cgi?id=46235 and the reproducible example: + // https://www.godbolt.org/z/Knbb5joYx. + return d.count() >= d.zero().count() ? d : -d; +} + +template ::is_signed)> +constexpr std::chrono::duration abs( + std::chrono::duration d) { + return d; } template (); specs.precision = precision; - specs.type = precision > 0 ? 'f' : 'g'; + specs.type = precision >= 0 ? presentation_type::fixed_lower + : presentation_type::general_lower; return write(out, val, specs); } @@ -926,6 +1548,26 @@ OutputIt format_duration_unit(OutputIt out) { return out; } +class get_locale { + private: + union { + std::locale locale_; + }; + bool has_locale_ = false; + + public: + get_locale(bool localized, locale_ref loc) : has_locale_(localized) { + if (localized) + ::new (&locale_) std::locale(loc.template get()); + } + ~get_locale() { + if (has_locale_) locale_.~locale(); + } + operator const std::locale&() const { + return has_locale_ ? locale_ : get_classic_locale(); + } +}; + template struct chrono_formatter { @@ -944,9 +1586,10 @@ struct chrono_formatter { bool negative; using char_type = typename FormatContext::char_type; + using tm_writer_type = tm_writer; - explicit chrono_formatter(FormatContext& ctx, OutputIt o, - std::chrono::duration d) + chrono_formatter(FormatContext& ctx, OutputIt o, + std::chrono::duration d) : context(ctx), out(o), val(static_cast(d.count())), @@ -1021,15 +1664,47 @@ struct chrono_formatter { out = format_decimal(out, n, num_digits).end; } + template void write_fractional_seconds(Duration d) { + FMT_ASSERT(!std::is_floating_point::value, ""); + constexpr auto num_fractional_digits = + count_fractional_digits::value; + + using subsecond_precision = std::chrono::duration< + typename std::common_type::type, + std::ratio<1, detail::pow10(num_fractional_digits)>>; + if (std::ratio_less::value) { + *out++ = '.'; + auto fractional = + detail::abs(d) - std::chrono::duration_cast(d); + auto subseconds = + std::chrono::treat_as_floating_point< + typename subsecond_precision::rep>::value + ? fractional.count() + : std::chrono::duration_cast(fractional) + .count(); + uint32_or_64_or_128_t n = + to_unsigned(to_nonnegative_int(subseconds, max_value())); + int num_digits = detail::count_digits(n); + if (num_fractional_digits > num_digits) + out = std::fill_n(out, num_fractional_digits - num_digits, '0'); + out = format_decimal(out, n, num_digits).end; + } + } + void write_nan() { std::copy_n("nan", 3, out); } void write_pinf() { std::copy_n("inf", 3, out); } void write_ninf() { std::copy_n("-inf", 4, out); } - void format_localized(const tm& time, char format, char modifier = 0) { + template + void format_tm(const tm& time, Callback cb, Args... args) { if (isnan(val)) return write_nan(); - const auto& loc = localized ? context.locale().template get() - : std::locale::classic(); - out = detail::write(out, time, loc, format, modifier); + get_locale loc(localized, context.locale()); + auto w = tm_writer_type(loc, out, time); + (w.*cb)(args...); + out = w.out(); } void on_text(const char_type* begin, const char_type* end) { @@ -1050,6 +1725,19 @@ struct chrono_formatter { void on_iso_date() {} void on_utc_offset() {} void on_tz_name() {} + void on_year(numeric_system) {} + void on_short_year(numeric_system) {} + void on_offset_year() {} + void on_century(numeric_system) {} + void on_iso_week_based_year() {} + void on_iso_week_based_short_year() {} + void on_dec_month(numeric_system) {} + void on_dec0_week_of_year(numeric_system) {} + void on_dec1_week_of_year(numeric_system) {} + void on_iso_week_of_year(numeric_system) {} + void on_day_of_year() {} + void on_day_of_month(numeric_system) {} + void on_day_of_month_space(numeric_system) {} void on_24_hour(numeric_system ns) { if (handle_nan_inf()) return; @@ -1057,7 +1745,7 @@ struct chrono_formatter { if (ns == numeric_system::standard) return write(hour(), 2); auto time = tm(); time.tm_hour = to_nonnegative_int(hour(), 24); - format_localized(time, 'H', 'O'); + format_tm(time, &tm_writer_type::on_24_hour, ns); } void on_12_hour(numeric_system ns) { @@ -1066,7 +1754,7 @@ struct chrono_formatter { if (ns == numeric_system::standard) return write(hour12(), 2); auto time = tm(); time.tm_hour = to_nonnegative_int(hour12(), 12); - format_localized(time, 'I', 'O'); + format_tm(time, &tm_writer_type::on_12_hour, ns); } void on_minute(numeric_system ns) { @@ -1075,37 +1763,39 @@ struct chrono_formatter { if (ns == numeric_system::standard) return write(minute(), 2); auto time = tm(); time.tm_min = to_nonnegative_int(minute(), 60); - format_localized(time, 'M', 'O'); + format_tm(time, &tm_writer_type::on_minute, ns); } void on_second(numeric_system ns) { if (handle_nan_inf()) return; if (ns == numeric_system::standard) { - write(second(), 2); -#if FMT_SAFE_DURATION_CAST - // convert rep->Rep - using duration_rep = std::chrono::duration; - using duration_Rep = std::chrono::duration; - auto tmpval = fmt_safe_duration_cast(duration_rep{val}); -#else - auto tmpval = std::chrono::duration(val); -#endif - auto ms = get_milliseconds(tmpval); - if (ms != std::chrono::milliseconds(0)) { - *out++ = '.'; - write(ms.count(), 3); + if (std::is_floating_point::value) { + constexpr auto num_fractional_digits = + count_fractional_digits::value; + auto buf = memory_buffer(); + format_to(std::back_inserter(buf), runtime("{:.{}f}"), + std::fmod(val * static_cast(Period::num) / + static_cast(Period::den), + static_cast(60)), + num_fractional_digits); + if (negative) *out++ = '-'; + if (buf.size() < 2 || buf[1] == '.') *out++ = '0'; + out = std::copy(buf.begin(), buf.end(), out); + } else { + write(second(), 2); + write_fractional_seconds(std::chrono::duration(val)); } return; } auto time = tm(); time.tm_sec = to_nonnegative_int(second(), 60); - format_localized(time, 'S', 'O'); + format_tm(time, &tm_writer_type::on_second, ns); } void on_12_hour_time() { if (handle_nan_inf()) return; - format_localized(time(), 'r'); + format_tm(time(), &tm_writer_type::on_12_hour_time); } void on_24_hour_time() { @@ -1124,12 +1814,12 @@ struct chrono_formatter { on_24_hour_time(); *out++ = ':'; if (handle_nan_inf()) return; - write(second(), 2); + on_second(numeric_system::standard); } void on_am_pm() { if (handle_nan_inf()) return; - format_localized(time(), 'p'); + format_tm(time(), &tm_writer_type::on_am_pm); } void on_duration_value() { @@ -1159,15 +1849,18 @@ class weekday { : value(static_cast(wd != 7 ? wd : 0)) {} constexpr unsigned c_encoding() const noexcept { return value; } }; + +class year_month_day {}; #endif // A rudimentary weekday formatter. -template <> struct formatter { +template struct formatter { private: bool localized = false; public: - FMT_CONSTEXPR auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) { + FMT_CONSTEXPR auto parse(basic_format_parse_context& ctx) + -> decltype(ctx.begin()) { auto begin = ctx.begin(), end = ctx.end(); if (begin != end && *begin == 'L') { ++begin; @@ -1176,12 +1869,14 @@ template <> struct formatter { return begin; } - auto format(weekday wd, format_context& ctx) -> decltype(ctx.out()) { + template + auto format(weekday wd, FormatContext& ctx) const -> decltype(ctx.out()) { auto time = std::tm(); time.tm_wday = static_cast(wd.c_encoding()); - const auto& loc = localized ? ctx.locale().template get() - : std::locale::classic(); - return detail::write(ctx.out(), time, loc, 'a'); + detail::get_locale loc(localized, ctx.locale()); + auto w = detail::tm_writer(loc, ctx.out(), time); + w.on_abbr_weekday(); + return w.out(); } }; @@ -1260,7 +1955,8 @@ struct formatter, Char> { ++begin; localized = true; } - end = parse_chrono_format(begin, end, detail::chrono_format_checker()); + end = detail::parse_chrono_format(begin, end, + detail::chrono_format_checker()); return {begin, end}; } @@ -1302,6 +1998,71 @@ struct formatter, Char> { } }; +template +struct formatter, + Char> : formatter { + FMT_CONSTEXPR formatter() { + basic_string_view default_specs = + detail::string_literal{}; + this->do_parse(default_specs.begin(), default_specs.end()); + } + + template + auto format(std::chrono::time_point val, + FormatContext& ctx) const -> decltype(ctx.out()) { + return formatter::format(localtime(val), ctx); + } +}; + +template struct formatter { + private: + enum class spec { + unknown, + year_month_day, + hh_mm_ss, + }; + spec spec_ = spec::unknown; + basic_string_view specs; + + protected: + template FMT_CONSTEXPR auto do_parse(It begin, It end) -> It { + if (begin != end && *begin == ':') ++begin; + end = detail::parse_chrono_format(begin, end, detail::tm_format_checker()); + // Replace default spec only if the new spec is not empty. + if (end != begin) specs = {begin, detail::to_unsigned(end - begin)}; + return end; + } + + public: + FMT_CONSTEXPR auto parse(basic_format_parse_context& ctx) + -> decltype(ctx.begin()) { + auto end = this->do_parse(ctx.begin(), ctx.end()); + // basic_string_view<>::compare isn't constexpr before C++17. + if (specs.size() == 2 && specs[0] == Char('%')) { + if (specs[1] == Char('F')) + spec_ = spec::year_month_day; + else if (specs[1] == Char('T')) + spec_ = spec::hh_mm_ss; + } + return end; + } + + template + auto format(const std::tm& tm, FormatContext& ctx) const + -> decltype(ctx.out()) { + const auto loc_ref = ctx.locale(); + detail::get_locale loc(static_cast(loc_ref), loc_ref); + auto w = detail::tm_writer(loc, ctx.out(), tm); + if (spec_ == spec::year_month_day) + w.on_iso_date(); + else if (spec_ == spec::hh_mm_ss) + w.on_iso_time(); + else + detail::parse_chrono_format(specs.begin(), specs.end(), w); + return w.out(); + } +}; + FMT_MODULE_EXPORT_END FMT_END_NAMESPACE diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bundled/color.h b/Lumos/External/spdlog/include/spdlog/fmt/bundled/color.h index 3d5490e87..4c163277e 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/bundled/color.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/bundled/color.h @@ -10,13 +10,6 @@ #include "format.h" -// __declspec(deprecated) is broken in some MSVC versions. -#if FMT_MSC_VER -# define FMT_DEPRECATED_NONMSVC -#else -# define FMT_DEPRECATED_NONMSVC FMT_DEPRECATED -#endif - FMT_BEGIN_NAMESPACE FMT_MODULE_EXPORT_BEGIN @@ -185,9 +178,13 @@ enum class terminal_color : uint8_t { enum class emphasis : uint8_t { bold = 1, - italic = 1 << 1, - underline = 1 << 2, - strikethrough = 1 << 3 + faint = 1 << 1, + italic = 1 << 2, + underline = 1 << 3, + blink = 1 << 4, + reverse = 1 << 5, + conceal = 1 << 6, + strikethrough = 1 << 7, }; // rgb is a struct for red, green and blue colors. @@ -210,17 +207,16 @@ FMT_BEGIN_DETAIL_NAMESPACE // color is a struct of either a rgb color or a terminal color. struct color_type { - FMT_CONSTEXPR color_type() FMT_NOEXCEPT : is_rgb(), value{} {} - FMT_CONSTEXPR color_type(color rgb_color) FMT_NOEXCEPT : is_rgb(true), - value{} { + FMT_CONSTEXPR color_type() noexcept : is_rgb(), value{} {} + FMT_CONSTEXPR color_type(color rgb_color) noexcept : is_rgb(true), value{} { value.rgb_color = static_cast(rgb_color); } - FMT_CONSTEXPR color_type(rgb rgb_color) FMT_NOEXCEPT : is_rgb(true), value{} { + FMT_CONSTEXPR color_type(rgb rgb_color) noexcept : is_rgb(true), value{} { value.rgb_color = (static_cast(rgb_color.r) << 16) | (static_cast(rgb_color.g) << 8) | rgb_color.b; } - FMT_CONSTEXPR color_type(terminal_color term_color) FMT_NOEXCEPT : is_rgb(), - value{} { + FMT_CONSTEXPR color_type(terminal_color term_color) noexcept + : is_rgb(), value{} { value.term_color = static_cast(term_color); } bool is_rgb; @@ -235,10 +231,8 @@ FMT_END_DETAIL_NAMESPACE /** A text style consisting of foreground and background colors and emphasis. */ class text_style { public: - FMT_CONSTEXPR text_style(emphasis em = emphasis()) FMT_NOEXCEPT - : set_foreground_color(), - set_background_color(), - ems(em) {} + FMT_CONSTEXPR text_style(emphasis em = emphasis()) noexcept + : set_foreground_color(), set_background_color(), ems(em) {} FMT_CONSTEXPR text_style& operator|=(const text_style& rhs) { if (!set_foreground_color) { @@ -269,44 +263,32 @@ class text_style { return lhs |= rhs; } - FMT_DEPRECATED_NONMSVC FMT_CONSTEXPR text_style& operator&=( - const text_style& rhs) { - return and_assign(rhs); - } - - FMT_DEPRECATED_NONMSVC friend FMT_CONSTEXPR text_style - operator&(text_style lhs, const text_style& rhs) { - return lhs.and_assign(rhs); - } - - FMT_CONSTEXPR bool has_foreground() const FMT_NOEXCEPT { + FMT_CONSTEXPR bool has_foreground() const noexcept { return set_foreground_color; } - FMT_CONSTEXPR bool has_background() const FMT_NOEXCEPT { + FMT_CONSTEXPR bool has_background() const noexcept { return set_background_color; } - FMT_CONSTEXPR bool has_emphasis() const FMT_NOEXCEPT { + FMT_CONSTEXPR bool has_emphasis() const noexcept { return static_cast(ems) != 0; } - FMT_CONSTEXPR detail::color_type get_foreground() const FMT_NOEXCEPT { + FMT_CONSTEXPR detail::color_type get_foreground() const noexcept { FMT_ASSERT(has_foreground(), "no foreground specified for this style"); return foreground_color; } - FMT_CONSTEXPR detail::color_type get_background() const FMT_NOEXCEPT { + FMT_CONSTEXPR detail::color_type get_background() const noexcept { FMT_ASSERT(has_background(), "no background specified for this style"); return background_color; } - FMT_CONSTEXPR emphasis get_emphasis() const FMT_NOEXCEPT { + FMT_CONSTEXPR emphasis get_emphasis() const noexcept { FMT_ASSERT(has_emphasis(), "no emphasis specified for this style"); return ems; } private: FMT_CONSTEXPR text_style(bool is_foreground, - detail::color_type text_color) FMT_NOEXCEPT - : set_foreground_color(), - set_background_color(), - ems() { + detail::color_type text_color) noexcept + : set_foreground_color(), set_background_color(), ems() { if (is_foreground) { foreground_color = text_color; set_foreground_color = true; @@ -316,36 +298,9 @@ class text_style { } } - // DEPRECATED! - FMT_CONSTEXPR text_style& and_assign(const text_style& rhs) { - if (!set_foreground_color) { - set_foreground_color = rhs.set_foreground_color; - foreground_color = rhs.foreground_color; - } else if (rhs.set_foreground_color) { - if (!foreground_color.is_rgb || !rhs.foreground_color.is_rgb) - FMT_THROW(format_error("can't AND a terminal color")); - foreground_color.value.rgb_color &= rhs.foreground_color.value.rgb_color; - } - - if (!set_background_color) { - set_background_color = rhs.set_background_color; - background_color = rhs.background_color; - } else if (rhs.set_background_color) { - if (!background_color.is_rgb || !rhs.background_color.is_rgb) - FMT_THROW(format_error("can't AND a terminal color")); - background_color.value.rgb_color &= rhs.background_color.value.rgb_color; - } - - ems = static_cast(static_cast(ems) & - static_cast(rhs.ems)); - return *this; - } - - friend FMT_CONSTEXPR_DECL text_style fg(detail::color_type foreground) - FMT_NOEXCEPT; + friend FMT_CONSTEXPR text_style fg(detail::color_type foreground) noexcept; - friend FMT_CONSTEXPR_DECL text_style bg(detail::color_type background) - FMT_NOEXCEPT; + friend FMT_CONSTEXPR text_style bg(detail::color_type background) noexcept; detail::color_type foreground_color; detail::color_type background_color; @@ -355,17 +310,16 @@ class text_style { }; /** Creates a text style from the foreground (text) color. */ -FMT_CONSTEXPR inline text_style fg(detail::color_type foreground) FMT_NOEXCEPT { +FMT_CONSTEXPR inline text_style fg(detail::color_type foreground) noexcept { return text_style(true, foreground); } /** Creates a text style from the background color. */ -FMT_CONSTEXPR inline text_style bg(detail::color_type background) FMT_NOEXCEPT { +FMT_CONSTEXPR inline text_style bg(detail::color_type background) noexcept { return text_style(false, background); } -FMT_CONSTEXPR inline text_style operator|(emphasis lhs, - emphasis rhs) FMT_NOEXCEPT { +FMT_CONSTEXPR inline text_style operator|(emphasis lhs, emphasis rhs) noexcept { return text_style(lhs) | rhs; } @@ -373,7 +327,7 @@ FMT_BEGIN_DETAIL_NAMESPACE template struct ansi_color_escape { FMT_CONSTEXPR ansi_color_escape(detail::color_type text_color, - const char* esc) FMT_NOEXCEPT { + const char* esc) noexcept { // If we have a terminal color, we need to output another escape code // sequence. if (!text_color.is_rgb) { @@ -408,17 +362,19 @@ template struct ansi_color_escape { to_esc(color.b, buffer + 15, 'm'); buffer[19] = static_cast(0); } - FMT_CONSTEXPR ansi_color_escape(emphasis em) FMT_NOEXCEPT { - uint8_t em_codes[4] = {}; - uint8_t em_bits = static_cast(em); - if (em_bits & static_cast(emphasis::bold)) em_codes[0] = 1; - if (em_bits & static_cast(emphasis::italic)) em_codes[1] = 3; - if (em_bits & static_cast(emphasis::underline)) em_codes[2] = 4; - if (em_bits & static_cast(emphasis::strikethrough)) - em_codes[3] = 9; + FMT_CONSTEXPR ansi_color_escape(emphasis em) noexcept { + uint8_t em_codes[num_emphases] = {}; + if (has_emphasis(em, emphasis::bold)) em_codes[0] = 1; + if (has_emphasis(em, emphasis::faint)) em_codes[1] = 2; + if (has_emphasis(em, emphasis::italic)) em_codes[2] = 3; + if (has_emphasis(em, emphasis::underline)) em_codes[3] = 4; + if (has_emphasis(em, emphasis::blink)) em_codes[4] = 5; + if (has_emphasis(em, emphasis::reverse)) em_codes[5] = 7; + if (has_emphasis(em, emphasis::conceal)) em_codes[6] = 8; + if (has_emphasis(em, emphasis::strikethrough)) em_codes[7] = 9; size_t index = 0; - for (int i = 0; i < 4; ++i) { + for (size_t i = 0; i < num_emphases; ++i) { if (!em_codes[i]) continue; buffer[index++] = static_cast('\x1b'); buffer[index++] = static_cast('['); @@ -427,66 +383,76 @@ template struct ansi_color_escape { } buffer[index++] = static_cast(0); } - FMT_CONSTEXPR operator const Char*() const FMT_NOEXCEPT { return buffer; } + FMT_CONSTEXPR operator const Char*() const noexcept { return buffer; } - FMT_CONSTEXPR const Char* begin() const FMT_NOEXCEPT { return buffer; } - FMT_CONSTEXPR_CHAR_TRAITS const Char* end() const FMT_NOEXCEPT { + FMT_CONSTEXPR const Char* begin() const noexcept { return buffer; } + FMT_CONSTEXPR_CHAR_TRAITS const Char* end() const noexcept { return buffer + std::char_traits::length(buffer); } private: - Char buffer[7u + 3u * 4u + 1u]; + static constexpr size_t num_emphases = 8; + Char buffer[7u + 3u * num_emphases + 1u]; static FMT_CONSTEXPR void to_esc(uint8_t c, Char* out, - char delimiter) FMT_NOEXCEPT { + char delimiter) noexcept { out[0] = static_cast('0' + c / 100); out[1] = static_cast('0' + c / 10 % 10); out[2] = static_cast('0' + c % 10); out[3] = static_cast(delimiter); } + static FMT_CONSTEXPR bool has_emphasis(emphasis em, emphasis mask) noexcept { + return static_cast(em) & static_cast(mask); + } }; template FMT_CONSTEXPR ansi_color_escape make_foreground_color( - detail::color_type foreground) FMT_NOEXCEPT { + detail::color_type foreground) noexcept { return ansi_color_escape(foreground, "\x1b[38;2;"); } template FMT_CONSTEXPR ansi_color_escape make_background_color( - detail::color_type background) FMT_NOEXCEPT { + detail::color_type background) noexcept { return ansi_color_escape(background, "\x1b[48;2;"); } template -FMT_CONSTEXPR ansi_color_escape make_emphasis(emphasis em) FMT_NOEXCEPT { +FMT_CONSTEXPR ansi_color_escape make_emphasis(emphasis em) noexcept { return ansi_color_escape(em); } -template -inline void fputs(const Char* chars, FILE* stream) FMT_NOEXCEPT { - std::fputs(chars, stream); +template inline void fputs(const Char* chars, FILE* stream) { + int result = std::fputs(chars, stream); + if (result < 0) + FMT_THROW(system_error(errno, FMT_STRING("cannot write to file"))); } -template <> -inline void fputs(const wchar_t* chars, FILE* stream) FMT_NOEXCEPT { - std::fputws(chars, stream); +template <> inline void fputs(const wchar_t* chars, FILE* stream) { + int result = std::fputws(chars, stream); + if (result < 0) + FMT_THROW(system_error(errno, FMT_STRING("cannot write to file"))); } -template inline void reset_color(FILE* stream) FMT_NOEXCEPT { +template inline void reset_color(FILE* stream) { fputs("\x1b[0m", stream); } -template <> inline void reset_color(FILE* stream) FMT_NOEXCEPT { +template <> inline void reset_color(FILE* stream) { fputs(L"\x1b[0m", stream); } -template -inline void reset_color(buffer& buffer) FMT_NOEXCEPT { +template inline void reset_color(buffer& buffer) { auto reset_color = string_view("\x1b[0m"); buffer.append(reset_color.begin(), reset_color.end()); } +template struct styled_arg { + const T& value; + text_style style; +}; + template void vformat_to(buffer& buf, const text_style& ts, basic_string_view format_str, @@ -517,9 +483,13 @@ template > void vprint(std::FILE* f, const text_style& ts, const S& format, basic_format_args>> args) { basic_memory_buffer buf; - detail::vformat_to(buf, ts, to_string_view(format), args); - buf.push_back(Char(0)); - detail::fputs(buf.data(), f); + detail::vformat_to(buf, ts, detail::to_string_view(format), args); + if (detail::is_utf8()) { + detail::print(f, basic_string_view(buf.begin(), buf.size())); + } else { + buf.push_back(Char(0)); + detail::fputs(buf.data(), f); + } } /** @@ -538,7 +508,7 @@ template (format_str, args...)); + fmt::make_format_args>>(args...)); } /** @@ -563,7 +533,7 @@ inline std::basic_string vformat( const text_style& ts, const S& format_str, basic_format_args>> args) { basic_memory_buffer buf; - detail::vformat_to(buf, ts, to_string_view(format_str), args); + detail::vformat_to(buf, ts, detail::to_string_view(format_str), args); return fmt::to_string(buf); } @@ -582,8 +552,8 @@ inline std::basic_string vformat( template > inline std::basic_string format(const text_style& ts, const S& format_str, const Args&... args) { - return fmt::vformat(ts, to_string_view(format_str), - fmt::make_args_checked(format_str, args...)); + return fmt::vformat(ts, detail::to_string_view(format_str), + fmt::make_format_args>(args...)); } /** @@ -617,8 +587,62 @@ template typename std::enable_if::type { - return vformat_to(out, ts, to_string_view(format_str), - fmt::make_args_checked(format_str, args...)); + return vformat_to(out, ts, detail::to_string_view(format_str), + fmt::make_format_args>>(args...)); +} + +template +struct formatter, Char> : formatter { + template + auto format(const detail::styled_arg& arg, FormatContext& ctx) const + -> decltype(ctx.out()) { + const auto& ts = arg.style; + const auto& value = arg.value; + auto out = ctx.out(); + + bool has_style = false; + if (ts.has_emphasis()) { + has_style = true; + auto emphasis = detail::make_emphasis(ts.get_emphasis()); + out = std::copy(emphasis.begin(), emphasis.end(), out); + } + if (ts.has_foreground()) { + has_style = true; + auto foreground = + detail::make_foreground_color(ts.get_foreground()); + out = std::copy(foreground.begin(), foreground.end(), out); + } + if (ts.has_background()) { + has_style = true; + auto background = + detail::make_background_color(ts.get_background()); + out = std::copy(background.begin(), background.end(), out); + } + out = formatter::format(value, ctx); + if (has_style) { + auto reset_color = string_view("\x1b[0m"); + out = std::copy(reset_color.begin(), reset_color.end(), out); + } + return out; + } +}; + +/** + \rst + Returns an argument that will be formatted using ANSI escape sequences, + to be used in a formatting function. + + **Example**:: + + fmt::print("Elapsed time: {0:.2f} seconds", + fmt::styled(1.23, fmt::fg(fmt::color::green) | + fmt::bg(fmt::color::blue))); + \endrst + */ +template +FMT_CONSTEXPR auto styled(const T& value, text_style ts) + -> detail::styled_arg> { + return detail::styled_arg>{value, ts}; } FMT_MODULE_EXPORT_END diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bundled/compile.h b/Lumos/External/spdlog/include/spdlog/fmt/bundled/compile.h index 00000c92e..933668c41 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/bundled/compile.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/bundled/compile.h @@ -13,48 +13,9 @@ FMT_BEGIN_NAMESPACE namespace detail { -// An output iterator that counts the number of objects written to it and -// discards them. -class counting_iterator { - private: - size_t count_; - - public: - using iterator_category = std::output_iterator_tag; - using difference_type = std::ptrdiff_t; - using pointer = void; - using reference = void; - using _Unchecked_type = counting_iterator; // Mark iterator as checked. - - struct value_type { - template void operator=(const T&) {} - }; - - counting_iterator() : count_(0) {} - - size_t count() const { return count_; } - - counting_iterator& operator++() { - ++count_; - return *this; - } - counting_iterator operator++(int) { - auto it = *this; - ++*this; - return it; - } - - friend counting_iterator operator+(counting_iterator it, difference_type n) { - it.count_ += static_cast(n); - return it; - } - - value_type operator*() const { return {}; } -}; - template -inline counting_iterator copy_str(InputIt begin, InputIt end, - counting_iterator it) { +FMT_CONSTEXPR inline counting_iterator copy_str(InputIt begin, InputIt end, + counting_iterator it) { return it + (end - begin); } @@ -75,8 +36,7 @@ template class truncating_iterator_base { using difference_type = std::ptrdiff_t; using pointer = void; using reference = void; - using _Unchecked_type = - truncating_iterator_base; // Mark iterator as checked. + FMT_UNCHECKED_ITERATOR(truncating_iterator_base); OutputIt base() const { return out_; } size_t count() const { return count_; } @@ -156,19 +116,19 @@ struct is_compiled_string : std::is_base_of {}; std::string s = fmt::format(FMT_COMPILE("{}"), 42); \endrst */ -#ifdef __cpp_if_constexpr +#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) # define FMT_COMPILE(s) \ FMT_STRING_IMPL(s, fmt::detail::compiled_string, explicit) #else # define FMT_COMPILE(s) FMT_STRING(s) #endif -#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +#if FMT_USE_NONTYPE_TEMPLATE_ARGS template Str> struct udl_compiled_string : compiled_string { using char_type = Char; - constexpr operator basic_string_view() const { + explicit constexpr operator basic_string_view() const { return {Str.data, N - 1}; } }; @@ -179,7 +139,7 @@ const T& first(const T& value, const Tail&...) { return value; } -#ifdef __cpp_if_constexpr +#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) template struct type_list {}; // Returns a reference to the argument at index N from [first, rest...]. @@ -190,7 +150,7 @@ constexpr const auto& get([[maybe_unused]] const T& first, if constexpr (N == 0) return first; else - return get(rest...); + return detail::get(rest...); } template @@ -202,7 +162,8 @@ constexpr int get_arg_index_by_name(basic_string_view name, template struct get_type_impl; template struct get_type_impl> { - using type = remove_cvref_t(std::declval()...))>; + using type = + remove_cvref_t(std::declval()...))>; }; template @@ -242,7 +203,7 @@ template struct code_unit { // This ensures that the argument type is convertible to `const T&`. template constexpr const T& get_arg_checked(const Args&... args) { - const auto& arg = get(args...); + const auto& arg = detail::get(args...); if constexpr (detail::is_named_arg>()) { return arg.value; } else { @@ -289,7 +250,7 @@ template struct runtime_named_field { constexpr OutputIt format(OutputIt out, const Args&... args) const { bool found = (try_format_argument(out, name, args) || ...); if (!found) { - throw format_error("argument with specified name is not found"); + FMT_THROW(format_error("argument with specified name is not found")); } return out; } @@ -376,10 +337,11 @@ template constexpr parse_specs_result parse_specs(basic_string_view str, size_t pos, int next_arg_id) { str.remove_prefix(pos); - auto ctx = basic_format_parse_context(str, {}, next_arg_id); + auto ctx = compile_parse_context(str, max_value(), nullptr, {}, + next_arg_id); auto f = formatter(); auto end = f.parse(ctx); - return {f, pos + fmt::detail::to_unsigned(end - str.data()) + 1, + return {f, pos + fmt::detail::to_unsigned(end - str.data()), next_arg_id == 0 ? manual_indexing_id : ctx.next_arg_id()}; } @@ -399,7 +361,9 @@ template struct arg_id_handler { return 0; } - constexpr void on_error(const char* message) { throw format_error(message); } + constexpr void on_error(const char* message) { + FMT_THROW(format_error(message)); + } }; template struct parse_arg_id_result { @@ -433,13 +397,20 @@ constexpr auto parse_replacement_field_then_tail(S format_str) { return parse_tail( field::type, ARG_INDEX>(), format_str); - } else if constexpr (c == ':') { + } else if constexpr (c != ':') { + FMT_THROW(format_error("expected ':'")); + } else { constexpr auto result = parse_specs::type>( str, END_POS + 1, NEXT_ID == manual_indexing_id ? 0 : NEXT_ID); - return parse_tail( - spec_field::type, ARG_INDEX>{ - result.fmt}, - format_str); + if constexpr (result.end >= str.size() || str[result.end] != '}') { + FMT_THROW(format_error("expected '}'")); + return 0; + } else { + return parse_tail( + spec_field::type, ARG_INDEX>{ + result.fmt}, + format_str); + } } } @@ -451,7 +422,7 @@ constexpr auto compile_format_string(S format_str) { constexpr auto str = basic_string_view(format_str); if constexpr (str[POS] == '{') { if constexpr (POS + 1 == str.size()) - throw format_error("unmatched '{' in format string"); + FMT_THROW(format_error("unmatched '{' in format string")); if constexpr (str[POS + 1] == '{') { return parse_tail(make_text(str, POS, 1), format_str); } else if constexpr (str[POS + 1] == '}' || str[POS + 1] == ':') { @@ -500,7 +471,7 @@ constexpr auto compile_format_string(S format_str) { } } else if constexpr (str[POS] == '}') { if constexpr (POS + 1 == str.size()) - throw format_error("unmatched '}' in format string"); + FMT_THROW(format_error("unmatched '}' in format string")); return parse_tail(make_text(str, POS, 1), format_str); } else { constexpr auto end = parse_text(str, POS + 1); @@ -527,12 +498,12 @@ constexpr auto compile(S format_str) { return result; } } -#endif // __cpp_if_constexpr +#endif // defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) } // namespace detail FMT_MODULE_EXPORT_BEGIN -#ifdef __cpp_if_constexpr +#if defined(__cpp_if_constexpr) && defined(__cpp_return_type_deduction) template format(const S&, constexpr auto compiled = detail::compile(S()); if constexpr (std::is_same, detail::unknown_format>()) { - return format(static_cast>(S()), - std::forward(args)...); + return fmt::format( + static_cast>(S()), + std::forward(args)...); } else { - return format(compiled, std::forward(args)...); + return fmt::format(compiled, std::forward(args)...); } } @@ -583,11 +555,11 @@ FMT_CONSTEXPR OutputIt format_to(OutputIt out, const S&, Args&&... args) { constexpr auto compiled = detail::compile(S()); if constexpr (std::is_same, detail::unknown_format>()) { - return format_to(out, - static_cast>(S()), - std::forward(args)...); + return fmt::format_to( + out, static_cast>(S()), + std::forward(args)...); } else { - return format_to(out, compiled, std::forward(args)...); + return fmt::format_to(out, compiled, std::forward(args)...); } } #endif @@ -596,22 +568,24 @@ template ::value)> format_to_n_result format_to_n(OutputIt out, size_t n, const S& format_str, Args&&... args) { - auto it = format_to(detail::truncating_iterator(out, n), format_str, - std::forward(args)...); + auto it = fmt::format_to(detail::truncating_iterator(out, n), + format_str, std::forward(args)...); return {it.base(), it.count()}; } template ::value)> -size_t formatted_size(const S& format_str, const Args&... args) { - return format_to(detail::counting_iterator(), format_str, args...).count(); +FMT_CONSTEXPR20 size_t formatted_size(const S& format_str, + const Args&... args) { + return fmt::format_to(detail::counting_iterator(), format_str, args...) + .count(); } template ::value)> void print(std::FILE* f, const S& format_str, const Args&... args) { memory_buffer buffer; - format_to(std::back_inserter(buffer), format_str, args...); + fmt::format_to(std::back_inserter(buffer), format_str, args...); detail::print(f, {buffer.data(), buffer.size()}); } @@ -621,14 +595,12 @@ void print(const S& format_str, const Args&... args) { print(stdout, format_str, args...); } -#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +#if FMT_USE_NONTYPE_TEMPLATE_ARGS inline namespace literals { -template -constexpr detail::udl_compiled_string< - remove_cvref_t, - sizeof(Str.data) / sizeof(decltype(Str.data[0])), Str> -operator""_cf() { - return {}; +template constexpr auto operator""_cf() { + using char_t = remove_cvref_t; + return detail::udl_compiled_string(); } } // namespace literals #endif diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bundled/core.h b/Lumos/External/spdlog/include/spdlog/fmt/bundled/core.h index d058398ac..f6a37af9e 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/bundled/core.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/bundled/core.h @@ -8,65 +8,70 @@ #ifndef FMT_CORE_H_ #define FMT_CORE_H_ -#include // std::FILE -#include +#include // std::byte +#include // std::FILE +#include // std::strlen #include #include #include #include // The fmt library version in the form major * 10000 + minor * 100 + patch. -#define FMT_VERSION 80001 +#define FMT_VERSION 90100 -#ifdef __clang__ +#if defined(__clang__) && !defined(__ibmxl__) # define FMT_CLANG_VERSION (__clang_major__ * 100 + __clang_minor__) #else # define FMT_CLANG_VERSION 0 #endif -#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) +#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) && \ + !defined(__NVCOMPILER) # define FMT_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__) -# define FMT_GCC_PRAGMA(arg) _Pragma(arg) #else # define FMT_GCC_VERSION 0 -# define FMT_GCC_PRAGMA(arg) #endif -#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) -# define FMT_HAS_GXX_CXX11 FMT_GCC_VERSION -#else -# define FMT_HAS_GXX_CXX11 0 +#ifndef FMT_GCC_PRAGMA +// Workaround _Pragma bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59884. +# if FMT_GCC_VERSION >= 504 +# define FMT_GCC_PRAGMA(arg) _Pragma(arg) +# else +# define FMT_GCC_PRAGMA(arg) +# endif #endif -#if defined(__INTEL_COMPILER) +#ifdef __ICL +# define FMT_ICC_VERSION __ICL +#elif defined(__INTEL_COMPILER) # define FMT_ICC_VERSION __INTEL_COMPILER #else # define FMT_ICC_VERSION 0 #endif -#ifdef __NVCC__ -# define FMT_NVCC __NVCC__ -#else -# define FMT_NVCC 0 -#endif - #ifdef _MSC_VER -# define FMT_MSC_VER _MSC_VER +# define FMT_MSC_VERSION _MSC_VER # define FMT_MSC_WARNING(...) __pragma(warning(__VA_ARGS__)) #else -# define FMT_MSC_VER 0 +# define FMT_MSC_VERSION 0 # define FMT_MSC_WARNING(...) #endif +#ifdef _MSVC_LANG +# define FMT_CPLUSPLUS _MSVC_LANG +#else +# define FMT_CPLUSPLUS __cplusplus +#endif + #ifdef __has_feature # define FMT_HAS_FEATURE(x) __has_feature(x) #else # define FMT_HAS_FEATURE(x) 0 #endif -#if defined(__has_include) && \ - (!defined(__INTELLISENSE__) || FMT_MSC_VER > 1900) && \ - (!FMT_ICC_VERSION || FMT_ICC_VERSION >= 1600) +#if (defined(__has_include) || FMT_ICC_VERSION >= 1600 || \ + FMT_MSC_VERSION > 1900) && \ + !defined(__INTELLISENSE__) # define FMT_HAS_INCLUDE(x) __has_include(x) #else # define FMT_HAS_INCLUDE(x) 0 @@ -79,117 +84,102 @@ #endif #define FMT_HAS_CPP14_ATTRIBUTE(attribute) \ - (__cplusplus >= 201402L && FMT_HAS_CPP_ATTRIBUTE(attribute)) + (FMT_CPLUSPLUS >= 201402L && FMT_HAS_CPP_ATTRIBUTE(attribute)) #define FMT_HAS_CPP17_ATTRIBUTE(attribute) \ - (__cplusplus >= 201703L && FMT_HAS_CPP_ATTRIBUTE(attribute)) + (FMT_CPLUSPLUS >= 201703L && FMT_HAS_CPP_ATTRIBUTE(attribute)) // Check if relaxed C++14 constexpr is supported. // GCC doesn't allow throw in constexpr until version 6 (bug 67371). #ifndef FMT_USE_CONSTEXPR -# define FMT_USE_CONSTEXPR \ - (FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VER >= 1910 || \ - (FMT_GCC_VERSION >= 600 && __cplusplus >= 201402L)) && \ - !FMT_NVCC && !FMT_ICC_VERSION +# if (FMT_HAS_FEATURE(cxx_relaxed_constexpr) || FMT_MSC_VERSION >= 1912 || \ + (FMT_GCC_VERSION >= 600 && FMT_CPLUSPLUS >= 201402L)) && \ + !FMT_ICC_VERSION && !defined(__NVCC__) +# define FMT_USE_CONSTEXPR 1 +# else +# define FMT_USE_CONSTEXPR 0 +# endif #endif #if FMT_USE_CONSTEXPR # define FMT_CONSTEXPR constexpr -# define FMT_CONSTEXPR_DECL constexpr #else # define FMT_CONSTEXPR -# define FMT_CONSTEXPR_DECL #endif -// Check if constexpr std::char_traits<>::compare,length is supported. +#if ((FMT_CPLUSPLUS >= 202002L) && \ + (!defined(_GLIBCXX_RELEASE) || _GLIBCXX_RELEASE > 9)) || \ + (FMT_CPLUSPLUS >= 201709L && FMT_GCC_VERSION >= 1002) +# define FMT_CONSTEXPR20 constexpr +#else +# define FMT_CONSTEXPR20 +#endif + +// Check if constexpr std::char_traits<>::{compare,length} are supported. #if defined(__GLIBCXX__) -# if __cplusplus >= 201703L && defined(_GLIBCXX_RELEASE) && \ +# if FMT_CPLUSPLUS >= 201703L && defined(_GLIBCXX_RELEASE) && \ _GLIBCXX_RELEASE >= 7 // GCC 7+ libstdc++ has _GLIBCXX_RELEASE. # define FMT_CONSTEXPR_CHAR_TRAITS constexpr # endif -#elif defined(_LIBCPP_VERSION) && __cplusplus >= 201703L && \ +#elif defined(_LIBCPP_VERSION) && FMT_CPLUSPLUS >= 201703L && \ _LIBCPP_VERSION >= 4000 # define FMT_CONSTEXPR_CHAR_TRAITS constexpr -#elif FMT_MSC_VER >= 1914 && _MSVC_LANG >= 201703L +#elif FMT_MSC_VERSION >= 1914 && FMT_CPLUSPLUS >= 201703L # define FMT_CONSTEXPR_CHAR_TRAITS constexpr #endif #ifndef FMT_CONSTEXPR_CHAR_TRAITS # define FMT_CONSTEXPR_CHAR_TRAITS #endif -#ifndef FMT_OVERRIDE -# if FMT_HAS_FEATURE(cxx_override_control) || \ - (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900 -# define FMT_OVERRIDE override -# else -# define FMT_OVERRIDE -# endif -#endif - // Check if exceptions are disabled. #ifndef FMT_EXCEPTIONS # if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \ - FMT_MSC_VER && !_HAS_EXCEPTIONS + (FMT_MSC_VERSION && !_HAS_EXCEPTIONS) # define FMT_EXCEPTIONS 0 # else # define FMT_EXCEPTIONS 1 # endif #endif -// Define FMT_USE_NOEXCEPT to make fmt use noexcept (C++11 feature). -#ifndef FMT_USE_NOEXCEPT -# define FMT_USE_NOEXCEPT 0 -#endif - -#if FMT_USE_NOEXCEPT || FMT_HAS_FEATURE(cxx_noexcept) || \ - (FMT_GCC_VERSION >= 408 && FMT_HAS_GXX_CXX11) || FMT_MSC_VER >= 1900 -# define FMT_DETECTED_NOEXCEPT noexcept -# define FMT_HAS_CXX11_NOEXCEPT 1 -#else -# define FMT_DETECTED_NOEXCEPT throw() -# define FMT_HAS_CXX11_NOEXCEPT 0 -#endif - -#ifndef FMT_NOEXCEPT -# if FMT_EXCEPTIONS || FMT_HAS_CXX11_NOEXCEPT -# define FMT_NOEXCEPT FMT_DETECTED_NOEXCEPT +#ifndef FMT_DEPRECATED +# if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VERSION >= 1900 +# define FMT_DEPRECATED [[deprecated]] # else -# define FMT_NOEXCEPT +# if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__) +# define FMT_DEPRECATED __attribute__((deprecated)) +# elif FMT_MSC_VERSION +# define FMT_DEPRECATED __declspec(deprecated) +# else +# define FMT_DEPRECATED /* deprecated */ +# endif # endif #endif // [[noreturn]] is disabled on MSVC and NVCC because of bogus unreachable code // warnings. -#if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VER && \ - !FMT_NVCC +#if FMT_EXCEPTIONS && FMT_HAS_CPP_ATTRIBUTE(noreturn) && !FMT_MSC_VERSION && \ + !defined(__NVCC__) # define FMT_NORETURN [[noreturn]] #else # define FMT_NORETURN #endif -#ifndef FMT_MAYBE_UNUSED -# if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused) -# define FMT_MAYBE_UNUSED [[maybe_unused]] -# else -# define FMT_MAYBE_UNUSED -# endif +#if FMT_HAS_CPP17_ATTRIBUTE(fallthrough) +# define FMT_FALLTHROUGH [[fallthrough]] +#elif defined(__clang__) +# define FMT_FALLTHROUGH [[clang::fallthrough]] +#elif FMT_GCC_VERSION >= 700 && \ + (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520) +# define FMT_FALLTHROUGH [[gnu::fallthrough]] +#else +# define FMT_FALLTHROUGH #endif -#if __cplusplus == 201103L || __cplusplus == 201402L -# if defined(__INTEL_COMPILER) || defined(__PGI) -# define FMT_FALLTHROUGH -# elif defined(__clang__) -# define FMT_FALLTHROUGH [[clang::fallthrough]] -# elif FMT_GCC_VERSION >= 700 && \ - (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= 520) -# define FMT_FALLTHROUGH [[gnu::fallthrough]] +#ifndef FMT_NODISCARD +# if FMT_HAS_CPP17_ATTRIBUTE(nodiscard) +# define FMT_NODISCARD [[nodiscard]] # else -# define FMT_FALLTHROUGH +# define FMT_NODISCARD # endif -#elif FMT_HAS_CPP17_ATTRIBUTE(fallthrough) || \ - (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) -# define FMT_FALLTHROUGH [[fallthrough]] -#else -# define FMT_FALLTHROUGH #endif #ifndef FMT_USE_FLOAT @@ -210,31 +200,23 @@ # endif #endif -#ifndef FMT_USE_INLINE_NAMESPACES -# if FMT_HAS_FEATURE(cxx_inline_namespaces) || FMT_GCC_VERSION >= 404 || \ - (FMT_MSC_VER >= 1900 && (!defined(_MANAGED) || !_MANAGED)) -# define FMT_USE_INLINE_NAMESPACES 1 -# else -# define FMT_USE_INLINE_NAMESPACES 0 -# endif +// An inline std::forward replacement. +#define FMT_FORWARD(...) static_cast(__VA_ARGS__) + +#ifdef _MSC_VER +# define FMT_UNCHECKED_ITERATOR(It) \ + using _Unchecked_type = It // Mark iterator as checked. +#else +# define FMT_UNCHECKED_ITERATOR(It) using unchecked_type = It #endif #ifndef FMT_BEGIN_NAMESPACE -# if FMT_USE_INLINE_NAMESPACES -# define FMT_INLINE_NAMESPACE inline namespace -# define FMT_END_NAMESPACE \ - } \ - } -# else -# define FMT_INLINE_NAMESPACE namespace -# define FMT_END_NAMESPACE \ - } \ - using namespace v8; \ - } -# endif # define FMT_BEGIN_NAMESPACE \ namespace fmt { \ - FMT_INLINE_NAMESPACE v8 { + inline namespace v9 { +# define FMT_END_NAMESPACE \ + } \ + } #endif #ifndef FMT_MODULE_EXPORT @@ -264,32 +246,26 @@ # define FMT_API #endif -#if FMT_GCC_VERSION -# define FMT_GCC_VISIBILITY_HIDDEN __attribute__((visibility("hidden"))) -#else -# define FMT_GCC_VISIBILITY_HIDDEN -#endif - // libc++ supports string_view in pre-c++17. -#if (FMT_HAS_INCLUDE() && \ - (__cplusplus > 201402L || defined(_LIBCPP_VERSION))) || \ - (defined(_MSVC_LANG) && _MSVC_LANG > 201402L && _MSC_VER >= 1910) +#if FMT_HAS_INCLUDE() && \ + (FMT_CPLUSPLUS >= 201703L || defined(_LIBCPP_VERSION)) # include # define FMT_USE_STRING_VIEW -#elif FMT_HAS_INCLUDE("experimental/string_view") && __cplusplus >= 201402L +#elif FMT_HAS_INCLUDE("experimental/string_view") && FMT_CPLUSPLUS >= 201402L # include # define FMT_USE_EXPERIMENTAL_STRING_VIEW #endif #ifndef FMT_UNICODE -# define FMT_UNICODE !FMT_MSC_VER +# define FMT_UNICODE !FMT_MSC_VERSION #endif #ifndef FMT_CONSTEVAL -# if ((FMT_GCC_VERSION >= 1000 || FMT_CLANG_VERSION >= 1101) && \ - __cplusplus > 201703L) || \ - (defined(__cpp_consteval) && \ - !FMT_MSC_VER) // consteval is broken in MSVC. +# if ((FMT_GCC_VERSION >= 1000 || FMT_CLANG_VERSION >= 1101) && \ + FMT_CPLUSPLUS >= 202002L && !defined(__apple_build_version__)) || \ + (defined(__cpp_consteval) && \ + (!FMT_MSC_VERSION || _MSC_FULL_VER >= 193030704)) +// consteval is broken in MSVC before VS2022 and Apple clang 13. # define FMT_CONSTEVAL consteval # define FMT_HAS_CONSTEVAL # else @@ -297,19 +273,20 @@ # endif #endif -#ifndef FMT_USE_NONTYPE_TEMPLATE_PARAMETERS -# if defined(__cpp_nontype_template_args) && \ - ((FMT_GCC_VERSION >= 903 && __cplusplus >= 201709L) || \ - __cpp_nontype_template_args >= 201911L) -# define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 1 +#ifndef FMT_USE_NONTYPE_TEMPLATE_ARGS +# if defined(__cpp_nontype_template_args) && \ + ((FMT_GCC_VERSION >= 903 && FMT_CPLUSPLUS >= 201709L) || \ + __cpp_nontype_template_args >= 201911L) && \ + !defined(__NVCOMPILER) +# define FMT_USE_NONTYPE_TEMPLATE_ARGS 1 # else -# define FMT_USE_NONTYPE_TEMPLATE_PARAMETERS 0 +# define FMT_USE_NONTYPE_TEMPLATE_ARGS 0 # endif #endif // Enable minimal optimizations for more compact code in debug mode. FMT_GCC_PRAGMA("GCC push_options") -#ifndef __OPTIMIZE__ +#if !defined(__OPTIMIZE__) && !defined(__NVCOMPILER) FMT_GCC_PRAGMA("GCC optimize(\"Og\")") #endif @@ -325,19 +302,30 @@ template using bool_constant = std::integral_constant; template using remove_reference_t = typename std::remove_reference::type; template +using remove_const_t = typename std::remove_const::type; +template using remove_cvref_t = typename std::remove_cv>::type; template struct type_identity { using type = T; }; template using type_identity_t = typename type_identity::type; +template +using underlying_t = typename std::underlying_type::type; + +template struct disjunction : std::false_type {}; +template struct disjunction

: P {}; +template +struct disjunction + : conditional_t> {}; + +template struct conjunction : std::true_type {}; +template struct conjunction

: P {}; +template +struct conjunction + : conditional_t, P1> {}; struct monostate { constexpr monostate() {} }; -// Suppress "unused variable" warnings with the method described in -// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/. -// (void)var does not work on many Intel compilers. -template FMT_CONSTEXPR void ignore_unused(const T&...) {} - // An enable_if helper to be used in template parameters which results in much // shorter symbols: https://godbolt.org/z/sWw4vP. Extra parentheses are needed // to workaround a bug in MSVC 2019 (see #1140 and #1186). @@ -349,25 +337,34 @@ template FMT_CONSTEXPR void ignore_unused(const T&...) {} FMT_BEGIN_DETAIL_NAMESPACE -constexpr FMT_INLINE auto is_constant_evaluated() FMT_NOEXCEPT -> bool { +// Suppresses "unused variable" warnings with the method described in +// https://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/. +// (void)var does not work on many Intel compilers. +template FMT_CONSTEXPR void ignore_unused(const T&...) {} + +constexpr FMT_INLINE auto is_constant_evaluated( + bool default_value = false) noexcept -> bool { #ifdef __cpp_lib_is_constant_evaluated + ignore_unused(default_value); return std::is_constant_evaluated(); #else - return false; + return default_value; #endif } -// A function to suppress "conditional expression is constant" warnings. -template constexpr auto const_check(T value) -> T { return value; } +// Suppresses "conditional expression is constant" warnings. +template constexpr FMT_INLINE auto const_check(T value) -> T { + return value; +} FMT_NORETURN FMT_API void assert_fail(const char* file, int line, const char* message); #ifndef FMT_ASSERT # ifdef NDEBUG -// FMT_ASSERT is not empty to avoid -Werror=empty-body. +// FMT_ASSERT is not empty to avoid -Wempty-body. # define FMT_ASSERT(condition, message) \ - ::fmt::ignore_unused((condition), (message)) + ::fmt::detail::ignore_unused((condition), (message)) # else # define FMT_ASSERT(condition, message) \ ((condition) /* void() fails with -Winvalid-constexpr on clang 4.0.1 */ \ @@ -387,11 +384,11 @@ template struct std_string_view {}; #ifdef FMT_USE_INT128 // Do nothing. -#elif defined(__SIZEOF_INT128__) && !FMT_NVCC && \ - !(FMT_CLANG_VERSION && FMT_MSC_VER) +#elif defined(__SIZEOF_INT128__) && !defined(__NVCC__) && \ + !(FMT_CLANG_VERSION && FMT_MSC_VERSION) # define FMT_USE_INT128 1 -using int128_t = __int128_t; -using uint128_t = __uint128_t; +using int128_opt = __int128_t; // An optional native 128-bit integer. +using uint128_opt = __uint128_t; template inline auto convert_for_visit(T value) -> T { return value; } @@ -399,27 +396,24 @@ template inline auto convert_for_visit(T value) -> T { # define FMT_USE_INT128 0 #endif #if !FMT_USE_INT128 -enum class int128_t {}; -enum class uint128_t {}; +enum class int128_opt {}; +enum class uint128_opt {}; // Reduce template instantiations. -template inline auto convert_for_visit(T) -> monostate { - return {}; -} +template auto convert_for_visit(T) -> monostate { return {}; } #endif // Casts a nonnegative integer to unsigned. template FMT_CONSTEXPR auto to_unsigned(Int value) -> typename std::make_unsigned::type { - FMT_ASSERT(value >= 0, "negative value"); + FMT_ASSERT(std::is_unsigned::value || value >= 0, "negative value"); return static_cast::type>(value); } FMT_MSC_WARNING(suppress : 4566) constexpr unsigned char micro[] = "\u00B5"; constexpr auto is_utf8() -> bool { - // Avoid buggy sign extensions in MSVC's constant evaluation mode. - // https://developercommunity.visualstudio.com/t/C-difference-in-behavior-for-unsigned/1233612 + // Avoid buggy sign extensions in MSVC's constant evaluation mode (#2297). using uchar = unsigned char; return FMT_UNICODE || (sizeof(micro) == 3 && uchar(micro[0]) == 0xC2 && uchar(micro[1]) == 0xB5); @@ -442,12 +436,11 @@ template class basic_string_view { using value_type = Char; using iterator = const Char*; - constexpr basic_string_view() FMT_NOEXCEPT : data_(nullptr), size_(0) {} + constexpr basic_string_view() noexcept : data_(nullptr), size_(0) {} /** Constructs a string reference object from a C string and a size. */ - constexpr basic_string_view(const Char* s, size_t count) FMT_NOEXCEPT - : data_(s), - size_(count) {} + constexpr basic_string_view(const Char* s, size_t count) noexcept + : data_(s), size_(count) {} /** \rst @@ -457,40 +450,38 @@ template class basic_string_view { */ FMT_CONSTEXPR_CHAR_TRAITS FMT_INLINE - basic_string_view(const Char* s) : data_(s) { - if (detail::const_check(std::is_same::value && - !detail::is_constant_evaluated())) - size_ = std::strlen(reinterpret_cast(s)); - else - size_ = std::char_traits::length(s); - } + basic_string_view(const Char* s) + : data_(s), + size_(detail::const_check(std::is_same::value && + !detail::is_constant_evaluated(true)) + ? std::strlen(reinterpret_cast(s)) + : std::char_traits::length(s)) {} /** Constructs a string reference from a ``std::basic_string`` object. */ template FMT_CONSTEXPR basic_string_view( - const std::basic_string& s) FMT_NOEXCEPT - : data_(s.data()), - size_(s.size()) {} + const std::basic_string& s) noexcept + : data_(s.data()), size_(s.size()) {} template >::value)> - FMT_CONSTEXPR basic_string_view(S s) FMT_NOEXCEPT : data_(s.data()), - size_(s.size()) {} + FMT_CONSTEXPR basic_string_view(S s) noexcept + : data_(s.data()), size_(s.size()) {} /** Returns a pointer to the string data. */ - constexpr auto data() const -> const Char* { return data_; } + constexpr auto data() const noexcept -> const Char* { return data_; } /** Returns the string size. */ - constexpr auto size() const -> size_t { return size_; } + constexpr auto size() const noexcept -> size_t { return size_; } - constexpr auto begin() const -> iterator { return data_; } - constexpr auto end() const -> iterator { return data_ + size_; } + constexpr auto begin() const noexcept -> iterator { return data_; } + constexpr auto end() const noexcept -> iterator { return data_ + size_; } - constexpr auto operator[](size_t pos) const -> const Char& { + constexpr auto operator[](size_t pos) const noexcept -> const Char& { return data_[pos]; } - FMT_CONSTEXPR void remove_prefix(size_t n) { + FMT_CONSTEXPR void remove_prefix(size_t n) noexcept { data_ += n; size_ -= n; } @@ -532,6 +523,14 @@ using string_view = basic_string_view; template struct is_char : std::false_type {}; template <> struct is_char : std::true_type {}; +FMT_BEGIN_DETAIL_NAMESPACE + +// A base class for compile-time strings. +struct compile_string {}; + +template +struct is_compile_string : std::is_base_of {}; + // Returns a string view of `s`. template ::value)> FMT_INLINE auto to_string_view(const Char* s) -> basic_string_view { @@ -548,33 +547,21 @@ constexpr auto to_string_view(basic_string_view s) return s; } template >::value)> -inline auto to_string_view(detail::std_string_view s) - -> basic_string_view { + FMT_ENABLE_IF(!std::is_empty>::value)> +inline auto to_string_view(std_string_view s) -> basic_string_view { return s; } - -// A base class for compile-time strings. It is defined in the fmt namespace to -// make formatting functions visible via ADL, e.g. format(FMT_STRING("{}"), 42). -struct compile_string {}; - -template -struct is_compile_string : std::is_base_of {}; - template ::value)> constexpr auto to_string_view(const S& s) -> basic_string_view { return basic_string_view(s); } - -FMT_BEGIN_DETAIL_NAMESPACE - void to_string_view(...); -using fmt::v8::to_string_view; // Specifies whether S is a string type convertible to fmt::basic_string_view. // It should be a constexpr function but MSVC 2017 fails to compile it in // enable_if and MSVC 2015 fails to compile it as an alias template. +// ADL invocation of to_string_view is DEPRECATED! template struct is_string : std::is_class()))> { }; @@ -585,24 +572,71 @@ template struct char_t_impl::value>> { using type = typename result::value_type; }; -// Reports a compile-time error if S is not a valid format string. -template ::value)> -FMT_INLINE void check_format_string(const S&) { -#ifdef FMT_ENFORCE_COMPILE_STRING - static_assert(is_compile_string::value, - "FMT_ENFORCE_COMPILE_STRING requires all format strings to use " - "FMT_STRING."); -#endif +enum class type { + none_type, + // Integer types should go first, + int_type, + uint_type, + long_long_type, + ulong_long_type, + int128_type, + uint128_type, + bool_type, + char_type, + last_integer_type = char_type, + // followed by floating-point types. + float_type, + double_type, + long_double_type, + last_numeric_type = long_double_type, + cstring_type, + string_type, + pointer_type, + custom_type +}; + +// Maps core type T to the corresponding type enum constant. +template +struct type_constant : std::integral_constant {}; + +#define FMT_TYPE_CONSTANT(Type, constant) \ + template \ + struct type_constant \ + : std::integral_constant {} + +FMT_TYPE_CONSTANT(int, int_type); +FMT_TYPE_CONSTANT(unsigned, uint_type); +FMT_TYPE_CONSTANT(long long, long_long_type); +FMT_TYPE_CONSTANT(unsigned long long, ulong_long_type); +FMT_TYPE_CONSTANT(int128_opt, int128_type); +FMT_TYPE_CONSTANT(uint128_opt, uint128_type); +FMT_TYPE_CONSTANT(bool, bool_type); +FMT_TYPE_CONSTANT(Char, char_type); +FMT_TYPE_CONSTANT(float, float_type); +FMT_TYPE_CONSTANT(double, double_type); +FMT_TYPE_CONSTANT(long double, long_double_type); +FMT_TYPE_CONSTANT(const Char*, cstring_type); +FMT_TYPE_CONSTANT(basic_string_view, string_type); +FMT_TYPE_CONSTANT(const void*, pointer_type); + +constexpr bool is_integral_type(type t) { + return t > type::none_type && t <= type::last_integer_type; } -template ::value)> -void check_format_string(S); + +constexpr bool is_arithmetic_type(type t) { + return t > type::none_type && t <= type::last_numeric_type; +} + +FMT_NORETURN FMT_API void throw_format_error(const char* message); struct error_handler { constexpr error_handler() = default; constexpr error_handler(const error_handler&) = default; // This function is intentionally not constexpr to give a compile-time error. - FMT_NORETURN FMT_API void on_error(const char* message); + FMT_NORETURN void on_error(const char* message) { + throw_format_error(message); + } }; FMT_END_DETAIL_NAMESPACE @@ -622,6 +656,8 @@ class basic_format_parse_context : private ErrorHandler { basic_string_view format_str_; int next_arg_id_; + FMT_CONSTEXPR void do_check_arg_id(int id); + public: using char_type = Char; using iterator = typename basic_string_view::iterator; @@ -635,16 +671,14 @@ class basic_format_parse_context : private ErrorHandler { Returns an iterator to the beginning of the format string range being parsed. */ - constexpr auto begin() const FMT_NOEXCEPT -> iterator { + constexpr auto begin() const noexcept -> iterator { return format_str_.begin(); } /** Returns an iterator past the end of the format string range being parsed. */ - constexpr auto end() const FMT_NOEXCEPT -> iterator { - return format_str_.end(); - } + constexpr auto end() const noexcept -> iterator { return format_str_.end(); } /** Advances the begin iterator to ``it``. */ FMT_CONSTEXPR void advance_to(iterator it) { @@ -656,25 +690,29 @@ class basic_format_parse_context : private ErrorHandler { the next argument index and switches to the automatic indexing. */ FMT_CONSTEXPR auto next_arg_id() -> int { - // Don't check if the argument id is valid to avoid overhead and because it - // will be checked during formatting anyway. - if (next_arg_id_ >= 0) return next_arg_id_++; - on_error("cannot switch from manual to automatic argument indexing"); - return 0; + if (next_arg_id_ < 0) { + on_error("cannot switch from manual to automatic argument indexing"); + return 0; + } + int id = next_arg_id_++; + do_check_arg_id(id); + return id; } /** Reports an error if using the automatic argument indexing; otherwise switches to the manual indexing. */ - FMT_CONSTEXPR void check_arg_id(int) { - if (next_arg_id_ > 0) + FMT_CONSTEXPR void check_arg_id(int id) { + if (next_arg_id_ > 0) { on_error("cannot switch from automatic to manual argument indexing"); - else - next_arg_id_ = -1; + return; + } + next_arg_id_ = -1; + do_check_arg_id(id); } - FMT_CONSTEXPR void check_arg_id(basic_string_view) {} + FMT_CONSTEXPR void check_dynamic_spec(int arg_id); FMT_CONSTEXPR void on_error(const char* message) { ErrorHandler::on_error(message); @@ -685,6 +723,65 @@ class basic_format_parse_context : private ErrorHandler { using format_parse_context = basic_format_parse_context; +FMT_BEGIN_DETAIL_NAMESPACE +// A parse context with extra data used only in compile-time checks. +template +class compile_parse_context + : public basic_format_parse_context { + private: + int num_args_; + const type* types_; + using base = basic_format_parse_context; + + public: + explicit FMT_CONSTEXPR compile_parse_context( + basic_string_view format_str, int num_args, const type* types, + ErrorHandler eh = {}, int next_arg_id = 0) + : base(format_str, eh, next_arg_id), num_args_(num_args), types_(types) {} + + constexpr auto num_args() const -> int { return num_args_; } + constexpr auto arg_type(int id) const -> type { return types_[id]; } + + FMT_CONSTEXPR auto next_arg_id() -> int { + int id = base::next_arg_id(); + if (id >= num_args_) this->on_error("argument not found"); + return id; + } + + FMT_CONSTEXPR void check_arg_id(int id) { + base::check_arg_id(id); + if (id >= num_args_) this->on_error("argument not found"); + } + using base::check_arg_id; + + FMT_CONSTEXPR void check_dynamic_spec(int arg_id) { + if (arg_id < num_args_ && types_ && !is_integral_type(types_[arg_id])) + this->on_error("width/precision is not integer"); + } +}; +FMT_END_DETAIL_NAMESPACE + +template +FMT_CONSTEXPR void +basic_format_parse_context::do_check_arg_id(int id) { + // Argument id is only checked at compile-time during parsing because + // formatting has its own validation. + if (detail::is_constant_evaluated() && FMT_GCC_VERSION >= 1200) { + using context = detail::compile_parse_context; + if (id >= static_cast(this)->num_args()) + on_error("argument not found"); + } +} + +template +FMT_CONSTEXPR void +basic_format_parse_context::check_dynamic_spec(int arg_id) { + if (detail::is_constant_evaluated()) { + using context = detail::compile_parse_context; + static_cast(this)->check_dynamic_spec(arg_id); + } +} + template class basic_format_arg; template class basic_format_args; template class dynamic_format_arg_store; @@ -711,14 +808,30 @@ class appender; FMT_BEGIN_DETAIL_NAMESPACE +template +constexpr auto has_const_formatter_impl(T*) + -> decltype(typename Context::template formatter_type().format( + std::declval(), std::declval()), + true) { + return true; +} +template +constexpr auto has_const_formatter_impl(...) -> bool { + return false; +} +template +constexpr auto has_const_formatter() -> bool { + return has_const_formatter_impl(static_cast(nullptr)); +} + // Extracts a reference to the container from back_insert_iterator. template inline auto get_container(std::back_insert_iterator it) -> Container& { - using bi_iterator = std::back_insert_iterator; - struct accessor : bi_iterator { - accessor(bi_iterator iter) : bi_iterator(iter) {} - using bi_iterator::container; + using base = std::back_insert_iterator; + struct accessor : base { + accessor(base b) : base(b) {} + using base::container; }; return *accessor(it).container; } @@ -730,13 +843,13 @@ FMT_CONSTEXPR auto copy_str(InputIt begin, InputIt end, OutputIt out) return out; } -template ::value)> -FMT_CONSTEXPR auto copy_str(const Char* begin, const Char* end, Char* out) - -> Char* { - if (is_constant_evaluated()) - return copy_str(begin, end, out); +template , U>::value&& is_char::value)> +FMT_CONSTEXPR auto copy_str(T* begin, T* end, U* out) -> U* { + if (is_constant_evaluated()) return copy_str(begin, end, out); auto size = to_unsigned(end - begin); - memcpy(out, begin, size); + memcpy(out, begin, size * sizeof(U)); return out + size; } @@ -755,24 +868,22 @@ template class buffer { protected: // Don't initialize ptr_ since it is not accessed to save a few cycles. FMT_MSC_WARNING(suppress : 26495) - buffer(size_t sz) FMT_NOEXCEPT : size_(sz), capacity_(sz) {} + buffer(size_t sz) noexcept : size_(sz), capacity_(sz) {} - buffer(T* p = nullptr, size_t sz = 0, size_t cap = 0) FMT_NOEXCEPT - : ptr_(p), - size_(sz), - capacity_(cap) {} + FMT_CONSTEXPR20 buffer(T* p = nullptr, size_t sz = 0, size_t cap = 0) noexcept + : ptr_(p), size_(sz), capacity_(cap) {} - ~buffer() = default; + FMT_CONSTEXPR20 ~buffer() = default; buffer(buffer&&) = default; /** Sets the buffer data and capacity. */ - void set(T* buf_data, size_t buf_capacity) FMT_NOEXCEPT { + FMT_CONSTEXPR void set(T* buf_data, size_t buf_capacity) noexcept { ptr_ = buf_data; capacity_ = buf_capacity; } /** Increases the buffer capacity to hold at least *capacity* elements. */ - virtual void grow(size_t capacity) = 0; + virtual FMT_CONSTEXPR20 void grow(size_t capacity) = 0; public: using value_type = T; @@ -781,30 +892,30 @@ template class buffer { buffer(const buffer&) = delete; void operator=(const buffer&) = delete; - auto begin() FMT_NOEXCEPT -> T* { return ptr_; } - auto end() FMT_NOEXCEPT -> T* { return ptr_ + size_; } + auto begin() noexcept -> T* { return ptr_; } + auto end() noexcept -> T* { return ptr_ + size_; } - auto begin() const FMT_NOEXCEPT -> const T* { return ptr_; } - auto end() const FMT_NOEXCEPT -> const T* { return ptr_ + size_; } + auto begin() const noexcept -> const T* { return ptr_; } + auto end() const noexcept -> const T* { return ptr_ + size_; } /** Returns the size of this buffer. */ - auto size() const FMT_NOEXCEPT -> size_t { return size_; } + constexpr auto size() const noexcept -> size_t { return size_; } /** Returns the capacity of this buffer. */ - auto capacity() const FMT_NOEXCEPT -> size_t { return capacity_; } + constexpr auto capacity() const noexcept -> size_t { return capacity_; } /** Returns a pointer to the buffer data. */ - auto data() FMT_NOEXCEPT -> T* { return ptr_; } + FMT_CONSTEXPR auto data() noexcept -> T* { return ptr_; } /** Returns a pointer to the buffer data. */ - auto data() const FMT_NOEXCEPT -> const T* { return ptr_; } + FMT_CONSTEXPR auto data() const noexcept -> const T* { return ptr_; } /** Clears this buffer. */ void clear() { size_ = 0; } // Tries resizing the buffer to contain *count* elements. If T is a POD type // the new elements may not be initialized. - void try_resize(size_t count) { + FMT_CONSTEXPR20 void try_resize(size_t count) { try_reserve(count); size_ = count <= capacity_ ? count : capacity_; } @@ -813,11 +924,11 @@ template class buffer { // capacity by a smaller amount than requested but guarantees there is space // for at least one additional element either by increasing the capacity or by // flushing the buffer if it is full. - void try_reserve(size_t new_capacity) { + FMT_CONSTEXPR20 void try_reserve(size_t new_capacity) { if (new_capacity > capacity_) grow(new_capacity); } - void push_back(const T& value) { + FMT_CONSTEXPR20 void push_back(const T& value) { try_reserve(size_ + 1); ptr_[size_++] = value; } @@ -825,8 +936,11 @@ template class buffer { /** Appends data to the end of the buffer. */ template void append(const U* begin, const U* end); - template auto operator[](I index) -> T& { return ptr_[index]; } - template auto operator[](I index) const -> const T& { + template FMT_CONSTEXPR auto operator[](Idx index) -> T& { + return ptr_[index]; + } + template + FMT_CONSTEXPR auto operator[](Idx index) const -> const T& { return ptr_[index]; } }; @@ -861,7 +975,7 @@ class iterator_buffer final : public Traits, public buffer { T data_[buffer_size]; protected: - void grow(size_t) final FMT_OVERRIDE { + FMT_CONSTEXPR20 void grow(size_t) override { if (this->size() == buffer_size) flush(); } @@ -885,9 +999,55 @@ class iterator_buffer final : public Traits, public buffer { auto count() const -> size_t { return Traits::count() + this->size(); } }; +template +class iterator_buffer final + : public fixed_buffer_traits, + public buffer { + private: + T* out_; + enum { buffer_size = 256 }; + T data_[buffer_size]; + + protected: + FMT_CONSTEXPR20 void grow(size_t) override { + if (this->size() == this->capacity()) flush(); + } + + void flush() { + size_t n = this->limit(this->size()); + if (this->data() == out_) { + out_ += n; + this->set(data_, buffer_size); + } + this->clear(); + } + + public: + explicit iterator_buffer(T* out, size_t n = buffer_size) + : fixed_buffer_traits(n), buffer(out, 0, n), out_(out) {} + iterator_buffer(iterator_buffer&& other) + : fixed_buffer_traits(other), + buffer(std::move(other)), + out_(other.out_) { + if (this->data() != out_) { + this->set(data_, buffer_size); + this->clear(); + } + } + ~iterator_buffer() { flush(); } + + auto out() -> T* { + flush(); + return out_; + } + auto count() const -> size_t { + return fixed_buffer_traits::count() + this->size(); + } +}; + template class iterator_buffer final : public buffer { protected: - void grow(size_t) final FMT_OVERRIDE {} + FMT_CONSTEXPR20 void grow(size_t) override {} public: explicit iterator_buffer(T* out, size_t = 0) : buffer(out, 0, ~size_t()) {} @@ -905,7 +1065,7 @@ class iterator_buffer, Container& container_; protected: - void grow(size_t capacity) final FMT_OVERRIDE { + FMT_CONSTEXPR20 void grow(size_t capacity) override { container_.resize(capacity); this->set(&container_[0], capacity); } @@ -915,6 +1075,7 @@ class iterator_buffer, : buffer(c.size()), container_(c) {} explicit iterator_buffer(std::back_insert_iterator out, size_t = 0) : iterator_buffer(get_container(out)) {} + auto out() -> std::back_insert_iterator { return std::back_inserter(container_); } @@ -928,7 +1089,7 @@ template class counting_buffer final : public buffer { size_t count_ = 0; protected: - void grow(size_t) final FMT_OVERRIDE { + FMT_CONSTEXPR20 void grow(size_t) override { if (this->size() != buffer_size) return; count_ += this->size(); this->clear(); @@ -966,7 +1127,11 @@ struct fallback_formatter { // Specifies if T has an enabled fallback_formatter specialization. template using has_fallback_formatter = +#ifdef FMT_DEPRECATED_OSTREAM std::is_constructible>; +#else + std::false_type; +#endif struct view {}; @@ -1045,60 +1210,15 @@ template constexpr auto count_named_args() -> size_t { return count::value...>(); } -enum class type { - none_type, - // Integer types should go first, - int_type, - uint_type, - long_long_type, - ulong_long_type, - int128_type, - uint128_type, - bool_type, - char_type, - last_integer_type = char_type, - // followed by floating-point types. - float_type, - double_type, - long_double_type, - last_numeric_type = long_double_type, - cstring_type, - string_type, - pointer_type, - custom_type -}; - -// Maps core type T to the corresponding type enum constant. -template -struct type_constant : std::integral_constant {}; - -#define FMT_TYPE_CONSTANT(Type, constant) \ - template \ - struct type_constant \ - : std::integral_constant {} - -FMT_TYPE_CONSTANT(int, int_type); -FMT_TYPE_CONSTANT(unsigned, uint_type); -FMT_TYPE_CONSTANT(long long, long_long_type); -FMT_TYPE_CONSTANT(unsigned long long, ulong_long_type); -FMT_TYPE_CONSTANT(int128_t, int128_type); -FMT_TYPE_CONSTANT(uint128_t, uint128_type); -FMT_TYPE_CONSTANT(bool, bool_type); -FMT_TYPE_CONSTANT(Char, char_type); -FMT_TYPE_CONSTANT(float, float_type); -FMT_TYPE_CONSTANT(double, double_type); -FMT_TYPE_CONSTANT(long double, long_double_type); -FMT_TYPE_CONSTANT(const Char*, cstring_type); -FMT_TYPE_CONSTANT(basic_string_view, string_type); -FMT_TYPE_CONSTANT(const void*, pointer_type); - -constexpr bool is_integral_type(type t) { - return t > type::none_type && t <= type::last_integer_type; +template +constexpr auto count_statically_named_args() -> size_t { + return count::value...>(); } -constexpr bool is_arithmetic_type(type t) { - return t > type::none_type && t <= type::last_numeric_type; -} +struct unformattable {}; +struct unformattable_char : unformattable {}; +struct unformattable_const : unformattable {}; +struct unformattable_pointer : unformattable {}; template struct string_value { const Char* data; @@ -1112,8 +1232,8 @@ template struct named_arg_value { template struct custom_value { using parse_context = typename Context::parse_context_type; - const void* value; - void (*format)(const void* arg, parse_context& parse_ctx, Context& ctx); + void* value; + void (*format)(void* arg, parse_context& parse_ctx, Context& ctx); }; // A formatting argument value. @@ -1127,8 +1247,8 @@ template class value { unsigned uint_value; long long long_long_value; unsigned long long ulong_long_value; - int128_t int128_value; - uint128_t uint128_value; + int128_opt int128_value; + uint128_opt uint128_value; bool bool_value; char_type char_value; float float_value; @@ -1145,10 +1265,10 @@ template class value { constexpr FMT_INLINE value(unsigned val) : uint_value(val) {} constexpr FMT_INLINE value(long long val) : long_long_value(val) {} constexpr FMT_INLINE value(unsigned long long val) : ulong_long_value(val) {} - FMT_INLINE value(int128_t val) : int128_value(val) {} - FMT_INLINE value(uint128_t val) : uint128_value(val) {} - FMT_INLINE value(float val) : float_value(val) {} - FMT_INLINE value(double val) : double_value(val) {} + FMT_INLINE value(int128_opt val) : int128_value(val) {} + FMT_INLINE value(uint128_opt val) : uint128_value(val) {} + constexpr FMT_INLINE value(float val) : float_value(val) {} + constexpr FMT_INLINE value(double val) : double_value(val) {} FMT_INLINE value(long double val) : long_double_value(val) {} constexpr FMT_INLINE value(bool val) : bool_value(val) {} constexpr FMT_INLINE value(char_type val) : char_value(val) {} @@ -1164,31 +1284,39 @@ template class value { FMT_INLINE value(const named_arg_info* args, size_t size) : named_args{args, size} {} - template FMT_CONSTEXPR FMT_INLINE value(const T& val) { - custom.value = &val; + template FMT_CONSTEXPR FMT_INLINE value(T& val) { + using value_type = remove_cvref_t; + custom.value = const_cast(&val); // Get the formatter type through the context to allow different contexts // have different extension points, e.g. `formatter` for `format` and // `printf_formatter` for `printf`. custom.format = format_custom_arg< - T, conditional_t::value, - typename Context::template formatter_type, - fallback_formatter>>; + value_type, + conditional_t::value, + typename Context::template formatter_type, + fallback_formatter>>; } + value(unformattable); + value(unformattable_char); + value(unformattable_const); + value(unformattable_pointer); private: // Formats an argument of a custom type, such as a user-defined class. template - static void format_custom_arg(const void* arg, + static void format_custom_arg(void* arg, typename Context::parse_context_type& parse_ctx, Context& ctx) { - Formatter f; + auto f = Formatter(); parse_ctx.advance_to(f.parse(parse_ctx)); - ctx.advance_to(f.format(*static_cast(arg), ctx)); + using qualified_type = + conditional_t(), const T, T>; + ctx.advance_to(f.format(*static_cast(arg), ctx)); } }; template -FMT_CONSTEXPR auto make_arg(const T& value) -> basic_format_arg; +FMT_CONSTEXPR auto make_arg(T&& value) -> basic_format_arg; // To minimize the number of types we need to deal with, long is translated // either to int or to long long depending on its size. @@ -1196,9 +1324,24 @@ enum { long_short = sizeof(long) == sizeof(int) }; using long_type = conditional_t; using ulong_type = conditional_t; -struct unformattable {}; +#ifdef __cpp_lib_byte +inline auto format_as(std::byte b) -> unsigned char { + return static_cast(b); +} +#endif + +template struct has_format_as { + template ::value&& std::is_integral::value)> + static auto check(U*) -> std::true_type; + static auto check(...) -> std::false_type; + + enum { value = decltype(check(static_cast(nullptr)))::value }; +}; // Maps formatting arguments to core types. +// arg_mapper reports errors by returning unformattable instead of using +// static_assert because it's used in the is_formattable trait. template struct arg_mapper { using char_type = typename Context::char_type; @@ -1221,17 +1364,30 @@ template struct arg_mapper { -> unsigned long long { return val; } - FMT_CONSTEXPR FMT_INLINE auto map(int128_t val) -> int128_t { return val; } - FMT_CONSTEXPR FMT_INLINE auto map(uint128_t val) -> uint128_t { return val; } + FMT_CONSTEXPR FMT_INLINE auto map(int128_opt val) -> int128_opt { + return val; + } + FMT_CONSTEXPR FMT_INLINE auto map(uint128_opt val) -> uint128_opt { + return val; + } FMT_CONSTEXPR FMT_INLINE auto map(bool val) -> bool { return val; } - template ::value)> + template ::value || + std::is_same::value)> FMT_CONSTEXPR FMT_INLINE auto map(T val) -> char_type { - static_assert( - std::is_same::value || std::is_same::value, - "mixing character types is disallowed"); return val; } + template ::value || +#ifdef __cpp_char8_t + std::is_same::value || +#endif + std::is_same::value || + std::is_same::value) && + !std::is_same::value, + int> = 0> + FMT_CONSTEXPR FMT_INLINE auto map(T) -> unformattable_char { + return {}; + } FMT_CONSTEXPR FMT_INLINE auto map(float val) -> float { return val; } FMT_CONSTEXPR FMT_INLINE auto map(double val) -> double { return val; } @@ -1245,49 +1401,38 @@ template struct arg_mapper { FMT_CONSTEXPR FMT_INLINE auto map(const char_type* val) -> const char_type* { return val; } - template ::value)> + template ::value && !std::is_pointer::value && + std::is_same>::value)> FMT_CONSTEXPR FMT_INLINE auto map(const T& val) -> basic_string_view { - static_assert(std::is_same>::value, - "mixing character types is disallowed"); return to_string_view(val); } + template ::value && !std::is_pointer::value && + !std::is_same>::value)> + FMT_CONSTEXPR FMT_INLINE auto map(const T&) -> unformattable_char { + return {}; + } template , T>::value && + std::is_convertible>::value && !is_string::value && !has_formatter::value && !has_fallback_formatter::value)> FMT_CONSTEXPR FMT_INLINE auto map(const T& val) -> basic_string_view { return basic_string_view(val); } - template < - typename T, - FMT_ENABLE_IF( - std::is_constructible, T>::value && - !std::is_constructible, T>::value && - !is_string::value && !has_formatter::value && - !has_fallback_formatter::value)> + template >::value && + !std::is_convertible>::value && + !is_string::value && !has_formatter::value && + !has_fallback_formatter::value)> FMT_CONSTEXPR FMT_INLINE auto map(const T& val) -> basic_string_view { return std_string_view(val); } - FMT_CONSTEXPR FMT_INLINE auto map(const signed char* val) -> const char* { - static_assert(std::is_same::value, "invalid string type"); - return reinterpret_cast(val); - } - FMT_CONSTEXPR FMT_INLINE auto map(const unsigned char* val) -> const char* { - static_assert(std::is_same::value, "invalid string type"); - return reinterpret_cast(val); - } - FMT_CONSTEXPR FMT_INLINE auto map(signed char* val) -> const char* { - const auto* const_val = val; - return map(const_val); - } - FMT_CONSTEXPR FMT_INLINE auto map(unsigned char* val) -> const char* { - const auto* const_val = val; - return map(const_val); - } FMT_CONSTEXPR FMT_INLINE auto map(void* val) -> const void* { return val; } FMT_CONSTEXPR FMT_INLINE auto map(const void* val) -> const void* { @@ -1299,37 +1444,76 @@ template struct arg_mapper { // We use SFINAE instead of a const T* parameter to avoid conflicting with // the C array overload. - template - FMT_CONSTEXPR auto map(T) -> enable_if_t::value, int> { - // Formatting of arbitrary pointers is disallowed. If you want to output - // a pointer cast it to "void *" or "const void *". In particular, this - // forbids formatting of "[const] volatile char *" which is printed as bool - // by iostreams. - static_assert(!sizeof(T), "formatting of non-void pointers is disallowed"); - return 0; + template < + typename T, + FMT_ENABLE_IF( + std::is_pointer::value || std::is_member_pointer::value || + std::is_function::type>::value || + (std::is_convertible::value && + !std::is_convertible::value && + !has_formatter::value))> + FMT_CONSTEXPR auto map(const T&) -> unformattable_pointer { + return {}; } - template + template ::value)> FMT_CONSTEXPR FMT_INLINE auto map(const T (&values)[N]) -> const T (&)[N] { return values; } template ::value && - !has_formatter::value && - !has_fallback_formatter::value)> - FMT_CONSTEXPR FMT_INLINE auto map(const T& val) + FMT_ENABLE_IF( + std::is_enum::value&& std::is_convertible::value && + !has_format_as::value && !has_formatter::value && + !has_fallback_formatter::value)> + FMT_DEPRECATED FMT_CONSTEXPR FMT_INLINE auto map(const T& val) -> decltype(std::declval().map( - static_cast::type>(val))) { - return map(static_cast::type>(val)); + static_cast>(val))) { + return map(static_cast>(val)); } - template ::value && !is_char::value && - (has_formatter::value || - has_fallback_formatter::value))> - FMT_CONSTEXPR FMT_INLINE auto map(const T& val) -> const T& { + + template ::value && + !has_formatter::value)> + FMT_CONSTEXPR FMT_INLINE auto map(const T& val) + -> decltype(std::declval().map(format_as(T()))) { + return map(format_as(val)); + } + + template > + struct formattable + : bool_constant() || + !std::is_const>::value || + has_fallback_formatter::value> {}; + +#if (FMT_MSC_VERSION != 0 && FMT_MSC_VERSION < 1910) || \ + FMT_ICC_VERSION != 0 || defined(__NVCC__) + // Workaround a bug in MSVC and Intel (Issue 2746). + template FMT_CONSTEXPR FMT_INLINE auto do_map(T&& val) -> T& { + return val; + } +#else + template ::value)> + FMT_CONSTEXPR FMT_INLINE auto do_map(T&& val) -> T& { return val; } + template ::value)> + FMT_CONSTEXPR FMT_INLINE auto do_map(T&&) -> unformattable_const { + return {}; + } +#endif + + template , + FMT_ENABLE_IF(!is_string::value && !is_char::value && + !std::is_array::value && + !std::is_pointer::value && + !has_format_as::value && + (has_formatter::value || + has_fallback_formatter::value))> + FMT_CONSTEXPR FMT_INLINE auto map(T&& val) + -> decltype(this->do_map(std::forward(val))) { + return do_map(std::forward(val)); + } template ::value)> FMT_CONSTEXPR FMT_INLINE auto map(const T& named_arg) @@ -1366,19 +1550,11 @@ class appender : public std::back_insert_iterator> { public: using std::back_insert_iterator>::back_insert_iterator; - appender(base it) : base(it) {} - using _Unchecked_type = appender; // Mark iterator as checked. + appender(base it) noexcept : base(it) {} + FMT_UNCHECKED_ITERATOR(appender); - auto operator++() -> appender& { - base::operator++(); - return *this; - } - - auto operator++(int) -> appender { - auto tmp = *this; - ++*this; - return tmp; - } + auto operator++() noexcept -> appender& { return *this; } + auto operator++(int) noexcept -> appender { return *this; } }; // A formatting argument. It is a trivially copyable/constructible type to @@ -1389,7 +1565,7 @@ template class basic_format_arg { detail::type type_; template - friend FMT_CONSTEXPR auto detail::make_arg(const T& value) + friend FMT_CONSTEXPR auto detail::make_arg(T&& value) -> basic_format_arg; template @@ -1424,7 +1600,7 @@ template class basic_format_arg { constexpr basic_format_arg() : type_(detail::type::none_type) {} - constexpr explicit operator bool() const FMT_NOEXCEPT { + constexpr explicit operator bool() const noexcept { return type_ != detail::type::none_type; } @@ -1492,6 +1668,11 @@ auto copy_str(InputIt begin, InputIt end, appender out) -> appender { return out; } +template +FMT_CONSTEXPR auto copy_str(R&& rng, OutputIt out) -> OutputIt { + return detail::copy_str(rng.begin(), rng.end(), out); +} + #if FMT_GCC_VERSION && FMT_GCC_VERSION < 500 // A workaround for gcc 4.8 to make void_t work in a SFINAE context. template struct void_t_impl { using type = void; }; @@ -1525,7 +1706,7 @@ struct is_contiguous_back_insert_iterator> template <> struct is_contiguous_back_insert_iterator : std::true_type {}; -// A type-erased reference to an std::locale to avoid heavy include. +// A type-erased reference to an std::locale to avoid a heavy include. class locale_ref { private: const void* locale_; // A type-erased pointer to std::locale. @@ -1534,7 +1715,7 @@ class locale_ref { constexpr locale_ref() : locale_(nullptr) {} template explicit locale_ref(const Locale& loc); - explicit operator bool() const FMT_NOEXCEPT { return locale_ != nullptr; } + explicit operator bool() const noexcept { return locale_ != nullptr; } template auto get() const -> Locale; }; @@ -1550,10 +1731,40 @@ constexpr auto encode_types() -> unsigned long long { } template -FMT_CONSTEXPR auto make_arg(const T& value) -> basic_format_arg { +FMT_CONSTEXPR FMT_INLINE auto make_value(T&& val) -> value { + const auto& arg = arg_mapper().map(FMT_FORWARD(val)); + + constexpr bool formattable_char = + !std::is_same::value; + static_assert(formattable_char, "Mixing character types is disallowed."); + + constexpr bool formattable_const = + !std::is_same::value; + static_assert(formattable_const, "Cannot format a const argument."); + + // Formatting of arbitrary pointers is disallowed. If you want to output + // a pointer cast it to "void *" or "const void *". In particular, this + // forbids formatting of "[const] volatile char *" which is printed as bool + // by iostreams. + constexpr bool formattable_pointer = + !std::is_same::value; + static_assert(formattable_pointer, + "Formatting of non-void pointers is disallowed."); + + constexpr bool formattable = + !std::is_same::value; + static_assert( + formattable, + "Cannot format an argument. To make type T formattable provide a " + "formatter specialization: https://fmt.dev/latest/api.html#udt"); + return {arg}; +} + +template +FMT_CONSTEXPR auto make_arg(T&& value) -> basic_format_arg { basic_format_arg arg; arg.type_ = mapped_type_constant::value; - arg.value_ = arg_mapper().map(value); + arg.value_ = make_value(value); return arg; } @@ -1562,18 +1773,13 @@ FMT_CONSTEXPR auto make_arg(const T& value) -> basic_format_arg { // another (not recommended). template -FMT_CONSTEXPR FMT_INLINE auto make_arg(const T& val) -> value { - const auto& arg = arg_mapper().map(val); - static_assert( - !std::is_same::value, - "Cannot format an argument. To make type T formattable provide a " - "formatter specialization: https://fmt.dev/latest/api.html#udt"); - return {arg}; +FMT_CONSTEXPR FMT_INLINE auto make_arg(T&& val) -> value { + return make_value(val); } template -inline auto make_arg(const T& value) -> basic_format_arg { +FMT_CONSTEXPR inline auto make_arg(T&& value) -> basic_format_arg { return make_arg(value); } FMT_END_DETAIL_NAMESPACE @@ -1643,9 +1849,9 @@ using format_context = buffer_context; template using is_formattable = bool_constant< - !std::is_same>().map( - std::declval())), - detail::unformattable>::value && + !std::is_base_of>().map( + std::declval()))>::value && !detail::has_fallback_formatter::value>; /** @@ -1684,14 +1890,16 @@ class format_arg_store : 0); public: - FMT_CONSTEXPR FMT_INLINE format_arg_store(const Args&... args) + template + FMT_CONSTEXPR FMT_INLINE format_arg_store(T&&... args) : #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 basic_format_args(*this), #endif data_{detail::make_arg< is_packed, Context, - detail::mapped_type_constant::value>(args)...} { + detail::mapped_type_constant, Context>::value>( + FMT_FORWARD(args))...} { detail::init_named_args(data_.named_args(), 0, 0, args...); } }; @@ -1705,9 +1913,9 @@ class format_arg_store \endrst */ template -constexpr auto make_format_args(const Args&... args) - -> format_arg_store { - return {args...}; +constexpr auto make_format_args(Args&&... args) + -> format_arg_store...> { + return {FMT_FORWARD(args)...}; } /** @@ -1853,21 +2061,27 @@ template class basic_format_args { // between clang and gcc on ARM (#1919). using format_args = basic_format_args; -// We cannot use enum classes as bit fields because of a gcc bug -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414. +// We cannot use enum classes as bit fields because of a gcc bug, so we put them +// in namespaces instead (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61414). +// Additionally, if an underlying type is specified, older gcc incorrectly warns +// that the type is too small. Both bugs are fixed in gcc 9.3. +#if FMT_GCC_VERSION && FMT_GCC_VERSION < 903 +# define FMT_ENUM_UNDERLYING_TYPE(type) +#else +# define FMT_ENUM_UNDERLYING_TYPE(type) : type +#endif namespace align { -enum type { none, left, right, center, numeric }; +enum type FMT_ENUM_UNDERLYING_TYPE(unsigned char){none, left, right, center, + numeric}; } using align_t = align::type; namespace sign { -enum type { none, minus, plus, space }; +enum type FMT_ENUM_UNDERLYING_TYPE(unsigned char){none, minus, plus, space}; } using sign_t = sign::type; FMT_BEGIN_DETAIL_NAMESPACE -void throw_format_error(const char* message); - // Workaround an array initialization issue in gcc 4.8. template struct fill_t { private: @@ -1893,11 +2107,34 @@ template struct fill_t { }; FMT_END_DETAIL_NAMESPACE +enum class presentation_type : unsigned char { + none, + // Integer types should go first, + dec, // 'd' + oct, // 'o' + hex_lower, // 'x' + hex_upper, // 'X' + bin_lower, // 'b' + bin_upper, // 'B' + hexfloat_lower, // 'a' + hexfloat_upper, // 'A' + exp_lower, // 'e' + exp_upper, // 'E' + fixed_lower, // 'f' + fixed_upper, // 'F' + general_lower, // 'g' + general_upper, // 'G' + chr, // 'c' + string, // 's' + pointer, // 'p' + debug // '?' +}; + // Format specifiers for built-in and string types. template struct basic_format_specs { int width; int precision; - char type; + presentation_type type; align_t align : 4; sign_t sign : 3; bool alt : 1; // Alternate form ('#'). @@ -1907,7 +2144,7 @@ template struct basic_format_specs { constexpr basic_format_specs() : width(0), precision(-1), - type(0), + type(presentation_type::none), align(align::none), sign(sign::none), alt(false), @@ -1987,9 +2224,7 @@ template class specs_setter { } FMT_CONSTEXPR void end_precision() {} - FMT_CONSTEXPR void on_type(Char type) { - specs_.type = static_cast(type); - } + FMT_CONSTEXPR void on_type(presentation_type type) { specs_.type = type; } }; // Format spec handler that saves references to arguments representing dynamic @@ -2029,11 +2264,14 @@ class dynamic_specs_handler FMT_CONSTEXPR auto make_arg_ref(int arg_id) -> arg_ref_type { context_.check_arg_id(arg_id); + context_.check_dynamic_spec(arg_id); return arg_ref_type(arg_id); } FMT_CONSTEXPR auto make_arg_ref(auto_id) -> arg_ref_type { - return arg_ref_type(context_.next_arg_id()); + int arg_id = context_.next_arg_id(); + context_.check_dynamic_spec(arg_id); + return arg_ref_type(arg_id); } FMT_CONSTEXPR auto make_arg_ref(basic_string_view arg_id) @@ -2051,21 +2289,23 @@ template constexpr bool is_ascii_letter(Char c) { // Converts a character to ASCII. Returns a number > 127 on conversion failure. template ::value)> -constexpr auto to_ascii(Char value) -> Char { - return value; +constexpr auto to_ascii(Char c) -> Char { + return c; } template ::value)> -constexpr auto to_ascii(Char value) -> - typename std::underlying_type::type { - return value; +constexpr auto to_ascii(Char c) -> underlying_t { + return c; +} + +FMT_CONSTEXPR inline auto code_point_length_impl(char c) -> int { + return "\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\1\0\0\0\0\0\0\0\0\2\2\2\2\3\3\4" + [static_cast(c) >> 3]; } template FMT_CONSTEXPR auto code_point_length(const Char* begin) -> int { if (const_check(sizeof(Char) != 1)) return 1; - constexpr char lengths[] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 3, 3, 4, 0}; - int len = lengths[static_cast(*begin) >> 3]; + int len = code_point_length_impl(static_cast(*begin)); // Compute the pointer to the next character early so that the next // iteration can start working on the next character. Neither Clang @@ -2122,7 +2362,7 @@ FMT_CONSTEXPR auto parse_align(const Char* begin, const Char* end, FMT_ASSERT(begin != end, ""); auto align = align::none; auto p = begin + code_point_length(begin); - if (p >= end) p = begin; + if (end - p <= 0) p = begin; for (;;) { switch (to_ascii(*p)) { case '<': @@ -2271,6 +2511,50 @@ FMT_CONSTEXPR auto parse_precision(const Char* begin, const Char* end, return begin; } +template +FMT_CONSTEXPR auto parse_presentation_type(Char type) -> presentation_type { + switch (to_ascii(type)) { + case 'd': + return presentation_type::dec; + case 'o': + return presentation_type::oct; + case 'x': + return presentation_type::hex_lower; + case 'X': + return presentation_type::hex_upper; + case 'b': + return presentation_type::bin_lower; + case 'B': + return presentation_type::bin_upper; + case 'a': + return presentation_type::hexfloat_lower; + case 'A': + return presentation_type::hexfloat_upper; + case 'e': + return presentation_type::exp_lower; + case 'E': + return presentation_type::exp_upper; + case 'f': + return presentation_type::fixed_lower; + case 'F': + return presentation_type::fixed_upper; + case 'g': + return presentation_type::general_lower; + case 'G': + return presentation_type::general_upper; + case 'c': + return presentation_type::chr; + case 's': + return presentation_type::string; + case 'p': + return presentation_type::pointer; + case '?': + return presentation_type::debug; + default: + return presentation_type::none; + } +} + // Parses standard format specifiers and sends notifications about parsed // components to handler. template @@ -2278,9 +2562,12 @@ FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(const Char* begin, const Char* end, SpecHandler&& handler) -> const Char* { - if (begin + 1 < end && begin[1] == '}' && is_ascii_letter(*begin) && + if (1 < end - begin && begin[1] == '}' && is_ascii_letter(*begin) && *begin != 'L') { - handler.on_type(*begin++); + presentation_type type = parse_presentation_type(*begin++); + if (type == presentation_type::none) + handler.on_error("invalid type specifier"); + handler.on_type(type); return begin; } @@ -2334,7 +2621,12 @@ FMT_CONSTEXPR FMT_INLINE auto parse_format_specs(const Char* begin, } // Parse type. - if (begin != end && *begin != '}') handler.on_type(*begin++); + if (begin != end && *begin != '}') { + presentation_type type = parse_presentation_type(*begin++); + if (type == presentation_type::none) + handler.on_error("invalid type specifier"); + handler.on_type(type); + } return begin; } @@ -2381,7 +2673,7 @@ FMT_CONSTEXPR auto parse_replacement_field(const Char* begin, const Char* end, template FMT_CONSTEXPR FMT_INLINE void parse_format_string( basic_string_view format_str, Handler&& handler) { - // this is most likely a name-lookup defect in msvc's modules implementation + // Workaround a name-lookup bug in MSVC's modules implementation. using detail::find; auto begin = format_str.data(); @@ -2405,21 +2697,21 @@ FMT_CONSTEXPR FMT_INLINE void parse_format_string( return; } struct writer { - FMT_CONSTEXPR void operator()(const Char* pbegin, const Char* pend) { - if (pbegin == pend) return; + FMT_CONSTEXPR void operator()(const Char* from, const Char* to) { + if (from == to) return; for (;;) { const Char* p = nullptr; - if (!find(pbegin, pend, Char('}'), p)) - return handler_.on_text(pbegin, pend); + if (!find(from, to, Char('}'), p)) + return handler_.on_text(from, to); ++p; - if (p == pend || *p != '}') + if (p == to || *p != '}') return handler_.on_error("unmatched '}' in format string"); - handler_.on_text(pbegin, p); - pbegin = p + 1; + handler_.on_text(from, p); + from = p + 1; } } Handler& handler_; - } write{handler}; + } write = {handler}; while (begin != end) { // Doing two passes with memchr (one for '{' and another for '}') is up to // 2.5x faster than the naive one-pass implementation on big format strings. @@ -2431,73 +2723,43 @@ FMT_CONSTEXPR FMT_INLINE void parse_format_string( } } +template ::value> struct strip_named_arg { + using type = T; +}; +template struct strip_named_arg { + using type = remove_cvref_t; +}; + template FMT_CONSTEXPR auto parse_format_specs(ParseContext& ctx) -> decltype(ctx.begin()) { using char_type = typename ParseContext::char_type; using context = buffer_context; + using stripped_type = typename strip_named_arg::type; using mapped_type = conditional_t< mapped_type_constant::value != type::custom_type, - decltype(arg_mapper().map(std::declval())), T>; + decltype(arg_mapper().map(std::declval())), + stripped_type>; auto f = conditional_t::value, formatter, - fallback_formatter>(); + fallback_formatter>(); return f.parse(ctx); } -// A parse context with extra argument id checks. It is only used at compile -// time because adding checks at runtime would introduce substantial overhead -// and would be redundant since argument ids are checked when arguments are -// retrieved anyway. -template -class compile_parse_context - : public basic_format_parse_context { - private: - int num_args_; - using base = basic_format_parse_context; - - public: - explicit FMT_CONSTEXPR compile_parse_context( - basic_string_view format_str, - int num_args = (std::numeric_limits::max)(), ErrorHandler eh = {}) - : base(format_str, eh), num_args_(num_args) {} - - FMT_CONSTEXPR auto next_arg_id() -> int { - int id = base::next_arg_id(); - if (id >= num_args_) this->on_error("argument not found"); - return id; - } - - FMT_CONSTEXPR void check_arg_id(int id) { - base::check_arg_id(id); - if (id >= num_args_) this->on_error("argument not found"); - } - using base::check_arg_id; -}; - template -FMT_CONSTEXPR void check_int_type_spec(char spec, ErrorHandler&& eh) { - switch (spec) { - case 0: - case 'd': - case 'x': - case 'X': - case 'b': - case 'B': - case 'o': - case 'c': - break; - default: +FMT_CONSTEXPR void check_int_type_spec(presentation_type type, + ErrorHandler&& eh) { + if (type > presentation_type::bin_upper && type != presentation_type::chr) eh.on_error("invalid type specifier"); - break; - } } // Checks char specs and returns true if the type spec is char (and not int). template FMT_CONSTEXPR auto check_char_specs(const basic_format_specs& specs, ErrorHandler&& eh = {}) -> bool { - if (specs.type && specs.type != 'c') { + if (specs.type != presentation_type::none && + specs.type != presentation_type::chr && + specs.type != presentation_type::debug) { check_int_type_spec(specs.type, eh); return false; } @@ -2521,7 +2783,6 @@ struct float_specs { bool upper : 1; bool locale : 1; bool binary32 : 1; - bool use_grisu : 1; bool showpoint : 1; }; @@ -2533,33 +2794,33 @@ FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs& specs, result.showpoint = specs.alt; result.locale = specs.localized; switch (specs.type) { - case 0: + case presentation_type::none: result.format = float_format::general; break; - case 'G': + case presentation_type::general_upper: result.upper = true; FMT_FALLTHROUGH; - case 'g': + case presentation_type::general_lower: result.format = float_format::general; break; - case 'E': + case presentation_type::exp_upper: result.upper = true; FMT_FALLTHROUGH; - case 'e': + case presentation_type::exp_lower: result.format = float_format::exp; result.showpoint |= specs.precision != 0; break; - case 'F': + case presentation_type::fixed_upper: result.upper = true; FMT_FALLTHROUGH; - case 'f': + case presentation_type::fixed_lower: result.format = float_format::fixed; result.showpoint |= specs.precision != 0; break; - case 'A': + case presentation_type::hexfloat_upper: result.upper = true; FMT_FALLTHROUGH; - case 'a': + case presentation_type::hexfloat_lower: result.format = float_format::hex; break; default: @@ -2569,22 +2830,29 @@ FMT_CONSTEXPR auto parse_float_type_spec(const basic_format_specs& specs, return result; } -template -FMT_CONSTEXPR auto check_cstring_type_spec(Char spec, ErrorHandler&& eh = {}) - -> bool { - if (spec == 0 || spec == 's') return true; - if (spec != 'p') eh.on_error("invalid type specifier"); +template +FMT_CONSTEXPR auto check_cstring_type_spec(presentation_type type, + ErrorHandler&& eh = {}) -> bool { + if (type == presentation_type::none || type == presentation_type::string || + type == presentation_type::debug) + return true; + if (type != presentation_type::pointer) eh.on_error("invalid type specifier"); return false; } -template -FMT_CONSTEXPR void check_string_type_spec(Char spec, ErrorHandler&& eh = {}) { - if (spec != 0 && spec != 's') eh.on_error("invalid type specifier"); +template +FMT_CONSTEXPR void check_string_type_spec(presentation_type type, + ErrorHandler&& eh = {}) { + if (type != presentation_type::none && type != presentation_type::string && + type != presentation_type::debug) + eh.on_error("invalid type specifier"); } -template -FMT_CONSTEXPR void check_pointer_type_spec(Char spec, ErrorHandler&& eh) { - if (spec != 0 && spec != 'p') eh.on_error("invalid type specifier"); +template +FMT_CONSTEXPR void check_pointer_type_spec(presentation_type type, + ErrorHandler&& eh) { + if (type != presentation_type::none && type != presentation_type::pointer) + eh.on_error("invalid type specifier"); } // A parse_format_specs handler that checks if specifiers are consistent with @@ -2610,7 +2878,8 @@ template class specs_checker : public Handler { FMT_CONSTEXPR void on_sign(sign_t s) { require_numeric_argument(); if (is_integral_type(arg_type_) && arg_type_ != type::int_type && - arg_type_ != type::long_long_type && arg_type_ != type::char_type) { + arg_type_ != type::long_long_type && arg_type_ != type::int128_type && + arg_type_ != type::char_type) { this->on_error("format specifier requires signed argument"); } Handler::on_sign(s); @@ -2639,53 +2908,54 @@ template class specs_checker : public Handler { constexpr int invalid_arg_index = -1; -#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +#if FMT_USE_NONTYPE_TEMPLATE_ARGS template constexpr auto get_arg_index_by_name(basic_string_view name) -> int { if constexpr (detail::is_statically_named_arg()) { if (name == T::name) return N; } - if constexpr (sizeof...(Args) > 0) { + if constexpr (sizeof...(Args) > 0) return get_arg_index_by_name(name); - } else { - (void)name; // Workaround an MSVC bug about "unused" parameter. - return invalid_arg_index; - } + (void)name; // Workaround an MSVC bug about "unused" parameter. + return invalid_arg_index; } #endif template FMT_CONSTEXPR auto get_arg_index_by_name(basic_string_view name) -> int { -#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS - if constexpr (sizeof...(Args) > 0) { +#if FMT_USE_NONTYPE_TEMPLATE_ARGS + if constexpr (sizeof...(Args) > 0) return get_arg_index_by_name<0, Args...>(name); - } else { - (void)name; - return invalid_arg_index; - } -#else +#endif (void)name; return invalid_arg_index; -#endif } template class format_string_checker { private: + // In the future basic_format_parse_context will replace compile_parse_context + // here and will use is_constant_evaluated and downcasting to access the data + // needed for compile-time checks: https://godbolt.org/z/GvWzcTjh1. using parse_context_type = compile_parse_context; - enum { num_args = sizeof...(Args) }; + static constexpr int num_args = sizeof...(Args); // Format specifier parsing function. using parse_func = const Char* (*)(parse_context_type&); parse_context_type context_; - parse_func parse_funcs_[num_args > 0 ? num_args : 1]; + parse_func parse_funcs_[num_args > 0 ? static_cast(num_args) : 1]; + type types_[num_args > 0 ? static_cast(num_args) : 1]; public: explicit FMT_CONSTEXPR format_string_checker( basic_string_view format_str, ErrorHandler eh) - : context_(format_str, num_args, eh), - parse_funcs_{&parse_format_specs...} {} + : context_(format_str, num_args, types_, eh), + parse_funcs_{&parse_format_specs...}, + types_{ + mapped_type_constant>::value...} { + } FMT_CONSTEXPR void on_text(const Char*, const Char*) {} @@ -2694,7 +2964,7 @@ class format_string_checker { return context_.check_arg_id(id), id; } FMT_CONSTEXPR auto on_arg_id(basic_string_view id) -> int { -#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +#if FMT_USE_NONTYPE_TEMPLATE_ARGS auto index = get_arg_index_by_name(id); if (index == invalid_arg_index) on_error("named argument is not found"); return context_.check_arg_id(index), index; @@ -2719,10 +2989,19 @@ class format_string_checker { } }; +// Reports a compile-time error if S is not a valid format string. +template ::value)> +FMT_INLINE void check_format_string(const S&) { +#ifdef FMT_ENFORCE_COMPILE_STRING + static_assert(is_compile_string::value, + "FMT_ENFORCE_COMPILE_STRING requires all format strings to use " + "FMT_STRING."); +#endif +} template ::value), int>> + FMT_ENABLE_IF(is_compile_string::value)> void check_format_string(S format_str) { - FMT_CONSTEXPR auto s = to_string_view(format_str); + FMT_CONSTEXPR auto s = basic_string_view(format_str); using checker = format_string_checker...>; FMT_CONSTEXPR bool invalid_format = @@ -2769,7 +3048,10 @@ struct formatter::value, + enable_if_t<(U == detail::type::string_type || + U == detail::type::cstring_type || + U == detail::type::char_type), + int> = 0> + FMT_CONSTEXPR void set_debug_format() { + specs_.type = presentation_type::debug; + } + template FMT_CONSTEXPR auto format(const T& val, FormatContext& ctx) const -> decltype(ctx.out()); }; +#define FMT_FORMAT_AS(Type, Base) \ + template \ + struct formatter : formatter { \ + template \ + auto format(Type const& val, FormatContext& ctx) const \ + -> decltype(ctx.out()) { \ + return formatter::format(static_cast(val), ctx); \ + } \ + } + +FMT_FORMAT_AS(signed char, int); +FMT_FORMAT_AS(unsigned char, unsigned); +FMT_FORMAT_AS(short, int); +FMT_FORMAT_AS(unsigned short, unsigned); +FMT_FORMAT_AS(long, long long); +FMT_FORMAT_AS(unsigned long, unsigned long long); +FMT_FORMAT_AS(Char*, const Char*); +FMT_FORMAT_AS(std::basic_string, basic_string_view); +FMT_FORMAT_AS(std::nullptr_t, const void*); +FMT_FORMAT_AS(detail::std_string_view, basic_string_view); + template struct basic_runtime { basic_string_view str; }; +/** A compile-time format string. */ template class basic_format_string { private: basic_string_view str_; @@ -2832,14 +3145,15 @@ template class basic_format_string { template >::value)> - FMT_CONSTEVAL basic_format_string(const S& s) : str_(s) { + FMT_CONSTEVAL FMT_INLINE basic_format_string(const S& s) : str_(s) { static_assert( detail::count< (std::is_base_of>::value && std::is_reference::value)...>() == 0, "passing views as lvalues is disallowed"); #ifdef FMT_HAS_CONSTEVAL - if constexpr (detail::count_named_args() == 0) { + if constexpr (detail::count_named_args() == + detail::count_statically_named_args()) { using checker = detail::format_string_checker...>; detail::parse_format_string(str_, checker(s, {})); @@ -2855,17 +3169,22 @@ template class basic_format_string { #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 // Workaround broken conversion on older gcc. -template using format_string = string_view; -template auto runtime(const S& s) -> basic_string_view> { - return s; -} +template using format_string = string_view; +inline auto runtime(string_view s) -> string_view { return s; } #else template using format_string = basic_format_string...>; -// Creates a runtime format string. -template auto runtime(const S& s) -> basic_runtime> { - return {{s}}; -} +/** + \rst + Creates a runtime format string. + + **Example**:: + + // Check format string at runtime instead of compile-time. + fmt::print(fmt::runtime("{:d}"), "I am not a number"); + \endrst + */ +inline auto runtime(string_view s) -> basic_runtime { return {{s}}; } #endif FMT_API auto vformat(string_view fmt, format_args args) -> std::string; @@ -2878,11 +3197,12 @@ FMT_API auto vformat(string_view fmt, format_args args) -> std::string; **Example**:: #include - std::string message = fmt::format("The answer is {}", 42); + std::string message = fmt::format("The answer is {}.", 42); \endrst */ template -FMT_INLINE auto format(format_string fmt, T&&... args) -> std::string { +FMT_NODISCARD FMT_INLINE auto format(format_string fmt, T&&... args) + -> std::string { return vformat(fmt, fmt::make_format_args(args...)); } @@ -2892,7 +3212,7 @@ template OutputIt { using detail::get_buffer; auto&& buf = get_buffer(out); - detail::vformat_to(buf, string_view(fmt), args, {}); + detail::vformat_to(buf, fmt, args, {}); return detail::get_iterator(buf); } @@ -2900,7 +3220,7 @@ auto vformat_to(OutputIt out, string_view fmt, format_args args) -> OutputIt { \rst Formats ``args`` according to specifications in ``fmt``, writes the result to the output iterator ``out`` and returns the iterator past the end of the output - range. + range. `format_to` does not append a terminating null character. **Example**:: @@ -2926,9 +3246,8 @@ template ::value)> auto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args) -> format_to_n_result { - using buffer = - detail::iterator_buffer; - auto buf = buffer(out, n); + using traits = detail::fixed_buffer_traits; + auto buf = detail::iterator_buffer(out, n); detail::vformat_to(buf, fmt, args, {}); return {buf.out(), buf.count()}; } @@ -2938,18 +3257,20 @@ auto vformat_to_n(OutputIt out, size_t n, string_view fmt, format_args args) Formats ``args`` according to specifications in ``fmt``, writes up to ``n`` characters of the result to the output iterator ``out`` and returns the total (not truncated) output size and the iterator past the end of the output range. + `format_to_n` does not append a terminating null character. \endrst */ template ::value)> FMT_INLINE auto format_to_n(OutputIt out, size_t n, format_string fmt, - const T&... args) -> format_to_n_result { + T&&... args) -> format_to_n_result { return vformat_to_n(out, n, fmt, fmt::make_format_args(args...)); } /** Returns the number of chars in the output of ``format(fmt, args...)``. */ template -FMT_INLINE auto formatted_size(format_string fmt, T&&... args) -> size_t { +FMT_NODISCARD FMT_INLINE auto formatted_size(format_string fmt, + T&&... args) -> size_t { auto buf = detail::counting_buffer<>(); detail::vformat_to(buf, string_view(fmt), fmt::make_format_args(args...), {}); return buf.count(); diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bundled/fmt.license.rst b/Lumos/External/spdlog/include/spdlog/fmt/bundled/fmt.license.rst new file mode 100644 index 000000000..f0ec3db4d --- /dev/null +++ b/Lumos/External/spdlog/include/spdlog/fmt/bundled/fmt.license.rst @@ -0,0 +1,27 @@ +Copyright (c) 2012 - present, Victor Zverovich + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- Optional exception to the license --- + +As an exception, if, as a result of your compiling your source code, portions +of this Software are embedded into a machine-executable object form of such +source code, you may redistribute such embedded portions in such object form +without including the above copyright and permission notices. diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bundled/format-inl.h b/Lumos/External/spdlog/include/spdlog/fmt/bundled/format-inl.h index 94a36d1bc..22b1ec8df 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/bundled/format-inl.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/bundled/format-inl.h @@ -40,21 +40,12 @@ FMT_FUNC void assert_fail(const char* file, int line, const char* message) { std::terminate(); } -#ifndef _MSC_VER -# define FMT_SNPRINTF snprintf -#else // _MSC_VER -inline int fmt_snprintf(char* buffer, size_t size, const char* format, ...) { - va_list args; - va_start(args, format); - int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args); - va_end(args); - return result; +FMT_FUNC void throw_format_error(const char* message) { + FMT_THROW(format_error(message)); } -# define FMT_SNPRINTF fmt_snprintf -#endif // _MSC_VER FMT_FUNC void format_error_code(detail::buffer& out, int error_code, - string_view message) FMT_NOEXCEPT { + string_view message) noexcept { // Report error code making sure that the output fits into // inline_buffer_size to avoid dynamic memory allocation and potential // bad_alloc. @@ -77,7 +68,7 @@ FMT_FUNC void format_error_code(detail::buffer& out, int error_code, } FMT_FUNC void report_error(format_func func, int error_code, - const char* message) FMT_NOEXCEPT { + const char* message) noexcept { memory_buffer full_message; func(full_message, error_code, message); // Don't use fwrite_fully because the latter may throw. @@ -89,7 +80,8 @@ FMT_FUNC void report_error(format_func func, int error_code, inline void fwrite_fully(const void* ptr, size_t size, size_t count, FILE* stream) { size_t written = std::fwrite(ptr, size, count, stream); - if (written < count) FMT_THROW(system_error(errno, "cannot write to file")); + if (written < count) + FMT_THROW(system_error(errno, FMT_STRING("cannot write to file"))); } #ifndef FMT_STATIC_THOUSANDS_SEPARATOR @@ -125,8 +117,8 @@ template FMT_FUNC Char decimal_point_impl(locale_ref) { #endif } // namespace detail -#if !FMT_MSC_VER -FMT_API FMT_FUNC format_error::~format_error() FMT_NOEXCEPT = default; +#if !FMT_MSC_VERSION +FMT_API FMT_FUNC format_error::~format_error() noexcept = default; #endif FMT_FUNC std::system_error vsystem_error(int error_code, string_view format_str, @@ -137,703 +129,31 @@ FMT_FUNC std::system_error vsystem_error(int error_code, string_view format_str, namespace detail { -template <> FMT_FUNC int count_digits<4>(detail::fallback_uintptr n) { - // fallback_uintptr is always stored in little endian. - int i = static_cast(sizeof(void*)) - 1; - while (i > 0 && n.value[i] == 0) --i; - auto char_digits = std::numeric_limits::digits / 4; - return i >= 0 ? i * char_digits + count_digits<4, unsigned>(n.value[i]) : 1; -} - -#if __cplusplus < 201703L -template constexpr const char basic_data::digits[][2]; -template constexpr const char basic_data::hex_digits[]; -template constexpr const char basic_data::signs[]; -template constexpr const unsigned basic_data::prefixes[]; -template constexpr const char basic_data::left_padding_shifts[]; -template -constexpr const char basic_data::right_padding_shifts[]; -#endif - -template struct bits { - static FMT_CONSTEXPR_DECL const int value = - static_cast(sizeof(T) * std::numeric_limits::digits); -}; - -class fp; -template fp normalize(fp value); - -// Lower (upper) boundary is a value half way between a floating-point value -// and its predecessor (successor). Boundaries have the same exponent as the -// value so only significands are stored. -struct boundaries { - uint64_t lower; - uint64_t upper; -}; - -// A handmade floating-point number f * pow(2, e). -class fp { - private: - using significand_type = uint64_t; - - template - using is_supported_float = bool_constant; - - public: - significand_type f; - int e; - - // All sizes are in bits. - // Subtract 1 to account for an implicit most significant bit in the - // normalized form. - static FMT_CONSTEXPR_DECL const int double_significand_size = - std::numeric_limits::digits - 1; - static FMT_CONSTEXPR_DECL const uint64_t implicit_bit = - 1ULL << double_significand_size; - static FMT_CONSTEXPR_DECL const int significand_size = - bits::value; - - fp() : f(0), e(0) {} - fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {} - - // Constructs fp from an IEEE754 double. It is a template to prevent compile - // errors on platforms where double is not IEEE754. - template explicit fp(Double d) { assign(d); } - - // Assigns d to this and return true iff predecessor is closer than successor. - template ::value)> - bool assign(Float d) { - // Assume float is in the format [sign][exponent][significand]. - using limits = std::numeric_limits; - const int float_significand_size = limits::digits - 1; - const int exponent_size = - bits::value - float_significand_size - 1; // -1 for sign - const uint64_t float_implicit_bit = 1ULL << float_significand_size; - const uint64_t significand_mask = float_implicit_bit - 1; - const uint64_t exponent_mask = (~0ULL >> 1) & ~significand_mask; - const int exponent_bias = (1 << exponent_size) - limits::max_exponent - 1; - constexpr bool is_double = sizeof(Float) == sizeof(uint64_t); - auto u = bit_cast>(d); - f = u & significand_mask; - int biased_e = - static_cast((u & exponent_mask) >> float_significand_size); - // Predecessor is closer if d is a normalized power of 2 (f == 0) other than - // the smallest normalized number (biased_e > 1). - bool is_predecessor_closer = f == 0 && biased_e > 1; - if (biased_e != 0) - f += float_implicit_bit; - else - biased_e = 1; // Subnormals use biased exponent 1 (min exponent). - e = biased_e - exponent_bias - float_significand_size; - return is_predecessor_closer; - } - - template ::value)> - bool assign(Float) { - *this = fp(); - return false; - } -}; - -// Normalizes the value converted from double and multiplied by (1 << SHIFT). -template fp normalize(fp value) { - // Handle subnormals. - const auto shifted_implicit_bit = fp::implicit_bit << SHIFT; - while ((value.f & shifted_implicit_bit) == 0) { - value.f <<= 1; - --value.e; - } - // Subtract 1 to account for hidden bit. - const auto offset = - fp::significand_size - fp::double_significand_size - SHIFT - 1; - value.f <<= offset; - value.e -= offset; - return value; -} - -inline bool operator==(fp x, fp y) { return x.f == y.f && x.e == y.e; } - -// Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking. -inline uint64_t multiply(uint64_t lhs, uint64_t rhs) { -#if FMT_USE_INT128 - auto product = static_cast<__uint128_t>(lhs) * rhs; - auto f = static_cast(product >> 64); - return (static_cast(product) & (1ULL << 63)) != 0 ? f + 1 : f; -#else - // Multiply 32-bit parts of significands. - uint64_t mask = (1ULL << 32) - 1; - uint64_t a = lhs >> 32, b = lhs & mask; - uint64_t c = rhs >> 32, d = rhs & mask; - uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d; - // Compute mid 64-bit of result and round. - uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31); - return ac + (ad >> 32) + (bc >> 32) + (mid >> 32); -#endif -} - -inline fp operator*(fp x, fp y) { return {multiply(x.f, y.f), x.e + y.e + 64}; } - -// Returns a cached power of 10 `c_k = c_k.f * pow(2, c_k.e)` such that its -// (binary) exponent satisfies `min_exponent <= c_k.e <= min_exponent + 28`. -inline fp get_cached_power(int min_exponent, int& pow10_exponent) { - // Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340. - // These are generated by support/compute-powers.py. - static constexpr const uint64_t pow10_significands[] = { - 0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76, - 0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df, - 0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c, - 0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5, - 0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57, - 0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7, - 0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e, - 0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996, - 0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126, - 0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053, - 0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f, - 0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b, - 0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06, - 0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb, - 0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000, - 0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984, - 0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068, - 0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8, - 0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758, - 0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85, - 0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d, - 0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25, - 0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2, - 0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a, - 0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410, - 0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129, - 0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85, - 0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841, - 0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b, - }; - - // Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding - // to significands above. - static constexpr const int16_t pow10_exponents[] = { - -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954, - -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661, - -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369, - -343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77, - -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216, - 242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508, - 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800, - 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066}; - - const int shift = 32; - const auto significand = static_cast(data::log10_2_significand); - int index = static_cast( - ((min_exponent + fp::significand_size - 1) * (significand >> shift) + - ((int64_t(1) << shift) - 1)) // ceil - >> 32 // arithmetic shift - ); - // Decimal exponent of the first (smallest) cached power of 10. - const int first_dec_exp = -348; - // Difference between 2 consecutive decimal exponents in cached powers of 10. - const int dec_exp_step = 8; - index = (index - first_dec_exp - 1) / dec_exp_step + 1; - pow10_exponent = first_dec_exp + index * dec_exp_step; - return {pow10_significands[index], pow10_exponents[index]}; -} - -// A simple accumulator to hold the sums of terms in bigint::square if uint128_t -// is not available. -struct accumulator { - uint64_t lower; - uint64_t upper; - - accumulator() : lower(0), upper(0) {} - explicit operator uint32_t() const { return static_cast(lower); } - - void operator+=(uint64_t n) { - lower += n; - if (lower < n) ++upper; - } - void operator>>=(int shift) { - FMT_ASSERT(shift == 32, ""); - (void)shift; - lower = (upper << 32) | (lower >> 32); - upper >>= 32; - } -}; - -class bigint { - private: - // A bigint is stored as an array of bigits (big digits), with bigit at index - // 0 being the least significant one. - using bigit = uint32_t; - using double_bigit = uint64_t; - enum { bigits_capacity = 32 }; - basic_memory_buffer bigits_; - int exp_; - - bigit operator[](int index) const { return bigits_[to_unsigned(index)]; } - bigit& operator[](int index) { return bigits_[to_unsigned(index)]; } - - static FMT_CONSTEXPR_DECL const int bigit_bits = bits::value; - - friend struct formatter; - - void subtract_bigits(int index, bigit other, bigit& borrow) { - auto result = static_cast((*this)[index]) - other - borrow; - (*this)[index] = static_cast(result); - borrow = static_cast(result >> (bigit_bits * 2 - 1)); - } - - void remove_leading_zeros() { - int num_bigits = static_cast(bigits_.size()) - 1; - while (num_bigits > 0 && (*this)[num_bigits] == 0) --num_bigits; - bigits_.resize(to_unsigned(num_bigits + 1)); - } - - // Computes *this -= other assuming aligned bigints and *this >= other. - void subtract_aligned(const bigint& other) { - FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints"); - FMT_ASSERT(compare(*this, other) >= 0, ""); - bigit borrow = 0; - int i = other.exp_ - exp_; - for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j) - subtract_bigits(i, other.bigits_[j], borrow); - while (borrow > 0) subtract_bigits(i, 0, borrow); - remove_leading_zeros(); - } - - void multiply(uint32_t value) { - const double_bigit wide_value = value; - bigit carry = 0; - for (size_t i = 0, n = bigits_.size(); i < n; ++i) { - double_bigit result = bigits_[i] * wide_value + carry; - bigits_[i] = static_cast(result); - carry = static_cast(result >> bigit_bits); - } - if (carry != 0) bigits_.push_back(carry); - } - - void multiply(uint64_t value) { - const bigit mask = ~bigit(0); - const double_bigit lower = value & mask; - const double_bigit upper = value >> bigit_bits; - double_bigit carry = 0; - for (size_t i = 0, n = bigits_.size(); i < n; ++i) { - double_bigit result = bigits_[i] * lower + (carry & mask); - carry = - bigits_[i] * upper + (result >> bigit_bits) + (carry >> bigit_bits); - bigits_[i] = static_cast(result); - } - while (carry != 0) { - bigits_.push_back(carry & mask); - carry >>= bigit_bits; - } - } - - public: - bigint() : exp_(0) {} - explicit bigint(uint64_t n) { assign(n); } - ~bigint() { FMT_ASSERT(bigits_.capacity() <= bigits_capacity, ""); } - - bigint(const bigint&) = delete; - void operator=(const bigint&) = delete; - - void assign(const bigint& other) { - auto size = other.bigits_.size(); - bigits_.resize(size); - auto data = other.bigits_.data(); - std::copy(data, data + size, make_checked(bigits_.data(), size)); - exp_ = other.exp_; - } - - void assign(uint64_t n) { - size_t num_bigits = 0; - do { - bigits_[num_bigits++] = n & ~bigit(0); - n >>= bigit_bits; - } while (n != 0); - bigits_.resize(num_bigits); - exp_ = 0; - } - - int num_bigits() const { return static_cast(bigits_.size()) + exp_; } - - FMT_NOINLINE bigint& operator<<=(int shift) { - FMT_ASSERT(shift >= 0, ""); - exp_ += shift / bigit_bits; - shift %= bigit_bits; - if (shift == 0) return *this; - bigit carry = 0; - for (size_t i = 0, n = bigits_.size(); i < n; ++i) { - bigit c = bigits_[i] >> (bigit_bits - shift); - bigits_[i] = (bigits_[i] << shift) + carry; - carry = c; - } - if (carry != 0) bigits_.push_back(carry); - return *this; - } - - template bigint& operator*=(Int value) { - FMT_ASSERT(value > 0, ""); - multiply(uint32_or_64_or_128_t(value)); - return *this; - } - - friend int compare(const bigint& lhs, const bigint& rhs) { - int num_lhs_bigits = lhs.num_bigits(), num_rhs_bigits = rhs.num_bigits(); - if (num_lhs_bigits != num_rhs_bigits) - return num_lhs_bigits > num_rhs_bigits ? 1 : -1; - int i = static_cast(lhs.bigits_.size()) - 1; - int j = static_cast(rhs.bigits_.size()) - 1; - int end = i - j; - if (end < 0) end = 0; - for (; i >= end; --i, --j) { - bigit lhs_bigit = lhs[i], rhs_bigit = rhs[j]; - if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1; - } - if (i != j) return i > j ? 1 : -1; - return 0; - } - - // Returns compare(lhs1 + lhs2, rhs). - friend int add_compare(const bigint& lhs1, const bigint& lhs2, - const bigint& rhs) { - int max_lhs_bigits = (std::max)(lhs1.num_bigits(), lhs2.num_bigits()); - int num_rhs_bigits = rhs.num_bigits(); - if (max_lhs_bigits + 1 < num_rhs_bigits) return -1; - if (max_lhs_bigits > num_rhs_bigits) return 1; - auto get_bigit = [](const bigint& n, int i) -> bigit { - return i >= n.exp_ && i < n.num_bigits() ? n[i - n.exp_] : 0; - }; - double_bigit borrow = 0; - int min_exp = (std::min)((std::min)(lhs1.exp_, lhs2.exp_), rhs.exp_); - for (int i = num_rhs_bigits - 1; i >= min_exp; --i) { - double_bigit sum = - static_cast(get_bigit(lhs1, i)) + get_bigit(lhs2, i); - bigit rhs_bigit = get_bigit(rhs, i); - if (sum > rhs_bigit + borrow) return 1; - borrow = rhs_bigit + borrow - sum; - if (borrow > 1) return -1; - borrow <<= bigit_bits; - } - return borrow != 0 ? -1 : 0; - } - - // Assigns pow(10, exp) to this bigint. - void assign_pow10(int exp) { - FMT_ASSERT(exp >= 0, ""); - if (exp == 0) return assign(1); - // Find the top bit. - int bitmask = 1; - while (exp >= bitmask) bitmask <<= 1; - bitmask >>= 1; - // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by - // repeated squaring and multiplication. - assign(5); - bitmask >>= 1; - while (bitmask != 0) { - square(); - if ((exp & bitmask) != 0) *this *= 5; - bitmask >>= 1; - } - *this <<= exp; // Multiply by pow(2, exp) by shifting. - } - - void square() { - int num_bigits = static_cast(bigits_.size()); - int num_result_bigits = 2 * num_bigits; - basic_memory_buffer n(std::move(bigits_)); - bigits_.resize(to_unsigned(num_result_bigits)); - using accumulator_t = conditional_t; - auto sum = accumulator_t(); - for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) { - // Compute bigit at position bigit_index of the result by adding - // cross-product terms n[i] * n[j] such that i + j == bigit_index. - for (int i = 0, j = bigit_index; j >= 0; ++i, --j) { - // Most terms are multiplied twice which can be optimized in the future. - sum += static_cast(n[i]) * n[j]; - } - (*this)[bigit_index] = static_cast(sum); - sum >>= bits::value; // Compute the carry. - } - // Do the same for the top half. - for (int bigit_index = num_bigits; bigit_index < num_result_bigits; - ++bigit_index) { - for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;) - sum += static_cast(n[i++]) * n[j--]; - (*this)[bigit_index] = static_cast(sum); - sum >>= bits::value; - } - remove_leading_zeros(); - exp_ *= 2; - } - - // If this bigint has a bigger exponent than other, adds trailing zero to make - // exponents equal. This simplifies some operations such as subtraction. - void align(const bigint& other) { - int exp_difference = exp_ - other.exp_; - if (exp_difference <= 0) return; - int num_bigits = static_cast(bigits_.size()); - bigits_.resize(to_unsigned(num_bigits + exp_difference)); - for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j) - bigits_[j] = bigits_[i]; - std::uninitialized_fill_n(bigits_.data(), exp_difference, 0); - exp_ -= exp_difference; - } - - // Divides this bignum by divisor, assigning the remainder to this and - // returning the quotient. - int divmod_assign(const bigint& divisor) { - FMT_ASSERT(this != &divisor, ""); - if (compare(*this, divisor) < 0) return 0; - FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, ""); - align(divisor); - int quotient = 0; - do { - subtract_aligned(divisor); - ++quotient; - } while (compare(*this, divisor) >= 0); - return quotient; - } -}; - -enum class round_direction { unknown, up, down }; - -// Given the divisor (normally a power of 10), the remainder = v % divisor for -// some number v and the error, returns whether v should be rounded up, down, or -// whether the rounding direction can't be determined due to error. -// error should be less than divisor / 2. -inline round_direction get_round_direction(uint64_t divisor, uint64_t remainder, - uint64_t error) { - FMT_ASSERT(remainder < divisor, ""); // divisor - remainder won't overflow. - FMT_ASSERT(error < divisor, ""); // divisor - error won't overflow. - FMT_ASSERT(error < divisor - error, ""); // error * 2 won't overflow. - // Round down if (remainder + error) * 2 <= divisor. - if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2) - return round_direction::down; - // Round up if (remainder - error) * 2 >= divisor. - if (remainder >= error && - remainder - error >= divisor - (remainder - error)) { - return round_direction::up; - } - return round_direction::unknown; -} - -namespace digits { -enum result { - more, // Generate more digits. - done, // Done generating digits. - error // Digit generation cancelled due to an error. -}; +template inline bool operator==(basic_fp x, basic_fp y) { + return x.f == y.f && x.e == y.e; } -inline uint64_t power_of_10_64(int exp) { - static constexpr const uint64_t data[] = {1, FMT_POWERS_OF_10(1), - FMT_POWERS_OF_10(1000000000ULL), - 10000000000000000000ULL}; - return data[exp]; +// Compilers should be able to optimize this into the ror instruction. +FMT_CONSTEXPR inline uint32_t rotr(uint32_t n, uint32_t r) noexcept { + r &= 31; + return (n >> r) | (n << (32 - r)); } - -// Generates output using the Grisu digit-gen algorithm. -// error: the size of the region (lower, upper) outside of which numbers -// definitely do not round to value (Delta in Grisu3). -template -FMT_INLINE digits::result grisu_gen_digits(fp value, uint64_t error, int& exp, - Handler& handler) { - const fp one(1ULL << -value.e, value.e); - // The integral part of scaled value (p1 in Grisu) = value / one. It cannot be - // zero because it contains a product of two 64-bit numbers with MSB set (due - // to normalization) - 1, shifted right by at most 60 bits. - auto integral = static_cast(value.f >> -one.e); - FMT_ASSERT(integral != 0, ""); - FMT_ASSERT(integral == value.f >> -one.e, ""); - // The fractional part of scaled value (p2 in Grisu) c = value % one. - uint64_t fractional = value.f & (one.f - 1); - exp = count_digits(integral); // kappa in Grisu. - // Divide by 10 to prevent overflow. - auto result = handler.on_start(power_of_10_64(exp - 1) << -one.e, - value.f / 10, error * 10, exp); - if (result != digits::more) return result; - // Generate digits for the integral part. This can produce up to 10 digits. - do { - uint32_t digit = 0; - auto divmod_integral = [&](uint32_t divisor) { - digit = integral / divisor; - integral %= divisor; - }; - // This optimization by Milo Yip reduces the number of integer divisions by - // one per iteration. - switch (exp) { - case 10: - divmod_integral(1000000000); - break; - case 9: - divmod_integral(100000000); - break; - case 8: - divmod_integral(10000000); - break; - case 7: - divmod_integral(1000000); - break; - case 6: - divmod_integral(100000); - break; - case 5: - divmod_integral(10000); - break; - case 4: - divmod_integral(1000); - break; - case 3: - divmod_integral(100); - break; - case 2: - divmod_integral(10); - break; - case 1: - digit = integral; - integral = 0; - break; - default: - FMT_ASSERT(false, "invalid number of digits"); - } - --exp; - auto remainder = (static_cast(integral) << -one.e) + fractional; - result = handler.on_digit(static_cast('0' + digit), - power_of_10_64(exp) << -one.e, remainder, error, - exp, true); - if (result != digits::more) return result; - } while (exp > 0); - // Generate digits for the fractional part. - for (;;) { - fractional *= 10; - error *= 10; - char digit = static_cast('0' + (fractional >> -one.e)); - fractional &= one.f - 1; - --exp; - result = handler.on_digit(digit, one.f, fractional, error, exp, false); - if (result != digits::more) return result; - } +FMT_CONSTEXPR inline uint64_t rotr(uint64_t n, uint32_t r) noexcept { + r &= 63; + return (n >> r) | (n << (64 - r)); } -// The fixed precision digit handler. -struct fixed_handler { - char* buf; - int size; - int precision; - int exp10; - bool fixed; - - digits::result on_start(uint64_t divisor, uint64_t remainder, uint64_t error, - int& exp) { - // Non-fixed formats require at least one digit and no precision adjustment. - if (!fixed) return digits::more; - // Adjust fixed precision by exponent because it is relative to decimal - // point. - precision += exp + exp10; - // Check if precision is satisfied just by leading zeros, e.g. - // format("{:.2f}", 0.001) gives "0.00" without generating any digits. - if (precision > 0) return digits::more; - if (precision < 0) return digits::done; - auto dir = get_round_direction(divisor, remainder, error); - if (dir == round_direction::unknown) return digits::error; - buf[size++] = dir == round_direction::up ? '1' : '0'; - return digits::done; - } - - digits::result on_digit(char digit, uint64_t divisor, uint64_t remainder, - uint64_t error, int, bool integral) { - FMT_ASSERT(remainder < divisor, ""); - buf[size++] = digit; - if (!integral && error >= remainder) return digits::error; - if (size < precision) return digits::more; - if (!integral) { - // Check if error * 2 < divisor with overflow prevention. - // The check is not needed for the integral part because error = 1 - // and divisor > (1 << 32) there. - if (error >= divisor || error >= divisor - error) return digits::error; - } else { - FMT_ASSERT(error == 1 && divisor > 2, ""); - } - auto dir = get_round_direction(divisor, remainder, error); - if (dir != round_direction::up) - return dir == round_direction::down ? digits::done : digits::error; - ++buf[size - 1]; - for (int i = size - 1; i > 0 && buf[i] > '9'; --i) { - buf[i] = '0'; - ++buf[i - 1]; - } - if (buf[0] > '9') { - buf[0] = '1'; - if (fixed) - buf[size++] = '0'; - else - ++exp10; - } - return digits::done; - } -}; - -// A 128-bit integer type used internally, -struct uint128_wrapper { - uint128_wrapper() = default; - -#if FMT_USE_INT128 - uint128_t internal_; - - constexpr uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT - : internal_{static_cast(low) | - (static_cast(high) << 64)} {} - - constexpr uint128_wrapper(uint128_t u) : internal_{u} {} - - constexpr uint64_t high() const FMT_NOEXCEPT { - return uint64_t(internal_ >> 64); - } - constexpr uint64_t low() const FMT_NOEXCEPT { return uint64_t(internal_); } - - uint128_wrapper& operator+=(uint64_t n) FMT_NOEXCEPT { - internal_ += n; - return *this; - } -#else - uint64_t high_; - uint64_t low_; - - constexpr uint128_wrapper(uint64_t high, uint64_t low) FMT_NOEXCEPT - : high_{high}, - low_{low} {} - - constexpr uint64_t high() const FMT_NOEXCEPT { return high_; } - constexpr uint64_t low() const FMT_NOEXCEPT { return low_; } - - uint128_wrapper& operator+=(uint64_t n) FMT_NOEXCEPT { -# if defined(_MSC_VER) && defined(_M_X64) - unsigned char carry = _addcarry_u64(0, low_, n, &low_); - _addcarry_u64(carry, high_, 0, &high_); - return *this; -# else - uint64_t sum = low_ + n; - high_ += (sum < low_ ? 1 : 0); - low_ = sum; - return *this; -# endif - } -#endif -}; - -// Implementation of Dragonbox algorithm: https://github.com/jk-jeon/dragonbox. -namespace dragonbox { // Computes 128-bit result of multiplication of two 64-bit unsigned integers. -inline uint128_wrapper umul128(uint64_t x, uint64_t y) FMT_NOEXCEPT { +inline uint128_fallback umul128(uint64_t x, uint64_t y) noexcept { #if FMT_USE_INT128 - return static_cast(x) * static_cast(y); + auto p = static_cast(x) * static_cast(y); + return {static_cast(p >> 64), static_cast(p)}; #elif defined(_MSC_VER) && defined(_M_X64) - uint128_wrapper result; - result.low_ = _umul128(x, y, &result.high_); + auto result = uint128_fallback(); + result.lo_ = _umul128(x, y, &result.hi_); return result; #else - const uint64_t mask = (uint64_t(1) << 32) - uint64_t(1); + const uint64_t mask = static_cast(max_value()); uint64_t a = x >> 32; uint64_t b = x & mask; @@ -852,10 +172,12 @@ inline uint128_wrapper umul128(uint64_t x, uint64_t y) FMT_NOEXCEPT { #endif } +// Implementation of Dragonbox algorithm: https://github.com/jk-jeon/dragonbox. +namespace dragonbox { // Computes upper 64 bits of multiplication of two 64-bit unsigned integers. -inline uint64_t umul128_upper64(uint64_t x, uint64_t y) FMT_NOEXCEPT { +inline uint64_t umul128_upper64(uint64_t x, uint64_t y) noexcept { #if FMT_USE_INT128 - auto p = static_cast(x) * static_cast(y); + auto p = static_cast(x) * static_cast(y); return static_cast(p >> 64); #elif defined(_MSC_VER) && defined(_M_X64) return __umulh(x, y); @@ -864,172 +186,105 @@ inline uint64_t umul128_upper64(uint64_t x, uint64_t y) FMT_NOEXCEPT { #endif } -// Computes upper 64 bits of multiplication of a 64-bit unsigned integer and a +// Computes upper 128 bits of multiplication of a 64-bit unsigned integer and a // 128-bit unsigned integer. -inline uint64_t umul192_upper64(uint64_t x, uint128_wrapper y) FMT_NOEXCEPT { - uint128_wrapper g0 = umul128(x, y.high()); - g0 += umul128_upper64(x, y.low()); - return g0.high(); +inline uint128_fallback umul192_upper128(uint64_t x, + uint128_fallback y) noexcept { + uint128_fallback r = umul128(x, y.high()); + r += umul128_upper64(x, y.low()); + return r; } -// Computes upper 32 bits of multiplication of a 32-bit unsigned integer and a +// Computes upper 64 bits of multiplication of a 32-bit unsigned integer and a // 64-bit unsigned integer. -inline uint32_t umul96_upper32(uint32_t x, uint64_t y) FMT_NOEXCEPT { - return static_cast(umul128_upper64(x, y)); +inline uint64_t umul96_upper64(uint32_t x, uint64_t y) noexcept { + return umul128_upper64(static_cast(x) << 32, y); } -// Computes middle 64 bits of multiplication of a 64-bit unsigned integer and a +// Computes lower 128 bits of multiplication of a 64-bit unsigned integer and a // 128-bit unsigned integer. -inline uint64_t umul192_middle64(uint64_t x, uint128_wrapper y) FMT_NOEXCEPT { - uint64_t g01 = x * y.high(); - uint64_t g10 = umul128_upper64(x, y.low()); - return g01 + g10; +inline uint128_fallback umul192_lower128(uint64_t x, + uint128_fallback y) noexcept { + uint64_t high = x * y.high(); + uint128_fallback high_low = umul128(x, y.low()); + return {high + high_low.high(), high_low.low()}; } // Computes lower 64 bits of multiplication of a 32-bit unsigned integer and a // 64-bit unsigned integer. -inline uint64_t umul96_lower64(uint32_t x, uint64_t y) FMT_NOEXCEPT { +inline uint64_t umul96_lower64(uint32_t x, uint64_t y) noexcept { return x * y; } -// Computes floor(log10(pow(2, e))) for e in [-1700, 1700] using the method from -// https://fmt.dev/papers/Grisu-Exact.pdf#page=5, section 3.4. -inline int floor_log10_pow2(int e) FMT_NOEXCEPT { - FMT_ASSERT(e <= 1700 && e >= -1700, "too large exponent"); - const int shift = 22; - return (e * static_cast(data::log10_2_significand >> (64 - shift))) >> - shift; +// Computes floor(log10(pow(2, e))) for e in [-2620, 2620] using the method from +// https://fmt.dev/papers/Dragonbox.pdf#page=28, section 6.1. +inline int floor_log10_pow2(int e) noexcept { + FMT_ASSERT(e <= 2620 && e >= -2620, "too large exponent"); + static_assert((-1 >> 1) == -1, "right shift is not arithmetic"); + return (e * 315653) >> 20; } // Various fast log computations. -inline int floor_log2_pow10(int e) FMT_NOEXCEPT { +inline int floor_log2_pow10(int e) noexcept { FMT_ASSERT(e <= 1233 && e >= -1233, "too large exponent"); - const uint64_t log2_10_integer_part = 3; - const uint64_t log2_10_fractional_digits = 0x5269e12f346e2bf9; - const int shift_amount = 19; - return (e * static_cast( - (log2_10_integer_part << shift_amount) | - (log2_10_fractional_digits >> (64 - shift_amount)))) >> - shift_amount; + return (e * 1741647) >> 19; } -inline int floor_log10_pow2_minus_log10_4_over_3(int e) FMT_NOEXCEPT { - FMT_ASSERT(e <= 1700 && e >= -1700, "too large exponent"); - const uint64_t log10_4_over_3_fractional_digits = 0x1ffbfc2bbc780375; - const int shift_amount = 22; - return (e * static_cast(data::log10_2_significand >> - (64 - shift_amount)) - - static_cast(log10_4_over_3_fractional_digits >> - (64 - shift_amount))) >> - shift_amount; +inline int floor_log10_pow2_minus_log10_4_over_3(int e) noexcept { + FMT_ASSERT(e <= 2936 && e >= -2985, "too large exponent"); + return (e * 631305 - 261663) >> 21; } -// Returns true iff x is divisible by pow(2, exp). -inline bool divisible_by_power_of_2(uint32_t x, int exp) FMT_NOEXCEPT { - FMT_ASSERT(exp >= 1, ""); - FMT_ASSERT(x != 0, ""); -#ifdef FMT_BUILTIN_CTZ - return FMT_BUILTIN_CTZ(x) >= exp; -#else - return exp < num_bits() && x == ((x >> exp) << exp); -#endif -} -inline bool divisible_by_power_of_2(uint64_t x, int exp) FMT_NOEXCEPT { - FMT_ASSERT(exp >= 1, ""); - FMT_ASSERT(x != 0, ""); -#ifdef FMT_BUILTIN_CTZLL - return FMT_BUILTIN_CTZLL(x) >= exp; -#else - return exp < num_bits() && x == ((x >> exp) << exp); -#endif -} - -// Table entry type for divisibility test. -template struct divtest_table_entry { - T mod_inv; - T max_quotient; -}; +static constexpr struct { + uint32_t divisor; + int shift_amount; +} div_small_pow10_infos[] = {{10, 16}, {100, 16}}; -// Returns true iff x is divisible by pow(5, exp). -inline bool divisible_by_power_of_5(uint32_t x, int exp) FMT_NOEXCEPT { - FMT_ASSERT(exp <= 10, "too large exponent"); - static constexpr const divtest_table_entry divtest_table[] = { - {0x00000001, 0xffffffff}, {0xcccccccd, 0x33333333}, - {0xc28f5c29, 0x0a3d70a3}, {0x26e978d5, 0x020c49ba}, - {0x3afb7e91, 0x0068db8b}, {0x0bcbe61d, 0x0014f8b5}, - {0x68c26139, 0x000431bd}, {0xae8d46a5, 0x0000d6bf}, - {0x22e90e21, 0x00002af3}, {0x3a2e9c6d, 0x00000897}, - {0x3ed61f49, 0x000001b7}}; - return x * divtest_table[exp].mod_inv <= divtest_table[exp].max_quotient; -} -inline bool divisible_by_power_of_5(uint64_t x, int exp) FMT_NOEXCEPT { - FMT_ASSERT(exp <= 23, "too large exponent"); - static constexpr const divtest_table_entry divtest_table[] = { - {0x0000000000000001, 0xffffffffffffffff}, - {0xcccccccccccccccd, 0x3333333333333333}, - {0x8f5c28f5c28f5c29, 0x0a3d70a3d70a3d70}, - {0x1cac083126e978d5, 0x020c49ba5e353f7c}, - {0xd288ce703afb7e91, 0x0068db8bac710cb2}, - {0x5d4e8fb00bcbe61d, 0x0014f8b588e368f0}, - {0x790fb65668c26139, 0x000431bde82d7b63}, - {0xe5032477ae8d46a5, 0x0000d6bf94d5e57a}, - {0xc767074b22e90e21, 0x00002af31dc46118}, - {0x8e47ce423a2e9c6d, 0x0000089705f4136b}, - {0x4fa7f60d3ed61f49, 0x000001b7cdfd9d7b}, - {0x0fee64690c913975, 0x00000057f5ff85e5}, - {0x3662e0e1cf503eb1, 0x000000119799812d}, - {0xa47a2cf9f6433fbd, 0x0000000384b84d09}, - {0x54186f653140a659, 0x00000000b424dc35}, - {0x7738164770402145, 0x0000000024075f3d}, - {0xe4a4d1417cd9a041, 0x000000000734aca5}, - {0xc75429d9e5c5200d, 0x000000000170ef54}, - {0xc1773b91fac10669, 0x000000000049c977}, - {0x26b172506559ce15, 0x00000000000ec1e4}, - {0xd489e3a9addec2d1, 0x000000000002f394}, - {0x90e860bb892c8d5d, 0x000000000000971d}, - {0x502e79bf1b6f4f79, 0x0000000000001e39}, - {0xdcd618596be30fe5, 0x000000000000060b}}; - return x * divtest_table[exp].mod_inv <= divtest_table[exp].max_quotient; -} - -// Replaces n by floor(n / pow(5, N)) returning true if and only if n is -// divisible by pow(5, N). -// Precondition: n <= 2 * pow(5, N + 1). +// Replaces n by floor(n / pow(10, N)) returning true if and only if n is +// divisible by pow(10, N). +// Precondition: n <= pow(10, N + 1). template -bool check_divisibility_and_divide_by_pow5(uint32_t& n) FMT_NOEXCEPT { - static constexpr struct { - uint32_t magic_number; - int bits_for_comparison; - uint32_t threshold; - int shift_amount; - } infos[] = {{0xcccd, 16, 0x3333, 18}, {0xa429, 8, 0x0a, 20}}; - constexpr auto info = infos[N - 1]; - n *= info.magic_number; - const uint32_t comparison_mask = (1u << info.bits_for_comparison) - 1; - bool result = (n & comparison_mask) <= info.threshold; +bool check_divisibility_and_divide_by_pow10(uint32_t& n) noexcept { + // The numbers below are chosen such that: + // 1. floor(n/d) = floor(nm / 2^k) where d=10 or d=100, + // 2. nm mod 2^k < m if and only if n is divisible by d, + // where m is magic_number, k is shift_amount + // and d is divisor. + // + // Item 1 is a common technique of replacing division by a constant with + // multiplication, see e.g. "Division by Invariant Integers Using + // Multiplication" by Granlund and Montgomery (1994). magic_number (m) is set + // to ceil(2^k/d) for large enough k. + // The idea for item 2 originates from Schubfach. + constexpr auto info = div_small_pow10_infos[N - 1]; + FMT_ASSERT(n <= info.divisor * 10, "n is too large"); + constexpr uint32_t magic_number = + (1u << info.shift_amount) / info.divisor + 1; + n *= magic_number; + const uint32_t comparison_mask = (1u << info.shift_amount) - 1; + bool result = (n & comparison_mask) < magic_number; n >>= info.shift_amount; return result; } // Computes floor(n / pow(10, N)) for small n and N. // Precondition: n <= pow(10, N + 1). -template uint32_t small_division_by_pow10(uint32_t n) FMT_NOEXCEPT { - static constexpr struct { - uint32_t magic_number; - int shift_amount; - uint32_t divisor_times_10; - } infos[] = {{0xcccd, 19, 100}, {0xa3d8, 22, 1000}}; - constexpr auto info = infos[N - 1]; - FMT_ASSERT(n <= info.divisor_times_10, "n is too large"); - return n * info.magic_number >> info.shift_amount; +template uint32_t small_division_by_pow10(uint32_t n) noexcept { + constexpr auto info = div_small_pow10_infos[N - 1]; + FMT_ASSERT(n <= info.divisor * 10, "n is too large"); + constexpr uint32_t magic_number = + (1u << info.shift_amount) / info.divisor + 1; + return (n * magic_number) >> info.shift_amount; } // Computes floor(n / 10^(kappa + 1)) (float) -inline uint32_t divide_by_10_to_kappa_plus_1(uint32_t n) FMT_NOEXCEPT { - return n / float_info::big_divisor; +inline uint32_t divide_by_10_to_kappa_plus_1(uint32_t n) noexcept { + // 1374389535 = ceil(2^37/100) + return static_cast((static_cast(n) * 1374389535) >> 37); } // Computes floor(n / 10^(kappa + 1)) (double) -inline uint64_t divide_by_10_to_kappa_plus_1(uint64_t n) FMT_NOEXCEPT { - return umul128_upper64(n, 0x83126e978d4fdf3c) >> 9; +inline uint64_t divide_by_10_to_kappa_plus_1(uint64_t n) noexcept { + // 2361183241434822607 = ceil(2^(64+7)/1000) + return umul128_upper64(n, 2361183241434822607ull) >> 7; } // Various subroutines using pow10 cache @@ -1039,10 +294,10 @@ template <> struct cache_accessor { using carrier_uint = float_info::carrier_uint; using cache_entry_type = uint64_t; - static uint64_t get_cached_power(int k) FMT_NOEXCEPT { + static uint64_t get_cached_power(int k) noexcept { FMT_ASSERT(k >= float_info::min_k && k <= float_info::max_k, "k is out of range"); - constexpr const uint64_t pow10_significands[] = { + static constexpr const uint64_t pow10_significands[] = { 0x81ceb32c4b43fcf5, 0xa2425ff75e14fc32, 0xcad2f7f5359a3b3f, 0xfd87b5f28300ca0e, 0x9e74d1b791e07e49, 0xc612062576589ddb, 0xf79687aed3eec552, 0x9abe14cd44753b53, 0xc16d9a0095928a28, @@ -1062,54 +317,65 @@ template <> struct cache_accessor { 0xb1a2bc2ec5000000, 0xde0b6b3a76400000, 0x8ac7230489e80000, 0xad78ebc5ac620000, 0xd8d726b7177a8000, 0x878678326eac9000, 0xa968163f0a57b400, 0xd3c21bcecceda100, 0x84595161401484a0, - 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940984, - 0xa18f07d736b90be5, 0xc9f2c9cd04674ede, 0xfc6f7c4045812296, - 0x9dc5ada82b70b59d, 0xc5371912364ce305, 0xf684df56c3e01bc6, - 0x9a130b963a6c115c, 0xc097ce7bc90715b3, 0xf0bdc21abb48db20, - 0x96769950b50d88f4, 0xbc143fa4e250eb31, 0xeb194f8e1ae525fd, - 0x92efd1b8d0cf37be, 0xb7abc627050305ad, 0xe596b7b0c643c719, - 0x8f7e32ce7bea5c6f, 0xb35dbf821ae4f38b, 0xe0352f62a19e306e}; + 0xa56fa5b99019a5c8, 0xcecb8f27f4200f3a, 0x813f3978f8940985, + 0xa18f07d736b90be6, 0xc9f2c9cd04674edf, 0xfc6f7c4045812297, + 0x9dc5ada82b70b59e, 0xc5371912364ce306, 0xf684df56c3e01bc7, + 0x9a130b963a6c115d, 0xc097ce7bc90715b4, 0xf0bdc21abb48db21, + 0x96769950b50d88f5, 0xbc143fa4e250eb32, 0xeb194f8e1ae525fe, + 0x92efd1b8d0cf37bf, 0xb7abc627050305ae, 0xe596b7b0c643c71a, + 0x8f7e32ce7bea5c70, 0xb35dbf821ae4f38c, 0xe0352f62a19e306f}; return pow10_significands[k - float_info::min_k]; } - static carrier_uint compute_mul(carrier_uint u, - const cache_entry_type& cache) FMT_NOEXCEPT { - return umul96_upper32(u, cache); + struct compute_mul_result { + carrier_uint result; + bool is_integer; + }; + struct compute_mul_parity_result { + bool parity; + bool is_integer; + }; + + static compute_mul_result compute_mul( + carrier_uint u, const cache_entry_type& cache) noexcept { + auto r = umul96_upper64(u, cache); + return {static_cast(r >> 32), + static_cast(r) == 0}; } static uint32_t compute_delta(const cache_entry_type& cache, - int beta_minus_1) FMT_NOEXCEPT { - return static_cast(cache >> (64 - 1 - beta_minus_1)); + int beta) noexcept { + return static_cast(cache >> (64 - 1 - beta)); } - static bool compute_mul_parity(carrier_uint two_f, - const cache_entry_type& cache, - int beta_minus_1) FMT_NOEXCEPT { - FMT_ASSERT(beta_minus_1 >= 1, ""); - FMT_ASSERT(beta_minus_1 < 64, ""); + static compute_mul_parity_result compute_mul_parity( + carrier_uint two_f, const cache_entry_type& cache, int beta) noexcept { + FMT_ASSERT(beta >= 1, ""); + FMT_ASSERT(beta < 64, ""); - return ((umul96_lower64(two_f, cache) >> (64 - beta_minus_1)) & 1) != 0; + auto r = umul96_lower64(two_f, cache); + return {((r >> (64 - beta)) & 1) != 0, + static_cast(r >> (32 - beta)) == 0}; } static carrier_uint compute_left_endpoint_for_shorter_interval_case( - const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + const cache_entry_type& cache, int beta) noexcept { return static_cast( - (cache - (cache >> (float_info::significand_bits + 2))) >> - (64 - float_info::significand_bits - 1 - beta_minus_1)); + (cache - (cache >> (num_significand_bits() + 2))) >> + (64 - num_significand_bits() - 1 - beta)); } static carrier_uint compute_right_endpoint_for_shorter_interval_case( - const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + const cache_entry_type& cache, int beta) noexcept { return static_cast( - (cache + (cache >> (float_info::significand_bits + 1))) >> - (64 - float_info::significand_bits - 1 - beta_minus_1)); + (cache + (cache >> (num_significand_bits() + 1))) >> + (64 - num_significand_bits() - 1 - beta)); } static carrier_uint compute_round_up_for_shorter_interval_case( - const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + const cache_entry_type& cache, int beta) noexcept { return (static_cast( - cache >> - (64 - float_info::significand_bits - 2 - beta_minus_1)) + + cache >> (64 - num_significand_bits() - 2 - beta)) + 1) / 2; } @@ -1117,13 +383,13 @@ template <> struct cache_accessor { template <> struct cache_accessor { using carrier_uint = float_info::carrier_uint; - using cache_entry_type = uint128_wrapper; + using cache_entry_type = uint128_fallback; - static uint128_wrapper get_cached_power(int k) FMT_NOEXCEPT { + static uint128_fallback get_cached_power(int k) noexcept { FMT_ASSERT(k >= float_info::min_k && k <= float_info::max_k, "k is out of range"); - static constexpr const uint128_wrapper pow10_significands[] = { + static constexpr const uint128_fallback pow10_significands[] = { #if FMT_USE_FULL_CACHE_DRAGONBOX {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b}, {0x9faacf3df73609b1, 0x77b191618c54e9ad}, @@ -1473,278 +739,278 @@ template <> struct cache_accessor { {0x85a36366eb71f041, 0x47a6da2b7f864750}, {0xa70c3c40a64e6c51, 0x999090b65f67d924}, {0xd0cf4b50cfe20765, 0xfff4b4e3f741cf6d}, - {0x82818f1281ed449f, 0xbff8f10e7a8921a4}, - {0xa321f2d7226895c7, 0xaff72d52192b6a0d}, - {0xcbea6f8ceb02bb39, 0x9bf4f8a69f764490}, - {0xfee50b7025c36a08, 0x02f236d04753d5b4}, - {0x9f4f2726179a2245, 0x01d762422c946590}, - {0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef5}, - {0xf8ebad2b84e0d58b, 0xd2e0898765a7deb2}, - {0x9b934c3b330c8577, 0x63cc55f49f88eb2f}, - {0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fb}, - {0xf316271c7fc3908a, 0x8bef464e3945ef7a}, - {0x97edd871cfda3a56, 0x97758bf0e3cbb5ac}, - {0xbde94e8e43d0c8ec, 0x3d52eeed1cbea317}, - {0xed63a231d4c4fb27, 0x4ca7aaa863ee4bdd}, - {0x945e455f24fb1cf8, 0x8fe8caa93e74ef6a}, - {0xb975d6b6ee39e436, 0xb3e2fd538e122b44}, - {0xe7d34c64a9c85d44, 0x60dbbca87196b616}, - {0x90e40fbeea1d3a4a, 0xbc8955e946fe31cd}, - {0xb51d13aea4a488dd, 0x6babab6398bdbe41}, - {0xe264589a4dcdab14, 0xc696963c7eed2dd1}, - {0x8d7eb76070a08aec, 0xfc1e1de5cf543ca2}, - {0xb0de65388cc8ada8, 0x3b25a55f43294bcb}, - {0xdd15fe86affad912, 0x49ef0eb713f39ebe}, - {0x8a2dbf142dfcc7ab, 0x6e3569326c784337}, - {0xacb92ed9397bf996, 0x49c2c37f07965404}, - {0xd7e77a8f87daf7fb, 0xdc33745ec97be906}, - {0x86f0ac99b4e8dafd, 0x69a028bb3ded71a3}, - {0xa8acd7c0222311bc, 0xc40832ea0d68ce0c}, - {0xd2d80db02aabd62b, 0xf50a3fa490c30190}, - {0x83c7088e1aab65db, 0x792667c6da79e0fa}, - {0xa4b8cab1a1563f52, 0x577001b891185938}, - {0xcde6fd5e09abcf26, 0xed4c0226b55e6f86}, - {0x80b05e5ac60b6178, 0x544f8158315b05b4}, - {0xa0dc75f1778e39d6, 0x696361ae3db1c721}, - {0xc913936dd571c84c, 0x03bc3a19cd1e38e9}, - {0xfb5878494ace3a5f, 0x04ab48a04065c723}, - {0x9d174b2dcec0e47b, 0x62eb0d64283f9c76}, - {0xc45d1df942711d9a, 0x3ba5d0bd324f8394}, - {0xf5746577930d6500, 0xca8f44ec7ee36479}, - {0x9968bf6abbe85f20, 0x7e998b13cf4e1ecb}, - {0xbfc2ef456ae276e8, 0x9e3fedd8c321a67e}, - {0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101e}, - {0x95d04aee3b80ece5, 0xbba1f1d158724a12}, - {0xbb445da9ca61281f, 0x2a8a6e45ae8edc97}, - {0xea1575143cf97226, 0xf52d09d71a3293bd}, - {0x924d692ca61be758, 0x593c2626705f9c56}, - {0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836c}, - {0xe498f455c38b997a, 0x0b6dfb9c0f956447}, - {0x8edf98b59a373fec, 0x4724bd4189bd5eac}, - {0xb2977ee300c50fe7, 0x58edec91ec2cb657}, - {0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ed}, - {0x8b865b215899f46c, 0xbd79e0d20082ee74}, - {0xae67f1e9aec07187, 0xecd8590680a3aa11}, - {0xda01ee641a708de9, 0xe80e6f4820cc9495}, - {0x884134fe908658b2, 0x3109058d147fdcdd}, - {0xaa51823e34a7eede, 0xbd4b46f0599fd415}, - {0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91a}, - {0x850fadc09923329e, 0x03e2cf6bc604ddb0}, - {0xa6539930bf6bff45, 0x84db8346b786151c}, - {0xcfe87f7cef46ff16, 0xe612641865679a63}, - {0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07e}, - {0xa26da3999aef7749, 0xe3be5e330f38f09d}, - {0xcb090c8001ab551c, 0x5cadf5bfd3072cc5}, - {0xfdcb4fa002162a63, 0x73d9732fc7c8f7f6}, - {0x9e9f11c4014dda7e, 0x2867e7fddcdd9afa}, - {0xc646d63501a1511d, 0xb281e1fd541501b8}, - {0xf7d88bc24209a565, 0x1f225a7ca91a4226}, - {0x9ae757596946075f, 0x3375788de9b06958}, - {0xc1a12d2fc3978937, 0x0052d6b1641c83ae}, - {0xf209787bb47d6b84, 0xc0678c5dbd23a49a}, - {0x9745eb4d50ce6332, 0xf840b7ba963646e0}, - {0xbd176620a501fbff, 0xb650e5a93bc3d898}, - {0xec5d3fa8ce427aff, 0xa3e51f138ab4cebe}, - {0x93ba47c980e98cdf, 0xc66f336c36b10137}, - {0xb8a8d9bbe123f017, 0xb80b0047445d4184}, - {0xe6d3102ad96cec1d, 0xa60dc059157491e5}, - {0x9043ea1ac7e41392, 0x87c89837ad68db2f}, - {0xb454e4a179dd1877, 0x29babe4598c311fb}, - {0xe16a1dc9d8545e94, 0xf4296dd6fef3d67a}, - {0x8ce2529e2734bb1d, 0x1899e4a65f58660c}, - {0xb01ae745b101e9e4, 0x5ec05dcff72e7f8f}, - {0xdc21a1171d42645d, 0x76707543f4fa1f73}, - {0x899504ae72497eba, 0x6a06494a791c53a8}, - {0xabfa45da0edbde69, 0x0487db9d17636892}, - {0xd6f8d7509292d603, 0x45a9d2845d3c42b6}, - {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b2}, - {0xa7f26836f282b732, 0x8e6cac7768d7141e}, - {0xd1ef0244af2364ff, 0x3207d795430cd926}, - {0x8335616aed761f1f, 0x7f44e6bd49e807b8}, - {0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a6}, - {0xcd036837130890a1, 0x36dba887c37a8c0f}, - {0x802221226be55a64, 0xc2494954da2c9789}, - {0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6c}, - {0xc83553c5c8965d3d, 0x6f92829494e5acc7}, - {0xfa42a8b73abbf48c, 0xcb772339ba1f17f9}, - {0x9c69a97284b578d7, 0xff2a760414536efb}, - {0xc38413cf25e2d70d, 0xfef5138519684aba}, - {0xf46518c2ef5b8cd1, 0x7eb258665fc25d69}, - {0x98bf2f79d5993802, 0xef2f773ffbd97a61}, - {0xbeeefb584aff8603, 0xaafb550ffacfd8fa}, - {0xeeaaba2e5dbf6784, 0x95ba2a53f983cf38}, - {0x952ab45cfa97a0b2, 0xdd945a747bf26183}, - {0xba756174393d88df, 0x94f971119aeef9e4}, - {0xe912b9d1478ceb17, 0x7a37cd5601aab85d}, - {0x91abb422ccb812ee, 0xac62e055c10ab33a}, - {0xb616a12b7fe617aa, 0x577b986b314d6009}, - {0xe39c49765fdf9d94, 0xed5a7e85fda0b80b}, - {0x8e41ade9fbebc27d, 0x14588f13be847307}, - {0xb1d219647ae6b31c, 0x596eb2d8ae258fc8}, - {0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bb}, - {0x8aec23d680043bee, 0x25de7bb9480d5854}, - {0xada72ccc20054ae9, 0xaf561aa79a10ae6a}, - {0xd910f7ff28069da4, 0x1b2ba1518094da04}, - {0x87aa9aff79042286, 0x90fb44d2f05d0842}, - {0xa99541bf57452b28, 0x353a1607ac744a53}, - {0xd3fa922f2d1675f2, 0x42889b8997915ce8}, - {0x847c9b5d7c2e09b7, 0x69956135febada11}, - {0xa59bc234db398c25, 0x43fab9837e699095}, - {0xcf02b2c21207ef2e, 0x94f967e45e03f4bb}, - {0x8161afb94b44f57d, 0x1d1be0eebac278f5}, - {0xa1ba1ba79e1632dc, 0x6462d92a69731732}, - {0xca28a291859bbf93, 0x7d7b8f7503cfdcfe}, - {0xfcb2cb35e702af78, 0x5cda735244c3d43e}, - {0x9defbf01b061adab, 0x3a0888136afa64a7}, - {0xc56baec21c7a1916, 0x088aaa1845b8fdd0}, - {0xf6c69a72a3989f5b, 0x8aad549e57273d45}, - {0x9a3c2087a63f6399, 0x36ac54e2f678864b}, - {0xc0cb28a98fcf3c7f, 0x84576a1bb416a7dd}, - {0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d5}, - {0x969eb7c47859e743, 0x9f644ae5a4b1b325}, - {0xbc4665b596706114, 0x873d5d9f0dde1fee}, - {0xeb57ff22fc0c7959, 0xa90cb506d155a7ea}, - {0x9316ff75dd87cbd8, 0x09a7f12442d588f2}, - {0xb7dcbf5354e9bece, 0x0c11ed6d538aeb2f}, - {0xe5d3ef282a242e81, 0x8f1668c8a86da5fa}, - {0x8fa475791a569d10, 0xf96e017d694487bc}, - {0xb38d92d760ec4455, 0x37c981dcc395a9ac}, - {0xe070f78d3927556a, 0x85bbe253f47b1417}, - {0x8c469ab843b89562, 0x93956d7478ccec8e}, - {0xaf58416654a6babb, 0x387ac8d1970027b2}, - {0xdb2e51bfe9d0696a, 0x06997b05fcc0319e}, - {0x88fcf317f22241e2, 0x441fece3bdf81f03}, - {0xab3c2fddeeaad25a, 0xd527e81cad7626c3}, - {0xd60b3bd56a5586f1, 0x8a71e223d8d3b074}, - {0x85c7056562757456, 0xf6872d5667844e49}, - {0xa738c6bebb12d16c, 0xb428f8ac016561db}, - {0xd106f86e69d785c7, 0xe13336d701beba52}, - {0x82a45b450226b39c, 0xecc0024661173473}, - {0xa34d721642b06084, 0x27f002d7f95d0190}, - {0xcc20ce9bd35c78a5, 0x31ec038df7b441f4}, - {0xff290242c83396ce, 0x7e67047175a15271}, - {0x9f79a169bd203e41, 0x0f0062c6e984d386}, - {0xc75809c42c684dd1, 0x52c07b78a3e60868}, - {0xf92e0c3537826145, 0xa7709a56ccdf8a82}, - {0x9bbcc7a142b17ccb, 0x88a66076400bb691}, - {0xc2abf989935ddbfe, 0x6acff893d00ea435}, - {0xf356f7ebf83552fe, 0x0583f6b8c4124d43}, - {0x98165af37b2153de, 0xc3727a337a8b704a}, - {0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5c}, - {0xeda2ee1c7064130c, 0x1162def06f79df73}, - {0x9485d4d1c63e8be7, 0x8addcb5645ac2ba8}, - {0xb9a74a0637ce2ee1, 0x6d953e2bd7173692}, - {0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0437}, - {0x910ab1d4db9914a0, 0x1d9c9892400a22a2}, - {0xb54d5e4a127f59c8, 0x2503beb6d00cab4b}, - {0xe2a0b5dc971f303a, 0x2e44ae64840fd61d}, - {0x8da471a9de737e24, 0x5ceaecfed289e5d2}, - {0xb10d8e1456105dad, 0x7425a83e872c5f47}, - {0xdd50f1996b947518, 0xd12f124e28f77719}, - {0x8a5296ffe33cc92f, 0x82bd6b70d99aaa6f}, - {0xace73cbfdc0bfb7b, 0x636cc64d1001550b}, - {0xd8210befd30efa5a, 0x3c47f7e05401aa4e}, - {0x8714a775e3e95c78, 0x65acfaec34810a71}, - {0xa8d9d1535ce3b396, 0x7f1839a741a14d0d}, - {0xd31045a8341ca07c, 0x1ede48111209a050}, - {0x83ea2b892091e44d, 0x934aed0aab460432}, - {0xa4e4b66b68b65d60, 0xf81da84d5617853f}, - {0xce1de40642e3f4b9, 0x36251260ab9d668e}, - {0x80d2ae83e9ce78f3, 0xc1d72b7c6b426019}, - {0xa1075a24e4421730, 0xb24cf65b8612f81f}, - {0xc94930ae1d529cfc, 0xdee033f26797b627}, - {0xfb9b7cd9a4a7443c, 0x169840ef017da3b1}, - {0x9d412e0806e88aa5, 0x8e1f289560ee864e}, - {0xc491798a08a2ad4e, 0xf1a6f2bab92a27e2}, - {0xf5b5d7ec8acb58a2, 0xae10af696774b1db}, - {0x9991a6f3d6bf1765, 0xacca6da1e0a8ef29}, - {0xbff610b0cc6edd3f, 0x17fd090a58d32af3}, - {0xeff394dcff8a948e, 0xddfc4b4cef07f5b0}, - {0x95f83d0a1fb69cd9, 0x4abdaf101564f98e}, - {0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f1}, - {0xea53df5fd18d5513, 0x84c86189216dc5ed}, - {0x92746b9be2f8552c, 0x32fd3cf5b4e49bb4}, - {0xb7118682dbb66a77, 0x3fbc8c33221dc2a1}, - {0xe4d5e82392a40515, 0x0fabaf3feaa5334a}, - {0x8f05b1163ba6832d, 0x29cb4d87f2a7400e}, - {0xb2c71d5bca9023f8, 0x743e20e9ef511012}, - {0xdf78e4b2bd342cf6, 0x914da9246b255416}, - {0x8bab8eefb6409c1a, 0x1ad089b6c2f7548e}, - {0xae9672aba3d0c320, 0xa184ac2473b529b1}, - {0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741e}, - {0x8865899617fb1871, 0x7e2fa67c7a658892}, - {0xaa7eebfb9df9de8d, 0xddbb901b98feeab7}, - {0xd51ea6fa85785631, 0x552a74227f3ea565}, - {0x8533285c936b35de, 0xd53a88958f87275f}, - {0xa67ff273b8460356, 0x8a892abaf368f137}, - {0xd01fef10a657842c, 0x2d2b7569b0432d85}, - {0x8213f56a67f6b29b, 0x9c3b29620e29fc73}, - {0xa298f2c501f45f42, 0x8349f3ba91b47b8f}, - {0xcb3f2f7642717713, 0x241c70a936219a73}, - {0xfe0efb53d30dd4d7, 0xed238cd383aa0110}, - {0x9ec95d1463e8a506, 0xf4363804324a40aa}, - {0xc67bb4597ce2ce48, 0xb143c6053edcd0d5}, - {0xf81aa16fdc1b81da, 0xdd94b7868e94050a}, - {0x9b10a4e5e9913128, 0xca7cf2b4191c8326}, - {0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f0}, - {0xf24a01a73cf2dccf, 0xbc633b39673c8cec}, - {0x976e41088617ca01, 0xd5be0503e085d813}, - {0xbd49d14aa79dbc82, 0x4b2d8644d8a74e18}, - {0xec9c459d51852ba2, 0xddf8e7d60ed1219e}, - {0x93e1ab8252f33b45, 0xcabb90e5c942b503}, - {0xb8da1662e7b00a17, 0x3d6a751f3b936243}, - {0xe7109bfba19c0c9d, 0x0cc512670a783ad4}, - {0x906a617d450187e2, 0x27fb2b80668b24c5}, - {0xb484f9dc9641e9da, 0xb1f9f660802dedf6}, - {0xe1a63853bbd26451, 0x5e7873f8a0396973}, - {0x8d07e33455637eb2, 0xdb0b487b6423e1e8}, - {0xb049dc016abc5e5f, 0x91ce1a9a3d2cda62}, - {0xdc5c5301c56b75f7, 0x7641a140cc7810fb}, - {0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9d}, - {0xac2820d9623bf429, 0x546345fa9fbdcd44}, - {0xd732290fbacaf133, 0xa97c177947ad4095}, - {0x867f59a9d4bed6c0, 0x49ed8eabcccc485d}, - {0xa81f301449ee8c70, 0x5c68f256bfff5a74}, - {0xd226fc195c6a2f8c, 0x73832eec6fff3111}, - {0x83585d8fd9c25db7, 0xc831fd53c5ff7eab}, - {0xa42e74f3d032f525, 0xba3e7ca8b77f5e55}, - {0xcd3a1230c43fb26f, 0x28ce1bd2e55f35eb}, - {0x80444b5e7aa7cf85, 0x7980d163cf5b81b3}, - {0xa0555e361951c366, 0xd7e105bcc332621f}, - {0xc86ab5c39fa63440, 0x8dd9472bf3fefaa7}, - {0xfa856334878fc150, 0xb14f98f6f0feb951}, - {0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d3}, - {0xc3b8358109e84f07, 0x0a862f80ec4700c8}, - {0xf4a642e14c6262c8, 0xcd27bb612758c0fa}, - {0x98e7e9cccfbd7dbd, 0x8038d51cb897789c}, - {0xbf21e44003acdd2c, 0xe0470a63e6bd56c3}, - {0xeeea5d5004981478, 0x1858ccfce06cac74}, - {0x95527a5202df0ccb, 0x0f37801e0c43ebc8}, - {0xbaa718e68396cffd, 0xd30560258f54e6ba}, - {0xe950df20247c83fd, 0x47c6b82ef32a2069}, - {0x91d28b7416cdd27e, 0x4cdc331d57fa5441}, - {0xb6472e511c81471d, 0xe0133fe4adf8e952}, - {0xe3d8f9e563a198e5, 0x58180fddd97723a6}, - {0x8e679c2f5e44ff8f, 0x570f09eaa7ea7648}, - {0xb201833b35d63f73, 0x2cd2cc6551e513da}, - {0xde81e40a034bcf4f, 0xf8077f7ea65e58d1}, - {0x8b112e86420f6191, 0xfb04afaf27faf782}, - {0xadd57a27d29339f6, 0x79c5db9af1f9b563}, - {0xd94ad8b1c7380874, 0x18375281ae7822bc}, - {0x87cec76f1c830548, 0x8f2293910d0b15b5}, - {0xa9c2794ae3a3c69a, 0xb2eb3875504ddb22}, - {0xd433179d9c8cb841, 0x5fa60692a46151eb}, - {0x849feec281d7f328, 0xdbc7c41ba6bcd333}, - {0xa5c7ea73224deff3, 0x12b9b522906c0800}, - {0xcf39e50feae16bef, 0xd768226b34870a00}, - {0x81842f29f2cce375, 0xe6a1158300d46640}, - {0xa1e53af46f801c53, 0x60495ae3c1097fd0}, - {0xca5e89b18b602368, 0x385bb19cb14bdfc4}, - {0xfcf62c1dee382c42, 0x46729e03dd9ed7b5}, - {0x9e19db92b4e31ba9, 0x6c07a2c26a8346d1}, - {0xc5a05277621be293, 0xc7098b7305241885}, + {0x82818f1281ed449f, 0xbff8f10e7a8921a5}, + {0xa321f2d7226895c7, 0xaff72d52192b6a0e}, + {0xcbea6f8ceb02bb39, 0x9bf4f8a69f764491}, + {0xfee50b7025c36a08, 0x02f236d04753d5b5}, + {0x9f4f2726179a2245, 0x01d762422c946591}, + {0xc722f0ef9d80aad6, 0x424d3ad2b7b97ef6}, + {0xf8ebad2b84e0d58b, 0xd2e0898765a7deb3}, + {0x9b934c3b330c8577, 0x63cc55f49f88eb30}, + {0xc2781f49ffcfa6d5, 0x3cbf6b71c76b25fc}, + {0xf316271c7fc3908a, 0x8bef464e3945ef7b}, + {0x97edd871cfda3a56, 0x97758bf0e3cbb5ad}, + {0xbde94e8e43d0c8ec, 0x3d52eeed1cbea318}, + {0xed63a231d4c4fb27, 0x4ca7aaa863ee4bde}, + {0x945e455f24fb1cf8, 0x8fe8caa93e74ef6b}, + {0xb975d6b6ee39e436, 0xb3e2fd538e122b45}, + {0xe7d34c64a9c85d44, 0x60dbbca87196b617}, + {0x90e40fbeea1d3a4a, 0xbc8955e946fe31ce}, + {0xb51d13aea4a488dd, 0x6babab6398bdbe42}, + {0xe264589a4dcdab14, 0xc696963c7eed2dd2}, + {0x8d7eb76070a08aec, 0xfc1e1de5cf543ca3}, + {0xb0de65388cc8ada8, 0x3b25a55f43294bcc}, + {0xdd15fe86affad912, 0x49ef0eb713f39ebf}, + {0x8a2dbf142dfcc7ab, 0x6e3569326c784338}, + {0xacb92ed9397bf996, 0x49c2c37f07965405}, + {0xd7e77a8f87daf7fb, 0xdc33745ec97be907}, + {0x86f0ac99b4e8dafd, 0x69a028bb3ded71a4}, + {0xa8acd7c0222311bc, 0xc40832ea0d68ce0d}, + {0xd2d80db02aabd62b, 0xf50a3fa490c30191}, + {0x83c7088e1aab65db, 0x792667c6da79e0fb}, + {0xa4b8cab1a1563f52, 0x577001b891185939}, + {0xcde6fd5e09abcf26, 0xed4c0226b55e6f87}, + {0x80b05e5ac60b6178, 0x544f8158315b05b5}, + {0xa0dc75f1778e39d6, 0x696361ae3db1c722}, + {0xc913936dd571c84c, 0x03bc3a19cd1e38ea}, + {0xfb5878494ace3a5f, 0x04ab48a04065c724}, + {0x9d174b2dcec0e47b, 0x62eb0d64283f9c77}, + {0xc45d1df942711d9a, 0x3ba5d0bd324f8395}, + {0xf5746577930d6500, 0xca8f44ec7ee3647a}, + {0x9968bf6abbe85f20, 0x7e998b13cf4e1ecc}, + {0xbfc2ef456ae276e8, 0x9e3fedd8c321a67f}, + {0xefb3ab16c59b14a2, 0xc5cfe94ef3ea101f}, + {0x95d04aee3b80ece5, 0xbba1f1d158724a13}, + {0xbb445da9ca61281f, 0x2a8a6e45ae8edc98}, + {0xea1575143cf97226, 0xf52d09d71a3293be}, + {0x924d692ca61be758, 0x593c2626705f9c57}, + {0xb6e0c377cfa2e12e, 0x6f8b2fb00c77836d}, + {0xe498f455c38b997a, 0x0b6dfb9c0f956448}, + {0x8edf98b59a373fec, 0x4724bd4189bd5ead}, + {0xb2977ee300c50fe7, 0x58edec91ec2cb658}, + {0xdf3d5e9bc0f653e1, 0x2f2967b66737e3ee}, + {0x8b865b215899f46c, 0xbd79e0d20082ee75}, + {0xae67f1e9aec07187, 0xecd8590680a3aa12}, + {0xda01ee641a708de9, 0xe80e6f4820cc9496}, + {0x884134fe908658b2, 0x3109058d147fdcde}, + {0xaa51823e34a7eede, 0xbd4b46f0599fd416}, + {0xd4e5e2cdc1d1ea96, 0x6c9e18ac7007c91b}, + {0x850fadc09923329e, 0x03e2cf6bc604ddb1}, + {0xa6539930bf6bff45, 0x84db8346b786151d}, + {0xcfe87f7cef46ff16, 0xe612641865679a64}, + {0x81f14fae158c5f6e, 0x4fcb7e8f3f60c07f}, + {0xa26da3999aef7749, 0xe3be5e330f38f09e}, + {0xcb090c8001ab551c, 0x5cadf5bfd3072cc6}, + {0xfdcb4fa002162a63, 0x73d9732fc7c8f7f7}, + {0x9e9f11c4014dda7e, 0x2867e7fddcdd9afb}, + {0xc646d63501a1511d, 0xb281e1fd541501b9}, + {0xf7d88bc24209a565, 0x1f225a7ca91a4227}, + {0x9ae757596946075f, 0x3375788de9b06959}, + {0xc1a12d2fc3978937, 0x0052d6b1641c83af}, + {0xf209787bb47d6b84, 0xc0678c5dbd23a49b}, + {0x9745eb4d50ce6332, 0xf840b7ba963646e1}, + {0xbd176620a501fbff, 0xb650e5a93bc3d899}, + {0xec5d3fa8ce427aff, 0xa3e51f138ab4cebf}, + {0x93ba47c980e98cdf, 0xc66f336c36b10138}, + {0xb8a8d9bbe123f017, 0xb80b0047445d4185}, + {0xe6d3102ad96cec1d, 0xa60dc059157491e6}, + {0x9043ea1ac7e41392, 0x87c89837ad68db30}, + {0xb454e4a179dd1877, 0x29babe4598c311fc}, + {0xe16a1dc9d8545e94, 0xf4296dd6fef3d67b}, + {0x8ce2529e2734bb1d, 0x1899e4a65f58660d}, + {0xb01ae745b101e9e4, 0x5ec05dcff72e7f90}, + {0xdc21a1171d42645d, 0x76707543f4fa1f74}, + {0x899504ae72497eba, 0x6a06494a791c53a9}, + {0xabfa45da0edbde69, 0x0487db9d17636893}, + {0xd6f8d7509292d603, 0x45a9d2845d3c42b7}, + {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b3}, + {0xa7f26836f282b732, 0x8e6cac7768d7141f}, + {0xd1ef0244af2364ff, 0x3207d795430cd927}, + {0x8335616aed761f1f, 0x7f44e6bd49e807b9}, + {0xa402b9c5a8d3a6e7, 0x5f16206c9c6209a7}, + {0xcd036837130890a1, 0x36dba887c37a8c10}, + {0x802221226be55a64, 0xc2494954da2c978a}, + {0xa02aa96b06deb0fd, 0xf2db9baa10b7bd6d}, + {0xc83553c5c8965d3d, 0x6f92829494e5acc8}, + {0xfa42a8b73abbf48c, 0xcb772339ba1f17fa}, + {0x9c69a97284b578d7, 0xff2a760414536efc}, + {0xc38413cf25e2d70d, 0xfef5138519684abb}, + {0xf46518c2ef5b8cd1, 0x7eb258665fc25d6a}, + {0x98bf2f79d5993802, 0xef2f773ffbd97a62}, + {0xbeeefb584aff8603, 0xaafb550ffacfd8fb}, + {0xeeaaba2e5dbf6784, 0x95ba2a53f983cf39}, + {0x952ab45cfa97a0b2, 0xdd945a747bf26184}, + {0xba756174393d88df, 0x94f971119aeef9e5}, + {0xe912b9d1478ceb17, 0x7a37cd5601aab85e}, + {0x91abb422ccb812ee, 0xac62e055c10ab33b}, + {0xb616a12b7fe617aa, 0x577b986b314d600a}, + {0xe39c49765fdf9d94, 0xed5a7e85fda0b80c}, + {0x8e41ade9fbebc27d, 0x14588f13be847308}, + {0xb1d219647ae6b31c, 0x596eb2d8ae258fc9}, + {0xde469fbd99a05fe3, 0x6fca5f8ed9aef3bc}, + {0x8aec23d680043bee, 0x25de7bb9480d5855}, + {0xada72ccc20054ae9, 0xaf561aa79a10ae6b}, + {0xd910f7ff28069da4, 0x1b2ba1518094da05}, + {0x87aa9aff79042286, 0x90fb44d2f05d0843}, + {0xa99541bf57452b28, 0x353a1607ac744a54}, + {0xd3fa922f2d1675f2, 0x42889b8997915ce9}, + {0x847c9b5d7c2e09b7, 0x69956135febada12}, + {0xa59bc234db398c25, 0x43fab9837e699096}, + {0xcf02b2c21207ef2e, 0x94f967e45e03f4bc}, + {0x8161afb94b44f57d, 0x1d1be0eebac278f6}, + {0xa1ba1ba79e1632dc, 0x6462d92a69731733}, + {0xca28a291859bbf93, 0x7d7b8f7503cfdcff}, + {0xfcb2cb35e702af78, 0x5cda735244c3d43f}, + {0x9defbf01b061adab, 0x3a0888136afa64a8}, + {0xc56baec21c7a1916, 0x088aaa1845b8fdd1}, + {0xf6c69a72a3989f5b, 0x8aad549e57273d46}, + {0x9a3c2087a63f6399, 0x36ac54e2f678864c}, + {0xc0cb28a98fcf3c7f, 0x84576a1bb416a7de}, + {0xf0fdf2d3f3c30b9f, 0x656d44a2a11c51d6}, + {0x969eb7c47859e743, 0x9f644ae5a4b1b326}, + {0xbc4665b596706114, 0x873d5d9f0dde1fef}, + {0xeb57ff22fc0c7959, 0xa90cb506d155a7eb}, + {0x9316ff75dd87cbd8, 0x09a7f12442d588f3}, + {0xb7dcbf5354e9bece, 0x0c11ed6d538aeb30}, + {0xe5d3ef282a242e81, 0x8f1668c8a86da5fb}, + {0x8fa475791a569d10, 0xf96e017d694487bd}, + {0xb38d92d760ec4455, 0x37c981dcc395a9ad}, + {0xe070f78d3927556a, 0x85bbe253f47b1418}, + {0x8c469ab843b89562, 0x93956d7478ccec8f}, + {0xaf58416654a6babb, 0x387ac8d1970027b3}, + {0xdb2e51bfe9d0696a, 0x06997b05fcc0319f}, + {0x88fcf317f22241e2, 0x441fece3bdf81f04}, + {0xab3c2fddeeaad25a, 0xd527e81cad7626c4}, + {0xd60b3bd56a5586f1, 0x8a71e223d8d3b075}, + {0x85c7056562757456, 0xf6872d5667844e4a}, + {0xa738c6bebb12d16c, 0xb428f8ac016561dc}, + {0xd106f86e69d785c7, 0xe13336d701beba53}, + {0x82a45b450226b39c, 0xecc0024661173474}, + {0xa34d721642b06084, 0x27f002d7f95d0191}, + {0xcc20ce9bd35c78a5, 0x31ec038df7b441f5}, + {0xff290242c83396ce, 0x7e67047175a15272}, + {0x9f79a169bd203e41, 0x0f0062c6e984d387}, + {0xc75809c42c684dd1, 0x52c07b78a3e60869}, + {0xf92e0c3537826145, 0xa7709a56ccdf8a83}, + {0x9bbcc7a142b17ccb, 0x88a66076400bb692}, + {0xc2abf989935ddbfe, 0x6acff893d00ea436}, + {0xf356f7ebf83552fe, 0x0583f6b8c4124d44}, + {0x98165af37b2153de, 0xc3727a337a8b704b}, + {0xbe1bf1b059e9a8d6, 0x744f18c0592e4c5d}, + {0xeda2ee1c7064130c, 0x1162def06f79df74}, + {0x9485d4d1c63e8be7, 0x8addcb5645ac2ba9}, + {0xb9a74a0637ce2ee1, 0x6d953e2bd7173693}, + {0xe8111c87c5c1ba99, 0xc8fa8db6ccdd0438}, + {0x910ab1d4db9914a0, 0x1d9c9892400a22a3}, + {0xb54d5e4a127f59c8, 0x2503beb6d00cab4c}, + {0xe2a0b5dc971f303a, 0x2e44ae64840fd61e}, + {0x8da471a9de737e24, 0x5ceaecfed289e5d3}, + {0xb10d8e1456105dad, 0x7425a83e872c5f48}, + {0xdd50f1996b947518, 0xd12f124e28f7771a}, + {0x8a5296ffe33cc92f, 0x82bd6b70d99aaa70}, + {0xace73cbfdc0bfb7b, 0x636cc64d1001550c}, + {0xd8210befd30efa5a, 0x3c47f7e05401aa4f}, + {0x8714a775e3e95c78, 0x65acfaec34810a72}, + {0xa8d9d1535ce3b396, 0x7f1839a741a14d0e}, + {0xd31045a8341ca07c, 0x1ede48111209a051}, + {0x83ea2b892091e44d, 0x934aed0aab460433}, + {0xa4e4b66b68b65d60, 0xf81da84d56178540}, + {0xce1de40642e3f4b9, 0x36251260ab9d668f}, + {0x80d2ae83e9ce78f3, 0xc1d72b7c6b42601a}, + {0xa1075a24e4421730, 0xb24cf65b8612f820}, + {0xc94930ae1d529cfc, 0xdee033f26797b628}, + {0xfb9b7cd9a4a7443c, 0x169840ef017da3b2}, + {0x9d412e0806e88aa5, 0x8e1f289560ee864f}, + {0xc491798a08a2ad4e, 0xf1a6f2bab92a27e3}, + {0xf5b5d7ec8acb58a2, 0xae10af696774b1dc}, + {0x9991a6f3d6bf1765, 0xacca6da1e0a8ef2a}, + {0xbff610b0cc6edd3f, 0x17fd090a58d32af4}, + {0xeff394dcff8a948e, 0xddfc4b4cef07f5b1}, + {0x95f83d0a1fb69cd9, 0x4abdaf101564f98f}, + {0xbb764c4ca7a4440f, 0x9d6d1ad41abe37f2}, + {0xea53df5fd18d5513, 0x84c86189216dc5ee}, + {0x92746b9be2f8552c, 0x32fd3cf5b4e49bb5}, + {0xb7118682dbb66a77, 0x3fbc8c33221dc2a2}, + {0xe4d5e82392a40515, 0x0fabaf3feaa5334b}, + {0x8f05b1163ba6832d, 0x29cb4d87f2a7400f}, + {0xb2c71d5bca9023f8, 0x743e20e9ef511013}, + {0xdf78e4b2bd342cf6, 0x914da9246b255417}, + {0x8bab8eefb6409c1a, 0x1ad089b6c2f7548f}, + {0xae9672aba3d0c320, 0xa184ac2473b529b2}, + {0xda3c0f568cc4f3e8, 0xc9e5d72d90a2741f}, + {0x8865899617fb1871, 0x7e2fa67c7a658893}, + {0xaa7eebfb9df9de8d, 0xddbb901b98feeab8}, + {0xd51ea6fa85785631, 0x552a74227f3ea566}, + {0x8533285c936b35de, 0xd53a88958f872760}, + {0xa67ff273b8460356, 0x8a892abaf368f138}, + {0xd01fef10a657842c, 0x2d2b7569b0432d86}, + {0x8213f56a67f6b29b, 0x9c3b29620e29fc74}, + {0xa298f2c501f45f42, 0x8349f3ba91b47b90}, + {0xcb3f2f7642717713, 0x241c70a936219a74}, + {0xfe0efb53d30dd4d7, 0xed238cd383aa0111}, + {0x9ec95d1463e8a506, 0xf4363804324a40ab}, + {0xc67bb4597ce2ce48, 0xb143c6053edcd0d6}, + {0xf81aa16fdc1b81da, 0xdd94b7868e94050b}, + {0x9b10a4e5e9913128, 0xca7cf2b4191c8327}, + {0xc1d4ce1f63f57d72, 0xfd1c2f611f63a3f1}, + {0xf24a01a73cf2dccf, 0xbc633b39673c8ced}, + {0x976e41088617ca01, 0xd5be0503e085d814}, + {0xbd49d14aa79dbc82, 0x4b2d8644d8a74e19}, + {0xec9c459d51852ba2, 0xddf8e7d60ed1219f}, + {0x93e1ab8252f33b45, 0xcabb90e5c942b504}, + {0xb8da1662e7b00a17, 0x3d6a751f3b936244}, + {0xe7109bfba19c0c9d, 0x0cc512670a783ad5}, + {0x906a617d450187e2, 0x27fb2b80668b24c6}, + {0xb484f9dc9641e9da, 0xb1f9f660802dedf7}, + {0xe1a63853bbd26451, 0x5e7873f8a0396974}, + {0x8d07e33455637eb2, 0xdb0b487b6423e1e9}, + {0xb049dc016abc5e5f, 0x91ce1a9a3d2cda63}, + {0xdc5c5301c56b75f7, 0x7641a140cc7810fc}, + {0x89b9b3e11b6329ba, 0xa9e904c87fcb0a9e}, + {0xac2820d9623bf429, 0x546345fa9fbdcd45}, + {0xd732290fbacaf133, 0xa97c177947ad4096}, + {0x867f59a9d4bed6c0, 0x49ed8eabcccc485e}, + {0xa81f301449ee8c70, 0x5c68f256bfff5a75}, + {0xd226fc195c6a2f8c, 0x73832eec6fff3112}, + {0x83585d8fd9c25db7, 0xc831fd53c5ff7eac}, + {0xa42e74f3d032f525, 0xba3e7ca8b77f5e56}, + {0xcd3a1230c43fb26f, 0x28ce1bd2e55f35ec}, + {0x80444b5e7aa7cf85, 0x7980d163cf5b81b4}, + {0xa0555e361951c366, 0xd7e105bcc3326220}, + {0xc86ab5c39fa63440, 0x8dd9472bf3fefaa8}, + {0xfa856334878fc150, 0xb14f98f6f0feb952}, + {0x9c935e00d4b9d8d2, 0x6ed1bf9a569f33d4}, + {0xc3b8358109e84f07, 0x0a862f80ec4700c9}, + {0xf4a642e14c6262c8, 0xcd27bb612758c0fb}, + {0x98e7e9cccfbd7dbd, 0x8038d51cb897789d}, + {0xbf21e44003acdd2c, 0xe0470a63e6bd56c4}, + {0xeeea5d5004981478, 0x1858ccfce06cac75}, + {0x95527a5202df0ccb, 0x0f37801e0c43ebc9}, + {0xbaa718e68396cffd, 0xd30560258f54e6bb}, + {0xe950df20247c83fd, 0x47c6b82ef32a206a}, + {0x91d28b7416cdd27e, 0x4cdc331d57fa5442}, + {0xb6472e511c81471d, 0xe0133fe4adf8e953}, + {0xe3d8f9e563a198e5, 0x58180fddd97723a7}, + {0x8e679c2f5e44ff8f, 0x570f09eaa7ea7649}, + {0xb201833b35d63f73, 0x2cd2cc6551e513db}, + {0xde81e40a034bcf4f, 0xf8077f7ea65e58d2}, + {0x8b112e86420f6191, 0xfb04afaf27faf783}, + {0xadd57a27d29339f6, 0x79c5db9af1f9b564}, + {0xd94ad8b1c7380874, 0x18375281ae7822bd}, + {0x87cec76f1c830548, 0x8f2293910d0b15b6}, + {0xa9c2794ae3a3c69a, 0xb2eb3875504ddb23}, + {0xd433179d9c8cb841, 0x5fa60692a46151ec}, + {0x849feec281d7f328, 0xdbc7c41ba6bcd334}, + {0xa5c7ea73224deff3, 0x12b9b522906c0801}, + {0xcf39e50feae16bef, 0xd768226b34870a01}, + {0x81842f29f2cce375, 0xe6a1158300d46641}, + {0xa1e53af46f801c53, 0x60495ae3c1097fd1}, + {0xca5e89b18b602368, 0x385bb19cb14bdfc5}, + {0xfcf62c1dee382c42, 0x46729e03dd9ed7b6}, + {0x9e19db92b4e31ba9, 0x6c07a2c26a8346d2}, + {0xc5a05277621be293, 0xc7098b7305241886}, { 0xf70867153aa2db38, - 0xb8cbee4fc66d1ea7 } + 0xb8cbee4fc66d1ea8 } #else {0xff77b1fcbebcdc4f, 0x25e8e89c13bb0f7b}, {0xce5d73ff402d98e3, 0xfb0a3d212dc81290}, @@ -1759,17 +1025,17 @@ template <> struct cache_accessor { {0xf1c90080baf72cb1, 0x5324c68b12dd6339}, {0xc350000000000000, 0x0000000000000000}, {0x9dc5ada82b70b59d, 0xf020000000000000}, - {0xfee50b7025c36a08, 0x02f236d04753d5b4}, - {0xcde6fd5e09abcf26, 0xed4c0226b55e6f86}, - {0xa6539930bf6bff45, 0x84db8346b786151c}, - {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b2}, - {0xd910f7ff28069da4, 0x1b2ba1518094da04}, - {0xaf58416654a6babb, 0x387ac8d1970027b2}, - {0x8da471a9de737e24, 0x5ceaecfed289e5d2}, - {0xe4d5e82392a40515, 0x0fabaf3feaa5334a}, - {0xb8da1662e7b00a17, 0x3d6a751f3b936243}, + {0xfee50b7025c36a08, 0x02f236d04753d5b5}, + {0xcde6fd5e09abcf26, 0xed4c0226b55e6f87}, + {0xa6539930bf6bff45, 0x84db8346b786151d}, + {0x865b86925b9bc5c2, 0x0b8a2392ba45a9b3}, + {0xd910f7ff28069da4, 0x1b2ba1518094da05}, + {0xaf58416654a6babb, 0x387ac8d1970027b3}, + {0x8da471a9de737e24, 0x5ceaecfed289e5d3}, + {0xe4d5e82392a40515, 0x0fabaf3feaa5334b}, + {0xb8da1662e7b00a17, 0x3d6a751f3b936244}, { 0x95527a5202df0ccb, - 0x0f37801e0c43ebc8 } + 0x0f37801e0c43ebc9 } #endif }; @@ -1787,15 +1053,6 @@ template <> struct cache_accessor { 0x0001b1ae4d6e2ef5, 0x000878678326eac9, 0x002a5a058fc295ed, 0x00d3c21bcecceda1, 0x0422ca8b0a00a425, 0x14adf4b7320334b9}; - static constexpr const uint32_t pow10_recovery_errors[] = { - 0x50001400, 0x54044100, 0x54014555, 0x55954415, 0x54115555, 0x00000001, - 0x50000000, 0x00104000, 0x54010004, 0x05004001, 0x55555544, 0x41545555, - 0x54040551, 0x15445545, 0x51555514, 0x10000015, 0x00101100, 0x01100015, - 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x04450514, 0x45414110, - 0x55555145, 0x50544050, 0x15040155, 0x11054140, 0x50111514, 0x11451454, - 0x00400541, 0x00000000, 0x55555450, 0x10056551, 0x10054011, 0x55551014, - 0x69514555, 0x05151109, 0x00155555}; - static const int compression_ratio = 27; // Compute base index. @@ -1804,7 +1061,7 @@ template <> struct cache_accessor { int offset = k - kb; // Get base cache. - uint128_wrapper base_cache = pow10_significands[cache_index]; + uint128_fallback base_cache = pow10_significands[cache_index]; if (offset == 0) return base_cache; // Compute the required amount of bit-shift. @@ -1813,9 +1070,8 @@ template <> struct cache_accessor { // Try to recover the real cache. uint64_t pow5 = powers_of_5_64[offset]; - uint128_wrapper recovered_cache = umul128(base_cache.high(), pow5); - uint128_wrapper middle_low = - umul128(base_cache.low() - (kb < 0 ? 1u : 0u), pow5); + uint128_fallback recovered_cache = umul128(base_cache.high(), pow5); + uint128_fallback middle_low = umul128(base_cache.low(), pow5); recovered_cache += middle_low.high(); @@ -1823,60 +1079,60 @@ template <> struct cache_accessor { uint64_t middle_to_low = recovered_cache.low() << (64 - alpha); recovered_cache = - uint128_wrapper{(recovered_cache.low() >> alpha) | high_to_middle, - ((middle_low.low() >> alpha) | middle_to_low)}; - - if (kb < 0) recovered_cache += 1; - - // Get error. - int error_idx = (k - float_info::min_k) / 16; - uint32_t error = (pow10_recovery_errors[error_idx] >> - ((k - float_info::min_k) % 16) * 2) & - 0x3; - - // Add the error back. - FMT_ASSERT(recovered_cache.low() + error >= recovered_cache.low(), ""); - return {recovered_cache.high(), recovered_cache.low() + error}; + uint128_fallback{(recovered_cache.low() >> alpha) | high_to_middle, + ((middle_low.low() >> alpha) | middle_to_low)}; + FMT_ASSERT(recovered_cache.low() + 1 != 0, ""); + return {recovered_cache.high(), recovered_cache.low() + 1}; #endif } - static carrier_uint compute_mul(carrier_uint u, - const cache_entry_type& cache) FMT_NOEXCEPT { - return umul192_upper64(u, cache); + struct compute_mul_result { + carrier_uint result; + bool is_integer; + }; + struct compute_mul_parity_result { + bool parity; + bool is_integer; + }; + + static compute_mul_result compute_mul( + carrier_uint u, const cache_entry_type& cache) noexcept { + auto r = umul192_upper128(u, cache); + return {r.high(), r.low() == 0}; } static uint32_t compute_delta(cache_entry_type const& cache, - int beta_minus_1) FMT_NOEXCEPT { - return static_cast(cache.high() >> (64 - 1 - beta_minus_1)); + int beta) noexcept { + return static_cast(cache.high() >> (64 - 1 - beta)); } - static bool compute_mul_parity(carrier_uint two_f, - const cache_entry_type& cache, - int beta_minus_1) FMT_NOEXCEPT { - FMT_ASSERT(beta_minus_1 >= 1, ""); - FMT_ASSERT(beta_minus_1 < 64, ""); + static compute_mul_parity_result compute_mul_parity( + carrier_uint two_f, const cache_entry_type& cache, int beta) noexcept { + FMT_ASSERT(beta >= 1, ""); + FMT_ASSERT(beta < 64, ""); - return ((umul192_middle64(two_f, cache) >> (64 - beta_minus_1)) & 1) != 0; + auto r = umul192_lower128(two_f, cache); + return {((r.high() >> (64 - beta)) & 1) != 0, + ((r.high() << beta) | (r.low() >> (64 - beta))) == 0}; } static carrier_uint compute_left_endpoint_for_shorter_interval_case( - const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + const cache_entry_type& cache, int beta) noexcept { return (cache.high() - - (cache.high() >> (float_info::significand_bits + 2))) >> - (64 - float_info::significand_bits - 1 - beta_minus_1); + (cache.high() >> (num_significand_bits() + 2))) >> + (64 - num_significand_bits() - 1 - beta); } static carrier_uint compute_right_endpoint_for_shorter_interval_case( - const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { + const cache_entry_type& cache, int beta) noexcept { return (cache.high() + - (cache.high() >> (float_info::significand_bits + 1))) >> - (64 - float_info::significand_bits - 1 - beta_minus_1); + (cache.high() >> (num_significand_bits() + 1))) >> + (64 - num_significand_bits() - 1 - beta); } static carrier_uint compute_round_up_for_shorter_interval_case( - const cache_entry_type& cache, int beta_minus_1) FMT_NOEXCEPT { - return ((cache.high() >> - (64 - float_info::significand_bits - 2 - beta_minus_1)) + + const cache_entry_type& cache, int beta) noexcept { + return ((cache.high() >> (64 - num_significand_bits() - 2 - beta)) + 1) / 2; } @@ -1884,166 +1140,104 @@ template <> struct cache_accessor { // Various integer checks template -bool is_left_endpoint_integer_shorter_interval(int exponent) FMT_NOEXCEPT { - return exponent >= - float_info< - T>::case_shorter_interval_left_endpoint_lower_threshold && - exponent <= - float_info::case_shorter_interval_left_endpoint_upper_threshold; -} -template -bool is_endpoint_integer(typename float_info::carrier_uint two_f, - int exponent, int minus_k) FMT_NOEXCEPT { - if (exponent < float_info::case_fc_pm_half_lower_threshold) return false; - // For k >= 0. - if (exponent <= float_info::case_fc_pm_half_upper_threshold) return true; - // For k < 0. - if (exponent > float_info::divisibility_check_by_5_threshold) return false; - return divisible_by_power_of_5(two_f, minus_k); -} - -template -bool is_center_integer(typename float_info::carrier_uint two_f, int exponent, - int minus_k) FMT_NOEXCEPT { - // Exponent for 5 is negative. - if (exponent > float_info::divisibility_check_by_5_threshold) return false; - if (exponent > float_info::case_fc_upper_threshold) - return divisible_by_power_of_5(two_f, minus_k); - // Both exponents are nonnegative. - if (exponent >= float_info::case_fc_lower_threshold) return true; - // Exponent for 2 is negative. - return divisible_by_power_of_2(two_f, minus_k - exponent + 1); +bool is_left_endpoint_integer_shorter_interval(int exponent) noexcept { + const int case_shorter_interval_left_endpoint_lower_threshold = 2; + const int case_shorter_interval_left_endpoint_upper_threshold = 3; + return exponent >= case_shorter_interval_left_endpoint_lower_threshold && + exponent <= case_shorter_interval_left_endpoint_upper_threshold; } // Remove trailing zeros from n and return the number of zeros removed (float) -FMT_INLINE int remove_trailing_zeros(uint32_t& n) FMT_NOEXCEPT { -#ifdef FMT_BUILTIN_CTZ - int t = FMT_BUILTIN_CTZ(n); -#else - int t = ctz(n); -#endif - if (t > float_info::max_trailing_zeros) - t = float_info::max_trailing_zeros; - - const uint32_t mod_inv1 = 0xcccccccd; - const uint32_t max_quotient1 = 0x33333333; - const uint32_t mod_inv2 = 0xc28f5c29; - const uint32_t max_quotient2 = 0x0a3d70a3; +FMT_INLINE int remove_trailing_zeros(uint32_t& n) noexcept { + FMT_ASSERT(n != 0, ""); + const uint32_t mod_inv_5 = 0xcccccccd; + const uint32_t mod_inv_25 = mod_inv_5 * mod_inv_5; int s = 0; - for (; s < t - 1; s += 2) { - if (n * mod_inv2 > max_quotient2) break; - n *= mod_inv2; + while (true) { + auto q = rotr(n * mod_inv_25, 2); + if (q > max_value() / 100) break; + n = q; + s += 2; } - if (s < t && n * mod_inv1 <= max_quotient1) { - n *= mod_inv1; - ++s; + auto q = rotr(n * mod_inv_5, 1); + if (q <= max_value() / 10) { + n = q; + s |= 1; } - n >>= s; + return s; } // Removes trailing zeros and returns the number of zeros removed (double) -FMT_INLINE int remove_trailing_zeros(uint64_t& n) FMT_NOEXCEPT { -#ifdef FMT_BUILTIN_CTZLL - int t = FMT_BUILTIN_CTZLL(n); -#else - int t = ctzll(n); -#endif - if (t > float_info::max_trailing_zeros) - t = float_info::max_trailing_zeros; - // Divide by 10^8 and reduce to 32-bits - // Since ret_value.significand <= (2^64 - 1) / 1000 < 10^17, - // both of the quotient and the r should fit in 32-bits - - const uint32_t mod_inv1 = 0xcccccccd; - const uint32_t max_quotient1 = 0x33333333; - const uint64_t mod_inv8 = 0xc767074b22e90e21; - const uint64_t max_quotient8 = 0x00002af31dc46118; - - // If the number is divisible by 1'0000'0000, work with the quotient - if (t >= 8) { - auto quotient_candidate = n * mod_inv8; - - if (quotient_candidate <= max_quotient8) { - auto quotient = static_cast(quotient_candidate >> 8); - - int s = 8; - for (; s < t; ++s) { - if (quotient * mod_inv1 > max_quotient1) break; - quotient *= mod_inv1; - } - quotient >>= (s - 8); - n = quotient; - return s; +FMT_INLINE int remove_trailing_zeros(uint64_t& n) noexcept { + FMT_ASSERT(n != 0, ""); + + // This magic number is ceil(2^90 / 10^8). + constexpr uint64_t magic_number = 12379400392853802749ull; + auto nm = umul128(n, magic_number); + + // Is n is divisible by 10^8? + if ((nm.high() & ((1ull << (90 - 64)) - 1)) == 0 && nm.low() < magic_number) { + // If yes, work with the quotient. + auto n32 = static_cast(nm.high() >> (90 - 64)); + + const uint32_t mod_inv_5 = 0xcccccccd; + const uint32_t mod_inv_25 = mod_inv_5 * mod_inv_5; + + int s = 8; + while (true) { + auto q = rotr(n32 * mod_inv_25, 2); + if (q > max_value() / 100) break; + n32 = q; + s += 2; + } + auto q = rotr(n32 * mod_inv_5, 1); + if (q <= max_value() / 10) { + n32 = q; + s |= 1; } - } - - // Otherwise, work with the remainder - auto quotient = static_cast(n / 100000000); - auto remainder = static_cast(n - 100000000 * quotient); - - if (t == 0 || remainder * mod_inv1 > max_quotient1) { - return 0; - } - remainder *= mod_inv1; - - if (t == 1 || remainder * mod_inv1 > max_quotient1) { - n = (remainder >> 1) + quotient * 10000000ull; - return 1; - } - remainder *= mod_inv1; - - if (t == 2 || remainder * mod_inv1 > max_quotient1) { - n = (remainder >> 2) + quotient * 1000000ull; - return 2; - } - remainder *= mod_inv1; - if (t == 3 || remainder * mod_inv1 > max_quotient1) { - n = (remainder >> 3) + quotient * 100000ull; - return 3; + n = n32; + return s; } - remainder *= mod_inv1; - if (t == 4 || remainder * mod_inv1 > max_quotient1) { - n = (remainder >> 4) + quotient * 10000ull; - return 4; - } - remainder *= mod_inv1; + // If n is not divisible by 10^8, work with n itself. + const uint64_t mod_inv_5 = 0xcccccccccccccccd; + const uint64_t mod_inv_25 = mod_inv_5 * mod_inv_5; - if (t == 5 || remainder * mod_inv1 > max_quotient1) { - n = (remainder >> 5) + quotient * 1000ull; - return 5; + int s = 0; + while (true) { + auto q = rotr(n * mod_inv_25, 2); + if (q > max_value() / 100) break; + n = q; + s += 2; } - remainder *= mod_inv1; - - if (t == 6 || remainder * mod_inv1 > max_quotient1) { - n = (remainder >> 6) + quotient * 100ull; - return 6; + auto q = rotr(n * mod_inv_5, 1); + if (q <= max_value() / 10) { + n = q; + s |= 1; } - remainder *= mod_inv1; - n = (remainder >> 7) + quotient * 10ull; - return 7; + return s; } // The main algorithm for shorter interval case template -FMT_INLINE decimal_fp shorter_interval_case(int exponent) FMT_NOEXCEPT { +FMT_INLINE decimal_fp shorter_interval_case(int exponent) noexcept { decimal_fp ret_value; // Compute k and beta const int minus_k = floor_log10_pow2_minus_log10_4_over_3(exponent); - const int beta_minus_1 = exponent + floor_log2_pow10(-minus_k); + const int beta = exponent + floor_log2_pow10(-minus_k); // Compute xi and zi using cache_entry_type = typename cache_accessor::cache_entry_type; const cache_entry_type cache = cache_accessor::get_cached_power(-minus_k); auto xi = cache_accessor::compute_left_endpoint_for_shorter_interval_case( - cache, beta_minus_1); + cache, beta); auto zi = cache_accessor::compute_right_endpoint_for_shorter_interval_case( - cache, beta_minus_1); + cache, beta); // If the left endpoint is not an integer, increase it if (!is_left_endpoint_integer_shorter_interval(exponent)) ++xi; @@ -2060,8 +1254,8 @@ FMT_INLINE decimal_fp shorter_interval_case(int exponent) FMT_NOEXCEPT { // Otherwise, compute the round-up of y ret_value.significand = - cache_accessor::compute_round_up_for_shorter_interval_case( - cache, beta_minus_1); + cache_accessor::compute_round_up_for_shorter_interval_case(cache, + beta); ret_value.exponent = minus_k; // When tie occurs, choose one of them according to the rule @@ -2076,7 +1270,7 @@ FMT_INLINE decimal_fp shorter_interval_case(int exponent) FMT_NOEXCEPT { return ret_value; } -template decimal_fp to_decimal(T x) FMT_NOEXCEPT { +template decimal_fp to_decimal(T x) noexcept { // Step 1: integer promotion & Schubfach multiplier calculation. using carrier_uint = typename float_info::carrier_uint; @@ -2085,23 +1279,25 @@ template decimal_fp to_decimal(T x) FMT_NOEXCEPT { // Extract significand bits and exponent bits. const carrier_uint significand_mask = - (static_cast(1) << float_info::significand_bits) - 1; + (static_cast(1) << num_significand_bits()) - 1; carrier_uint significand = (br & significand_mask); - int exponent = static_cast((br & exponent_mask()) >> - float_info::significand_bits); + int exponent = + static_cast((br & exponent_mask()) >> num_significand_bits()); if (exponent != 0) { // Check if normal. - exponent += float_info::exponent_bias - float_info::significand_bits; + exponent -= exponent_bias() + num_significand_bits(); // Shorter interval case; proceed like Schubfach. + // In fact, when exponent == 1 and significand == 0, the interval is + // regular. However, it can be shown that the end-results are anyway same. if (significand == 0) return shorter_interval_case(exponent); - significand |= - (static_cast(1) << float_info::significand_bits); + significand |= (static_cast(1) << num_significand_bits()); } else { // Subnormal case; the interval is always regular. if (significand == 0) return {0, 0}; - exponent = float_info::min_exponent - float_info::significand_bits; + exponent = + std::numeric_limits::min_exponent - num_significand_bits() - 1; } const bool include_left_endpoint = (significand % 2 == 0); @@ -2110,402 +1306,116 @@ template decimal_fp to_decimal(T x) FMT_NOEXCEPT { // Compute k and beta. const int minus_k = floor_log10_pow2(exponent) - float_info::kappa; const cache_entry_type cache = cache_accessor::get_cached_power(-minus_k); - const int beta_minus_1 = exponent + floor_log2_pow10(-minus_k); + const int beta = exponent + floor_log2_pow10(-minus_k); - // Compute zi and deltai + // Compute zi and deltai. // 10^kappa <= deltai < 10^(kappa + 1) - const uint32_t deltai = cache_accessor::compute_delta(cache, beta_minus_1); + const uint32_t deltai = cache_accessor::compute_delta(cache, beta); const carrier_uint two_fc = significand << 1; - const carrier_uint two_fr = two_fc | 1; - const carrier_uint zi = - cache_accessor::compute_mul(two_fr << beta_minus_1, cache); - // Step 2: Try larger divisor; remove trailing zeros if necessary + // For the case of binary32, the result of integer check is not correct for + // 29711844 * 2^-82 + // = 6.1442653300000000008655037797566933477355632930994033813476... * 10^-18 + // and 29711844 * 2^-81 + // = 1.2288530660000000001731007559513386695471126586198806762695... * 10^-17, + // and they are the unique counterexamples. However, since 29711844 is even, + // this does not cause any problem for the endpoints calculations; it can only + // cause a problem when we need to perform integer check for the center. + // Fortunately, with these inputs, that branch is never executed, so we are + // fine. + const typename cache_accessor::compute_mul_result z_mul = + cache_accessor::compute_mul((two_fc | 1) << beta, cache); + + // Step 2: Try larger divisor; remove trailing zeros if necessary. // Using an upper bound on zi, we might be able to optimize the division - // better than the compiler; we are computing zi / big_divisor here + // better than the compiler; we are computing zi / big_divisor here. decimal_fp ret_value; - ret_value.significand = divide_by_10_to_kappa_plus_1(zi); - uint32_t r = static_cast(zi - float_info::big_divisor * - ret_value.significand); + ret_value.significand = divide_by_10_to_kappa_plus_1(z_mul.result); + uint32_t r = static_cast(z_mul.result - float_info::big_divisor * + ret_value.significand); - if (r > deltai) { - goto small_divisor_case_label; - } else if (r < deltai) { - // Exclude the right endpoint if necessary - if (r == 0 && !include_right_endpoint && - is_endpoint_integer(two_fr, exponent, minus_k)) { + if (r < deltai) { + // Exclude the right endpoint if necessary. + if (r == 0 && (z_mul.is_integer & !include_right_endpoint)) { --ret_value.significand; r = float_info::big_divisor; goto small_divisor_case_label; } + } else if (r > deltai) { + goto small_divisor_case_label; } else { - // r == deltai; compare fractional parts - // Check conditions in the order different from the paper - // to take advantage of short-circuiting - const carrier_uint two_fl = two_fc - 1; - if ((!include_left_endpoint || - !is_endpoint_integer(two_fl, exponent, minus_k)) && - !cache_accessor::compute_mul_parity(two_fl, cache, beta_minus_1)) { + // r == deltai; compare fractional parts. + const typename cache_accessor::compute_mul_parity_result x_mul = + cache_accessor::compute_mul_parity(two_fc - 1, cache, beta); + + if (!(x_mul.parity | (x_mul.is_integer & include_left_endpoint))) goto small_divisor_case_label; - } } ret_value.exponent = minus_k + float_info::kappa + 1; - // We may need to remove trailing zeros + // We may need to remove trailing zeros. ret_value.exponent += remove_trailing_zeros(ret_value.significand); return ret_value; - // Step 3: Find the significand with the smaller divisor + // Step 3: Find the significand with the smaller divisor. small_divisor_case_label: ret_value.significand *= 10; ret_value.exponent = minus_k + float_info::kappa; - const uint32_t mask = (1u << float_info::kappa) - 1; - auto dist = r - (deltai / 2) + (float_info::small_divisor / 2); - - // Is dist divisible by 2^kappa? - if ((dist & mask) == 0) { - const bool approx_y_parity = - ((dist ^ (float_info::small_divisor / 2)) & 1) != 0; - dist >>= float_info::kappa; - - // Is dist divisible by 5^kappa? - if (check_divisibility_and_divide_by_pow5::kappa>(dist)) { - ret_value.significand += dist; - - // Check z^(f) >= epsilon^(f) - // We have either yi == zi - epsiloni or yi == (zi - epsiloni) - 1, - // where yi == zi - epsiloni if and only if z^(f) >= epsilon^(f) - // Since there are only 2 possibilities, we only need to care about the - // parity. Also, zi and r should have the same parity since the divisor - // is an even number - if (cache_accessor::compute_mul_parity(two_fc, cache, beta_minus_1) != - approx_y_parity) { - --ret_value.significand; - } else { - // If z^(f) >= epsilon^(f), we might have a tie - // when z^(f) == epsilon^(f), or equivalently, when y is an integer - if (is_center_integer(two_fc, exponent, minus_k)) { - ret_value.significand = ret_value.significand % 2 == 0 - ? ret_value.significand - : ret_value.significand - 1; - } - } - } - // Is dist not divisible by 5^kappa? - else { - ret_value.significand += dist; - } - } - // Is dist not divisible by 2^kappa? - else { - // Since we know dist is small, we might be able to optimize the division - // better than the compiler; we are computing dist / small_divisor here - ret_value.significand += - small_division_by_pow10::kappa>(dist); - } + uint32_t dist = r - (deltai / 2) + (float_info::small_divisor / 2); + const bool approx_y_parity = + ((dist ^ (float_info::small_divisor / 2)) & 1) != 0; + + // Is dist divisible by 10^kappa? + const bool divisible_by_small_divisor = + check_divisibility_and_divide_by_pow10::kappa>(dist); + + // Add dist / 10^kappa to the significand. + ret_value.significand += dist; + + if (!divisible_by_small_divisor) return ret_value; + + // Check z^(f) >= epsilon^(f). + // We have either yi == zi - epsiloni or yi == (zi - epsiloni) - 1, + // where yi == zi - epsiloni if and only if z^(f) >= epsilon^(f). + // Since there are only 2 possibilities, we only need to care about the + // parity. Also, zi and r should have the same parity since the divisor + // is an even number. + const auto y_mul = cache_accessor::compute_mul_parity(two_fc, cache, beta); + + // If z^(f) >= epsilon^(f), we might have a tie when z^(f) == epsilon^(f), + // or equivalently, when y is an integer. + if (y_mul.parity != approx_y_parity) + --ret_value.significand; + else if (y_mul.is_integer & (ret_value.significand % 2 != 0)) + --ret_value.significand; return ret_value; } } // namespace dragonbox -// Formats value using a variation of the Fixed-Precision Positive -// Floating-Point Printout ((FPP)^2) algorithm by Steele & White: -// https://fmt.dev/papers/p372-steele.pdf. -template -void fallback_format(Double d, int num_digits, bool binary32, buffer& buf, - int& exp10) { - bigint numerator; // 2 * R in (FPP)^2. - bigint denominator; // 2 * S in (FPP)^2. - // lower and upper are differences between value and corresponding boundaries. - bigint lower; // (M^- in (FPP)^2). - bigint upper_store; // upper's value if different from lower. - bigint* upper = nullptr; // (M^+ in (FPP)^2). - fp value; - // Shift numerator and denominator by an extra bit or two (if lower boundary - // is closer) to make lower and upper integers. This eliminates multiplication - // by 2 during later computations. - const bool is_predecessor_closer = - binary32 ? value.assign(static_cast(d)) : value.assign(d); - int shift = is_predecessor_closer ? 2 : 1; - uint64_t significand = value.f << shift; - if (value.e >= 0) { - numerator.assign(significand); - numerator <<= value.e; - lower.assign(1); - lower <<= value.e; - if (shift != 1) { - upper_store.assign(1); - upper_store <<= value.e + 1; - upper = &upper_store; - } - denominator.assign_pow10(exp10); - denominator <<= shift; - } else if (exp10 < 0) { - numerator.assign_pow10(-exp10); - lower.assign(numerator); - if (shift != 1) { - upper_store.assign(numerator); - upper_store <<= 1; - upper = &upper_store; - } - numerator *= significand; - denominator.assign(1); - denominator <<= shift - value.e; - } else { - numerator.assign(significand); - denominator.assign_pow10(exp10); - denominator <<= shift - value.e; - lower.assign(1); - if (shift != 1) { - upper_store.assign(1ULL << 1); - upper = &upper_store; - } - } - // Invariant: value == (numerator / denominator) * pow(10, exp10). - if (num_digits < 0) { - // Generate the shortest representation. - if (!upper) upper = &lower; - bool even = (value.f & 1) == 0; - num_digits = 0; - char* data = buf.data(); - for (;;) { - int digit = numerator.divmod_assign(denominator); - bool low = compare(numerator, lower) - even < 0; // numerator <[=] lower. - // numerator + upper >[=] pow10: - bool high = add_compare(numerator, *upper, denominator) + even > 0; - data[num_digits++] = static_cast('0' + digit); - if (low || high) { - if (!low) { - ++data[num_digits - 1]; - } else if (high) { - int result = add_compare(numerator, numerator, denominator); - // Round half to even. - if (result > 0 || (result == 0 && (digit % 2) != 0)) - ++data[num_digits - 1]; - } - buf.try_resize(to_unsigned(num_digits)); - exp10 -= num_digits - 1; - return; - } - numerator *= 10; - lower *= 10; - if (upper != &lower) *upper *= 10; - } - } - // Generate the given number of digits. - exp10 -= num_digits - 1; - if (num_digits == 0) { - buf.try_resize(1); - denominator *= 10; - buf[0] = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0'; - return; - } - buf.try_resize(to_unsigned(num_digits)); - for (int i = 0; i < num_digits - 1; ++i) { - int digit = numerator.divmod_assign(denominator); - buf[i] = static_cast('0' + digit); - numerator *= 10; - } - int digit = numerator.divmod_assign(denominator); - auto result = add_compare(numerator, numerator, denominator); - if (result > 0 || (result == 0 && (digit % 2) != 0)) { - if (digit == 9) { - const auto overflow = '0' + 10; - buf[num_digits - 1] = overflow; - // Propagate the carry. - for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) { - buf[i] = '0'; - ++buf[i - 1]; - } - if (buf[0] == overflow) { - buf[0] = '1'; - ++exp10; - } - return; - } - ++digit; - } - buf[num_digits - 1] = static_cast('0' + digit); +#ifdef _MSC_VER +FMT_FUNC auto fmt_snprintf(char* buf, size_t size, const char* fmt, ...) + -> int { + auto args = va_list(); + va_start(args, fmt); + int result = vsnprintf_s(buf, size, _TRUNCATE, fmt, args); + va_end(args); + return result; } - -template -int format_float(T value, int precision, float_specs specs, buffer& buf) { - static_assert(!std::is_same::value, ""); - FMT_ASSERT(value >= 0, "value is negative"); - - const bool fixed = specs.format == float_format::fixed; - if (value <= 0) { // <= instead of == to silence a warning. - if (precision <= 0 || !fixed) { - buf.push_back('0'); - return 0; - } - buf.try_resize(to_unsigned(precision)); - std::uninitialized_fill_n(buf.data(), precision, '0'); - return -precision; - } - - if (!specs.use_grisu) return snprintf_float(value, precision, specs, buf); - - if (precision < 0) { - // Use Dragonbox for the shortest format. - if (specs.binary32) { - auto dec = dragonbox::to_decimal(static_cast(value)); - write(buffer_appender(buf), dec.significand); - return dec.exponent; - } - auto dec = dragonbox::to_decimal(static_cast(value)); - write(buffer_appender(buf), dec.significand); - return dec.exponent; - } - - // Use Grisu + Dragon4 for the given precision: - // https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf. - int exp = 0; - const int min_exp = -60; // alpha in Grisu. - int cached_exp10 = 0; // K in Grisu. - fp normalized = normalize(fp(value)); - const auto cached_pow = get_cached_power( - min_exp - (normalized.e + fp::significand_size), cached_exp10); - normalized = normalized * cached_pow; - // Limit precision to the maximum possible number of significant digits in an - // IEEE754 double because we don't need to generate zeros. - const int max_double_digits = 767; - if (precision > max_double_digits) precision = max_double_digits; - fixed_handler handler{buf.data(), 0, precision, -cached_exp10, fixed}; - if (grisu_gen_digits(normalized, 1, exp, handler) == digits::error) { - exp += handler.size - cached_exp10 - 1; - fallback_format(value, handler.precision, specs.binary32, buf, exp); - } else { - exp += handler.exp10; - buf.try_resize(to_unsigned(handler.size)); - } - if (!fixed && !specs.showpoint) { - // Remove trailing zeros. - auto num_digits = buf.size(); - while (num_digits > 0 && buf[num_digits - 1] == '0') { - --num_digits; - ++exp; - } - buf.try_resize(num_digits); - } - return exp; -} // namespace detail - -template -int snprintf_float(T value, int precision, float_specs specs, - buffer& buf) { - // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail. - FMT_ASSERT(buf.capacity() > buf.size(), "empty buffer"); - static_assert(!std::is_same::value, ""); - - // Subtract 1 to account for the difference in precision since we use %e for - // both general and exponent format. - if (specs.format == float_format::general || - specs.format == float_format::exp) - precision = (precision >= 0 ? precision : 6) - 1; - - // Build the format string. - enum { max_format_size = 7 }; // The longest format is "%#.*Le". - char format[max_format_size]; - char* format_ptr = format; - *format_ptr++ = '%'; - if (specs.showpoint && specs.format == float_format::hex) *format_ptr++ = '#'; - if (precision >= 0) { - *format_ptr++ = '.'; - *format_ptr++ = '*'; - } - if (std::is_same()) *format_ptr++ = 'L'; - *format_ptr++ = specs.format != float_format::hex - ? (specs.format == float_format::fixed ? 'f' : 'e') - : (specs.upper ? 'A' : 'a'); - *format_ptr = '\0'; - - // Format using snprintf. - auto offset = buf.size(); - for (;;) { - auto begin = buf.data() + offset; - auto capacity = buf.capacity() - offset; -#ifdef FMT_FUZZ - if (precision > 100000) - throw std::runtime_error( - "fuzz mode - avoid large allocation inside snprintf"); #endif - // Suppress the warning about a nonliteral format string. - // Cannot use auto because of a bug in MinGW (#1532). - int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF; - int result = precision >= 0 - ? snprintf_ptr(begin, capacity, format, precision, value) - : snprintf_ptr(begin, capacity, format, value); - if (result < 0) { - // The buffer will grow exponentially. - buf.try_reserve(buf.capacity() + 1); - continue; - } - auto size = to_unsigned(result); - // Size equal to capacity means that the last character was truncated. - if (size >= capacity) { - buf.try_reserve(size + offset + 1); // Add 1 for the terminating '\0'. - continue; - } - auto is_digit = [](char c) { return c >= '0' && c <= '9'; }; - if (specs.format == float_format::fixed) { - if (precision == 0) { - buf.try_resize(size); - return 0; - } - // Find and remove the decimal point. - auto end = begin + size, p = end; - do { - --p; - } while (is_digit(*p)); - int fraction_size = static_cast(end - p - 1); - std::memmove(p, p + 1, to_unsigned(fraction_size)); - buf.try_resize(size - 1); - return -fraction_size; - } - if (specs.format == float_format::hex) { - buf.try_resize(size + offset); - return 0; - } - // Find and parse the exponent. - auto end = begin + size, exp_pos = end; - do { - --exp_pos; - } while (*exp_pos != 'e'); - char sign = exp_pos[1]; - FMT_ASSERT(sign == '+' || sign == '-', ""); - int exp = 0; - auto p = exp_pos + 2; // Skip 'e' and sign. - do { - FMT_ASSERT(is_digit(*p), ""); - exp = exp * 10 + (*p++ - '0'); - } while (p != end); - if (sign == '-') exp = -exp; - int fraction_size = 0; - if (exp_pos != begin + 1) { - // Remove trailing zeros. - auto fraction_end = exp_pos - 1; - while (*fraction_end == '0') --fraction_end; - // Move the fractional part left to get rid of the decimal point. - fraction_size = static_cast(fraction_end - begin - 1); - std::memmove(begin + 1, begin + 2, to_unsigned(fraction_size)); - } - buf.try_resize(to_unsigned(fraction_size) + offset + 1); - return exp - fraction_size; - } -} } // namespace detail template <> struct formatter { - FMT_CONSTEXPR format_parse_context::iterator parse( - format_parse_context& ctx) { + FMT_CONSTEXPR auto parse(format_parse_context& ctx) + -> format_parse_context::iterator { return ctx.begin(); } - format_context::iterator format(const detail::bigint& n, - format_context& ctx) { + template + auto format(const detail::bigint& n, FormatContext& ctx) const -> + typename FormatContext::iterator { auto out = ctx.out(); bool first = true; for (auto i = n.bigits_.size(); i > 0; --i) { @@ -2525,8 +1435,8 @@ template <> struct formatter { }; FMT_FUNC detail::utf8_to_utf16::utf8_to_utf16(string_view s) { - for_each_codepoint(s, [this](uint32_t cp, int error) { - if (error != 0) FMT_THROW(std::runtime_error("invalid utf8")); + for_each_codepoint(s, [this](uint32_t cp, string_view) { + if (cp == invalid_code_point) FMT_THROW(std::runtime_error("invalid utf8")); if (cp <= 0xFFFF) { buffer_.push_back(static_cast(cp)); } else { @@ -2534,12 +1444,13 @@ FMT_FUNC detail::utf8_to_utf16::utf8_to_utf16(string_view s) { buffer_.push_back(static_cast(0xD800 + (cp >> 10))); buffer_.push_back(static_cast(0xDC00 + (cp & 0x3FF))); } + return true; }); buffer_.push_back(0); } FMT_FUNC void format_system_error(detail::buffer& out, int error_code, - const char* message) FMT_NOEXCEPT { + const char* message) noexcept { FMT_TRY { auto ec = std::error_code(error_code, std::generic_category()); write(std::back_inserter(out), std::system_error(ec, message).what()); @@ -2549,12 +1460,8 @@ FMT_FUNC void format_system_error(detail::buffer& out, int error_code, format_error_code(out, error_code, message); } -FMT_FUNC void detail::error_handler::on_error(const char* message) { - FMT_THROW(format_error(message)); -} - FMT_FUNC void report_system_error(int error_code, - const char* message) FMT_NOEXCEPT { + const char* message) noexcept { report_error(format_system_error, error_code, message); } @@ -2566,17 +1473,13 @@ FMT_FUNC std::string vformat(string_view fmt, format_args args) { return to_string(buffer); } -#ifdef _WIN32 namespace detail { +#ifdef _WIN32 using dword = conditional_t; extern "C" __declspec(dllimport) int __stdcall WriteConsoleW( // void*, const void*, dword, dword*, void*); -} // namespace detail -#endif -namespace detail { -FMT_FUNC void print(std::FILE* f, string_view text) { -#ifdef _WIN32 +FMT_FUNC bool write_console(std::FILE* f, string_view text) { auto fd = _fileno(f); if (_isatty(fd)) { detail::utf8_to_utf16 u16(string_view(text.data(), text.size())); @@ -2584,11 +1487,20 @@ FMT_FUNC void print(std::FILE* f, string_view text) { if (detail::WriteConsoleW(reinterpret_cast(_get_osfhandle(fd)), u16.c_str(), static_cast(u16.size()), &written, nullptr)) { - return; + return true; } - // Fallback to fwrite on failure. It can happen if the output has been - // redirected to NUL. } + // We return false if the file descriptor was not TTY, or it was but + // SetConsoleW failed which can happen if the output has been redirected to + // NUL. In both cases when we return false, we should attempt to do regular + // write via fwrite or std::ostream::write. + return false; +} +#endif + +FMT_FUNC void print(std::FILE* f, string_view text) { +#ifdef _WIN32 + if (write_console(f, text)) return; #endif detail::fwrite_fully(text.data(), 1, text.size(), f); } @@ -2615,6 +1527,197 @@ FMT_FUNC void vprint(string_view format_str, format_args args) { vprint(stdout, format_str, args); } +namespace detail { + +struct singleton { + unsigned char upper; + unsigned char lower_count; +}; + +inline auto is_printable(uint16_t x, const singleton* singletons, + size_t singletons_size, + const unsigned char* singleton_lowers, + const unsigned char* normal, size_t normal_size) + -> bool { + auto upper = x >> 8; + auto lower_start = 0; + for (size_t i = 0; i < singletons_size; ++i) { + auto s = singletons[i]; + auto lower_end = lower_start + s.lower_count; + if (upper < s.upper) break; + if (upper == s.upper) { + for (auto j = lower_start; j < lower_end; ++j) { + if (singleton_lowers[j] == (x & 0xff)) return false; + } + } + lower_start = lower_end; + } + + auto xsigned = static_cast(x); + auto current = true; + for (size_t i = 0; i < normal_size; ++i) { + auto v = static_cast(normal[i]); + auto len = (v & 0x80) != 0 ? (v & 0x7f) << 8 | normal[++i] : v; + xsigned -= len; + if (xsigned < 0) break; + current = !current; + } + return current; +} + +// This code is generated by support/printable.py. +FMT_FUNC auto is_printable(uint32_t cp) -> bool { + static constexpr singleton singletons0[] = { + {0x00, 1}, {0x03, 5}, {0x05, 6}, {0x06, 3}, {0x07, 6}, {0x08, 8}, + {0x09, 17}, {0x0a, 28}, {0x0b, 25}, {0x0c, 20}, {0x0d, 16}, {0x0e, 13}, + {0x0f, 4}, {0x10, 3}, {0x12, 18}, {0x13, 9}, {0x16, 1}, {0x17, 5}, + {0x18, 2}, {0x19, 3}, {0x1a, 7}, {0x1c, 2}, {0x1d, 1}, {0x1f, 22}, + {0x20, 3}, {0x2b, 3}, {0x2c, 2}, {0x2d, 11}, {0x2e, 1}, {0x30, 3}, + {0x31, 2}, {0x32, 1}, {0xa7, 2}, {0xa9, 2}, {0xaa, 4}, {0xab, 8}, + {0xfa, 2}, {0xfb, 5}, {0xfd, 4}, {0xfe, 3}, {0xff, 9}, + }; + static constexpr unsigned char singletons0_lower[] = { + 0xad, 0x78, 0x79, 0x8b, 0x8d, 0xa2, 0x30, 0x57, 0x58, 0x8b, 0x8c, 0x90, + 0x1c, 0x1d, 0xdd, 0x0e, 0x0f, 0x4b, 0x4c, 0xfb, 0xfc, 0x2e, 0x2f, 0x3f, + 0x5c, 0x5d, 0x5f, 0xb5, 0xe2, 0x84, 0x8d, 0x8e, 0x91, 0x92, 0xa9, 0xb1, + 0xba, 0xbb, 0xc5, 0xc6, 0xc9, 0xca, 0xde, 0xe4, 0xe5, 0xff, 0x00, 0x04, + 0x11, 0x12, 0x29, 0x31, 0x34, 0x37, 0x3a, 0x3b, 0x3d, 0x49, 0x4a, 0x5d, + 0x84, 0x8e, 0x92, 0xa9, 0xb1, 0xb4, 0xba, 0xbb, 0xc6, 0xca, 0xce, 0xcf, + 0xe4, 0xe5, 0x00, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a, + 0x3b, 0x45, 0x46, 0x49, 0x4a, 0x5e, 0x64, 0x65, 0x84, 0x91, 0x9b, 0x9d, + 0xc9, 0xce, 0xcf, 0x0d, 0x11, 0x29, 0x45, 0x49, 0x57, 0x64, 0x65, 0x8d, + 0x91, 0xa9, 0xb4, 0xba, 0xbb, 0xc5, 0xc9, 0xdf, 0xe4, 0xe5, 0xf0, 0x0d, + 0x11, 0x45, 0x49, 0x64, 0x65, 0x80, 0x84, 0xb2, 0xbc, 0xbe, 0xbf, 0xd5, + 0xd7, 0xf0, 0xf1, 0x83, 0x85, 0x8b, 0xa4, 0xa6, 0xbe, 0xbf, 0xc5, 0xc7, + 0xce, 0xcf, 0xda, 0xdb, 0x48, 0x98, 0xbd, 0xcd, 0xc6, 0xce, 0xcf, 0x49, + 0x4e, 0x4f, 0x57, 0x59, 0x5e, 0x5f, 0x89, 0x8e, 0x8f, 0xb1, 0xb6, 0xb7, + 0xbf, 0xc1, 0xc6, 0xc7, 0xd7, 0x11, 0x16, 0x17, 0x5b, 0x5c, 0xf6, 0xf7, + 0xfe, 0xff, 0x80, 0x0d, 0x6d, 0x71, 0xde, 0xdf, 0x0e, 0x0f, 0x1f, 0x6e, + 0x6f, 0x1c, 0x1d, 0x5f, 0x7d, 0x7e, 0xae, 0xaf, 0xbb, 0xbc, 0xfa, 0x16, + 0x17, 0x1e, 0x1f, 0x46, 0x47, 0x4e, 0x4f, 0x58, 0x5a, 0x5c, 0x5e, 0x7e, + 0x7f, 0xb5, 0xc5, 0xd4, 0xd5, 0xdc, 0xf0, 0xf1, 0xf5, 0x72, 0x73, 0x8f, + 0x74, 0x75, 0x96, 0x2f, 0x5f, 0x26, 0x2e, 0x2f, 0xa7, 0xaf, 0xb7, 0xbf, + 0xc7, 0xcf, 0xd7, 0xdf, 0x9a, 0x40, 0x97, 0x98, 0x30, 0x8f, 0x1f, 0xc0, + 0xc1, 0xce, 0xff, 0x4e, 0x4f, 0x5a, 0x5b, 0x07, 0x08, 0x0f, 0x10, 0x27, + 0x2f, 0xee, 0xef, 0x6e, 0x6f, 0x37, 0x3d, 0x3f, 0x42, 0x45, 0x90, 0x91, + 0xfe, 0xff, 0x53, 0x67, 0x75, 0xc8, 0xc9, 0xd0, 0xd1, 0xd8, 0xd9, 0xe7, + 0xfe, 0xff, + }; + static constexpr singleton singletons1[] = { + {0x00, 6}, {0x01, 1}, {0x03, 1}, {0x04, 2}, {0x08, 8}, {0x09, 2}, + {0x0a, 5}, {0x0b, 2}, {0x0e, 4}, {0x10, 1}, {0x11, 2}, {0x12, 5}, + {0x13, 17}, {0x14, 1}, {0x15, 2}, {0x17, 2}, {0x19, 13}, {0x1c, 5}, + {0x1d, 8}, {0x24, 1}, {0x6a, 3}, {0x6b, 2}, {0xbc, 2}, {0xd1, 2}, + {0xd4, 12}, {0xd5, 9}, {0xd6, 2}, {0xd7, 2}, {0xda, 1}, {0xe0, 5}, + {0xe1, 2}, {0xe8, 2}, {0xee, 32}, {0xf0, 4}, {0xf8, 2}, {0xf9, 2}, + {0xfa, 2}, {0xfb, 1}, + }; + static constexpr unsigned char singletons1_lower[] = { + 0x0c, 0x27, 0x3b, 0x3e, 0x4e, 0x4f, 0x8f, 0x9e, 0x9e, 0x9f, 0x06, 0x07, + 0x09, 0x36, 0x3d, 0x3e, 0x56, 0xf3, 0xd0, 0xd1, 0x04, 0x14, 0x18, 0x36, + 0x37, 0x56, 0x57, 0x7f, 0xaa, 0xae, 0xaf, 0xbd, 0x35, 0xe0, 0x12, 0x87, + 0x89, 0x8e, 0x9e, 0x04, 0x0d, 0x0e, 0x11, 0x12, 0x29, 0x31, 0x34, 0x3a, + 0x45, 0x46, 0x49, 0x4a, 0x4e, 0x4f, 0x64, 0x65, 0x5c, 0xb6, 0xb7, 0x1b, + 0x1c, 0x07, 0x08, 0x0a, 0x0b, 0x14, 0x17, 0x36, 0x39, 0x3a, 0xa8, 0xa9, + 0xd8, 0xd9, 0x09, 0x37, 0x90, 0x91, 0xa8, 0x07, 0x0a, 0x3b, 0x3e, 0x66, + 0x69, 0x8f, 0x92, 0x6f, 0x5f, 0xee, 0xef, 0x5a, 0x62, 0x9a, 0x9b, 0x27, + 0x28, 0x55, 0x9d, 0xa0, 0xa1, 0xa3, 0xa4, 0xa7, 0xa8, 0xad, 0xba, 0xbc, + 0xc4, 0x06, 0x0b, 0x0c, 0x15, 0x1d, 0x3a, 0x3f, 0x45, 0x51, 0xa6, 0xa7, + 0xcc, 0xcd, 0xa0, 0x07, 0x19, 0x1a, 0x22, 0x25, 0x3e, 0x3f, 0xc5, 0xc6, + 0x04, 0x20, 0x23, 0x25, 0x26, 0x28, 0x33, 0x38, 0x3a, 0x48, 0x4a, 0x4c, + 0x50, 0x53, 0x55, 0x56, 0x58, 0x5a, 0x5c, 0x5e, 0x60, 0x63, 0x65, 0x66, + 0x6b, 0x73, 0x78, 0x7d, 0x7f, 0x8a, 0xa4, 0xaa, 0xaf, 0xb0, 0xc0, 0xd0, + 0xae, 0xaf, 0x79, 0xcc, 0x6e, 0x6f, 0x93, + }; + static constexpr unsigned char normal0[] = { + 0x00, 0x20, 0x5f, 0x22, 0x82, 0xdf, 0x04, 0x82, 0x44, 0x08, 0x1b, 0x04, + 0x06, 0x11, 0x81, 0xac, 0x0e, 0x80, 0xab, 0x35, 0x28, 0x0b, 0x80, 0xe0, + 0x03, 0x19, 0x08, 0x01, 0x04, 0x2f, 0x04, 0x34, 0x04, 0x07, 0x03, 0x01, + 0x07, 0x06, 0x07, 0x11, 0x0a, 0x50, 0x0f, 0x12, 0x07, 0x55, 0x07, 0x03, + 0x04, 0x1c, 0x0a, 0x09, 0x03, 0x08, 0x03, 0x07, 0x03, 0x02, 0x03, 0x03, + 0x03, 0x0c, 0x04, 0x05, 0x03, 0x0b, 0x06, 0x01, 0x0e, 0x15, 0x05, 0x3a, + 0x03, 0x11, 0x07, 0x06, 0x05, 0x10, 0x07, 0x57, 0x07, 0x02, 0x07, 0x15, + 0x0d, 0x50, 0x04, 0x43, 0x03, 0x2d, 0x03, 0x01, 0x04, 0x11, 0x06, 0x0f, + 0x0c, 0x3a, 0x04, 0x1d, 0x25, 0x5f, 0x20, 0x6d, 0x04, 0x6a, 0x25, 0x80, + 0xc8, 0x05, 0x82, 0xb0, 0x03, 0x1a, 0x06, 0x82, 0xfd, 0x03, 0x59, 0x07, + 0x15, 0x0b, 0x17, 0x09, 0x14, 0x0c, 0x14, 0x0c, 0x6a, 0x06, 0x0a, 0x06, + 0x1a, 0x06, 0x59, 0x07, 0x2b, 0x05, 0x46, 0x0a, 0x2c, 0x04, 0x0c, 0x04, + 0x01, 0x03, 0x31, 0x0b, 0x2c, 0x04, 0x1a, 0x06, 0x0b, 0x03, 0x80, 0xac, + 0x06, 0x0a, 0x06, 0x21, 0x3f, 0x4c, 0x04, 0x2d, 0x03, 0x74, 0x08, 0x3c, + 0x03, 0x0f, 0x03, 0x3c, 0x07, 0x38, 0x08, 0x2b, 0x05, 0x82, 0xff, 0x11, + 0x18, 0x08, 0x2f, 0x11, 0x2d, 0x03, 0x20, 0x10, 0x21, 0x0f, 0x80, 0x8c, + 0x04, 0x82, 0x97, 0x19, 0x0b, 0x15, 0x88, 0x94, 0x05, 0x2f, 0x05, 0x3b, + 0x07, 0x02, 0x0e, 0x18, 0x09, 0x80, 0xb3, 0x2d, 0x74, 0x0c, 0x80, 0xd6, + 0x1a, 0x0c, 0x05, 0x80, 0xff, 0x05, 0x80, 0xdf, 0x0c, 0xee, 0x0d, 0x03, + 0x84, 0x8d, 0x03, 0x37, 0x09, 0x81, 0x5c, 0x14, 0x80, 0xb8, 0x08, 0x80, + 0xcb, 0x2a, 0x38, 0x03, 0x0a, 0x06, 0x38, 0x08, 0x46, 0x08, 0x0c, 0x06, + 0x74, 0x0b, 0x1e, 0x03, 0x5a, 0x04, 0x59, 0x09, 0x80, 0x83, 0x18, 0x1c, + 0x0a, 0x16, 0x09, 0x4c, 0x04, 0x80, 0x8a, 0x06, 0xab, 0xa4, 0x0c, 0x17, + 0x04, 0x31, 0xa1, 0x04, 0x81, 0xda, 0x26, 0x07, 0x0c, 0x05, 0x05, 0x80, + 0xa5, 0x11, 0x81, 0x6d, 0x10, 0x78, 0x28, 0x2a, 0x06, 0x4c, 0x04, 0x80, + 0x8d, 0x04, 0x80, 0xbe, 0x03, 0x1b, 0x03, 0x0f, 0x0d, + }; + static constexpr unsigned char normal1[] = { + 0x5e, 0x22, 0x7b, 0x05, 0x03, 0x04, 0x2d, 0x03, 0x66, 0x03, 0x01, 0x2f, + 0x2e, 0x80, 0x82, 0x1d, 0x03, 0x31, 0x0f, 0x1c, 0x04, 0x24, 0x09, 0x1e, + 0x05, 0x2b, 0x05, 0x44, 0x04, 0x0e, 0x2a, 0x80, 0xaa, 0x06, 0x24, 0x04, + 0x24, 0x04, 0x28, 0x08, 0x34, 0x0b, 0x01, 0x80, 0x90, 0x81, 0x37, 0x09, + 0x16, 0x0a, 0x08, 0x80, 0x98, 0x39, 0x03, 0x63, 0x08, 0x09, 0x30, 0x16, + 0x05, 0x21, 0x03, 0x1b, 0x05, 0x01, 0x40, 0x38, 0x04, 0x4b, 0x05, 0x2f, + 0x04, 0x0a, 0x07, 0x09, 0x07, 0x40, 0x20, 0x27, 0x04, 0x0c, 0x09, 0x36, + 0x03, 0x3a, 0x05, 0x1a, 0x07, 0x04, 0x0c, 0x07, 0x50, 0x49, 0x37, 0x33, + 0x0d, 0x33, 0x07, 0x2e, 0x08, 0x0a, 0x81, 0x26, 0x52, 0x4e, 0x28, 0x08, + 0x2a, 0x56, 0x1c, 0x14, 0x17, 0x09, 0x4e, 0x04, 0x1e, 0x0f, 0x43, 0x0e, + 0x19, 0x07, 0x0a, 0x06, 0x48, 0x08, 0x27, 0x09, 0x75, 0x0b, 0x3f, 0x41, + 0x2a, 0x06, 0x3b, 0x05, 0x0a, 0x06, 0x51, 0x06, 0x01, 0x05, 0x10, 0x03, + 0x05, 0x80, 0x8b, 0x62, 0x1e, 0x48, 0x08, 0x0a, 0x80, 0xa6, 0x5e, 0x22, + 0x45, 0x0b, 0x0a, 0x06, 0x0d, 0x13, 0x39, 0x07, 0x0a, 0x36, 0x2c, 0x04, + 0x10, 0x80, 0xc0, 0x3c, 0x64, 0x53, 0x0c, 0x48, 0x09, 0x0a, 0x46, 0x45, + 0x1b, 0x48, 0x08, 0x53, 0x1d, 0x39, 0x81, 0x07, 0x46, 0x0a, 0x1d, 0x03, + 0x47, 0x49, 0x37, 0x03, 0x0e, 0x08, 0x0a, 0x06, 0x39, 0x07, 0x0a, 0x81, + 0x36, 0x19, 0x80, 0xb7, 0x01, 0x0f, 0x32, 0x0d, 0x83, 0x9b, 0x66, 0x75, + 0x0b, 0x80, 0xc4, 0x8a, 0xbc, 0x84, 0x2f, 0x8f, 0xd1, 0x82, 0x47, 0xa1, + 0xb9, 0x82, 0x39, 0x07, 0x2a, 0x04, 0x02, 0x60, 0x26, 0x0a, 0x46, 0x0a, + 0x28, 0x05, 0x13, 0x82, 0xb0, 0x5b, 0x65, 0x4b, 0x04, 0x39, 0x07, 0x11, + 0x40, 0x05, 0x0b, 0x02, 0x0e, 0x97, 0xf8, 0x08, 0x84, 0xd6, 0x2a, 0x09, + 0xa2, 0xf7, 0x81, 0x1f, 0x31, 0x03, 0x11, 0x04, 0x08, 0x81, 0x8c, 0x89, + 0x04, 0x6b, 0x05, 0x0d, 0x03, 0x09, 0x07, 0x10, 0x93, 0x60, 0x80, 0xf6, + 0x0a, 0x73, 0x08, 0x6e, 0x17, 0x46, 0x80, 0x9a, 0x14, 0x0c, 0x57, 0x09, + 0x19, 0x80, 0x87, 0x81, 0x47, 0x03, 0x85, 0x42, 0x0f, 0x15, 0x85, 0x50, + 0x2b, 0x80, 0xd5, 0x2d, 0x03, 0x1a, 0x04, 0x02, 0x81, 0x70, 0x3a, 0x05, + 0x01, 0x85, 0x00, 0x80, 0xd7, 0x29, 0x4c, 0x04, 0x0a, 0x04, 0x02, 0x83, + 0x11, 0x44, 0x4c, 0x3d, 0x80, 0xc2, 0x3c, 0x06, 0x01, 0x04, 0x55, 0x05, + 0x1b, 0x34, 0x02, 0x81, 0x0e, 0x2c, 0x04, 0x64, 0x0c, 0x56, 0x0a, 0x80, + 0xae, 0x38, 0x1d, 0x0d, 0x2c, 0x04, 0x09, 0x07, 0x02, 0x0e, 0x06, 0x80, + 0x9a, 0x83, 0xd8, 0x08, 0x0d, 0x03, 0x0d, 0x03, 0x74, 0x0c, 0x59, 0x07, + 0x0c, 0x14, 0x0c, 0x04, 0x38, 0x08, 0x0a, 0x06, 0x28, 0x08, 0x22, 0x4e, + 0x81, 0x54, 0x0c, 0x15, 0x03, 0x03, 0x05, 0x07, 0x09, 0x19, 0x07, 0x07, + 0x09, 0x03, 0x0d, 0x07, 0x29, 0x80, 0xcb, 0x25, 0x0a, 0x84, 0x06, + }; + auto lower = static_cast(cp); + if (cp < 0x10000) { + return is_printable(lower, singletons0, + sizeof(singletons0) / sizeof(*singletons0), + singletons0_lower, normal0, sizeof(normal0)); + } + if (cp < 0x20000) { + return is_printable(lower, singletons1, + sizeof(singletons1) / sizeof(*singletons1), + singletons1_lower, normal1, sizeof(normal1)); + } + if (0x2a6de <= cp && cp < 0x2a700) return false; + if (0x2b735 <= cp && cp < 0x2b740) return false; + if (0x2b81e <= cp && cp < 0x2b820) return false; + if (0x2cea2 <= cp && cp < 0x2ceb0) return false; + if (0x2ebe1 <= cp && cp < 0x2f800) return false; + if (0x2fa1e <= cp && cp < 0x30000) return false; + if (0x3134b <= cp && cp < 0xe0100) return false; + if (0xe01f0 <= cp && cp < 0x110000) return false; + return cp < 0x110000; +} + +} // namespace detail + FMT_END_NAMESPACE #endif // FMT_FORMAT_INL_H_ diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bundled/format.h b/Lumos/External/spdlog/include/spdlog/fmt/bundled/format.h index 5398a23a8..7c607dbd3 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/bundled/format.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/bundled/format.h @@ -1,33 +1,33 @@ /* - Formatting library for C++ - - Copyright (c) 2012 - present, Victor Zverovich - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - --- Optional exception to the license --- - - As an exception, if, as a result of your compiling your source code, portions - of this Software are embedded into a machine-executable object form of such - source code, you may redistribute such embedded portions in such object form - without including the above copyright and permission notices. + Formatting library for C++ + + Copyright (c) 2012 - present, Victor Zverovich + + Permission is hereby granted, free of charge, to any person obtaining + a copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to + permit persons to whom the Software is furnished to do so, subject to + the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + --- Optional exception to the license --- + + As an exception, if, as a result of your compiling your source code, portions + of this Software are embedded into a machine-executable object form of such + source code, you may redistribute such embedded portions in such object form + without including the above copyright and permission notices. */ #ifndef FMT_FORMAT_H_ @@ -35,20 +35,22 @@ #include // std::signbit #include // uint32_t +#include // std::memcpy #include // std::numeric_limits #include // std::uninitialized_copy #include // std::runtime_error #include // std::system_error -#include // std::swap + +#ifdef __cpp_lib_bit_cast +# include // std::bitcast +#endif #include "core.h" -#ifdef __INTEL_COMPILER -# define FMT_ICC_VERSION __INTEL_COMPILER -#elif defined(__ICL) -# define FMT_ICC_VERSION __ICL +#if FMT_GCC_VERSION +# define FMT_GCC_VISIBILITY_HIDDEN __attribute__((visibility("hidden"))) #else -# define FMT_ICC_VERSION 0 +# define FMT_GCC_VISIBILITY_HIDDEN #endif #ifdef __NVCC__ @@ -69,7 +71,7 @@ # define FMT_NOINLINE #endif -#if FMT_MSC_VER +#if FMT_MSC_VERSION # define FMT_MSC_DEFAULT = default #else # define FMT_MSC_DEFAULT @@ -77,7 +79,7 @@ #ifndef FMT_THROW # if FMT_EXCEPTIONS -# if FMT_MSC_VER || FMT_NVCC +# if FMT_MSC_VERSION || defined(__NVCC__) FMT_BEGIN_NAMESPACE namespace detail { template inline void do_throw(const Exception& x) { @@ -108,31 +110,18 @@ FMT_END_NAMESPACE # define FMT_CATCH(x) if (false) #endif -#ifndef FMT_DEPRECATED -# if FMT_HAS_CPP14_ATTRIBUTE(deprecated) || FMT_MSC_VER >= 1900 -# define FMT_DEPRECATED [[deprecated]] +#ifndef FMT_MAYBE_UNUSED +# if FMT_HAS_CPP17_ATTRIBUTE(maybe_unused) +# define FMT_MAYBE_UNUSED [[maybe_unused]] # else -# if (defined(__GNUC__) && !defined(__LCC__)) || defined(__clang__) -# define FMT_DEPRECATED __attribute__((deprecated)) -# elif FMT_MSC_VER -# define FMT_DEPRECATED __declspec(deprecated) -# else -# define FMT_DEPRECATED /* deprecated */ -# endif +# define FMT_MAYBE_UNUSED # endif #endif -// Workaround broken [[deprecated]] in the Intel, PGI and NVCC compilers. -#if FMT_ICC_VERSION || defined(__PGI) || FMT_NVCC -# define FMT_DEPRECATED_ALIAS -#else -# define FMT_DEPRECATED_ALIAS FMT_DEPRECATED -#endif - #ifndef FMT_USE_USER_DEFINED_LITERALS // EDG based compilers (Intel, NVIDIA, Elbrus, etc), GCC and MSVC support UDLs. # if (FMT_HAS_FEATURE(cxx_user_literals) || FMT_GCC_VERSION >= 407 || \ - FMT_MSC_VER >= 1900) && \ + FMT_MSC_VERSION >= 1900) && \ (!defined(__EDG_VERSION__) || __EDG_VERSION__ >= /* UDL feature */ 480) # define FMT_USE_USER_DEFINED_LITERALS 1 # else @@ -149,33 +138,42 @@ FMT_END_NAMESPACE #endif // __builtin_clz is broken in clang with Microsoft CodeGen: -// https://github.com/fmtlib/fmt/issues/519 -#if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clz)) && !FMT_MSC_VER -# define FMT_BUILTIN_CLZ(n) __builtin_clz(n) -#endif -#if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_clzll)) && !FMT_MSC_VER -# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) -#endif -#if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_ctz)) -# define FMT_BUILTIN_CTZ(n) __builtin_ctz(n) +// https://github.com/fmtlib/fmt/issues/519. +#if !FMT_MSC_VERSION +# if FMT_HAS_BUILTIN(__builtin_clz) || FMT_GCC_VERSION || FMT_ICC_VERSION +# define FMT_BUILTIN_CLZ(n) __builtin_clz(n) +# endif +# if FMT_HAS_BUILTIN(__builtin_clzll) || FMT_GCC_VERSION || FMT_ICC_VERSION +# define FMT_BUILTIN_CLZLL(n) __builtin_clzll(n) +# endif #endif -#if (FMT_GCC_VERSION || FMT_HAS_BUILTIN(__builtin_ctzll)) -# define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n) + +// __builtin_ctz is broken in Intel Compiler Classic on Windows: +// https://github.com/fmtlib/fmt/issues/2510. +#ifndef __ICL +# if FMT_HAS_BUILTIN(__builtin_ctz) || FMT_GCC_VERSION || FMT_ICC_VERSION || \ + defined(__NVCOMPILER) +# define FMT_BUILTIN_CTZ(n) __builtin_ctz(n) +# endif +# if FMT_HAS_BUILTIN(__builtin_ctzll) || FMT_GCC_VERSION || \ + FMT_ICC_VERSION || defined(__NVCOMPILER) +# define FMT_BUILTIN_CTZLL(n) __builtin_ctzll(n) +# endif #endif -#if FMT_MSC_VER +#if FMT_MSC_VERSION # include // _BitScanReverse[64], _BitScanForward[64], _umul128 #endif // Some compilers masquerade as both MSVC and GCC-likes or otherwise support // __builtin_clz and __builtin_clzll, so only define FMT_BUILTIN_CLZ using the // MSVC intrinsics if the clz and clzll builtins are not available. -#if FMT_MSC_VER && !defined(FMT_BUILTIN_CLZLL) && !defined(FMT_BUILTIN_CTZLL) +#if FMT_MSC_VERSION && !defined(FMT_BUILTIN_CLZLL) && \ + !defined(FMT_BUILTIN_CTZLL) FMT_BEGIN_NAMESPACE namespace detail { // Avoid Clang with Microsoft CodeGen's -Wunknown-pragmas warning. # if !defined(__clang__) -# pragma managed(push, off) # pragma intrinsic(_BitScanForward) # pragma intrinsic(_BitScanReverse) # if defined(_WIN64) @@ -237,9 +235,6 @@ inline auto ctzll(uint64_t x) -> int { return static_cast(r); } # define FMT_BUILTIN_CTZLL(n) detail::ctzll(n) -# if !defined(__clang__) -# pragma managed(pop) -# endif } // namespace detail FMT_END_NAMESPACE #endif @@ -247,55 +242,194 @@ FMT_END_NAMESPACE FMT_BEGIN_NAMESPACE namespace detail { -#if __cplusplus >= 202002L || \ - (__cplusplus >= 201709L && FMT_GCC_VERSION >= 1002) -# define FMT_CONSTEXPR20 constexpr -#else -# define FMT_CONSTEXPR20 +FMT_CONSTEXPR inline void abort_fuzzing_if(bool condition) { + ignore_unused(condition); +#ifdef FMT_FUZZ + if (condition) throw std::runtime_error("fuzzing limit reached"); +#endif +} + +template struct string_literal { + static constexpr CharT value[sizeof...(C)] = {C...}; + constexpr operator basic_string_view() const { + return {value, sizeof...(C)}; + } +}; + +#if FMT_CPLUSPLUS < 201703L +template +constexpr CharT string_literal::value[sizeof...(C)]; #endif -// An equivalent of `*reinterpret_cast(&source)` that doesn't have -// undefined behavior (e.g. due to type aliasing). -// Example: uint64_t d = bit_cast(2.718); -template -inline auto bit_cast(const Source& source) -> Dest { - static_assert(sizeof(Dest) == sizeof(Source), "size mismatch"); - Dest dest; - std::memcpy(&dest, &source, sizeof(dest)); - return dest; +template class formatbuf : public Streambuf { + private: + using char_type = typename Streambuf::char_type; + using streamsize = decltype(std::declval().sputn(nullptr, 0)); + using int_type = typename Streambuf::int_type; + using traits_type = typename Streambuf::traits_type; + + buffer& buffer_; + + public: + explicit formatbuf(buffer& buf) : buffer_(buf) {} + + protected: + // The put area is always empty. This makes the implementation simpler and has + // the advantage that the streambuf and the buffer are always in sync and + // sputc never writes into uninitialized memory. A disadvantage is that each + // call to sputc always results in a (virtual) call to overflow. There is no + // disadvantage here for sputn since this always results in a call to xsputn. + + auto overflow(int_type ch) -> int_type override { + if (!traits_type::eq_int_type(ch, traits_type::eof())) + buffer_.push_back(static_cast(ch)); + return ch; + } + + auto xsputn(const char_type* s, streamsize count) -> streamsize override { + buffer_.append(s, s + count); + return count; + } +}; + +// Implementation of std::bit_cast for pre-C++20. +template +FMT_CONSTEXPR20 auto bit_cast(const From& from) -> To { +#ifdef __cpp_lib_bit_cast + if (is_constant_evaluated()) return std::bit_cast(from); +#endif + auto to = To(); + // The cast suppresses a bogus -Wclass-memaccess on GCC. + std::memcpy(static_cast(&to), &from, sizeof(to)); + return to; } inline auto is_big_endian() -> bool { - const auto u = 1u; +#ifdef _WIN32 + return false; +#elif defined(__BIG_ENDIAN__) + return true; +#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) + return __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__; +#else struct bytes { - char data[sizeof(u)]; + char data[sizeof(int)]; }; - return bit_cast(u).data[0] == 0; + return bit_cast(1).data[0] == 0; +#endif } -// A fallback implementation of uintptr_t for systems that lack it. -struct fallback_uintptr { - unsigned char value[sizeof(void*)]; +class uint128_fallback { + private: + uint64_t lo_, hi_; + + friend uint128_fallback umul128(uint64_t x, uint64_t y) noexcept; + + public: + constexpr uint128_fallback(uint64_t hi, uint64_t lo) : lo_(lo), hi_(hi) {} + constexpr uint128_fallback(uint64_t value = 0) : lo_(value), hi_(0) {} + + constexpr uint64_t high() const noexcept { return hi_; } + constexpr uint64_t low() const noexcept { return lo_; } + + template ::value)> + constexpr explicit operator T() const { + return static_cast(lo_); + } + + friend constexpr auto operator==(const uint128_fallback& lhs, + const uint128_fallback& rhs) -> bool { + return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_; + } + friend constexpr auto operator!=(const uint128_fallback& lhs, + const uint128_fallback& rhs) -> bool { + return !(lhs == rhs); + } + friend constexpr auto operator>(const uint128_fallback& lhs, + const uint128_fallback& rhs) -> bool { + return lhs.hi_ != rhs.hi_ ? lhs.hi_ > rhs.hi_ : lhs.lo_ > rhs.lo_; + } + friend constexpr auto operator|(const uint128_fallback& lhs, + const uint128_fallback& rhs) + -> uint128_fallback { + return {lhs.hi_ | rhs.hi_, lhs.lo_ | rhs.lo_}; + } + friend constexpr auto operator&(const uint128_fallback& lhs, + const uint128_fallback& rhs) + -> uint128_fallback { + return {lhs.hi_ & rhs.hi_, lhs.lo_ & rhs.lo_}; + } + friend auto operator+(const uint128_fallback& lhs, + const uint128_fallback& rhs) -> uint128_fallback { + auto result = uint128_fallback(lhs); + result += rhs; + return result; + } + friend auto operator*(const uint128_fallback& lhs, uint32_t rhs) + -> uint128_fallback { + FMT_ASSERT(lhs.hi_ == 0, ""); + uint64_t hi = (lhs.lo_ >> 32) * rhs; + uint64_t lo = (lhs.lo_ & ~uint32_t()) * rhs; + uint64_t new_lo = (hi << 32) + lo; + return {(hi >> 32) + (new_lo < lo ? 1 : 0), new_lo}; + } + friend auto operator-(const uint128_fallback& lhs, uint64_t rhs) + -> uint128_fallback { + return {lhs.hi_ - (lhs.lo_ < rhs ? 1 : 0), lhs.lo_ - rhs}; + } + FMT_CONSTEXPR auto operator>>(int shift) const -> uint128_fallback { + if (shift == 64) return {0, hi_}; + if (shift > 64) return uint128_fallback(0, hi_) >> (shift - 64); + return {hi_ >> shift, (hi_ << (64 - shift)) | (lo_ >> shift)}; + } + FMT_CONSTEXPR auto operator<<(int shift) const -> uint128_fallback { + if (shift == 64) return {lo_, 0}; + if (shift > 64) return uint128_fallback(lo_, 0) << (shift - 64); + return {hi_ << shift | (lo_ >> (64 - shift)), (lo_ << shift)}; + } + FMT_CONSTEXPR auto operator>>=(int shift) -> uint128_fallback& { + return *this = *this >> shift; + } + FMT_CONSTEXPR void operator+=(uint128_fallback n) { + uint64_t new_lo = lo_ + n.lo_; + uint64_t new_hi = hi_ + n.hi_ + (new_lo < lo_ ? 1 : 0); + FMT_ASSERT(new_hi >= hi_, ""); + lo_ = new_lo; + hi_ = new_hi; + } - fallback_uintptr() = default; - explicit fallback_uintptr(const void* p) { - *this = bit_cast(p); - if (is_big_endian()) { - for (size_t i = 0, j = sizeof(void*) - 1; i < j; ++i, --j) - std::swap(value[i], value[j]); + FMT_CONSTEXPR20 uint128_fallback& operator+=(uint64_t n) noexcept { + if (is_constant_evaluated()) { + lo_ += n; + hi_ += (lo_ < n ? 1 : 0); + return *this; } +#if FMT_HAS_BUILTIN(__builtin_addcll) && !defined(__ibmxl__) + unsigned long long carry; + lo_ = __builtin_addcll(lo_, n, 0, &carry); + hi_ += carry; +#elif FMT_HAS_BUILTIN(__builtin_ia32_addcarryx_u64) && !defined(__ibmxl__) + unsigned long long result; + auto carry = __builtin_ia32_addcarryx_u64(0, lo_, n, &result); + lo_ = result; + hi_ += carry; +#elif defined(_MSC_VER) && defined(_M_X64) + auto carry = _addcarry_u64(0, lo_, n, &lo_); + _addcarry_u64(carry, hi_, 0, &hi_); +#else + lo_ += n; + hi_ += (lo_ < n ? 1 : 0); +#endif + return *this; } }; + +using uint128_t = conditional_t; + #ifdef UINTPTR_MAX using uintptr_t = ::uintptr_t; -inline auto to_uintptr(const void* p) -> uintptr_t { - return bit_cast(p); -} #else -using uintptr_t = fallback_uintptr; -inline auto to_uintptr(const void* p) -> fallback_uintptr { - return fallback_uintptr(p); -} +using uintptr_t = uint128_t; #endif // Returns the largest possible value for type T. Same as @@ -307,16 +441,31 @@ template constexpr auto num_bits() -> int { return std::numeric_limits::digits; } // std::numeric_limits::digits may return 0 for 128-bit ints. -template <> constexpr auto num_bits() -> int { return 128; } +template <> constexpr auto num_bits() -> int { return 128; } template <> constexpr auto num_bits() -> int { return 128; } -template <> constexpr auto num_bits() -> int { - return static_cast(sizeof(void*) * - std::numeric_limits::digits); + +// A heterogeneous bit_cast used for converting 96-bit long double to uint128_t +// and 128-bit pointers to uint128_fallback. +template sizeof(From))> +inline auto bit_cast(const From& from) -> To { + constexpr auto size = static_cast(sizeof(From) / sizeof(unsigned)); + struct data_t { + unsigned value[static_cast(size)]; + } data = bit_cast(from); + auto result = To(); + if (const_check(is_big_endian())) { + for (int i = 0; i < size; ++i) + result = (result << num_bits()) | data.value[i]; + } else { + for (int i = size - 1; i >= 0; --i) + result = (result << num_bits()) | data.value[i]; + } + return result; } FMT_INLINE void assume(bool condition) { (void)condition; -#if FMT_HAS_BUILTIN(__builtin_assume) +#if FMT_HAS_BUILTIN(__builtin_assume) && !FMT_ICC_VERSION __builtin_assume(condition); #endif } @@ -339,12 +488,15 @@ inline auto get_data(Container& c) -> typename Container::value_type* { #if defined(_SECURE_SCL) && _SECURE_SCL // Make a checked iterator to avoid MSVC warnings. template using checked_ptr = stdext::checked_array_iterator; -template auto make_checked(T* p, size_t size) -> checked_ptr { +template +constexpr auto make_checked(T* p, size_t size) -> checked_ptr { return {p, size}; } #else template using checked_ptr = T*; -template inline auto make_checked(T* p, size_t) -> T* { return p; } +template constexpr auto make_checked(T* p, size_t) -> T* { + return p; +} #endif // Attempts to reserve space for n extra characters in the output range. @@ -455,19 +607,23 @@ FMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e) constexpr const int shiftc[] = {0, 18, 12, 6, 0}; constexpr const int shifte[] = {0, 6, 4, 2, 0}; - int len = code_point_length(s); - const char* next = s + len; + int len = code_point_length_impl(*s); + // Compute the pointer to the next character early so that the next + // iteration can start working on the next character. Neither Clang + // nor GCC figure out this reordering on their own. + const char* next = s + len + !len; + + using uchar = unsigned char; // Assume a four-byte character and load four bytes. Unused bits are // shifted out. - *c = uint32_t(s[0] & masks[len]) << 18; - *c |= uint32_t(s[1] & 0x3f) << 12; - *c |= uint32_t(s[2] & 0x3f) << 6; - *c |= uint32_t(s[3] & 0x3f) << 0; + *c = uint32_t(uchar(s[0]) & masks[len]) << 18; + *c |= uint32_t(uchar(s[1]) & 0x3f) << 12; + *c |= uint32_t(uchar(s[2]) & 0x3f) << 6; + *c |= uint32_t(uchar(s[3]) & 0x3f) << 0; *c >>= shiftc[len]; // Accumulate the various error conditions. - using uchar = unsigned char; *e = (*c < mins[len]) << 6; // non-canonical encoding *e |= ((*c >> 11) == 0x1b) << 7; // surrogate half? *e |= (*c > 0x10FFFF) << 8; // out of range? @@ -480,27 +636,38 @@ FMT_CONSTEXPR inline auto utf8_decode(const char* s, uint32_t* c, int* e) return next; } +constexpr uint32_t invalid_code_point = ~uint32_t(); + +// Invokes f(cp, sv) for every code point cp in s with sv being the string view +// corresponding to the code point. cp is invalid_code_point on error. template FMT_CONSTEXPR void for_each_codepoint(string_view s, F f) { - auto decode = [f](const char* p) { + auto decode = [f](const char* buf_ptr, const char* ptr) { auto cp = uint32_t(); auto error = 0; - p = utf8_decode(p, &cp, &error); - f(cp, error); - return p; + auto end = utf8_decode(buf_ptr, &cp, &error); + bool result = f(error ? invalid_code_point : cp, + string_view(ptr, error ? 1 : to_unsigned(end - buf_ptr))); + return result ? (error ? buf_ptr + 1 : end) : nullptr; }; auto p = s.data(); const size_t block_size = 4; // utf8_decode always reads blocks of 4 chars. if (s.size() >= block_size) { - for (auto end = p + s.size() - block_size + 1; p < end;) p = decode(p); + for (auto end = p + s.size() - block_size + 1; p < end;) { + p = decode(p, p); + if (!p) return; + } } if (auto num_chars_left = s.data() + s.size() - p) { char buf[2 * block_size - 1] = {}; copy_str(p, p + num_chars_left, buf); - p = buf; + const char* buf_ptr = buf; do { - p = decode(p); - } while (p - buf < num_chars_left); + auto end = decode(buf_ptr, p); + if (!end) return; + p += end - buf_ptr; + buf_ptr = end; + } while (buf_ptr - buf < num_chars_left); } } @@ -515,10 +682,10 @@ FMT_CONSTEXPR inline size_t compute_width(string_view s) { // It is not a lambda for compatibility with C++14. struct count_code_points { size_t* count; - FMT_CONSTEXPR void operator()(uint32_t cp, int error) const { + FMT_CONSTEXPR auto operator()(uint32_t cp, string_view) const -> bool { *count += detail::to_unsigned( 1 + - (error == 0 && cp >= 0x1100 && + (cp >= 0x1100 && (cp <= 0x115f || // Hangul Jamo init. consonants cp == 0x2329 || // LEFT-POINTING ANGLE BRACKET cp == 0x232a || // RIGHT-POINTING ANGLE BRACKET @@ -536,6 +703,7 @@ FMT_CONSTEXPR inline size_t compute_width(string_view s) { (cp >= 0x1f300 && cp <= 0x1f64f) || // Supplemental Symbols and Pictographs: (cp >= 0x1f900 && cp <= 0x1f9ff)))); + return true; } }; for_each_codepoint(s, count_code_points{&num_code_points}); @@ -543,8 +711,8 @@ FMT_CONSTEXPR inline size_t compute_width(string_view s) { } inline auto compute_width(basic_string_view s) -> size_t { - return compute_width(basic_string_view( - reinterpret_cast(s.data()), s.size())); + return compute_width( + string_view(reinterpret_cast(s.data()), s.size())); } template @@ -554,9 +722,8 @@ inline auto code_point_index(basic_string_view s, size_t n) -> size_t { } // Calculates the index of the nth code point in a UTF-8 string. -inline auto code_point_index(basic_string_view s, size_t n) - -> size_t { - const char8_type* data = s.data(); +inline auto code_point_index(string_view s, size_t n) -> size_t { + const char* data = s.data(); size_t num_code_points = 0; for (size_t i = 0, size = s.size(); i != size; ++i) { if ((data[i] & 0xc0) != 0x80 && ++num_code_points > n) return i; @@ -564,9 +731,37 @@ inline auto code_point_index(basic_string_view s, size_t n) return s.size(); } +inline auto code_point_index(basic_string_view s, size_t n) + -> size_t { + return code_point_index( + string_view(reinterpret_cast(s.data()), s.size()), n); +} + +#ifndef FMT_USE_FLOAT128 +# ifdef __SIZEOF_FLOAT128__ +# define FMT_USE_FLOAT128 1 +# else +# define FMT_USE_FLOAT128 0 +# endif +#endif +#if FMT_USE_FLOAT128 +using float128 = __float128; +#else +using float128 = void; +#endif +template using is_float128 = std::is_same; + +template +using is_floating_point = + bool_constant::value || is_float128::value>; + +template ::value> +struct is_fast_float : bool_constant::is_iec559 && + sizeof(T) <= sizeof(double)> {}; +template struct is_fast_float : std::false_type {}; + template -using is_fast_float = bool_constant::is_iec559 && - sizeof(T) <= sizeof(double)>; +using is_double_double = bool_constant::digits == 106>; #ifndef FMT_USE_FULL_CACHE_DRAGONBOX # define FMT_USE_FULL_CACHE_DRAGONBOX 0 @@ -607,8 +802,8 @@ enum { inline_buffer_size = 500 }; **Example**:: - fmt::memory_buffer out; - format_to(out, "The answer is {}.", 42); + auto out = fmt::memory_buffer(); + format_to(std::back_inserter(out), "The answer is {}.", 42); This will append the following output to the ``out`` object: @@ -629,39 +824,42 @@ class basic_memory_buffer final : public detail::buffer { Allocator alloc_; // Deallocate memory allocated by the buffer. - void deallocate() { + FMT_CONSTEXPR20 void deallocate() { T* data = this->data(); if (data != store_) alloc_.deallocate(data, this->capacity()); } protected: - void grow(size_t size) final FMT_OVERRIDE; + FMT_CONSTEXPR20 void grow(size_t size) override; public: using value_type = T; using const_reference = const T&; - explicit basic_memory_buffer(const Allocator& alloc = Allocator()) + FMT_CONSTEXPR20 explicit basic_memory_buffer( + const Allocator& alloc = Allocator()) : alloc_(alloc) { this->set(store_, SIZE); + if (detail::is_constant_evaluated()) detail::fill_n(store_, SIZE, T()); } - ~basic_memory_buffer() { deallocate(); } + FMT_CONSTEXPR20 ~basic_memory_buffer() { deallocate(); } private: // Move data from other to this buffer. - void move(basic_memory_buffer& other) { + FMT_CONSTEXPR20 void move(basic_memory_buffer& other) { alloc_ = std::move(other.alloc_); T* data = other.data(); size_t size = other.size(), capacity = other.capacity(); if (data == other.store_) { this->set(store_, capacity); - std::uninitialized_copy(other.store_, other.store_ + size, - detail::make_checked(store_, capacity)); + detail::copy_str(other.store_, other.store_ + size, + detail::make_checked(store_, capacity)); } else { this->set(data, capacity); // Set pointer to the inline array so that delete is not called // when deallocating. other.set(other.store_, 0); + other.clear(); } this->resize(size); } @@ -673,15 +871,16 @@ class basic_memory_buffer final : public detail::buffer { of the other object to it. \endrst */ - basic_memory_buffer(basic_memory_buffer&& other) FMT_NOEXCEPT { move(other); } + FMT_CONSTEXPR20 basic_memory_buffer(basic_memory_buffer&& other) noexcept { + move(other); + } /** \rst Moves the content of the other ``basic_memory_buffer`` object to this one. \endrst */ - auto operator=(basic_memory_buffer&& other) FMT_NOEXCEPT - -> basic_memory_buffer& { + auto operator=(basic_memory_buffer&& other) noexcept -> basic_memory_buffer& { FMT_ASSERT(this != &other, ""); deallocate(); move(other); @@ -695,7 +894,7 @@ class basic_memory_buffer final : public detail::buffer { Resizes the buffer to contain *count* elements. If T is a POD type new elements may not be initialized. */ - void resize(size_t count) { this->try_resize(count); } + FMT_CONSTEXPR20 void resize(size_t count) { this->try_resize(count); } /** Increases the buffer capacity to *new_capacity*. */ void reserve(size_t new_capacity) { this->try_reserve(new_capacity); } @@ -709,10 +908,9 @@ class basic_memory_buffer final : public detail::buffer { }; template -void basic_memory_buffer::grow(size_t size) { -#ifdef FMT_FUZZ - if (size > 5000) throw std::runtime_error("fuzz mode - won't grow that much"); -#endif +FMT_CONSTEXPR20 void basic_memory_buffer::grow( + size_t size) { + detail::abort_fuzzing_if(size > 5000); const size_t max_size = std::allocator_traits::max_size(alloc_); size_t old_capacity = this->capacity(); size_t new_capacity = old_capacity + old_capacity / 2; @@ -740,8 +938,11 @@ struct is_contiguous> : std::true_type { }; namespace detail { +#ifdef _WIN32 +FMT_API bool write_console(std::FILE* f, string_view text); +#endif FMT_API void print(std::FILE*, string_view); -} +} // namespace detail /** A formatting error such as invalid format string. */ FMT_CLASS_API @@ -754,39 +955,17 @@ class FMT_API format_error : public std::runtime_error { format_error& operator=(const format_error&) = default; format_error(format_error&&) = default; format_error& operator=(format_error&&) = default; - ~format_error() FMT_NOEXCEPT FMT_OVERRIDE FMT_MSC_DEFAULT; + ~format_error() noexcept override FMT_MSC_DEFAULT; }; -/** - \rst - Constructs a `~fmt::format_arg_store` object that contains references - to arguments and can be implicitly converted to `~fmt::format_args`. - If ``fmt`` is a compile-time string then `make_args_checked` checks - its validity at compile time. - \endrst - */ -template > -FMT_INLINE auto make_args_checked(const S& fmt, - const remove_reference_t&... args) - -> format_arg_store, remove_reference_t...> { - static_assert( - detail::count<( - std::is_base_of>::value && - std::is_reference::value)...>() == 0, - "passing views as lvalues is disallowed"); - detail::check_format_string(fmt); - return {args...}; -} - -// compile-time support namespace detail_exported { -#if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +#if FMT_USE_NONTYPE_TEMPLATE_ARGS template struct fixed_string { constexpr fixed_string(const Char (&str)[N]) { detail::copy_str(static_cast(str), str + N, data); } - Char data[N]{}; + Char data[N] = {}; }; #endif @@ -807,35 +986,32 @@ constexpr auto compile_string_to_view(detail::std_string_view s) FMT_BEGIN_DETAIL_NAMESPACE -inline void throw_format_error(const char* message) { - FMT_THROW(format_error(message)); -} - template struct is_integral : std::is_integral {}; -template <> struct is_integral : std::true_type {}; +template <> struct is_integral : std::true_type {}; template <> struct is_integral : std::true_type {}; template using is_signed = std::integral_constant::is_signed || - std::is_same::value>; + std::is_same::value>; // Returns true if value is negative, false otherwise. // Same as `value < 0` but doesn't produce warnings if T is an unsigned type. template ::value)> -FMT_CONSTEXPR auto is_negative(T value) -> bool { +constexpr auto is_negative(T value) -> bool { return value < 0; } template ::value)> -FMT_CONSTEXPR auto is_negative(T) -> bool { +constexpr auto is_negative(T) -> bool { return false; } -template ::value)> -FMT_CONSTEXPR auto is_supported_floating_point(T) -> uint16_t { - return (std::is_same::value && FMT_USE_FLOAT) || - (std::is_same::value && FMT_USE_DOUBLE) || - (std::is_same::value && FMT_USE_LONG_DOUBLE); +template +FMT_CONSTEXPR auto is_supported_floating_point(T) -> bool { + if (std::is_same()) return FMT_USE_FLOAT; + if (std::is_same()) return FMT_USE_DOUBLE; + if (std::is_same()) return FMT_USE_LONG_DOUBLE; + return true; } // Smallest of uint32_t, uint64_t, uint128_t that is large enough to @@ -853,48 +1029,23 @@ using uint64_or_128_t = conditional_t() <= 64, uint64_t, uint128_t>; (factor)*1000000, (factor)*10000000, (factor)*100000000, \ (factor)*1000000000 -// Static data is placed in this class template for the header-only config. -template struct basic_data { - // log10(2) = 0x0.4d104d427de7fbcc... - static const uint64_t log10_2_significand = 0x4d104d427de7fbcc; - - // GCC generates slightly better code for pairs than chars. - FMT_API static constexpr const char digits[100][2] = { - {'0', '0'}, {'0', '1'}, {'0', '2'}, {'0', '3'}, {'0', '4'}, {'0', '5'}, - {'0', '6'}, {'0', '7'}, {'0', '8'}, {'0', '9'}, {'1', '0'}, {'1', '1'}, - {'1', '2'}, {'1', '3'}, {'1', '4'}, {'1', '5'}, {'1', '6'}, {'1', '7'}, - {'1', '8'}, {'1', '9'}, {'2', '0'}, {'2', '1'}, {'2', '2'}, {'2', '3'}, - {'2', '4'}, {'2', '5'}, {'2', '6'}, {'2', '7'}, {'2', '8'}, {'2', '9'}, - {'3', '0'}, {'3', '1'}, {'3', '2'}, {'3', '3'}, {'3', '4'}, {'3', '5'}, - {'3', '6'}, {'3', '7'}, {'3', '8'}, {'3', '9'}, {'4', '0'}, {'4', '1'}, - {'4', '2'}, {'4', '3'}, {'4', '4'}, {'4', '5'}, {'4', '6'}, {'4', '7'}, - {'4', '8'}, {'4', '9'}, {'5', '0'}, {'5', '1'}, {'5', '2'}, {'5', '3'}, - {'5', '4'}, {'5', '5'}, {'5', '6'}, {'5', '7'}, {'5', '8'}, {'5', '9'}, - {'6', '0'}, {'6', '1'}, {'6', '2'}, {'6', '3'}, {'6', '4'}, {'6', '5'}, - {'6', '6'}, {'6', '7'}, {'6', '8'}, {'6', '9'}, {'7', '0'}, {'7', '1'}, - {'7', '2'}, {'7', '3'}, {'7', '4'}, {'7', '5'}, {'7', '6'}, {'7', '7'}, - {'7', '8'}, {'7', '9'}, {'8', '0'}, {'8', '1'}, {'8', '2'}, {'8', '3'}, - {'8', '4'}, {'8', '5'}, {'8', '6'}, {'8', '7'}, {'8', '8'}, {'8', '9'}, - {'9', '0'}, {'9', '1'}, {'9', '2'}, {'9', '3'}, {'9', '4'}, {'9', '5'}, - {'9', '6'}, {'9', '7'}, {'9', '8'}, {'9', '9'}}; - - FMT_API static constexpr const char hex_digits[] = "0123456789abcdef"; - FMT_API static constexpr const char signs[4] = {0, '-', '+', ' '}; - FMT_API static constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+', - 0x1000000u | ' '}; - FMT_API static constexpr const char left_padding_shifts[5] = {31, 31, 0, 1, - 0}; - FMT_API static constexpr const char right_padding_shifts[5] = {0, 31, 0, 1, - 0}; -}; +// Converts value in the range [0, 100) to a string. +constexpr const char* digits2(size_t value) { + // GCC generates slightly better code when value is pointer-size. + return &"0001020304050607080910111213141516171819" + "2021222324252627282930313233343536373839" + "4041424344454647484950515253545556575859" + "6061626364656667686970717273747576777879" + "8081828384858687888990919293949596979899"[value * 2]; +} -#ifdef FMT_SHARED -// Required for -flto, -fivisibility=hidden and -shared to work -extern template struct basic_data; +// Sign is a template parameter to workaround a bug in gcc 4.8. +template constexpr Char sign(Sign s) { +#if !FMT_GCC_VERSION || FMT_GCC_VERSION >= 604 + static_assert(std::is_same::value, ""); #endif - -// This is a struct rather than an alias to avoid shadowing warnings in gcc. -struct data : basic_data<> {}; + return static_cast("\0-+ "[s]); +} template FMT_CONSTEXPR auto count_digits_fallback(T n) -> int { int count = 1; @@ -911,28 +1062,38 @@ template FMT_CONSTEXPR auto count_digits_fallback(T n) -> int { } } #if FMT_USE_INT128 -FMT_CONSTEXPR inline auto count_digits(uint128_t n) -> int { +FMT_CONSTEXPR inline auto count_digits(uint128_opt n) -> int { return count_digits_fallback(n); } #endif +#ifdef FMT_BUILTIN_CLZLL +// It is a separate function rather than a part of count_digits to workaround +// the lack of static constexpr in constexpr functions. +inline auto do_count_digits(uint64_t n) -> int { + // This has comparable performance to the version by Kendall Willets + // (https://github.com/fmtlib/format-benchmark/blob/master/digits10) + // but uses smaller tables. + // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)). + static constexpr uint8_t bsr2log10[] = { + 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, + 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, + 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, + 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20}; + auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63]; + static constexpr const uint64_t zero_or_powers_of_10[] = { + 0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL), + 10000000000000000000ULL}; + return t - (n < zero_or_powers_of_10[t]); +} +#endif + // Returns the number of decimal digits in n. Leading zeros are not counted // except for n == 0 in which case count_digits returns 1. FMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int { #ifdef FMT_BUILTIN_CLZLL if (!is_constant_evaluated()) { - // https://github.com/fmtlib/format-benchmark/blob/master/digits10 - // Maps bsr(n) to ceil(log10(pow(2, bsr(n) + 1) - 1)). - constexpr uint16_t bsr2log10[] = { - 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, - 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10, - 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 15, 15, - 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 19, 20}; - auto t = bsr2log10[FMT_BUILTIN_CLZLL(n | 1) ^ 63]; - constexpr const uint64_t zero_or_powers_of_10[] = { - 0, 0, FMT_POWERS_OF_10(1U), FMT_POWERS_OF_10(1000000000ULL), - 10000000000000000000ULL}; - return t - (n < zero_or_powers_of_10[t]); + return do_count_digits(n); } #endif return count_digits_fallback(n); @@ -942,24 +1103,26 @@ FMT_CONSTEXPR20 inline auto count_digits(uint64_t n) -> int { template FMT_CONSTEXPR auto count_digits(UInt n) -> int { #ifdef FMT_BUILTIN_CLZ - if (num_bits() == 32) + if (!is_constant_evaluated() && num_bits() == 32) return (FMT_BUILTIN_CLZ(static_cast(n) | 1) ^ 31) / BITS + 1; #endif - int num_digits = 0; - do { - ++num_digits; - } while ((n >>= BITS) != 0); - return num_digits; + // Lambda avoids unreachable code warnings from NVHPC. + return [](UInt m) { + int num_digits = 0; + do { + ++num_digits; + } while ((m >>= BITS) != 0); + return num_digits; + }(n); } -template <> auto count_digits<4>(detail::fallback_uintptr n) -> int; - +#ifdef FMT_BUILTIN_CLZ // It is a separate function rather than a part of count_digits to workaround // the lack of static constexpr in constexpr functions. -FMT_INLINE uint64_t count_digits_inc(int n) { - // An optimization by Kendall Willets from https://bit.ly/3uOIQrB. - // This increments the upper 32 bits (log10(T) - 1) when >= T is added. -#define FMT_INC(T) (((sizeof(#T) - 1ull) << 32) - T) +FMT_INLINE auto do_count_digits(uint32_t n) -> int { +// An optimization by Kendall Willets from https://bit.ly/3uOIQrB. +// This increments the upper 32 bits (log10(T) - 1) when >= T is added. +# define FMT_INC(T) (((sizeof(# T) - 1ull) << 32) - T) static constexpr uint64_t table[] = { FMT_INC(0), FMT_INC(0), FMT_INC(0), // 8 FMT_INC(10), FMT_INC(10), FMT_INC(10), // 64 @@ -973,29 +1136,26 @@ FMT_INLINE uint64_t count_digits_inc(int n) { FMT_INC(1000000000), FMT_INC(1000000000), FMT_INC(1000000000), // 1024M FMT_INC(1000000000), FMT_INC(1000000000) // 4B }; - return table[n]; + auto inc = table[FMT_BUILTIN_CLZ(n | 1) ^ 31]; + return static_cast((n + inc) >> 32); } +#endif // Optional version of count_digits for better performance on 32-bit platforms. FMT_CONSTEXPR20 inline auto count_digits(uint32_t n) -> int { #ifdef FMT_BUILTIN_CLZ if (!is_constant_evaluated()) { - auto inc = count_digits_inc(FMT_BUILTIN_CLZ(n | 1) ^ 31); - return static_cast((n + inc) >> 32); + return do_count_digits(n); } #endif return count_digits_fallback(n); } -template constexpr auto digits10() FMT_NOEXCEPT -> int { +template constexpr auto digits10() noexcept -> int { return std::numeric_limits::digits10; } -template <> constexpr auto digits10() FMT_NOEXCEPT -> int { - return 38; -} -template <> constexpr auto digits10() FMT_NOEXCEPT -> int { - return 38; -} +template <> constexpr auto digits10() noexcept -> int { return 38; } +template <> constexpr auto digits10() noexcept -> int { return 38; } template struct thousands_sep_result { std::string grouping; @@ -1032,11 +1192,15 @@ inline auto equal2(const char* lhs, const char* rhs) -> bool { } // Copies two characters from src to dst. -template void copy2(Char* dst, const char* src) { +template +FMT_CONSTEXPR20 FMT_INLINE void copy2(Char* dst, const char* src) { + if (!is_constant_evaluated() && sizeof(Char) == sizeof(char)) { + memcpy(dst, src, 2); + return; + } *dst++ = static_cast(*src++); *dst = static_cast(*src); } -FMT_INLINE void copy2(char* dst, const char* src) { memcpy(dst, src, 2); } template struct format_decimal_result { Iterator begin; @@ -1052,20 +1216,12 @@ FMT_CONSTEXPR20 auto format_decimal(Char* out, UInt value, int size) FMT_ASSERT(size >= count_digits(value), "invalid digit count"); out += size; Char* end = out; - if (is_constant_evaluated()) { - while (value >= 10) { - *--out = static_cast('0' + value % 10); - value /= 10; - } - *--out = static_cast('0' + value); - return {out, end}; - } while (value >= 100) { // Integer division is slow so do it for a group of two digits instead // of for every digit. The idea comes from the talk by Alexandrescu // "Three Optimization Tips for C++". See speed-test for a comparison. out -= 2; - copy2(out, data::digits[value % 100]); + copy2(out, digits2(static_cast(value % 100))); value /= 100; } if (value < 10) { @@ -1073,13 +1229,13 @@ FMT_CONSTEXPR20 auto format_decimal(Char* out, UInt value, int size) return {out, end}; } out -= 2; - copy2(out, data::digits[value]); + copy2(out, digits2(static_cast(value))); return {out, end}; } template >::value)> -inline auto format_decimal(Iterator out, UInt value, int size) +FMT_CONSTEXPR inline auto format_decimal(Iterator out, UInt value, int size) -> format_decimal_result { // Buffer is large enough to hold all digits (digits10 + 1). Char buffer[digits10() + 1]; @@ -1093,36 +1249,14 @@ FMT_CONSTEXPR auto format_uint(Char* buffer, UInt value, int num_digits, buffer += num_digits; Char* end = buffer; do { - const char* digits = upper ? "0123456789ABCDEF" : data::hex_digits; - unsigned digit = (value & ((1 << BASE_BITS) - 1)); + const char* digits = upper ? "0123456789ABCDEF" : "0123456789abcdef"; + unsigned digit = static_cast(value & ((1 << BASE_BITS) - 1)); *--buffer = static_cast(BASE_BITS < 4 ? static_cast('0' + digit) : digits[digit]); } while ((value >>= BASE_BITS) != 0); return end; } -template -auto format_uint(Char* buffer, detail::fallback_uintptr n, int num_digits, - bool = false) -> Char* { - auto char_digits = std::numeric_limits::digits / 4; - int start = (num_digits + char_digits - 1) / char_digits - 1; - if (int start_digits = num_digits % char_digits) { - unsigned value = n.value[start--]; - buffer = format_uint(buffer, value, start_digits); - } - for (; start >= 0; --start) { - unsigned value = n.value[start]; - buffer += char_digits; - auto p = buffer; - for (int i = 0; i < char_digits; ++i) { - unsigned digit = (value & ((1 << BASE_BITS) - 1)); - *--p = static_cast(data::hex_digits[digit]); - value >>= BASE_BITS; - } - } - return buffer; -} - template inline auto format_uint(It out, UInt value, int num_digits, bool upper = false) -> It { @@ -1152,58 +1286,45 @@ class utf8_to_utf16 { namespace dragonbox { // Type-specific information that Dragonbox uses. -template struct float_info; +template struct float_info; template <> struct float_info { using carrier_uint = uint32_t; - static const int significand_bits = 23; static const int exponent_bits = 8; - static const int min_exponent = -126; - static const int max_exponent = 127; - static const int exponent_bias = -127; - static const int decimal_digits = 9; static const int kappa = 1; static const int big_divisor = 100; static const int small_divisor = 10; static const int min_k = -31; static const int max_k = 46; - static const int cache_bits = 64; - static const int divisibility_check_by_5_threshold = 39; - static const int case_fc_pm_half_lower_threshold = -1; - static const int case_fc_pm_half_upper_threshold = 6; - static const int case_fc_lower_threshold = -2; - static const int case_fc_upper_threshold = 6; - static const int case_shorter_interval_left_endpoint_lower_threshold = 2; - static const int case_shorter_interval_left_endpoint_upper_threshold = 3; static const int shorter_interval_tie_lower_threshold = -35; static const int shorter_interval_tie_upper_threshold = -35; - static const int max_trailing_zeros = 7; }; template <> struct float_info { using carrier_uint = uint64_t; - static const int significand_bits = 52; static const int exponent_bits = 11; - static const int min_exponent = -1022; - static const int max_exponent = 1023; - static const int exponent_bias = -1023; - static const int decimal_digits = 17; static const int kappa = 2; static const int big_divisor = 1000; static const int small_divisor = 100; static const int min_k = -292; static const int max_k = 326; - static const int cache_bits = 128; - static const int divisibility_check_by_5_threshold = 86; - static const int case_fc_pm_half_lower_threshold = -2; - static const int case_fc_pm_half_upper_threshold = 9; - static const int case_fc_lower_threshold = -4; - static const int case_fc_upper_threshold = 9; - static const int case_shorter_interval_left_endpoint_lower_threshold = 2; - static const int case_shorter_interval_left_endpoint_upper_threshold = 3; static const int shorter_interval_tie_lower_threshold = -77; static const int shorter_interval_tie_upper_threshold = -77; - static const int max_trailing_zeros = 16; +}; + +// An 80- or 128-bit floating point number. +template +struct float_info::digits == 64 || + std::numeric_limits::digits == 113 || + is_float128::value>> { + using carrier_uint = detail::uint128_t; + static const int exponent_bits = 15; +}; + +// A double-double floating point number. +template +struct float_info::value>> { + using carrier_uint = detail::uint128_t; }; template struct decimal_fp { @@ -1212,21 +1333,40 @@ template struct decimal_fp { int exponent; }; -template -FMT_API auto to_decimal(T x) FMT_NOEXCEPT -> decimal_fp; +template FMT_API auto to_decimal(T x) noexcept -> decimal_fp; } // namespace dragonbox -template +// Returns true iff Float has the implicit bit which is not stored. +template constexpr bool has_implicit_bit() { + // An 80-bit FP number has a 64-bit significand an no implicit bit. + return std::numeric_limits::digits != 64; +} + +// Returns the number of significand bits stored in Float. The implicit bit is +// not counted since it is not stored. +template constexpr int num_significand_bits() { + // std::numeric_limits may not support __float128. + return is_float128() ? 112 + : (std::numeric_limits::digits - + (has_implicit_bit() ? 1 : 0)); +} + +template constexpr auto exponent_mask() -> - typename dragonbox::float_info::carrier_uint { - using uint = typename dragonbox::float_info::carrier_uint; - return ((uint(1) << dragonbox::float_info::exponent_bits) - 1) - << dragonbox::float_info::significand_bits; + typename dragonbox::float_info::carrier_uint { + using uint = typename dragonbox::float_info::carrier_uint; + return ((uint(1) << dragonbox::float_info::exponent_bits) - 1) + << num_significand_bits(); +} +template constexpr auto exponent_bias() -> int { + // std::numeric_limits may not support __float128. + return is_float128() ? 16383 + : std::numeric_limits::max_exponent - 1; } // Writes the exponent exp in the form "[+-]d{2,3}" to buffer. template -auto write_exponent(int exp, It it) -> It { +FMT_CONSTEXPR auto write_exponent(int exp, It it) -> It { FMT_ASSERT(-10000 < exp && exp < 10000, "exponent out of range"); if (exp < 0) { *it++ = static_cast('-'); @@ -1235,29 +1375,262 @@ auto write_exponent(int exp, It it) -> It { *it++ = static_cast('+'); } if (exp >= 100) { - const char* top = data::digits[exp / 100]; + const char* top = digits2(to_unsigned(exp / 100)); if (exp >= 1000) *it++ = static_cast(top[0]); *it++ = static_cast(top[1]); exp %= 100; } - const char* d = data::digits[exp]; + const char* d = digits2(to_unsigned(exp)); *it++ = static_cast(d[0]); *it++ = static_cast(d[1]); return it; } -template -auto format_float(T value, int precision, float_specs specs, buffer& buf) - -> int; +// A floating-point number f * pow(2, e) where F is an unsigned type. +template struct basic_fp { + F f; + int e; + + static constexpr const int num_significand_bits = + static_cast(sizeof(F) * num_bits()); + + constexpr basic_fp() : f(0), e(0) {} + constexpr basic_fp(uint64_t f_val, int e_val) : f(f_val), e(e_val) {} + + // Constructs fp from an IEEE754 floating-point number. + template FMT_CONSTEXPR basic_fp(Float n) { assign(n); } + + // Assigns n to this and return true iff predecessor is closer than successor. + template ::value)> + FMT_CONSTEXPR auto assign(Float n) -> bool { + static_assert(std::numeric_limits::digits <= 113, "unsupported FP"); + // Assume Float is in the format [sign][exponent][significand]. + using carrier_uint = typename dragonbox::float_info::carrier_uint; + const auto num_float_significand_bits = + detail::num_significand_bits(); + const auto implicit_bit = carrier_uint(1) << num_float_significand_bits; + const auto significand_mask = implicit_bit - 1; + auto u = bit_cast(n); + f = static_cast(u & significand_mask); + auto biased_e = static_cast((u & exponent_mask()) >> + num_float_significand_bits); + // The predecessor is closer if n is a normalized power of 2 (f == 0) + // other than the smallest normalized number (biased_e > 1). + auto is_predecessor_closer = f == 0 && biased_e > 1; + if (biased_e == 0) + biased_e = 1; // Subnormals use biased exponent 1 (min exponent). + else if (has_implicit_bit()) + f += static_cast(implicit_bit); + e = biased_e - exponent_bias() - num_float_significand_bits; + if (!has_implicit_bit()) ++e; + return is_predecessor_closer; + } + + template ::value)> + FMT_CONSTEXPR auto assign(Float n) -> bool { + static_assert(std::numeric_limits::is_iec559, "unsupported FP"); + return assign(static_cast(n)); + } +}; + +using fp = basic_fp; + +// Normalizes the value converted from double and multiplied by (1 << SHIFT). +template +FMT_CONSTEXPR basic_fp normalize(basic_fp value) { + // Handle subnormals. + const auto implicit_bit = F(1) << num_significand_bits(); + const auto shifted_implicit_bit = implicit_bit << SHIFT; + while ((value.f & shifted_implicit_bit) == 0) { + value.f <<= 1; + --value.e; + } + // Subtract 1 to account for hidden bit. + const auto offset = basic_fp::num_significand_bits - + num_significand_bits() - SHIFT - 1; + value.f <<= offset; + value.e -= offset; + return value; +} + +// Computes lhs * rhs / pow(2, 64) rounded to nearest with half-up tie breaking. +FMT_CONSTEXPR inline uint64_t multiply(uint64_t lhs, uint64_t rhs) { +#if FMT_USE_INT128 + auto product = static_cast<__uint128_t>(lhs) * rhs; + auto f = static_cast(product >> 64); + return (static_cast(product) & (1ULL << 63)) != 0 ? f + 1 : f; +#else + // Multiply 32-bit parts of significands. + uint64_t mask = (1ULL << 32) - 1; + uint64_t a = lhs >> 32, b = lhs & mask; + uint64_t c = rhs >> 32, d = rhs & mask; + uint64_t ac = a * c, bc = b * c, ad = a * d, bd = b * d; + // Compute mid 64-bit of result and round. + uint64_t mid = (bd >> 32) + (ad & mask) + (bc & mask) + (1U << 31); + return ac + (ad >> 32) + (bc >> 32) + (mid >> 32); +#endif +} + +FMT_CONSTEXPR inline fp operator*(fp x, fp y) { + return {multiply(x.f, y.f), x.e + y.e + 64}; +} + +template struct basic_data { + // Normalized 64-bit significands of pow(10, k), for k = -348, -340, ..., 340. + // These are generated by support/compute-powers.py. + static constexpr uint64_t pow10_significands[87] = { + 0xfa8fd5a0081c0288, 0xbaaee17fa23ebf76, 0x8b16fb203055ac76, + 0xcf42894a5dce35ea, 0x9a6bb0aa55653b2d, 0xe61acf033d1a45df, + 0xab70fe17c79ac6ca, 0xff77b1fcbebcdc4f, 0xbe5691ef416bd60c, + 0x8dd01fad907ffc3c, 0xd3515c2831559a83, 0x9d71ac8fada6c9b5, + 0xea9c227723ee8bcb, 0xaecc49914078536d, 0x823c12795db6ce57, + 0xc21094364dfb5637, 0x9096ea6f3848984f, 0xd77485cb25823ac7, + 0xa086cfcd97bf97f4, 0xef340a98172aace5, 0xb23867fb2a35b28e, + 0x84c8d4dfd2c63f3b, 0xc5dd44271ad3cdba, 0x936b9fcebb25c996, + 0xdbac6c247d62a584, 0xa3ab66580d5fdaf6, 0xf3e2f893dec3f126, + 0xb5b5ada8aaff80b8, 0x87625f056c7c4a8b, 0xc9bcff6034c13053, + 0x964e858c91ba2655, 0xdff9772470297ebd, 0xa6dfbd9fb8e5b88f, + 0xf8a95fcf88747d94, 0xb94470938fa89bcf, 0x8a08f0f8bf0f156b, + 0xcdb02555653131b6, 0x993fe2c6d07b7fac, 0xe45c10c42a2b3b06, + 0xaa242499697392d3, 0xfd87b5f28300ca0e, 0xbce5086492111aeb, + 0x8cbccc096f5088cc, 0xd1b71758e219652c, 0x9c40000000000000, + 0xe8d4a51000000000, 0xad78ebc5ac620000, 0x813f3978f8940984, + 0xc097ce7bc90715b3, 0x8f7e32ce7bea5c70, 0xd5d238a4abe98068, + 0x9f4f2726179a2245, 0xed63a231d4c4fb27, 0xb0de65388cc8ada8, + 0x83c7088e1aab65db, 0xc45d1df942711d9a, 0x924d692ca61be758, + 0xda01ee641a708dea, 0xa26da3999aef774a, 0xf209787bb47d6b85, + 0xb454e4a179dd1877, 0x865b86925b9bc5c2, 0xc83553c5c8965d3d, + 0x952ab45cfa97a0b3, 0xde469fbd99a05fe3, 0xa59bc234db398c25, + 0xf6c69a72a3989f5c, 0xb7dcbf5354e9bece, 0x88fcf317f22241e2, + 0xcc20ce9bd35c78a5, 0x98165af37b2153df, 0xe2a0b5dc971f303a, + 0xa8d9d1535ce3b396, 0xfb9b7cd9a4a7443c, 0xbb764c4ca7a44410, + 0x8bab8eefb6409c1a, 0xd01fef10a657842c, 0x9b10a4e5e9913129, + 0xe7109bfba19c0c9d, 0xac2820d9623bf429, 0x80444b5e7aa7cf85, + 0xbf21e44003acdd2d, 0x8e679c2f5e44ff8f, 0xd433179d9c8cb841, + 0x9e19db92b4e31ba9, 0xeb96bf6ebadf77d9, 0xaf87023b9bf0ee6b, + }; + +#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wnarrowing" +#endif + // Binary exponents of pow(10, k), for k = -348, -340, ..., 340, corresponding + // to significands above. + static constexpr int16_t pow10_exponents[87] = { + -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980, -954, + -927, -901, -874, -847, -821, -794, -768, -741, -715, -688, -661, + -635, -608, -582, -555, -529, -502, -475, -449, -422, -396, -369, + -343, -316, -289, -263, -236, -210, -183, -157, -130, -103, -77, + -50, -24, 3, 30, 56, 83, 109, 136, 162, 189, 216, + 242, 269, 295, 322, 348, 375, 402, 428, 455, 481, 508, + 534, 561, 588, 614, 641, 667, 694, 720, 747, 774, 800, + 827, 853, 880, 907, 933, 960, 986, 1013, 1039, 1066}; +#if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 +# pragma GCC diagnostic pop +#endif + + static constexpr uint64_t power_of_10_64[20] = { + 1, FMT_POWERS_OF_10(1ULL), FMT_POWERS_OF_10(1000000000ULL), + 10000000000000000000ULL}; +}; + +#if FMT_CPLUSPLUS < 201703L +template constexpr uint64_t basic_data::pow10_significands[]; +template constexpr int16_t basic_data::pow10_exponents[]; +template constexpr uint64_t basic_data::power_of_10_64[]; +#endif + +// This is a struct rather than an alias to avoid shadowing warnings in gcc. +struct data : basic_data<> {}; + +// Returns a cached power of 10 `c_k = c_k.f * pow(2, c_k.e)` such that its +// (binary) exponent satisfies `min_exponent <= c_k.e <= min_exponent + 28`. +FMT_CONSTEXPR inline fp get_cached_power(int min_exponent, + int& pow10_exponent) { + const int shift = 32; + // log10(2) = 0x0.4d104d427de7fbcc... + const int64_t significand = 0x4d104d427de7fbcc; + int index = static_cast( + ((min_exponent + fp::num_significand_bits - 1) * (significand >> shift) + + ((int64_t(1) << shift) - 1)) // ceil + >> 32 // arithmetic shift + ); + // Decimal exponent of the first (smallest) cached power of 10. + const int first_dec_exp = -348; + // Difference between 2 consecutive decimal exponents in cached powers of 10. + const int dec_exp_step = 8; + index = (index - first_dec_exp - 1) / dec_exp_step + 1; + pow10_exponent = first_dec_exp + index * dec_exp_step; + // Using *(x + index) instead of x[index] avoids an issue with some compilers + // using the EDG frontend (e.g. nvhpc/22.3 in C++17 mode). + return {*(data::pow10_significands + index), + *(data::pow10_exponents + index)}; +} + +#ifndef _MSC_VER +# define FMT_SNPRINTF snprintf +#else +FMT_API auto fmt_snprintf(char* buf, size_t size, const char* fmt, ...) -> int; +# define FMT_SNPRINTF fmt_snprintf +#endif // _MSC_VER -// Formats a floating-point number with snprintf. +// Formats a floating-point number with snprintf using the hexfloat format. template auto snprintf_float(T value, int precision, float_specs specs, - buffer& buf) -> int; + buffer& buf) -> int { + // Buffer capacity must be non-zero, otherwise MSVC's vsnprintf_s will fail. + FMT_ASSERT(buf.capacity() > buf.size(), "empty buffer"); + FMT_ASSERT(specs.format == float_format::hex, ""); + static_assert(!std::is_same::value, ""); + + // Build the format string. + char format[7]; // The longest format is "%#.*Le". + char* format_ptr = format; + *format_ptr++ = '%'; + if (specs.showpoint) *format_ptr++ = '#'; + if (precision >= 0) { + *format_ptr++ = '.'; + *format_ptr++ = '*'; + } + if (std::is_same()) *format_ptr++ = 'L'; + *format_ptr++ = specs.upper ? 'A' : 'a'; + *format_ptr = '\0'; + + // Format using snprintf. + auto offset = buf.size(); + for (;;) { + auto begin = buf.data() + offset; + auto capacity = buf.capacity() - offset; + abort_fuzzing_if(precision > 100000); + // Suppress the warning about a nonliteral format string. + // Cannot use auto because of a bug in MinGW (#1532). + int (*snprintf_ptr)(char*, size_t, const char*, ...) = FMT_SNPRINTF; + int result = precision >= 0 + ? snprintf_ptr(begin, capacity, format, precision, value) + : snprintf_ptr(begin, capacity, format, value); + if (result < 0) { + // The buffer will grow exponentially. + buf.try_reserve(buf.capacity() + 1); + continue; + } + auto size = to_unsigned(result); + // Size equal to capacity means that the last character was truncated. + if (size < capacity) { + buf.try_resize(size + offset); + return 0; + } + buf.try_reserve(size + offset + 1); // Add 1 for the terminating '\0'. + } +} + +template +using convert_float_result = + conditional_t::value || sizeof(T) == sizeof(double), + double, T>; -template auto promote_float(T value) -> T { return value; } -inline auto promote_float(float value) -> double { - return static_cast(value); +template +constexpr auto convert_float(T value) -> convert_float_result { + return static_cast>(value); } template @@ -1282,8 +1655,9 @@ FMT_CONSTEXPR auto write_padded(OutputIt out, static_assert(align == align::left || align == align::right, ""); unsigned spec_width = to_unsigned(specs.width); size_t padding = spec_width > width ? spec_width - width : 0; - auto* shifts = align == align::left ? data::left_padding_shifts - : data::right_padding_shifts; + // Shifts are encoded as string literals because static constexpr is not + // supported in constexpr functions. + auto* shifts = align == align::left ? "\x1f\x1f\x00\x01" : "\x00\x1f\x00\x01"; size_t left_padding = padding >> shifts[specs.align]; size_t right_padding = padding - left_padding; auto it = reserve(out, size + padding * specs.fill.size()); @@ -1325,11 +1699,172 @@ auto write_ptr(OutputIt out, UIntPtr value, : base_iterator(out, write(reserve(out, size))); } +// Returns true iff the code point cp is printable. +FMT_API auto is_printable(uint32_t cp) -> bool; + +inline auto needs_escape(uint32_t cp) -> bool { + return cp < 0x20 || cp == 0x7f || cp == '"' || cp == '\\' || + !is_printable(cp); +} + +template struct find_escape_result { + const Char* begin; + const Char* end; + uint32_t cp; +}; + +template +using make_unsigned_char = + typename conditional_t::value, + std::make_unsigned, + type_identity>::type; + +template +auto find_escape(const Char* begin, const Char* end) + -> find_escape_result { + for (; begin != end; ++begin) { + uint32_t cp = static_cast>(*begin); + if (const_check(sizeof(Char) == 1) && cp >= 0x80) continue; + if (needs_escape(cp)) return {begin, begin + 1, cp}; + } + return {begin, nullptr, 0}; +} + +inline auto find_escape(const char* begin, const char* end) + -> find_escape_result { + if (!is_utf8()) return find_escape(begin, end); + auto result = find_escape_result{end, nullptr, 0}; + for_each_codepoint(string_view(begin, to_unsigned(end - begin)), + [&](uint32_t cp, string_view sv) { + if (needs_escape(cp)) { + result = {sv.begin(), sv.end(), cp}; + return false; + } + return true; + }); + return result; +} + +#define FMT_STRING_IMPL(s, base, explicit) \ + [] { \ + /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \ + /* Use a macro-like name to avoid shadowing warnings. */ \ + struct FMT_GCC_VISIBILITY_HIDDEN FMT_COMPILE_STRING : base { \ + using char_type FMT_MAYBE_UNUSED = fmt::remove_cvref_t; \ + FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit \ + operator fmt::basic_string_view() const { \ + return fmt::detail_exported::compile_string_to_view(s); \ + } \ + }; \ + return FMT_COMPILE_STRING(); \ + }() + +/** + \rst + Constructs a compile-time format string from a string literal *s*. + + **Example**:: + + // A compile-time error because 'd' is an invalid specifier for strings. + std::string s = fmt::format(FMT_STRING("{:d}"), "foo"); + \endrst + */ +#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::detail::compile_string, ) + +template +auto write_codepoint(OutputIt out, char prefix, uint32_t cp) -> OutputIt { + *out++ = static_cast('\\'); + *out++ = static_cast(prefix); + Char buf[width]; + fill_n(buf, width, static_cast('0')); + format_uint<4>(buf, cp, width); + return copy_str(buf, buf + width, out); +} + +template +auto write_escaped_cp(OutputIt out, const find_escape_result& escape) + -> OutputIt { + auto c = static_cast(escape.cp); + switch (escape.cp) { + case '\n': + *out++ = static_cast('\\'); + c = static_cast('n'); + break; + case '\r': + *out++ = static_cast('\\'); + c = static_cast('r'); + break; + case '\t': + *out++ = static_cast('\\'); + c = static_cast('t'); + break; + case '"': + FMT_FALLTHROUGH; + case '\'': + FMT_FALLTHROUGH; + case '\\': + *out++ = static_cast('\\'); + break; + default: + if (is_utf8()) { + if (escape.cp < 0x100) { + return write_codepoint<2, Char>(out, 'x', escape.cp); + } + if (escape.cp < 0x10000) { + return write_codepoint<4, Char>(out, 'u', escape.cp); + } + if (escape.cp < 0x110000) { + return write_codepoint<8, Char>(out, 'U', escape.cp); + } + } + for (Char escape_char : basic_string_view( + escape.begin, to_unsigned(escape.end - escape.begin))) { + out = write_codepoint<2, Char>(out, 'x', + static_cast(escape_char) & 0xFF); + } + return out; + } + *out++ = c; + return out; +} + +template +auto write_escaped_string(OutputIt out, basic_string_view str) + -> OutputIt { + *out++ = static_cast('"'); + auto begin = str.begin(), end = str.end(); + do { + auto escape = find_escape(begin, end); + out = copy_str(begin, escape.begin, out); + begin = escape.end; + if (!begin) break; + out = write_escaped_cp(out, escape); + } while (begin != end); + *out++ = static_cast('"'); + return out; +} + +template +auto write_escaped_char(OutputIt out, Char v) -> OutputIt { + *out++ = static_cast('\''); + if ((needs_escape(static_cast(v)) && v != static_cast('"')) || + v == static_cast('\'')) { + out = write_escaped_cp( + out, find_escape_result{&v, &v + 1, static_cast(v)}); + } else { + *out++ = v; + } + *out++ = static_cast('\''); + return out; +} + template FMT_CONSTEXPR auto write_char(OutputIt out, Char value, const basic_format_specs& specs) -> OutputIt { + bool is_debug = specs.type == presentation_type::debug; return write_padded(out, specs, 1, [=](reserve_iterator it) { + if (is_debug) return write_escaped_char(it, value); *it++ = value; return it; }); @@ -1393,56 +1928,94 @@ FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, int num_digits, }); } -template -auto write_int_localized(OutputIt& out, UInt value, unsigned prefix, - const basic_format_specs& specs, locale_ref loc) - -> bool { +template class digit_grouping { + private: + thousands_sep_result sep_; + + struct next_state { + std::string::const_iterator group; + int pos; + }; + next_state initial_state() const { return {sep_.grouping.begin(), 0}; } + + // Returns the next digit group separator position. + int next(next_state& state) const { + if (!sep_.thousands_sep) return max_value(); + if (state.group == sep_.grouping.end()) + return state.pos += sep_.grouping.back(); + if (*state.group <= 0 || *state.group == max_value()) + return max_value(); + state.pos += *state.group++; + return state.pos; + } + + public: + explicit digit_grouping(locale_ref loc, bool localized = true) { + if (localized) + sep_ = thousands_sep(loc); + else + sep_.thousands_sep = Char(); + } + explicit digit_grouping(thousands_sep_result sep) : sep_(sep) {} + + Char separator() const { return sep_.thousands_sep; } + + int count_separators(int num_digits) const { + int count = 0; + auto state = initial_state(); + while (num_digits > next(state)) ++count; + return count; + } + + // Applies grouping to digits and write the output to out. + template + Out apply(Out out, basic_string_view digits) const { + auto num_digits = static_cast(digits.size()); + auto separators = basic_memory_buffer(); + separators.push_back(0); + auto state = initial_state(); + while (int i = next(state)) { + if (i >= num_digits) break; + separators.push_back(i); + } + for (int i = 0, sep_index = static_cast(separators.size() - 1); + i < num_digits; ++i) { + if (num_digits - i == separators[sep_index]) { + *out++ = separator(); + --sep_index; + } + *out++ = static_cast(digits[to_unsigned(i)]); + } + return out; + } +}; + +template +auto write_int_localized(OutputIt out, UInt value, unsigned prefix, + const basic_format_specs& specs, + const digit_grouping& grouping) -> OutputIt { static_assert(std::is_same, UInt>::value, ""); - const auto sep_size = 1; - auto ts = thousands_sep(loc); - if (!ts.thousands_sep) return false; int num_digits = count_digits(value); - int size = num_digits, n = num_digits; - const std::string& groups = ts.grouping; - std::string::const_iterator group = groups.cbegin(); - while (group != groups.cend() && n > *group && *group > 0 && - *group != max_value()) { - size += sep_size; - n -= *group; - ++group; - } - if (group == groups.cend()) size += sep_size * ((n - 1) / groups.back()); char digits[40]; format_decimal(digits, value, num_digits); - basic_memory_buffer buffer; - if (prefix != 0) ++size; - const auto usize = to_unsigned(size); - buffer.resize(usize); - basic_string_view s(&ts.thousands_sep, sep_size); - // Index of a decimal digit with the least significant digit having index 0. - int digit_index = 0; - group = groups.cbegin(); - auto p = buffer.data() + size - 1; - for (int i = num_digits - 1; i > 0; --i) { - *p-- = static_cast(digits[i]); - if (*group <= 0 || ++digit_index % *group != 0 || - *group == max_value()) - continue; - if (group + 1 != groups.cend()) { - digit_index = 0; - ++group; - } - std::uninitialized_copy(s.data(), s.data() + s.size(), - make_checked(p, s.size())); - p -= s.size(); - } - *p-- = static_cast(*digits); - if (prefix != 0) *p = static_cast(prefix); - auto data = buffer.data(); - out = write_padded( - out, specs, usize, usize, [=](reserve_iterator it) { - return copy_str(data, data + size, it); + unsigned size = to_unsigned((prefix != 0 ? 1 : 0) + num_digits + + grouping.count_separators(num_digits)); + return write_padded( + out, specs, size, size, [&](reserve_iterator it) { + if (prefix != 0) { + char sign = static_cast(prefix); + *it++ = static_cast(sign); + } + return grouping.apply(it, string_view(digits, to_unsigned(num_digits))); }); +} + +template +auto write_int_localized(OutputIt& out, UInt value, unsigned prefix, + const basic_format_specs& specs, locale_ref loc) + -> bool { + auto grouping = digit_grouping(loc); + out = write_int_localized(out, value, prefix, specs, grouping); return true; } @@ -1465,7 +2038,9 @@ FMT_CONSTEXPR auto make_write_int_arg(T value, sign_t sign) prefix = 0x01000000 | '-'; abs_value = 0 - abs_value; } else { - prefix = data::prefixes[sign]; + constexpr const unsigned prefixes[4] = {0, 0, 0x1000000u | '+', + 0x1000000u | ' '}; + prefix = prefixes[sign]; } return {abs_value, prefix}; } @@ -1477,10 +2052,9 @@ FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg arg, static_assert(std::is_same>::value, ""); auto abs_value = arg.abs_value; auto prefix = arg.prefix; - auto utype = static_cast(specs.type); switch (specs.type) { - case 0: - case 'd': { + case presentation_type::none: + case presentation_type::dec: { if (specs.localized && write_int_localized(out, static_cast>(abs_value), prefix, specs, loc)) { @@ -1492,52 +2066,61 @@ FMT_CONSTEXPR FMT_INLINE auto write_int(OutputIt out, write_int_arg arg, return format_decimal(it, abs_value, num_digits).end; }); } - case 'x': - case 'X': { - if (specs.alt) prefix_append(prefix, (utype << 8) | '0'); - bool upper = specs.type != 'x'; + case presentation_type::hex_lower: + case presentation_type::hex_upper: { + bool upper = specs.type == presentation_type::hex_upper; + if (specs.alt) + prefix_append(prefix, unsigned(upper ? 'X' : 'x') << 8 | '0'); int num_digits = count_digits<4>(abs_value); return write_int( out, num_digits, prefix, specs, [=](reserve_iterator it) { return format_uint<4, Char>(it, abs_value, num_digits, upper); }); } - case 'b': - case 'B': { - if (specs.alt) prefix_append(prefix, (utype << 8) | '0'); + case presentation_type::bin_lower: + case presentation_type::bin_upper: { + bool upper = specs.type == presentation_type::bin_upper; + if (specs.alt) + prefix_append(prefix, unsigned(upper ? 'B' : 'b') << 8 | '0'); int num_digits = count_digits<1>(abs_value); return write_int(out, num_digits, prefix, specs, [=](reserve_iterator it) { return format_uint<1, Char>(it, abs_value, num_digits); }); } - case 'o': { + case presentation_type::oct: { int num_digits = count_digits<3>(abs_value); - if (specs.alt && specs.precision <= num_digits && abs_value != 0) { - // Octal prefix '0' is counted as a digit, so only add it if precision - // is not greater than the number of digits. + // Octal prefix '0' is counted as a digit, so only add it if precision + // is not greater than the number of digits. + if (specs.alt && specs.precision <= num_digits && abs_value != 0) prefix_append(prefix, '0'); - } return write_int(out, num_digits, prefix, specs, [=](reserve_iterator it) { return format_uint<3, Char>(it, abs_value, num_digits); }); } - case 'c': + case presentation_type::chr: return write_char(out, static_cast(abs_value), specs); default: - FMT_THROW(format_error("invalid type specifier")); + throw_format_error("invalid type specifier"); } return out; } +template +FMT_CONSTEXPR FMT_NOINLINE auto write_int_noinline( + OutputIt out, write_int_arg arg, const basic_format_specs& specs, + locale_ref loc) -> OutputIt { + return write_int(out, arg, specs, loc); +} template ::value && !std::is_same::value && std::is_same>::value)> -FMT_CONSTEXPR auto write(OutputIt out, T value, - const basic_format_specs& specs, locale_ref loc) - -> OutputIt { - return write_int(out, make_write_int_arg(value, specs.sign), specs, loc); +FMT_CONSTEXPR FMT_INLINE auto write(OutputIt out, T value, + const basic_format_specs& specs, + locale_ref loc) -> OutputIt { + return write_int_noinline(out, make_write_int_arg(value, specs.sign), specs, + loc); } // An inlined version of write used in format string compilation. template FMT_CONSTEXPR void operator=(const T&) {} + }; + + FMT_CONSTEXPR counting_iterator() : count_(0) {} + + FMT_CONSTEXPR size_t count() const { return count_; } + + FMT_CONSTEXPR counting_iterator& operator++() { + ++count_; + return *this; + } + FMT_CONSTEXPR counting_iterator operator++(int) { + auto it = *this; + ++*this; + return it; + } + + FMT_CONSTEXPR friend counting_iterator operator+(counting_iterator it, + difference_type n) { + it.count_ += static_cast(n); + return it; + } + + FMT_CONSTEXPR value_type operator*() const { return {}; } +}; + template FMT_CONSTEXPR auto write(OutputIt out, basic_string_view s, const basic_format_specs& specs) -> OutputIt { @@ -1557,10 +2180,17 @@ FMT_CONSTEXPR auto write(OutputIt out, basic_string_view s, auto size = s.size(); if (specs.precision >= 0 && to_unsigned(specs.precision) < size) size = code_point_index(s, to_unsigned(specs.precision)); - auto width = - specs.width != 0 ? compute_width(basic_string_view(data, size)) : 0; + bool is_debug = specs.type == presentation_type::debug; + size_t width = 0; + if (specs.width != 0) { + if (is_debug) + width = write_escaped_string(counting_iterator{}, s).count(); + else + width = compute_width(basic_string_view(data, size)); + } return write_padded(out, specs, size, width, [=](reserve_iterator it) { + if (is_debug) return write_escaped_string(it, s); return copy_str(data, data + size, it); }); } @@ -1578,14 +2208,37 @@ FMT_CONSTEXPR auto write(OutputIt out, const Char* s, -> OutputIt { return check_cstring_type_spec(specs.type) ? write(out, basic_string_view(s), specs, {}) - : write_ptr(out, to_uintptr(s), &specs); + : write_ptr(out, bit_cast(s), &specs); +} + +template ::value && + !std::is_same::value && + !std::is_same::value)> +FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { + auto abs_value = static_cast>(value); + bool negative = is_negative(value); + // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer. + if (negative) abs_value = ~abs_value + 1; + int num_digits = count_digits(abs_value); + auto size = (negative ? 1 : 0) + static_cast(num_digits); + auto it = reserve(out, size); + if (auto ptr = to_pointer(it, size)) { + if (negative) *ptr++ = static_cast('-'); + format_decimal(ptr, abs_value, num_digits); + return out; + } + if (negative) *it++ = static_cast('-'); + it = format_decimal(it, abs_value, num_digits).end; + return base_iterator(out, it); } template -auto write_nonfinite(OutputIt out, bool isinf, basic_format_specs specs, - const float_specs& fspecs) -> OutputIt { +FMT_CONSTEXPR20 auto write_nonfinite(OutputIt out, bool isnan, + basic_format_specs specs, + const float_specs& fspecs) -> OutputIt { auto str = - isinf ? (fspecs.upper ? "INF" : "inf") : (fspecs.upper ? "NAN" : "nan"); + isnan ? (fspecs.upper ? "NAN" : "nan") : (fspecs.upper ? "INF" : "inf"); constexpr size_t str_size = 3; auto sign = fspecs.sign; auto size = str_size + (sign ? 1 : 0); @@ -1594,7 +2247,7 @@ auto write_nonfinite(OutputIt out, bool isinf, basic_format_specs specs, specs.fill.size() == 1 && *specs.fill.data() == static_cast('0'); if (is_zero_fill) specs.fill[0] = static_cast(' '); return write_padded(out, specs, size, [=](reserve_iterator it) { - if (sign) *it++ = static_cast(data::signs[sign]); + if (sign) *it++ = detail::sign(sign); return copy_str(str, str + str_size, it); }); } @@ -1606,17 +2259,17 @@ struct big_decimal_fp { int exponent; }; -inline auto get_significand_size(const big_decimal_fp& fp) -> int { - return fp.significand_size; +constexpr auto get_significand_size(const big_decimal_fp& f) -> int { + return f.significand_size; } template -inline auto get_significand_size(const dragonbox::decimal_fp& fp) -> int { - return count_digits(fp.significand); +inline auto get_significand_size(const dragonbox::decimal_fp& f) -> int { + return count_digits(f.significand); } template -inline auto write_significand(OutputIt out, const char* significand, - int& significand_size) -> OutputIt { +constexpr auto write_significand(OutputIt out, const char* significand, + int significand_size) -> OutputIt { return copy_str(significand, significand + significand_size, out); } template @@ -1624,6 +2277,19 @@ inline auto write_significand(OutputIt out, UInt significand, int significand_size) -> OutputIt { return format_decimal(out, significand, significand_size).end; } +template +FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand, + int significand_size, int exponent, + const Grouping& grouping) -> OutputIt { + if (!grouping.separator()) { + out = write_significand(out, significand, significand_size); + return detail::fill_n(out, exponent, static_cast('0')); + } + auto buffer = memory_buffer(); + write_significand(appender(buffer), significand, significand_size); + detail::fill_n(appender(buffer), exponent, '0'); + return grouping.apply(out, string_view(buffer.data(), buffer.size())); +} template ::value)> @@ -1631,14 +2297,20 @@ inline auto write_significand(Char* out, UInt significand, int significand_size, int integral_size, Char decimal_point) -> Char* { if (!decimal_point) return format_decimal(out, significand, significand_size).end; - auto end = format_decimal(out + 1, significand, significand_size).end; - if (integral_size == 1) { - out[0] = out[1]; - } else { - std::uninitialized_copy_n(out + 1, integral_size, - make_checked(out, to_unsigned(integral_size))); + out += significand_size + 1; + Char* end = out; + int floating_size = significand_size - integral_size; + for (int i = floating_size / 2; i > 0; --i) { + out -= 2; + copy2(out, digits2(static_cast(significand % 100))); + significand /= 100; + } + if (floating_size % 2 != 0) { + *--out = static_cast('0' + significand % 10); + significand /= 10; } - out[integral_size] = decimal_point; + *--out = decimal_point; + format_decimal(out - integral_size, significand, integral_size); return end; } @@ -1655,9 +2327,9 @@ inline auto write_significand(OutputIt out, UInt significand, } template -inline auto write_significand(OutputIt out, const char* significand, - int significand_size, int integral_size, - Char decimal_point) -> OutputIt { +FMT_CONSTEXPR auto write_significand(OutputIt out, const char* significand, + int significand_size, int integral_size, + Char decimal_point) -> OutputIt { out = detail::copy_str_noinline(significand, significand + integral_size, out); if (!decimal_point) return out; @@ -1666,18 +2338,41 @@ inline auto write_significand(OutputIt out, const char* significand, significand + significand_size, out); } -template -auto write_float(OutputIt out, const DecimalFP& fp, - const basic_format_specs& specs, float_specs fspecs, - Char decimal_point) -> OutputIt { - auto significand = fp.significand; - int significand_size = get_significand_size(fp); - static const Char zero = static_cast('0'); +template +FMT_CONSTEXPR20 auto write_significand(OutputIt out, T significand, + int significand_size, int integral_size, + Char decimal_point, + const Grouping& grouping) -> OutputIt { + if (!grouping.separator()) { + return write_significand(out, significand, significand_size, integral_size, + decimal_point); + } + auto buffer = basic_memory_buffer(); + write_significand(buffer_appender(buffer), significand, + significand_size, integral_size, decimal_point); + grouping.apply( + out, basic_string_view(buffer.data(), to_unsigned(integral_size))); + return detail::copy_str_noinline(buffer.data() + integral_size, + buffer.end(), out); +} + +template > +FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f, + const basic_format_specs& specs, + float_specs fspecs, locale_ref loc) + -> OutputIt { + auto significand = f.significand; + int significand_size = get_significand_size(f); + const Char zero = static_cast('0'); auto sign = fspecs.sign; size_t size = to_unsigned(significand_size) + (sign ? 1 : 0); using iterator = reserve_iterator; - int output_exp = fp.exponent + significand_size - 1; + Char decimal_point = + fspecs.locale ? detail::decimal_point(loc) : static_cast('.'); + + int output_exp = f.exponent + significand_size - 1; auto use_exp_format = [=]() { if (fspecs.format == float_format::exp) return true; if (fspecs.format != float_format::general) return false; @@ -1703,7 +2398,7 @@ auto write_float(OutputIt out, const DecimalFP& fp, size += to_unsigned((decimal_point ? 1 : 0) + 2 + exp_digits); char exp_char = fspecs.upper ? 'E' : 'e'; auto write = [=](iterator it) { - if (sign) *it++ = static_cast(data::signs[sign]); + if (sign) *it++ = detail::sign(sign); // Insert a decimal point after the first digit and add an exponent. it = write_significand(it, significand, significand_size, 1, decimal_point); @@ -1715,23 +2410,23 @@ auto write_float(OutputIt out, const DecimalFP& fp, : base_iterator(out, write(reserve(out, size))); } - int exp = fp.exponent + significand_size; - if (fp.exponent >= 0) { + int exp = f.exponent + significand_size; + if (f.exponent >= 0) { // 1234e5 -> 123400000[.0+] - size += to_unsigned(fp.exponent); + size += to_unsigned(f.exponent); int num_zeros = fspecs.precision - exp; -#ifdef FMT_FUZZ - if (num_zeros > 5000) - throw std::runtime_error("fuzz mode - avoiding excessive cpu use"); -#endif + abort_fuzzing_if(num_zeros > 5000); if (fspecs.showpoint) { + ++size; if (num_zeros <= 0 && fspecs.format != float_format::fixed) num_zeros = 1; - if (num_zeros > 0) size += to_unsigned(num_zeros) + 1; + if (num_zeros > 0) size += to_unsigned(num_zeros); } + auto grouping = Grouping(loc, fspecs.locale); + size += to_unsigned(grouping.count_separators(exp)); return write_padded(out, specs, size, [&](iterator it) { - if (sign) *it++ = static_cast(data::signs[sign]); - it = write_significand(it, significand, significand_size); - it = detail::fill_n(it, fp.exponent, zero); + if (sign) *it++ = detail::sign(sign); + it = write_significand(it, significand, significand_size, + f.exponent, grouping); if (!fspecs.showpoint) return it; *it++ = decimal_point; return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it; @@ -1740,10 +2435,12 @@ auto write_float(OutputIt out, const DecimalFP& fp, // 1234e-2 -> 12.34[0+] int num_zeros = fspecs.showpoint ? fspecs.precision - significand_size : 0; size += 1 + to_unsigned(num_zeros > 0 ? num_zeros : 0); + auto grouping = Grouping(loc, fspecs.locale); + size += to_unsigned(grouping.count_separators(significand_size)); return write_padded(out, specs, size, [&](iterator it) { - if (sign) *it++ = static_cast(data::signs[sign]); + if (sign) *it++ = detail::sign(sign); it = write_significand(it, significand, significand_size, exp, - decimal_point); + decimal_point, grouping); return num_zeros > 0 ? detail::fill_n(it, num_zeros, zero) : it; }); } @@ -1756,7 +2453,7 @@ auto write_float(OutputIt out, const DecimalFP& fp, bool pointy = num_zeros != 0 || significand_size != 0 || fspecs.showpoint; size += 1 + (pointy ? 1 : 0) + to_unsigned(num_zeros); return write_padded(out, specs, size, [&](iterator it) { - if (sign) *it++ = static_cast(data::signs[sign]); + if (sign) *it++ = detail::sign(sign); *it++ = zero; if (!pointy) return it; *it++ = decimal_point; @@ -1765,26 +2462,747 @@ auto write_float(OutputIt out, const DecimalFP& fp, }); } +template class fallback_digit_grouping { + public: + constexpr fallback_digit_grouping(locale_ref, bool) {} + + constexpr Char separator() const { return Char(); } + + constexpr int count_separators(int) const { return 0; } + + template + constexpr Out apply(Out out, basic_string_view) const { + return out; + } +}; + +template +FMT_CONSTEXPR20 auto write_float(OutputIt out, const DecimalFP& f, + const basic_format_specs& specs, + float_specs fspecs, locale_ref loc) + -> OutputIt { + if (is_constant_evaluated()) { + return do_write_float>(out, f, specs, fspecs, + loc); + } else { + return do_write_float(out, f, specs, fspecs, loc); + } +} + +template constexpr bool isnan(T value) { + return !(value >= value); // std::isnan doesn't support __float128. +} + +template +struct has_isfinite : std::false_type {}; + +template +struct has_isfinite> + : std::true_type {}; + +template ::value&& + has_isfinite::value)> +FMT_CONSTEXPR20 bool isfinite(T value) { + constexpr T inf = T(std::numeric_limits::infinity()); + if (is_constant_evaluated()) + return !detail::isnan(value) && value != inf && value != -inf; + return std::isfinite(value); +} +template ::value)> +FMT_CONSTEXPR bool isfinite(T value) { + T inf = T(std::numeric_limits::infinity()); + // std::isfinite doesn't support __float128. + return !detail::isnan(value) && value != inf && value != -inf; +} + +template ::value)> +FMT_INLINE FMT_CONSTEXPR bool signbit(T value) { + if (is_constant_evaluated()) { +#ifdef __cpp_if_constexpr + if constexpr (std::numeric_limits::is_iec559) { + auto bits = detail::bit_cast(static_cast(value)); + return (bits >> (num_bits() - 1)) != 0; + } +#endif + } + return std::signbit(static_cast(value)); +} + +enum class round_direction { unknown, up, down }; + +// Given the divisor (normally a power of 10), the remainder = v % divisor for +// some number v and the error, returns whether v should be rounded up, down, or +// whether the rounding direction can't be determined due to error. +// error should be less than divisor / 2. +FMT_CONSTEXPR inline round_direction get_round_direction(uint64_t divisor, + uint64_t remainder, + uint64_t error) { + FMT_ASSERT(remainder < divisor, ""); // divisor - remainder won't overflow. + FMT_ASSERT(error < divisor, ""); // divisor - error won't overflow. + FMT_ASSERT(error < divisor - error, ""); // error * 2 won't overflow. + // Round down if (remainder + error) * 2 <= divisor. + if (remainder <= divisor - remainder && error * 2 <= divisor - remainder * 2) + return round_direction::down; + // Round up if (remainder - error) * 2 >= divisor. + if (remainder >= error && + remainder - error >= divisor - (remainder - error)) { + return round_direction::up; + } + return round_direction::unknown; +} + +namespace digits { +enum result { + more, // Generate more digits. + done, // Done generating digits. + error // Digit generation cancelled due to an error. +}; +} + +struct gen_digits_handler { + char* buf; + int size; + int precision; + int exp10; + bool fixed; + + FMT_CONSTEXPR digits::result on_digit(char digit, uint64_t divisor, + uint64_t remainder, uint64_t error, + bool integral) { + FMT_ASSERT(remainder < divisor, ""); + buf[size++] = digit; + if (!integral && error >= remainder) return digits::error; + if (size < precision) return digits::more; + if (!integral) { + // Check if error * 2 < divisor with overflow prevention. + // The check is not needed for the integral part because error = 1 + // and divisor > (1 << 32) there. + if (error >= divisor || error >= divisor - error) return digits::error; + } else { + FMT_ASSERT(error == 1 && divisor > 2, ""); + } + auto dir = get_round_direction(divisor, remainder, error); + if (dir != round_direction::up) + return dir == round_direction::down ? digits::done : digits::error; + ++buf[size - 1]; + for (int i = size - 1; i > 0 && buf[i] > '9'; --i) { + buf[i] = '0'; + ++buf[i - 1]; + } + if (buf[0] > '9') { + buf[0] = '1'; + if (fixed) + buf[size++] = '0'; + else + ++exp10; + } + return digits::done; + } +}; + +inline FMT_CONSTEXPR20 void adjust_precision(int& precision, int exp10) { + // Adjust fixed precision by exponent because it is relative to decimal + // point. + if (exp10 > 0 && precision > max_value() - exp10) + FMT_THROW(format_error("number is too big")); + precision += exp10; +} + +// Generates output using the Grisu digit-gen algorithm. +// error: the size of the region (lower, upper) outside of which numbers +// definitely do not round to value (Delta in Grisu3). +FMT_INLINE FMT_CONSTEXPR20 auto grisu_gen_digits(fp value, uint64_t error, + int& exp, + gen_digits_handler& handler) + -> digits::result { + const fp one(1ULL << -value.e, value.e); + // The integral part of scaled value (p1 in Grisu) = value / one. It cannot be + // zero because it contains a product of two 64-bit numbers with MSB set (due + // to normalization) - 1, shifted right by at most 60 bits. + auto integral = static_cast(value.f >> -one.e); + FMT_ASSERT(integral != 0, ""); + FMT_ASSERT(integral == value.f >> -one.e, ""); + // The fractional part of scaled value (p2 in Grisu) c = value % one. + uint64_t fractional = value.f & (one.f - 1); + exp = count_digits(integral); // kappa in Grisu. + // Non-fixed formats require at least one digit and no precision adjustment. + if (handler.fixed) { + adjust_precision(handler.precision, exp + handler.exp10); + // Check if precision is satisfied just by leading zeros, e.g. + // format("{:.2f}", 0.001) gives "0.00" without generating any digits. + if (handler.precision <= 0) { + if (handler.precision < 0) return digits::done; + // Divide by 10 to prevent overflow. + uint64_t divisor = data::power_of_10_64[exp - 1] << -one.e; + auto dir = get_round_direction(divisor, value.f / 10, error * 10); + if (dir == round_direction::unknown) return digits::error; + handler.buf[handler.size++] = dir == round_direction::up ? '1' : '0'; + return digits::done; + } + } + // Generate digits for the integral part. This can produce up to 10 digits. + do { + uint32_t digit = 0; + auto divmod_integral = [&](uint32_t divisor) { + digit = integral / divisor; + integral %= divisor; + }; + // This optimization by Milo Yip reduces the number of integer divisions by + // one per iteration. + switch (exp) { + case 10: + divmod_integral(1000000000); + break; + case 9: + divmod_integral(100000000); + break; + case 8: + divmod_integral(10000000); + break; + case 7: + divmod_integral(1000000); + break; + case 6: + divmod_integral(100000); + break; + case 5: + divmod_integral(10000); + break; + case 4: + divmod_integral(1000); + break; + case 3: + divmod_integral(100); + break; + case 2: + divmod_integral(10); + break; + case 1: + digit = integral; + integral = 0; + break; + default: + FMT_ASSERT(false, "invalid number of digits"); + } + --exp; + auto remainder = (static_cast(integral) << -one.e) + fractional; + auto result = handler.on_digit(static_cast('0' + digit), + data::power_of_10_64[exp] << -one.e, + remainder, error, true); + if (result != digits::more) return result; + } while (exp > 0); + // Generate digits for the fractional part. + for (;;) { + fractional *= 10; + error *= 10; + char digit = static_cast('0' + (fractional >> -one.e)); + fractional &= one.f - 1; + --exp; + auto result = handler.on_digit(digit, one.f, fractional, error, false); + if (result != digits::more) return result; + } +} + +class bigint { + private: + // A bigint is stored as an array of bigits (big digits), with bigit at index + // 0 being the least significant one. + using bigit = uint32_t; + using double_bigit = uint64_t; + enum { bigits_capacity = 32 }; + basic_memory_buffer bigits_; + int exp_; + + FMT_CONSTEXPR20 bigit operator[](int index) const { + return bigits_[to_unsigned(index)]; + } + FMT_CONSTEXPR20 bigit& operator[](int index) { + return bigits_[to_unsigned(index)]; + } + + static constexpr const int bigit_bits = num_bits(); + + friend struct formatter; + + FMT_CONSTEXPR20 void subtract_bigits(int index, bigit other, bigit& borrow) { + auto result = static_cast((*this)[index]) - other - borrow; + (*this)[index] = static_cast(result); + borrow = static_cast(result >> (bigit_bits * 2 - 1)); + } + + FMT_CONSTEXPR20 void remove_leading_zeros() { + int num_bigits = static_cast(bigits_.size()) - 1; + while (num_bigits > 0 && (*this)[num_bigits] == 0) --num_bigits; + bigits_.resize(to_unsigned(num_bigits + 1)); + } + + // Computes *this -= other assuming aligned bigints and *this >= other. + FMT_CONSTEXPR20 void subtract_aligned(const bigint& other) { + FMT_ASSERT(other.exp_ >= exp_, "unaligned bigints"); + FMT_ASSERT(compare(*this, other) >= 0, ""); + bigit borrow = 0; + int i = other.exp_ - exp_; + for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j) + subtract_bigits(i, other.bigits_[j], borrow); + while (borrow > 0) subtract_bigits(i, 0, borrow); + remove_leading_zeros(); + } + + FMT_CONSTEXPR20 void multiply(uint32_t value) { + const double_bigit wide_value = value; + bigit carry = 0; + for (size_t i = 0, n = bigits_.size(); i < n; ++i) { + double_bigit result = bigits_[i] * wide_value + carry; + bigits_[i] = static_cast(result); + carry = static_cast(result >> bigit_bits); + } + if (carry != 0) bigits_.push_back(carry); + } + + template ::value || + std::is_same::value)> + FMT_CONSTEXPR20 void multiply(UInt value) { + using half_uint = + conditional_t::value, uint64_t, uint32_t>; + const int shift = num_bits() - bigit_bits; + const UInt lower = static_cast(value); + const UInt upper = value >> num_bits(); + UInt carry = 0; + for (size_t i = 0, n = bigits_.size(); i < n; ++i) { + UInt result = lower * bigits_[i] + static_cast(carry); + carry = (upper * bigits_[i] << shift) + (result >> bigit_bits) + + (carry >> bigit_bits); + bigits_[i] = static_cast(result); + } + while (carry != 0) { + bigits_.push_back(static_cast(carry)); + carry >>= bigit_bits; + } + } + + template ::value || + std::is_same::value)> + FMT_CONSTEXPR20 void assign(UInt n) { + size_t num_bigits = 0; + do { + bigits_[num_bigits++] = static_cast(n); + n >>= bigit_bits; + } while (n != 0); + bigits_.resize(num_bigits); + exp_ = 0; + } + + public: + FMT_CONSTEXPR20 bigint() : exp_(0) {} + explicit bigint(uint64_t n) { assign(n); } + + bigint(const bigint&) = delete; + void operator=(const bigint&) = delete; + + FMT_CONSTEXPR20 void assign(const bigint& other) { + auto size = other.bigits_.size(); + bigits_.resize(size); + auto data = other.bigits_.data(); + std::copy(data, data + size, make_checked(bigits_.data(), size)); + exp_ = other.exp_; + } + + template FMT_CONSTEXPR20 void operator=(Int n) { + FMT_ASSERT(n > 0, ""); + assign(uint64_or_128_t(n)); + } + + FMT_CONSTEXPR20 int num_bigits() const { + return static_cast(bigits_.size()) + exp_; + } + + FMT_NOINLINE FMT_CONSTEXPR20 bigint& operator<<=(int shift) { + FMT_ASSERT(shift >= 0, ""); + exp_ += shift / bigit_bits; + shift %= bigit_bits; + if (shift == 0) return *this; + bigit carry = 0; + for (size_t i = 0, n = bigits_.size(); i < n; ++i) { + bigit c = bigits_[i] >> (bigit_bits - shift); + bigits_[i] = (bigits_[i] << shift) + carry; + carry = c; + } + if (carry != 0) bigits_.push_back(carry); + return *this; + } + + template FMT_CONSTEXPR20 bigint& operator*=(Int value) { + FMT_ASSERT(value > 0, ""); + multiply(uint32_or_64_or_128_t(value)); + return *this; + } + + friend FMT_CONSTEXPR20 int compare(const bigint& lhs, const bigint& rhs) { + int num_lhs_bigits = lhs.num_bigits(), num_rhs_bigits = rhs.num_bigits(); + if (num_lhs_bigits != num_rhs_bigits) + return num_lhs_bigits > num_rhs_bigits ? 1 : -1; + int i = static_cast(lhs.bigits_.size()) - 1; + int j = static_cast(rhs.bigits_.size()) - 1; + int end = i - j; + if (end < 0) end = 0; + for (; i >= end; --i, --j) { + bigit lhs_bigit = lhs[i], rhs_bigit = rhs[j]; + if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1; + } + if (i != j) return i > j ? 1 : -1; + return 0; + } + + // Returns compare(lhs1 + lhs2, rhs). + friend FMT_CONSTEXPR20 int add_compare(const bigint& lhs1, const bigint& lhs2, + const bigint& rhs) { + auto minimum = [](int a, int b) { return a < b ? a : b; }; + auto maximum = [](int a, int b) { return a > b ? a : b; }; + int max_lhs_bigits = maximum(lhs1.num_bigits(), lhs2.num_bigits()); + int num_rhs_bigits = rhs.num_bigits(); + if (max_lhs_bigits + 1 < num_rhs_bigits) return -1; + if (max_lhs_bigits > num_rhs_bigits) return 1; + auto get_bigit = [](const bigint& n, int i) -> bigit { + return i >= n.exp_ && i < n.num_bigits() ? n[i - n.exp_] : 0; + }; + double_bigit borrow = 0; + int min_exp = minimum(minimum(lhs1.exp_, lhs2.exp_), rhs.exp_); + for (int i = num_rhs_bigits - 1; i >= min_exp; --i) { + double_bigit sum = + static_cast(get_bigit(lhs1, i)) + get_bigit(lhs2, i); + bigit rhs_bigit = get_bigit(rhs, i); + if (sum > rhs_bigit + borrow) return 1; + borrow = rhs_bigit + borrow - sum; + if (borrow > 1) return -1; + borrow <<= bigit_bits; + } + return borrow != 0 ? -1 : 0; + } + + // Assigns pow(10, exp) to this bigint. + FMT_CONSTEXPR20 void assign_pow10(int exp) { + FMT_ASSERT(exp >= 0, ""); + if (exp == 0) return *this = 1; + // Find the top bit. + int bitmask = 1; + while (exp >= bitmask) bitmask <<= 1; + bitmask >>= 1; + // pow(10, exp) = pow(5, exp) * pow(2, exp). First compute pow(5, exp) by + // repeated squaring and multiplication. + *this = 5; + bitmask >>= 1; + while (bitmask != 0) { + square(); + if ((exp & bitmask) != 0) *this *= 5; + bitmask >>= 1; + } + *this <<= exp; // Multiply by pow(2, exp) by shifting. + } + + FMT_CONSTEXPR20 void square() { + int num_bigits = static_cast(bigits_.size()); + int num_result_bigits = 2 * num_bigits; + basic_memory_buffer n(std::move(bigits_)); + bigits_.resize(to_unsigned(num_result_bigits)); + auto sum = uint128_t(); + for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) { + // Compute bigit at position bigit_index of the result by adding + // cross-product terms n[i] * n[j] such that i + j == bigit_index. + for (int i = 0, j = bigit_index; j >= 0; ++i, --j) { + // Most terms are multiplied twice which can be optimized in the future. + sum += static_cast(n[i]) * n[j]; + } + (*this)[bigit_index] = static_cast(sum); + sum >>= num_bits(); // Compute the carry. + } + // Do the same for the top half. + for (int bigit_index = num_bigits; bigit_index < num_result_bigits; + ++bigit_index) { + for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;) + sum += static_cast(n[i++]) * n[j--]; + (*this)[bigit_index] = static_cast(sum); + sum >>= num_bits(); + } + remove_leading_zeros(); + exp_ *= 2; + } + + // If this bigint has a bigger exponent than other, adds trailing zero to make + // exponents equal. This simplifies some operations such as subtraction. + FMT_CONSTEXPR20 void align(const bigint& other) { + int exp_difference = exp_ - other.exp_; + if (exp_difference <= 0) return; + int num_bigits = static_cast(bigits_.size()); + bigits_.resize(to_unsigned(num_bigits + exp_difference)); + for (int i = num_bigits - 1, j = i + exp_difference; i >= 0; --i, --j) + bigits_[j] = bigits_[i]; + std::uninitialized_fill_n(bigits_.data(), exp_difference, 0); + exp_ -= exp_difference; + } + + // Divides this bignum by divisor, assigning the remainder to this and + // returning the quotient. + FMT_CONSTEXPR20 int divmod_assign(const bigint& divisor) { + FMT_ASSERT(this != &divisor, ""); + if (compare(*this, divisor) < 0) return 0; + FMT_ASSERT(divisor.bigits_[divisor.bigits_.size() - 1u] != 0, ""); + align(divisor); + int quotient = 0; + do { + subtract_aligned(divisor); + ++quotient; + } while (compare(*this, divisor) >= 0); + return quotient; + } +}; + +// format_dragon flags. +enum dragon { + predecessor_closer = 1, + fixup = 2, // Run fixup to correct exp10 which can be off by one. + fixed = 4, +}; + +// Formats a floating-point number using a variation of the Fixed-Precision +// Positive Floating-Point Printout ((FPP)^2) algorithm by Steele & White: +// https://fmt.dev/papers/p372-steele.pdf. +FMT_CONSTEXPR20 inline void format_dragon(basic_fp value, + unsigned flags, int num_digits, + buffer& buf, int& exp10) { + bigint numerator; // 2 * R in (FPP)^2. + bigint denominator; // 2 * S in (FPP)^2. + // lower and upper are differences between value and corresponding boundaries. + bigint lower; // (M^- in (FPP)^2). + bigint upper_store; // upper's value if different from lower. + bigint* upper = nullptr; // (M^+ in (FPP)^2). + // Shift numerator and denominator by an extra bit or two (if lower boundary + // is closer) to make lower and upper integers. This eliminates multiplication + // by 2 during later computations. + bool is_predecessor_closer = (flags & dragon::predecessor_closer) != 0; + int shift = is_predecessor_closer ? 2 : 1; + if (value.e >= 0) { + numerator = value.f; + numerator <<= value.e + shift; + lower = 1; + lower <<= value.e; + if (is_predecessor_closer) { + upper_store = 1; + upper_store <<= value.e + 1; + upper = &upper_store; + } + denominator.assign_pow10(exp10); + denominator <<= shift; + } else if (exp10 < 0) { + numerator.assign_pow10(-exp10); + lower.assign(numerator); + if (is_predecessor_closer) { + upper_store.assign(numerator); + upper_store <<= 1; + upper = &upper_store; + } + numerator *= value.f; + numerator <<= shift; + denominator = 1; + denominator <<= shift - value.e; + } else { + numerator = value.f; + numerator <<= shift; + denominator.assign_pow10(exp10); + denominator <<= shift - value.e; + lower = 1; + if (is_predecessor_closer) { + upper_store = 1ULL << 1; + upper = &upper_store; + } + } + int even = static_cast((value.f & 1) == 0); + if (!upper) upper = &lower; + if ((flags & dragon::fixup) != 0) { + if (add_compare(numerator, *upper, denominator) + even <= 0) { + --exp10; + numerator *= 10; + if (num_digits < 0) { + lower *= 10; + if (upper != &lower) *upper *= 10; + } + } + if ((flags & dragon::fixed) != 0) adjust_precision(num_digits, exp10 + 1); + } + // Invariant: value == (numerator / denominator) * pow(10, exp10). + if (num_digits < 0) { + // Generate the shortest representation. + num_digits = 0; + char* data = buf.data(); + for (;;) { + int digit = numerator.divmod_assign(denominator); + bool low = compare(numerator, lower) - even < 0; // numerator <[=] lower. + // numerator + upper >[=] pow10: + bool high = add_compare(numerator, *upper, denominator) + even > 0; + data[num_digits++] = static_cast('0' + digit); + if (low || high) { + if (!low) { + ++data[num_digits - 1]; + } else if (high) { + int result = add_compare(numerator, numerator, denominator); + // Round half to even. + if (result > 0 || (result == 0 && (digit % 2) != 0)) + ++data[num_digits - 1]; + } + buf.try_resize(to_unsigned(num_digits)); + exp10 -= num_digits - 1; + return; + } + numerator *= 10; + lower *= 10; + if (upper != &lower) *upper *= 10; + } + } + // Generate the given number of digits. + exp10 -= num_digits - 1; + if (num_digits == 0) { + denominator *= 10; + auto digit = add_compare(numerator, numerator, denominator) > 0 ? '1' : '0'; + buf.push_back(digit); + return; + } + buf.try_resize(to_unsigned(num_digits)); + for (int i = 0; i < num_digits - 1; ++i) { + int digit = numerator.divmod_assign(denominator); + buf[i] = static_cast('0' + digit); + numerator *= 10; + } + int digit = numerator.divmod_assign(denominator); + auto result = add_compare(numerator, numerator, denominator); + if (result > 0 || (result == 0 && (digit % 2) != 0)) { + if (digit == 9) { + const auto overflow = '0' + 10; + buf[num_digits - 1] = overflow; + // Propagate the carry. + for (int i = num_digits - 1; i > 0 && buf[i] == overflow; --i) { + buf[i] = '0'; + ++buf[i - 1]; + } + if (buf[0] == overflow) { + buf[0] = '1'; + ++exp10; + } + return; + } + ++digit; + } + buf[num_digits - 1] = static_cast('0' + digit); +} + +template +FMT_CONSTEXPR20 auto format_float(Float value, int precision, float_specs specs, + buffer& buf) -> int { + // float is passed as double to reduce the number of instantiations. + static_assert(!std::is_same::value, ""); + FMT_ASSERT(value >= 0, "value is negative"); + auto converted_value = convert_float(value); + + const bool fixed = specs.format == float_format::fixed; + if (value <= 0) { // <= instead of == to silence a warning. + if (precision <= 0 || !fixed) { + buf.push_back('0'); + return 0; + } + buf.try_resize(to_unsigned(precision)); + fill_n(buf.data(), precision, '0'); + return -precision; + } + + int exp = 0; + bool use_dragon = true; + unsigned dragon_flags = 0; + if (!is_fast_float()) { + const auto inv_log2_10 = 0.3010299956639812; // 1 / log2(10) + using info = dragonbox::float_info; + const auto f = basic_fp(converted_value); + // Compute exp, an approximate power of 10, such that + // 10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1). + // This is based on log10(value) == log2(value) / log2(10) and approximation + // of log2(value) by e + num_fraction_bits idea from double-conversion. + exp = static_cast( + std::ceil((f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10)); + dragon_flags = dragon::fixup; + } else if (!is_constant_evaluated() && precision < 0) { + // Use Dragonbox for the shortest format. + if (specs.binary32) { + auto dec = dragonbox::to_decimal(static_cast(value)); + write(buffer_appender(buf), dec.significand); + return dec.exponent; + } + auto dec = dragonbox::to_decimal(static_cast(value)); + write(buffer_appender(buf), dec.significand); + return dec.exponent; + } else { + // Use Grisu + Dragon4 for the given precision: + // https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf. + const int min_exp = -60; // alpha in Grisu. + int cached_exp10 = 0; // K in Grisu. + fp normalized = normalize(fp(converted_value)); + const auto cached_pow = get_cached_power( + min_exp - (normalized.e + fp::num_significand_bits), cached_exp10); + normalized = normalized * cached_pow; + gen_digits_handler handler{buf.data(), 0, precision, -cached_exp10, fixed}; + if (grisu_gen_digits(normalized, 1, exp, handler) != digits::error && + !is_constant_evaluated()) { + exp += handler.exp10; + buf.try_resize(to_unsigned(handler.size)); + use_dragon = false; + } else { + exp += handler.size - cached_exp10 - 1; + precision = handler.precision; + } + } + if (use_dragon) { + auto f = basic_fp(); + bool is_predecessor_closer = specs.binary32 + ? f.assign(static_cast(value)) + : f.assign(converted_value); + if (is_predecessor_closer) dragon_flags |= dragon::predecessor_closer; + if (fixed) dragon_flags |= dragon::fixed; + // Limit precision to the maximum possible number of significant digits in + // an IEEE754 double because we don't need to generate zeros. + const int max_double_digits = 767; + if (precision > max_double_digits) precision = max_double_digits; + format_dragon(f, dragon_flags, precision, buf, exp); + } + if (!fixed && !specs.showpoint) { + // Remove trailing zeros. + auto num_digits = buf.size(); + while (num_digits > 0 && buf[num_digits - 1] == '0') { + --num_digits; + ++exp; + } + buf.try_resize(num_digits); + } + return exp; +} + template ::value)> -auto write(OutputIt out, T value, basic_format_specs specs, - locale_ref loc = {}) -> OutputIt { + FMT_ENABLE_IF(is_floating_point::value)> +FMT_CONSTEXPR20 auto write(OutputIt out, T value, + basic_format_specs specs, locale_ref loc = {}) + -> OutputIt { if (const_check(!is_supported_floating_point(value))) return out; float_specs fspecs = parse_float_type_spec(specs); fspecs.sign = specs.sign; - if (std::signbit(value)) { // value < 0 is false for NaN so use signbit. + if (detail::signbit(value)) { // value < 0 is false for NaN so use signbit. fspecs.sign = sign::minus; value = -value; } else if (fspecs.sign == sign::minus) { fspecs.sign = sign::none; } - if (!std::isfinite(value)) - return write_nonfinite(out, std::isinf(value), specs, fspecs); + if (!detail::isfinite(value)) + return write_nonfinite(out, detail::isnan(value), specs, fspecs); if (specs.align == align::numeric && fspecs.sign) { auto it = reserve(out, 1); - *it++ = static_cast(data::signs[fspecs.sign]); + *it++ = detail::sign(fspecs.sign); out = base_iterator(out, it); fspecs.sign = sign::none; if (specs.width != 0) --specs.width; @@ -1792,55 +3210,55 @@ auto write(OutputIt out, T value, basic_format_specs specs, memory_buffer buffer; if (fspecs.format == float_format::hex) { - if (fspecs.sign) buffer.push_back(data::signs[fspecs.sign]); - snprintf_float(promote_float(value), specs.precision, fspecs, buffer); + if (fspecs.sign) buffer.push_back(detail::sign(fspecs.sign)); + snprintf_float(convert_float(value), specs.precision, fspecs, buffer); return write_bytes(out, {buffer.data(), buffer.size()}, specs); } - int precision = specs.precision >= 0 || !specs.type ? specs.precision : 6; + int precision = specs.precision >= 0 || specs.type == presentation_type::none + ? specs.precision + : 6; if (fspecs.format == float_format::exp) { if (precision == max_value()) - FMT_THROW(format_error("number is too big")); + throw_format_error("number is too big"); else ++precision; + } else if (fspecs.format != float_format::fixed && precision == 0) { + precision = 1; } if (const_check(std::is_same())) fspecs.binary32 = true; - fspecs.use_grisu = is_fast_float(); - int exp = format_float(promote_float(value), precision, fspecs, buffer); + int exp = format_float(convert_float(value), precision, fspecs, buffer); fspecs.precision = precision; - Char point = - fspecs.locale ? decimal_point(loc) : static_cast('.'); - auto fp = big_decimal_fp{buffer.data(), static_cast(buffer.size()), exp}; - return write_float(out, fp, specs, fspecs, point); + auto f = big_decimal_fp{buffer.data(), static_cast(buffer.size()), exp}; + return write_float(out, f, specs, fspecs, loc); } template ::value)> -auto write(OutputIt out, T value) -> OutputIt { +FMT_CONSTEXPR20 auto write(OutputIt out, T value) -> OutputIt { + if (is_constant_evaluated()) + return write(out, value, basic_format_specs()); if (const_check(!is_supported_floating_point(value))) return out; - using floaty = conditional_t::value, double, T>; - using uint = typename dragonbox::float_info::carrier_uint; - auto bits = bit_cast(value); - auto fspecs = float_specs(); - auto sign_bit = bits & (uint(1) << (num_bits() - 1)); - if (sign_bit != 0) { + if (detail::signbit(value)) { fspecs.sign = sign::minus; value = -value; } - static const auto specs = basic_format_specs(); + constexpr auto specs = basic_format_specs(); + using floaty = conditional_t::value, double, T>; + using uint = typename dragonbox::float_info::carrier_uint; uint mask = exponent_mask(); - if ((bits & mask) == mask) - return write_nonfinite(out, std::isinf(value), specs, fspecs); + if ((bit_cast(value) & mask) == mask) + return write_nonfinite(out, std::isnan(value), specs, fspecs); auto dec = dragonbox::to_decimal(static_cast(value)); - return write_float(out, dec, specs, fspecs, static_cast('.')); + return write_float(out, dec, specs, fspecs, {}); } template ::value && + FMT_ENABLE_IF(is_floating_point::value && !is_fast_float::value)> inline auto write(OutputIt out, T value) -> OutputIt { return write(out, value, basic_format_specs()); @@ -1867,29 +3285,7 @@ constexpr auto write(OutputIt out, const T& value) -> OutputIt { return write(out, to_string_view(value)); } -template ::value && - !std::is_same::value && - !std::is_same::value)> -FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { - auto abs_value = static_cast>(value); - bool negative = is_negative(value); - // Don't do -abs_value since it trips unsigned-integer-overflow sanitizer. - if (negative) abs_value = ~abs_value + 1; - int num_digits = count_digits(abs_value); - auto size = (negative ? 1 : 0) + static_cast(num_digits); - auto it = reserve(out, size); - if (auto ptr = to_pointer(it, size)) { - if (negative) *ptr++ = static_cast('-'); - format_decimal(ptr, abs_value, num_digits); - return out; - } - if (negative) *it++ = static_cast('-'); - it = format_decimal(it, abs_value, num_digits).end; - return base_iterator(out, it); -} - -// FMT_ENABLE_IF() condition separated to workaround MSVC bug +// FMT_ENABLE_IF() condition separated to workaround an MSVC bug. template < typename Char, typename OutputIt, typename T, bool check = @@ -1898,8 +3294,7 @@ template < type::custom_type, FMT_ENABLE_IF(check)> FMT_CONSTEXPR auto write(OutputIt out, T value) -> OutputIt { - return write( - out, static_cast::type>(value)); + return write(out, static_cast>(value)); } template & specs = {}, locale_ref = {}) -> OutputIt { - return specs.type && specs.type != 's' + return specs.type != presentation_type::none && + specs.type != presentation_type::string ? write(out, value ? 1 : 0, specs, {}) : write_bytes(out, value ? "true" : "false", specs); } @@ -1923,10 +3319,9 @@ template FMT_CONSTEXPR_CHAR_TRAITS auto write(OutputIt out, const Char* value) -> OutputIt { if (!value) { - FMT_THROW(format_error("string pointer is null")); + throw_format_error("string pointer is null"); } else { - auto length = std::char_traits::length(value); - out = write(out, basic_string_view(value, length)); + out = write(out, basic_string_view(value)); } return out; } @@ -1937,21 +3332,31 @@ auto write(OutputIt out, const T* value, const basic_format_specs& specs = {}, locale_ref = {}) -> OutputIt { check_pointer_type_spec(specs.type, error_handler()); - return write_ptr(out, to_uintptr(value), &specs); + return write_ptr(out, bit_cast(value), &specs); } -template -FMT_CONSTEXPR auto write(OutputIt out, const T& value) -> - typename std::enable_if< - mapped_type_constant>::value == - type::custom_type, - OutputIt>::type { - using context_type = basic_format_context; +// A write overload that handles implicit conversions. +template > +FMT_CONSTEXPR auto write(OutputIt out, const T& value) -> enable_if_t< + std::is_class::value && !is_string::value && + !is_floating_point::value && !std::is_same::value && + !std::is_same().map(value))>::value, + OutputIt> { + return write(out, arg_mapper().map(value)); +} + +template > +FMT_CONSTEXPR auto write(OutputIt out, const T& value) + -> enable_if_t::value == type::custom_type, + OutputIt> { using formatter_type = - conditional_t::value, - typename context_type::template formatter_type, + conditional_t::value, + typename Context::template formatter_type, fallback_formatter>; - context_type ctx(out, {}, {}); + auto ctx = Context(out, {}, {}); return formatter_type().format(value, ctx); } @@ -2128,43 +3533,17 @@ FMT_CONSTEXPR void handle_dynamic_spec(int& value, } } -#define FMT_STRING_IMPL(s, base, explicit) \ - [] { \ - /* Use the hidden visibility as a workaround for a GCC bug (#1973). */ \ - /* Use a macro-like name to avoid shadowing warnings. */ \ - struct FMT_GCC_VISIBILITY_HIDDEN FMT_COMPILE_STRING : base { \ - using char_type = fmt::remove_cvref_t; \ - FMT_MAYBE_UNUSED FMT_CONSTEXPR explicit \ - operator fmt::basic_string_view() const { \ - return fmt::detail_exported::compile_string_to_view(s); \ - } \ - }; \ - return FMT_COMPILE_STRING(); \ - }() - -/** - \rst - Constructs a compile-time format string from a string literal *s*. - - **Example**:: - - // A compile-time error because 'd' is an invalid specifier for strings. - std::string s = fmt::format(FMT_STRING("{:d}"), "foo"); - \endrst - */ -#define FMT_STRING(s) FMT_STRING_IMPL(s, fmt::compile_string, ) - #if FMT_USE_USER_DEFINED_LITERALS template struct udl_formatter { basic_string_view str; template auto operator()(T&&... args) const -> std::basic_string { - return vformat(str, fmt::make_args_checked(str, args...)); + return vformat(str, fmt::make_format_args>(args...)); } }; -# if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +# if FMT_USE_NONTYPE_TEMPLATE_ARGS template Str> struct statically_named_arg : view { @@ -2213,10 +3592,10 @@ auto vformat(const Locale& loc, basic_string_view format_str, using format_func = void (*)(detail::buffer&, int, const char*); FMT_API void format_error_code(buffer& out, int error_code, - string_view message) FMT_NOEXCEPT; + string_view message) noexcept; FMT_API void report_error(format_func func, int error_code, - const char* message) FMT_NOEXCEPT; + const char* message) noexcept; FMT_END_DETAIL_NAMESPACE FMT_API auto vsystem_error(int error_code, string_view format_str, @@ -2262,12 +3641,11 @@ auto system_error(int error_code, format_string fmt, T&&... args) \endrst */ FMT_API void format_system_error(detail::buffer& out, int error_code, - const char* message) FMT_NOEXCEPT; + const char* message) noexcept; // Reports a system error without throwing an exception. // Can be used to report errors from destructors. -FMT_API void report_system_error(int error_code, - const char* message) FMT_NOEXCEPT; +FMT_API void report_system_error(int error_code, const char* message) noexcept; /** Fast integer formatter. */ class format_int { @@ -2349,27 +3727,6 @@ formatter(ctx.out(), val, specs_, ctx.locale()); } -#define FMT_FORMAT_AS(Type, Base) \ - template \ - struct formatter : formatter { \ - template \ - auto format(Type const& val, FormatContext& ctx) const \ - -> decltype(ctx.out()) { \ - return formatter::format(static_cast(val), ctx); \ - } \ - } - -FMT_FORMAT_AS(signed char, int); -FMT_FORMAT_AS(unsigned char, unsigned); -FMT_FORMAT_AS(short, int); -FMT_FORMAT_AS(unsigned short, unsigned); -FMT_FORMAT_AS(long, long long); -FMT_FORMAT_AS(unsigned long, unsigned long long); -FMT_FORMAT_AS(Char*, const Char*); -FMT_FORMAT_AS(std::basic_string, basic_string_view); -FMT_FORMAT_AS(std::nullptr_t, const void*); -FMT_FORMAT_AS(detail::std_string_view, basic_string_view); - template struct formatter : formatter { template @@ -2459,6 +3816,28 @@ template auto ptr(const std::shared_ptr& p) -> const void* { return p.get(); } +/** + \rst + Converts ``e`` to the underlying type. + + **Example**:: + + enum class color { red, green, blue }; + auto s = fmt::format("{}", fmt::underlying(color::red)); + \endrst + */ +template +constexpr auto underlying(Enum e) noexcept -> underlying_t { + return static_cast>(e); +} + +namespace enums { +template ::value)> +constexpr auto format_as(Enum e) noexcept -> underlying_t { + return static_cast>(e); +} +} // namespace enums + class bytes { private: string_view data_; @@ -2493,6 +3872,52 @@ template <> struct formatter { } }; +// group_digits_view is not derived from view because it copies the argument. +template struct group_digits_view { T value; }; + +/** + \rst + Returns a view that formats an integer value using ',' as a locale-independent + thousands separator. + + **Example**:: + + fmt::print("{}", fmt::group_digits(12345)); + // Output: "12,345" + \endrst + */ +template auto group_digits(T value) -> group_digits_view { + return {value}; +} + +template struct formatter> : formatter { + private: + detail::dynamic_format_specs specs_; + + public: + template + FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + using handler_type = detail::dynamic_specs_handler; + detail::specs_checker handler(handler_type(specs_, ctx), + detail::type::int_type); + auto it = parse_format_specs(ctx.begin(), ctx.end(), handler); + detail::check_string_type_spec(specs_.type, ctx.error_handler()); + return it; + } + + template + auto format(group_digits_view t, FormatContext& ctx) + -> decltype(ctx.out()) { + detail::handle_dynamic_spec(specs_.width, + specs_.width_ref, ctx); + detail::handle_dynamic_spec( + specs_.precision, specs_.precision_ref, ctx); + return detail::write_int_localized( + ctx.out(), static_cast>(t.value), 0, specs_, + detail::digit_grouping({"\3", ','})); + } +}; + template struct join_view : detail::view { It begin; @@ -2503,13 +3928,15 @@ struct join_view : detail::view { : begin(b), end(e), sep(s) {} }; -template -using arg_join FMT_DEPRECATED_ALIAS = join_view; - template struct formatter, Char> { private: - using value_type = typename std::iterator_traits::value_type; + using value_type = +#ifdef __cpp_lib_ranges + std::iter_value_t; +#else + typename std::iterator_traits::value_type; +#endif using context = buffer_context; using mapper = detail::arg_mapper; @@ -2538,16 +3965,18 @@ struct formatter, Char> { } template - auto format(const join_view& value, FormatContext& ctx) - -> decltype(ctx.out()) { + auto format(const join_view& value, + FormatContext& ctx) const -> decltype(ctx.out()) { auto it = value.begin; auto out = ctx.out(); if (it != value.end) { - out = value_formatter_.format(map(*it++), ctx); + out = value_formatter_.format(map(*it), ctx); + ++it; while (it != value.end) { out = detail::copy_str(value.sep.begin(), value.sep.end(), out); ctx.advance_to(out); - out = value_formatter_.format(map(*it++), ctx); + out = value_formatter_.format(map(*it), ctx); + ++it; } } return out; @@ -2555,8 +3984,8 @@ struct formatter, Char> { }; /** - Returns an object that formats the iterator range `[begin, end)` with - elements separated by `sep`. + Returns a view that formats the iterator range `[begin, end)` with elements + separated by `sep`. */ template auto join(It begin, Sentinel end, string_view sep) -> join_view { @@ -2565,7 +3994,7 @@ auto join(It begin, Sentinel end, string_view sep) -> join_view { /** \rst - Returns an object that formats `range` with elements separated by `sep`. + Returns a view that formats `range` with elements separated by `sep`. **Example**:: @@ -2604,7 +4033,7 @@ inline auto to_string(const T& value) -> std::string { } template ::value)> -inline auto to_string(T value) -> std::string { +FMT_NODISCARD inline auto to_string(T value) -> std::string { // The buffer should be large enough to store the number including the sign // or "false" for bool. constexpr int max_size = detail::digits10() + 2; @@ -2614,7 +4043,7 @@ inline auto to_string(T value) -> std::string { } template -auto to_string(const basic_memory_buffer& buf) +FMT_NODISCARD auto to_string(const basic_memory_buffer& buf) -> std::basic_string { auto size = buf.size(); detail::assume(size < std::basic_string().max_size()); @@ -2654,9 +4083,10 @@ void vformat_to( basic_format_parse_context parse_context; buffer_context context; - format_handler(buffer_appender out, basic_string_view str, - basic_format_args> args, locale_ref loc) - : parse_context(str), context(out, args, loc) {} + format_handler(buffer_appender p_out, basic_string_view str, + basic_format_args> p_args, + locale_ref p_loc) + : parse_context(str), context(p_out, p_args, p_loc) {} void on_text(const Char* begin, const Char* end) { auto text = basic_string_view(begin, to_unsigned(end - begin)); @@ -2713,20 +4143,6 @@ extern template FMT_API auto thousands_sep_impl(locale_ref) -> thousands_sep_result; extern template FMT_API auto decimal_point_impl(locale_ref) -> char; extern template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t; -extern template auto format_float(double value, int precision, - float_specs specs, buffer& buf) - -> int; -extern template auto format_float(long double value, int precision, - float_specs specs, - buffer& buf) -> int; -void snprintf_float(float, int, float_specs, buffer&) = delete; -extern template auto snprintf_float(double value, int precision, - float_specs specs, - buffer& buf) -> int; -extern template auto snprintf_float(long double value, - int precision, - float_specs specs, - buffer& buf) -> int; #endif // FMT_HEADER_ONLY FMT_END_DETAIL_NAMESPACE @@ -2743,33 +4159,16 @@ inline namespace literals { fmt::print("Elapsed time: {s:.2f} seconds", "s"_a=1.23); \endrst */ -# if FMT_USE_NONTYPE_TEMPLATE_PARAMETERS -template -constexpr auto operator""_a() - -> detail::udl_arg, - sizeof(Str.data) / sizeof(decltype(Str.data[0])), Str> { - return {}; +# if FMT_USE_NONTYPE_TEMPLATE_ARGS +template constexpr auto operator""_a() { + using char_t = remove_cvref_t; + return detail::udl_arg(); } # else constexpr auto operator"" _a(const char* s, size_t) -> detail::udl_arg { return {s}; } # endif - -/** - \rst - User-defined literal equivalent of :func:`fmt::format`. - - **Example**:: - - using namespace fmt::literals; - std::string message = "The answer is {}"_format(42); - \endrst - */ -constexpr auto operator"" _format(const char* s, size_t n) - -> detail::udl_formatter { - return {{s, n}}; -} } // namespace literals #endif // FMT_USE_USER_DEFINED_LITERALS @@ -2786,14 +4185,6 @@ inline auto format(const Locale& loc, format_string fmt, T&&... args) return vformat(loc, string_view(fmt), fmt::make_format_args(args...)); } -template -FMT_DEPRECATED auto format_to(basic_memory_buffer& buf, - format_string fmt, T&&... args) - -> appender { - detail::vformat_to(buf, string_view(fmt), fmt::make_format_args(args...)); - return appender(buf); -} - template ::value&& detail::is_locale::value)> @@ -2816,10 +4207,6 @@ FMT_INLINE auto format_to(OutputIt out, const Locale& loc, FMT_MODULE_EXPORT_END FMT_END_NAMESPACE -#ifdef FMT_DEPRECATED_INCLUDE_XCHAR -# include "xchar.h" -#endif - #ifdef FMT_HEADER_ONLY # define FMT_FUNC inline # include "format-inl.h" diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bundled/os.h b/Lumos/External/spdlog/include/spdlog/fmt/bundled/os.h index f6c0f3298..d82be1125 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/bundled/os.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/bundled/os.h @@ -9,10 +9,8 @@ #define FMT_OS_H_ #include -#include // locale_t #include #include -#include // strtod_l #include // std::system_error #if defined __APPLE__ || defined(__FreeBSD__) @@ -21,17 +19,20 @@ #include "format.h" +#ifndef FMT_USE_FCNTL // UWP doesn't provide _pipe. -#if FMT_HAS_INCLUDE("winapifamily.h") -# include -#endif -#if (FMT_HAS_INCLUDE() || defined(__APPLE__) || \ - defined(__linux__)) && \ - (!defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)) -# include // for O_RDONLY -# define FMT_USE_FCNTL 1 -#else -# define FMT_USE_FCNTL 0 +# if FMT_HAS_INCLUDE("winapifamily.h") +# include +# endif +# if (FMT_HAS_INCLUDE() || defined(__APPLE__) || \ + defined(__linux__)) && \ + (!defined(WINAPI_FAMILY) || \ + (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP)) +# include // for O_RDONLY +# define FMT_USE_FCNTL 1 +# else +# define FMT_USE_FCNTL 0 +# endif #endif #ifndef FMT_POSIX @@ -138,7 +139,7 @@ template struct formatter { }; #ifdef _WIN32 -FMT_API const std::error_category& system_category() FMT_NOEXCEPT; +FMT_API const std::error_category& system_category() noexcept; FMT_BEGIN_DETAIL_NAMESPACE // A converter from UTF-16 to UTF-8. @@ -162,7 +163,7 @@ class utf16_to_utf8 { }; FMT_API void format_windows_error(buffer& out, int error_code, - const char* message) FMT_NOEXCEPT; + const char* message) noexcept; FMT_END_DETAIL_NAMESPACE FMT_API std::system_error vwindows_error(int error_code, string_view format_str, @@ -204,10 +205,9 @@ std::system_error windows_error(int error_code, string_view message, // Reports a Windows error without throwing an exception. // Can be used to report errors from destructors. -FMT_API void report_windows_error(int error_code, - const char* message) FMT_NOEXCEPT; +FMT_API void report_windows_error(int error_code, const char* message) noexcept; #else -inline const std::error_category& system_category() FMT_NOEXCEPT { +inline const std::error_category& system_category() noexcept { return std::system_category(); } #endif // _WIN32 @@ -234,13 +234,13 @@ class buffered_file { void operator=(const buffered_file&) = delete; // Constructs a buffered_file object which doesn't represent any file. - buffered_file() FMT_NOEXCEPT : file_(nullptr) {} + buffered_file() noexcept : file_(nullptr) {} // Destroys the object closing the file it represents if any. - FMT_API ~buffered_file() FMT_NOEXCEPT; + FMT_API ~buffered_file() noexcept; public: - buffered_file(buffered_file&& other) FMT_NOEXCEPT : file_(other.file_) { + buffered_file(buffered_file&& other) noexcept : file_(other.file_) { other.file_ = nullptr; } @@ -258,11 +258,9 @@ class buffered_file { FMT_API void close(); // Returns the pointer to a FILE object representing this file. - FILE* get() const FMT_NOEXCEPT { return file_; } + FILE* get() const noexcept { return file_; } - // We place parentheses around fileno to workaround a bug in some versions - // of MinGW that define fileno as a macro. - FMT_API int(fileno)() const; + FMT_API int descriptor() const; void vprint(string_view format_str, format_args args) { fmt::vprint(file_, format_str, args); @@ -276,12 +274,12 @@ class buffered_file { #if FMT_USE_FCNTL // A file. Closed file is represented by a file object with descriptor -1. -// Methods that are not declared with FMT_NOEXCEPT may throw +// Methods that are not declared with noexcept may throw // fmt::system_error in case of failure. Note that some errors such as // closing the file multiple times will cause a crash on Windows rather // than an exception. You can get standard behavior by overriding the // invalid parameter handler with _set_invalid_parameter_handler. -class file { +class FMT_API file { private: int fd_; // File descriptor. @@ -300,16 +298,16 @@ class file { }; // Constructs a file object which doesn't represent any file. - file() FMT_NOEXCEPT : fd_(-1) {} + file() noexcept : fd_(-1) {} // Opens a file and constructs a file object representing this file. - FMT_API file(cstring_view path, int oflag); + file(cstring_view path, int oflag); public: file(const file&) = delete; void operator=(const file&) = delete; - file(file&& other) FMT_NOEXCEPT : fd_(other.fd_) { other.fd_ = -1; } + file(file&& other) noexcept : fd_(other.fd_) { other.fd_ = -1; } // Move assignment is not noexcept because close may throw. file& operator=(file&& other) { @@ -320,43 +318,43 @@ class file { } // Destroys the object closing the file it represents if any. - FMT_API ~file() FMT_NOEXCEPT; + ~file() noexcept; // Returns the file descriptor. - int descriptor() const FMT_NOEXCEPT { return fd_; } + int descriptor() const noexcept { return fd_; } // Closes the file. - FMT_API void close(); + void close(); // Returns the file size. The size has signed type for consistency with // stat::st_size. - FMT_API long long size() const; + long long size() const; // Attempts to read count bytes from the file into the specified buffer. - FMT_API size_t read(void* buffer, size_t count); + size_t read(void* buffer, size_t count); // Attempts to write count bytes from the specified buffer to the file. - FMT_API size_t write(const void* buffer, size_t count); + size_t write(const void* buffer, size_t count); // Duplicates a file descriptor with the dup function and returns // the duplicate as a file object. - FMT_API static file dup(int fd); + static file dup(int fd); // Makes fd be the copy of this file descriptor, closing fd first if // necessary. - FMT_API void dup2(int fd); + void dup2(int fd); // Makes fd be the copy of this file descriptor, closing fd first if // necessary. - FMT_API void dup2(int fd, std::error_code& ec) FMT_NOEXCEPT; + void dup2(int fd, std::error_code& ec) noexcept; // Creates a pipe setting up read_end and write_end file objects for reading // and writing respectively. - FMT_API static void pipe(file& read_end, file& write_end); + static void pipe(file& read_end, file& write_end); // Creates a buffered_file object associated with this file and detaches // this file object from the file. - FMT_API buffered_file fdopen(const char* mode); + buffered_file fdopen(const char* mode); }; // Returns the memory page size. @@ -390,23 +388,26 @@ struct ostream_params { : ostream_params(params...) { this->buffer_size = bs.value; } + +// Intel has a bug that results in failure to deduce a constructor +// for empty parameter packs. +# if defined(__INTEL_COMPILER) && __INTEL_COMPILER < 2000 + ostream_params(int new_oflag) : oflag(new_oflag) {} + ostream_params(detail::buffer_size bs) : buffer_size(bs.value) {} +# endif }; FMT_END_DETAIL_NAMESPACE -constexpr detail::buffer_size buffer_size; +// Added {} below to work around default constructor error known to +// occur in Xcode versions 7.2.1 and 8.2.1. +constexpr detail::buffer_size buffer_size{}; /** A fast output stream which is not thread-safe. */ class FMT_API ostream final : private detail::buffer { private: file file_; - void flush() { - if (size() == 0) return; - file_.write(data(), size()); - clear(); - } - void grow(size_t) override; ostream(cstring_view path, const detail::ostream_params& params) @@ -426,6 +427,12 @@ class FMT_API ostream final : private detail::buffer { delete[] data(); } + void flush() { + if (size() == 0) return; + file_.write(data(), size()); + clear(); + } + template friend ostream output_file(cstring_view path, T... params); @@ -450,7 +457,7 @@ class FMT_API ostream final : private detail::buffer { * ````: Flags passed to `open `_ - (``file::WRONLY | file::CREATE`` by default) + (``file::WRONLY | file::CREATE | file::TRUNC`` by default) * ``buffer_size=``: Output buffer size **Example**:: @@ -465,50 +472,6 @@ inline ostream output_file(cstring_view path, T... params) { } #endif // FMT_USE_FCNTL -#ifdef FMT_LOCALE -// A "C" numeric locale. -class locale { - private: -# ifdef _WIN32 - using locale_t = _locale_t; - - static void freelocale(locale_t loc) { _free_locale(loc); } - - static double strtod_l(const char* nptr, char** endptr, _locale_t loc) { - return _strtod_l(nptr, endptr, loc); - } -# endif - - locale_t locale_; - - public: - using type = locale_t; - locale(const locale&) = delete; - void operator=(const locale&) = delete; - - locale() { -# ifndef _WIN32 - locale_ = FMT_SYSTEM(newlocale(LC_NUMERIC_MASK, "C", nullptr)); -# else - locale_ = _create_locale(LC_NUMERIC, "C"); -# endif - if (!locale_) FMT_THROW(system_error(errno, "cannot create locale")); - } - ~locale() { freelocale(locale_); } - - type get() const { return locale_; } - - // Converts string to floating-point number and advances str past the end - // of the parsed input. - double strtod(const char*& str) const { - char* end = nullptr; - double result = strtod_l(str, &end, locale_); - str = end; - return result; - } -}; -using Locale FMT_DEPRECATED_ALIAS = locale; -#endif // FMT_LOCALE FMT_MODULE_EXPORT_END FMT_END_NAMESPACE diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bundled/ostream.h b/Lumos/External/spdlog/include/spdlog/fmt/bundled/ostream.h index d66248a60..c3cdd4a61 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/bundled/ostream.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/bundled/ostream.h @@ -8,79 +8,33 @@ #ifndef FMT_OSTREAM_H_ #define FMT_OSTREAM_H_ +#include #include +#if defined(_WIN32) && defined(__GLIBCXX__) +# include +# include +#elif defined(_WIN32) && defined(_LIBCPP_VERSION) +# include <__std_stream> +#endif #include "format.h" FMT_BEGIN_NAMESPACE -template class basic_printf_parse_context; template class basic_printf_context; namespace detail { -template class formatbuf : public std::basic_streambuf { - private: - using int_type = typename std::basic_streambuf::int_type; - using traits_type = typename std::basic_streambuf::traits_type; - - buffer& buffer_; - - public: - formatbuf(buffer& buf) : buffer_(buf) {} - - protected: - // The put-area is actually always empty. This makes the implementation - // simpler and has the advantage that the streambuf and the buffer are always - // in sync and sputc never writes into uninitialized memory. The obvious - // disadvantage is that each call to sputc always results in a (virtual) call - // to overflow. There is no disadvantage here for sputn since this always - // results in a call to xsputn. - - int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE { - if (!traits_type::eq_int_type(ch, traits_type::eof())) - buffer_.push_back(static_cast(ch)); - return ch; - } - - std::streamsize xsputn(const Char* s, std::streamsize count) FMT_OVERRIDE { - buffer_.append(s, s + count); - return count; - } -}; - -struct converter { - template ::value)> converter(T); -}; - -template struct test_stream : std::basic_ostream { - private: - void_t<> operator<<(converter); -}; - -// Hide insertion operators for built-in types. -template -void_t<> operator<<(std::basic_ostream&, Char); -template -void_t<> operator<<(std::basic_ostream&, char); -template -void_t<> operator<<(std::basic_ostream&, char); -template -void_t<> operator<<(std::basic_ostream&, signed char); -template -void_t<> operator<<(std::basic_ostream&, unsigned char); - -// Checks if T has a user-defined operator<< (e.g. not a member of -// std::ostream). -template class is_streamable { +// Checks if T has a user-defined operator<<. +template +class is_streamable { private: template - static bool_constant&>() - << std::declval()), - void_t<>>::value> - test(int); + static auto test(int) + -> bool_constant&>() + << std::declval()) != 0>; - template static std::false_type test(...); + template static auto test(...) -> std::false_type; using result = decltype(test(0)); @@ -90,7 +44,68 @@ template class is_streamable { static const bool value = result::value; }; +// Formatting of built-in types and arrays is intentionally disabled because +// it's handled by standard (non-ostream) formatters. +template +struct is_streamable< + T, Char, + enable_if_t< + std::is_arithmetic::value || std::is_array::value || + std::is_pointer::value || std::is_same::value || + std::is_convertible>::value || + std::is_same>::value || + (std::is_convertible::value && !std::is_enum::value)>> + : std::false_type {}; + +// Generate a unique explicit instantion in every translation unit using a tag +// type in an anonymous namespace. +namespace { +struct file_access_tag {}; +} // namespace +template +class file_access { + friend auto get_file(BufType& obj) -> FILE* { return obj.*FileMemberPtr; } +}; + +#if FMT_MSC_VERSION +template class file_access; +auto get_file(std::filebuf&) -> FILE*; +#elif defined(_WIN32) && defined(_LIBCPP_VERSION) +template class file_access, + &std::__stdoutbuf::__file_>; +auto get_file(std::__stdoutbuf&) -> FILE*; +#endif + +inline bool write_ostream_unicode(std::ostream& os, fmt::string_view data) { +#if FMT_MSC_VERSION + if (auto* buf = dynamic_cast(os.rdbuf())) + if (FILE* f = get_file(*buf)) return write_console(f, data); +#elif defined(_WIN32) && defined(__GLIBCXX__) + auto* rdbuf = os.rdbuf(); + FILE* c_file; + if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_sync_filebuf*>(rdbuf)) + c_file = fbuf->file(); + else if (auto* fbuf = dynamic_cast<__gnu_cxx::stdio_filebuf*>(rdbuf)) + c_file = fbuf->file(); + else + return false; + if (c_file) return write_console(c_file, data); +#elif defined(_WIN32) && defined(_LIBCPP_VERSION) + if (auto* buf = dynamic_cast*>(os.rdbuf())) + if (FILE* f = get_file(*buf)) return write_console(f, data); +#else + ignore_unused(os, data); +#endif + return false; +} +inline bool write_ostream_unicode(std::wostream&, + fmt::basic_string_view) { + return false; +} + // Write the content of buf to os. +// It is a separate function rather than a part of vprint to simplify testing. template void write_buffer(std::basic_ostream& os, buffer& buf) { const Char* buf_data = buf.data(); @@ -108,55 +123,86 @@ void write_buffer(std::basic_ostream& os, buffer& buf) { template void format_value(buffer& buf, const T& value, locale_ref loc = locale_ref()) { - formatbuf format_buf(buf); - std::basic_ostream output(&format_buf); + auto&& format_buf = formatbuf>(buf); + auto&& output = std::basic_ostream(&format_buf); #if !defined(FMT_STATIC_THOUSANDS_SEPARATOR) if (loc) output.imbue(loc.get()); #endif output << value; output.exceptions(std::ios_base::failbit | std::ios_base::badbit); - buf.try_resize(buf.size()); } +template struct streamed_view { const T& value; }; + +} // namespace detail + // Formats an object of type T that has an overloaded ostream operator<<. -template -struct fallback_formatter::value>> - : private formatter, Char> { - FMT_CONSTEXPR auto parse(basic_format_parse_context& ctx) - -> decltype(ctx.begin()) { - return formatter, Char>::parse(ctx); - } - template >::value)> - auto parse(ParseCtx& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } +template +struct basic_ostream_formatter : formatter, Char> { + void set_debug_format() = delete; - template - auto format(const T& value, basic_format_context& ctx) + template + auto format(const T& value, basic_format_context& ctx) const -> OutputIt { - basic_memory_buffer buffer; + auto buffer = basic_memory_buffer(); format_value(buffer, value, ctx.locale()); - basic_string_view str(buffer.data(), buffer.size()); - return formatter, Char>::format(str, ctx); + return formatter, Char>::format( + {buffer.data(), buffer.size()}, ctx); } +}; + +using ostream_formatter = basic_ostream_formatter; + +template +struct formatter, Char> + : basic_ostream_formatter { template - auto format(const T& value, basic_printf_context& ctx) - -> OutputIt { - basic_memory_buffer buffer; - format_value(buffer, value, ctx.locale()); - return std::copy(buffer.begin(), buffer.end(), ctx.out()); + auto format(detail::streamed_view view, + basic_format_context& ctx) const -> OutputIt { + return basic_ostream_formatter::format(view.value, ctx); } }; + +/** + \rst + Returns a view that formats `value` via an ostream ``operator<<``. + + **Example**:: + + fmt::print("Current thread id: {}\n", + fmt::streamed(std::this_thread::get_id())); + \endrst + */ +template +auto streamed(const T& value) -> detail::streamed_view { + return {value}; +} + +namespace detail { + +// Formats an object of type T that has an overloaded ostream operator<<. +template +struct fallback_formatter::value>> + : basic_ostream_formatter { + using basic_ostream_formatter::format; +}; + +inline void vprint_directly(std::ostream& os, string_view format_str, + format_args args) { + auto buffer = memory_buffer(); + detail::vformat_to(buffer, format_str, args); + detail::write_buffer(os, buffer); +} + } // namespace detail -FMT_MODULE_EXPORT -template -void vprint(std::basic_ostream& os, basic_string_view format_str, +FMT_MODULE_EXPORT template +void vprint(std::basic_ostream& os, + basic_string_view> format_str, basic_format_args>> args) { - basic_memory_buffer buffer; + auto buffer = basic_memory_buffer(); detail::vformat_to(buffer, format_str, args); + if (detail::write_ostream_unicode(os, {buffer.data(), buffer.size()})) return; detail::write_buffer(os, buffer); } @@ -169,13 +215,23 @@ void vprint(std::basic_ostream& os, basic_string_view format_str, fmt::print(cerr, "Don't {}!", "panic"); \endrst */ +FMT_MODULE_EXPORT template +void print(std::ostream& os, format_string fmt, T&&... args) { + const auto& vargs = fmt::make_format_args(args...); + if (detail::is_utf8()) + vprint(os, fmt, vargs); + else + detail::vprint_directly(os, fmt, vargs); +} + FMT_MODULE_EXPORT -template ::value, char_t>> -void print(std::basic_ostream& os, const S& format_str, Args&&... args) { - vprint(os, to_string_view(format_str), - fmt::make_args_checked(format_str, args...)); +template +void print(std::wostream& os, + basic_format_string...> fmt, + Args&&... args) { + vprint(os, fmt, fmt::make_format_args>(args...)); } + FMT_END_NAMESPACE #endif // FMT_OSTREAM_H_ diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bundled/printf.h b/Lumos/External/spdlog/include/spdlog/fmt/bundled/printf.h index 3a3cd1528..70a592dc2 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/bundled/printf.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/bundled/printf.h @@ -10,7 +10,6 @@ #include // std::max #include // std::numeric_limits -#include #include "format.h" @@ -233,7 +232,7 @@ class printf_arg_formatter : public arg_formatter { OutputIt write_null_pointer(bool is_string = false) { auto s = this->specs; - s.type = 0; + s.type = presentation_type::none; return write_bytes(this->out, is_string ? "(null)" : "(nil)", s); } @@ -249,8 +248,10 @@ class printf_arg_formatter : public arg_formatter { // std::is_same instead. if (std::is_same::value) { format_specs fmt_specs = this->specs; - if (fmt_specs.type && fmt_specs.type != 'c') + if (fmt_specs.type != presentation_type::none && + fmt_specs.type != presentation_type::chr) { return (*this)(static_cast(value)); + } fmt_specs.sign = sign::none; fmt_specs.alt = false; fmt_specs.fill[0] = ' '; // Ignore '0' flag for char types. @@ -271,13 +272,13 @@ class printf_arg_formatter : public arg_formatter { /** Formats a null-terminated C string. */ OutputIt operator()(const char* value) { if (value) return base::operator()(value); - return write_null_pointer(this->specs.type != 'p'); + return write_null_pointer(this->specs.type != presentation_type::pointer); } /** Formats a null-terminated wide C string. */ OutputIt operator()(const wchar_t* value) { if (value) return base::operator()(value); - return write_null_pointer(this->specs.type != 'p'); + return write_null_pointer(this->specs.type != presentation_type::pointer); } OutputIt operator()(basic_string_view value) { @@ -490,13 +491,13 @@ void vprintf(buffer& buf, basic_string_view format, // Parse type. if (it == end) FMT_THROW(format_error("invalid format string")); - specs.type = static_cast(*it++); + char type = static_cast(*it++); if (arg.is_integral()) { // Normalize type. - switch (specs.type) { + switch (type) { case 'i': case 'u': - specs.type = 'd'; + type = 'd'; break; case 'c': visit_format_arg( @@ -505,6 +506,9 @@ void vprintf(buffer& buf, basic_string_view format, break; } } + specs.type = parse_presentation_type(type); + if (specs.type == presentation_type::none) + parse_ctx.on_error("invalid type specifier"); start = it; @@ -556,7 +560,7 @@ inline auto vsprintf( basic_format_args>> args) -> std::basic_string { basic_memory_buffer buffer; - vprintf(buffer, to_string_view(fmt), args); + vprintf(buffer, detail::to_string_view(fmt), args); return to_string(buffer); } @@ -573,7 +577,8 @@ template ::value, char_t>> inline auto sprintf(const S& fmt, const T&... args) -> std::basic_string { using context = basic_printf_context_t; - return vsprintf(to_string_view(fmt), fmt::make_format_args(args...)); + return vsprintf(detail::to_string_view(fmt), + fmt::make_format_args(args...)); } template > @@ -582,7 +587,7 @@ inline auto vfprintf( basic_format_args>> args) -> int { basic_memory_buffer buffer; - vprintf(buffer, to_string_view(fmt), args); + vprintf(buffer, detail::to_string_view(fmt), args); size_t size = buffer.size(); return std::fwrite(buffer.data(), sizeof(Char), size, f) < size ? -1 @@ -601,7 +606,7 @@ inline auto vfprintf( template > inline auto fprintf(std::FILE* f, const S& fmt, const T&... args) -> int { using context = basic_printf_context_t; - return vfprintf(f, to_string_view(fmt), + return vfprintf(f, detail::to_string_view(fmt), fmt::make_format_args(args...)); } @@ -610,7 +615,7 @@ inline auto vprintf( const S& fmt, basic_format_args>> args) -> int { - return vfprintf(stdout, to_string_view(fmt), args); + return vfprintf(stdout, detail::to_string_view(fmt), args); } /** @@ -625,27 +630,10 @@ inline auto vprintf( template ::value)> inline auto printf(const S& fmt, const T&... args) -> int { return vprintf( - to_string_view(fmt), + detail::to_string_view(fmt), fmt::make_format_args>>(args...)); } -template > -FMT_DEPRECATED auto vfprintf( - std::basic_ostream& os, const S& fmt, - basic_format_args>> args) - -> int { - basic_memory_buffer buffer; - vprintf(buffer, to_string_view(fmt), args); - os.write(buffer.data(), static_cast(buffer.size())); - return static_cast(buffer.size()); -} -template > -FMT_DEPRECATED auto fprintf(std::basic_ostream& os, const S& fmt, - const T&... args) -> int { - return vfprintf(os, to_string_view(fmt), - fmt::make_format_args>(args...)); -} - FMT_MODULE_EXPORT_END FMT_END_NAMESPACE diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bundled/ranges.h b/Lumos/External/spdlog/include/spdlog/fmt/bundled/ranges.h index f0390df21..dea7d60dd 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/bundled/ranges.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/bundled/ranges.h @@ -13,37 +13,13 @@ #define FMT_RANGES_H_ #include +#include #include #include "format.h" FMT_BEGIN_NAMESPACE -template struct formatting_range { -#ifdef FMT_DEPRECATED_BRACED_RANGES - Char prefix = '{'; - Char postfix = '}'; -#else - Char prefix = '['; - Char postfix = ']'; -#endif - - template - FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } -}; - -template struct formatting_tuple { - Char prefix = '('; - Char postfix = ')'; - - template - FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); - } -}; - namespace detail { template @@ -71,7 +47,7 @@ OutputIterator copy(wchar_t ch, OutputIterator out) { return out; } -/// Return true value if T has std::string interface, like std::string_view. +// Returns true if T has a std::string-like interface, like std::string_view. template class is_std_string_like { template static auto check(U* p) @@ -79,18 +55,46 @@ template class is_std_string_like { template static void check(...); public: - static FMT_CONSTEXPR_DECL const bool value = - is_string::value || !std::is_void(nullptr))>::value; + static constexpr const bool value = + is_string::value || + std::is_convertible>::value || + !std::is_void(nullptr))>::value; }; template struct is_std_string_like> : std::true_type {}; +template class is_map { + template static auto check(U*) -> typename U::mapped_type; + template static void check(...); + + public: +#ifdef FMT_FORMAT_MAP_AS_LIST + static constexpr const bool value = false; +#else + static constexpr const bool value = + !std::is_void(nullptr))>::value; +#endif +}; + +template class is_set { + template static auto check(U*) -> typename U::key_type; + template static void check(...); + + public: +#ifdef FMT_FORMAT_SET_AS_LIST + static constexpr const bool value = false; +#else + static constexpr const bool value = + !std::is_void(nullptr))>::value && !is_map::value; +#endif +}; + template struct conditional_helper {}; template struct is_range_ : std::false_type {}; -#if !FMT_MSC_VER || FMT_MSC_VER > 1800 +#if !FMT_MSC_VERSION || FMT_MSC_VERSION > 1800 # define FMT_DECLTYPE_RETURN(val) \ ->decltype(val) { return val; } \ @@ -143,16 +147,16 @@ struct has_mutable_begin_end : std::false_type {}; template struct has_const_begin_end< - T, void_t&>())), - decltype(detail::range_begin( - std::declval&>()))>> + T, + void_t< + decltype(detail::range_begin(std::declval&>())), + decltype(detail::range_end(std::declval&>()))>> : std::true_type {}; template struct has_mutable_begin_end< T, void_t())), - decltype(detail::range_begin(std::declval())), + decltype(detail::range_end(std::declval())), enable_if_t::value>>> : std::true_type {}; @@ -160,46 +164,22 @@ template struct is_range_ : std::integral_constant::value || has_mutable_begin_end::value)> {}; - -template struct range_to_view; -template -struct range_to_view::value>> { - struct view_t { - const T* m_range_ptr; - - auto begin() const FMT_DECLTYPE_RETURN(detail::range_begin(*m_range_ptr)); - auto end() const FMT_DECLTYPE_RETURN(detail::range_end(*m_range_ptr)); - }; - static auto view(const T& range) -> view_t { return {&range}; } -}; - -template -struct range_to_view::value && - has_mutable_begin_end::value>> { - struct view_t { - T m_range_copy; - - auto begin() FMT_DECLTYPE_RETURN(detail::range_begin(m_range_copy)); - auto end() FMT_DECLTYPE_RETURN(detail::range_end(m_range_copy)); - }; - static auto view(const T& range) -> view_t { return {range}; } -}; # undef FMT_DECLTYPE_RETURN #endif -/// tuple_size and tuple_element check. +// tuple_size and tuple_element check. template class is_tuple_like_ { template static auto check(U* p) -> decltype(std::tuple_size::value, int()); template static void check(...); public: - static FMT_CONSTEXPR_DECL const bool value = + static constexpr const bool value = !std::is_void(nullptr))>::value; }; // Check for integer_sequence -#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VER >= 1900 +#if defined(__cpp_lib_integer_sequence) || FMT_MSC_VERSION >= 1900 template using integer_sequence = std::integer_sequence; template using index_sequence = std::index_sequence; @@ -222,8 +202,33 @@ template using make_index_sequence = make_integer_sequence; #endif +template +using tuple_index_sequence = make_index_sequence::value>; + +template ::value> +class is_tuple_formattable_ { + public: + static constexpr const bool value = false; +}; +template class is_tuple_formattable_ { + template + static std::true_type check2(index_sequence, + integer_sequence); + static std::false_type check2(...); + template + static decltype(check2( + index_sequence{}, + integer_sequence< + bool, (is_formattable::type, + C>::value)...>{})) check(index_sequence); + + public: + static constexpr const bool value = + decltype(check(tuple_index_sequence{}))::value; +}; + template -void for_each(index_sequence, Tuple&& tup, F&& f) FMT_NOEXCEPT { +void for_each(index_sequence, Tuple&& tup, F&& f) noexcept { using std::get; // using free function get(T) now. const int _[] = {0, ((void)f(get(tup)), 0)...}; @@ -241,9 +246,36 @@ template void for_each(Tuple&& tup, F&& f) { for_each(indexes, std::forward(tup), std::forward(f)); } +#if FMT_MSC_VERSION && FMT_MSC_VERSION < 1920 +// Older MSVC doesn't get the reference type correctly for arrays. +template struct range_reference_type_impl { + using type = decltype(*detail::range_begin(std::declval())); +}; + +template struct range_reference_type_impl { + using type = T&; +}; + +template +using range_reference_type = typename range_reference_type_impl::type; +#else template -using value_type = - remove_cvref_t()))>; +using range_reference_type = + decltype(*detail::range_begin(std::declval())); +#endif + +// We don't use the Range's value_type for anything, but we do need the Range's +// reference type, with cv-ref stripped. +template +using uncvref_type = remove_cvref_t>; + +template +using uncvref_first_type = + remove_cvref_t>().first)>; + +template +using uncvref_second_type = remove_cvref_t< + decltype(std::declval>().second)>; template OutputIt write_delimiter(OutputIt out) { *out++ = ','; @@ -251,23 +283,22 @@ template OutputIt write_delimiter(OutputIt out) { return out; } -template < - typename Char, typename OutputIt, typename Arg, - FMT_ENABLE_IF(is_std_string_like::type>::value)> -OutputIt write_range_entry(OutputIt out, const Arg& v) { - *out++ = '"'; - out = write(out, v); - *out++ = '"'; - return out; +template +auto write_range_entry(OutputIt out, basic_string_view str) -> OutputIt { + return write_escaped_string(out, str); +} + +template >::value)> +inline auto write_range_entry(OutputIt out, const T& str) -> OutputIt { + auto sv = std_string_view(str); + return write_range_entry(out, basic_string_view(sv)); } template ::value)> OutputIt write_range_entry(OutputIt out, const Arg v) { - *out++ = '\''; - *out++ = v; - *out++ = '\''; - return out; + return write_escaped_char(out, v); } template < @@ -281,88 +312,287 @@ OutputIt write_range_entry(OutputIt out, const Arg& v) { } // namespace detail template struct is_tuple_like { - static FMT_CONSTEXPR_DECL const bool value = + static constexpr const bool value = detail::is_tuple_like_::value && !detail::is_range_::value; }; +template struct is_tuple_formattable { + static constexpr const bool value = + detail::is_tuple_formattable_::value; +}; + template -struct formatter::value>> { +struct formatter::value && + fmt::is_tuple_formattable::value>> { private: - // C++11 generic lambda for format() + basic_string_view separator_ = detail::string_literal{}; + basic_string_view opening_bracket_ = + detail::string_literal{}; + basic_string_view closing_bracket_ = + detail::string_literal{}; + + // C++11 generic lambda for format(). template struct format_each { template void operator()(const T& v) { - if (i > 0) out = detail::write_delimiter(out); + if (i > 0) out = detail::copy_str(separator, out); out = detail::write_range_entry(out, v); ++i; } - formatting_tuple& formatting; - size_t& i; - typename std::add_lvalue_reference< - decltype(std::declval().out())>::type out; + int i; + typename FormatContext::iterator& out; + basic_string_view separator; }; public: - formatting_tuple formatting; + FMT_CONSTEXPR formatter() {} + + FMT_CONSTEXPR void set_separator(basic_string_view sep) { + separator_ = sep; + } + + FMT_CONSTEXPR void set_brackets(basic_string_view open, + basic_string_view close) { + opening_bracket_ = open; + closing_bracket_ = close; + } template FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return formatting.parse(ctx); + return ctx.begin(); } template - auto format(const TupleT& values, FormatContext& ctx) -> decltype(ctx.out()) { + auto format(const TupleT& values, FormatContext& ctx) const + -> decltype(ctx.out()) { auto out = ctx.out(); - size_t i = 0; - - detail::copy(formatting.prefix, out); - detail::for_each(values, format_each{formatting, i, out}); - detail::copy(formatting.postfix, out); - - return ctx.out(); + out = detail::copy_str(opening_bracket_, out); + detail::for_each(values, format_each{0, out, separator_}); + out = detail::copy_str(closing_bracket_, out); + return out; } }; template struct is_range { - static FMT_CONSTEXPR_DECL const bool value = + static constexpr const bool value = detail::is_range_::value && !detail::is_std_string_like::value && !std::is_convertible>::value && - !std::is_constructible, T>::value; + !std::is_convertible>::value; +}; + +namespace detail { +template struct range_mapper { + using mapper = arg_mapper; + + template , Context>::value)> + static auto map(T&& value) -> T&& { + return static_cast(value); + } + template , Context>::value)> + static auto map(T&& value) + -> decltype(mapper().map(static_cast(value))) { + return mapper().map(static_cast(value)); + } }; +template +using range_formatter_type = conditional_t< + is_formattable::value, + formatter>{}.map( + std::declval()))>, + Char>, + fallback_formatter>; + +template +using maybe_const_range = + conditional_t::value, const R, R>; + +// Workaround a bug in MSVC 2015 and earlier. +#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910 +template +struct is_formattable_delayed + : disjunction< + is_formattable>, Char>, + has_fallback_formatter>, Char>> {}; +#endif + +} // namespace detail + +template +struct range_formatter; + template -struct formatter< +struct range_formatter< T, Char, - enable_if_t< - fmt::is_range::value -// Workaround a bug in MSVC 2017 and earlier. -#if !FMT_MSC_VER || FMT_MSC_VER >= 1927 - && (has_formatter, format_context>::value || - detail::has_fallback_formatter, Char>::value) -#endif - >> { - formatting_range formatting; + enable_if_t>, + disjunction, + detail::has_fallback_formatter>>::value>> { + private: + detail::range_formatter_type underlying_; + bool custom_specs_ = false; + basic_string_view separator_ = detail::string_literal{}; + basic_string_view opening_bracket_ = + detail::string_literal{}; + basic_string_view closing_bracket_ = + detail::string_literal{}; + + template + FMT_CONSTEXPR static auto maybe_set_debug_format(U& u, int) + -> decltype(u.set_debug_format()) { + u.set_debug_format(); + } + + template + FMT_CONSTEXPR static void maybe_set_debug_format(U&, ...) {} + + FMT_CONSTEXPR void maybe_set_debug_format() { + maybe_set_debug_format(underlying_, 0); + } + + public: + FMT_CONSTEXPR range_formatter() {} + + FMT_CONSTEXPR auto underlying() -> detail::range_formatter_type& { + return underlying_; + } + + FMT_CONSTEXPR void set_separator(basic_string_view sep) { + separator_ = sep; + } + + FMT_CONSTEXPR void set_brackets(basic_string_view open, + basic_string_view close) { + opening_bracket_ = open; + closing_bracket_ = close; + } template FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return formatting.parse(ctx); + auto it = ctx.begin(); + auto end = ctx.end(); + if (it == end || *it == '}') { + maybe_set_debug_format(); + return it; + } + + if (*it == 'n') { + set_brackets({}, {}); + ++it; + } + + if (*it == '}') { + maybe_set_debug_format(); + return it; + } + + if (*it != ':') + FMT_THROW(format_error("no other top-level range formatters supported")); + + custom_specs_ = true; + ++it; + ctx.advance_to(it); + return underlying_.parse(ctx); } - template - typename FormatContext::iterator format(const T& values, FormatContext& ctx) { - auto out = detail::copy(formatting.prefix, ctx.out()); - size_t i = 0; - auto view = detail::range_to_view::view(values); - auto it = view.begin(); - auto end = view.end(); + template + auto format(R&& range, FormatContext& ctx) const -> decltype(ctx.out()) { + detail::range_mapper> mapper; + auto out = ctx.out(); + out = detail::copy_str(opening_bracket_, out); + int i = 0; + auto it = detail::range_begin(range); + auto end = detail::range_end(range); for (; it != end; ++it) { - if (i > 0) out = detail::write_delimiter(out); - out = detail::write_range_entry(out, *it); + if (i > 0) out = detail::copy_str(separator_, out); + ; + ctx.advance_to(out); + out = underlying_.format(mapper.map(*it), ctx); ++i; } - return detail::copy(formatting.postfix, out); + out = detail::copy_str(closing_bracket_, out); + return out; } }; +enum class range_format { disabled, map, set, sequence, string, debug_string }; + +namespace detail { +template struct range_format_kind_ { + static constexpr auto value = std::is_same, T>::value + ? range_format::disabled + : is_map::value ? range_format::map + : is_set::value ? range_format::set + : range_format::sequence; +}; + +template +struct range_default_formatter; + +template +using range_format_constant = std::integral_constant; + +template +struct range_default_formatter< + K, R, Char, + enable_if_t<(K == range_format::sequence || K == range_format::map || + K == range_format::set)>> { + using range_type = detail::maybe_const_range; + range_formatter, Char> underlying_; + + FMT_CONSTEXPR range_default_formatter() { init(range_format_constant()); } + + FMT_CONSTEXPR void init(range_format_constant) { + underlying_.set_brackets(detail::string_literal{}, + detail::string_literal{}); + } + + FMT_CONSTEXPR void init(range_format_constant) { + underlying_.set_brackets(detail::string_literal{}, + detail::string_literal{}); + underlying_.underlying().set_brackets({}, {}); + underlying_.underlying().set_separator( + detail::string_literal{}); + } + + FMT_CONSTEXPR void init(range_format_constant) {} + + template + FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + return underlying_.parse(ctx); + } + + template + auto format(range_type& range, FormatContext& ctx) const + -> decltype(ctx.out()) { + return underlying_.format(range, ctx); + } +}; +} // namespace detail + +template +struct range_format_kind + : conditional_t< + is_range::value, detail::range_format_kind_, + std::integral_constant> {}; + +template +struct formatter< + R, Char, + enable_if_t::value != + range_format::disabled> +// Workaround a bug in MSVC 2015 and earlier. +#if !FMT_MSC_VERSION || FMT_MSC_VERSION >= 1910 + , + detail::is_formattable_delayed +#endif + >::value>> + : detail::range_default_formatter::value, R, + Char> { +}; + template struct tuple_join_view : detail::view { const std::tuple& tuple; basic_string_view sep; @@ -374,46 +604,70 @@ template struct tuple_join_view : detail::view { template using tuple_arg_join = tuple_join_view; +// Define FMT_TUPLE_JOIN_SPECIFIERS to enable experimental format specifiers +// support in tuple_join. It is disabled by default because of issues with +// the dynamic width and precision. +#ifndef FMT_TUPLE_JOIN_SPECIFIERS +# define FMT_TUPLE_JOIN_SPECIFIERS 0 +#endif + template struct formatter, Char> { template FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { - return ctx.begin(); + return do_parse(ctx, std::integral_constant()); } template - auto format(const tuple_join_view& value, FormatContext& ctx) -> - typename FormatContext::iterator { - return format(value, ctx, detail::make_index_sequence{}); + auto format(const tuple_join_view& value, + FormatContext& ctx) const -> typename FormatContext::iterator { + return do_format(value, ctx, + std::integral_constant()); } private: - template - auto format(const tuple_join_view& value, FormatContext& ctx, - detail::index_sequence) -> - typename FormatContext::iterator { - using std::get; - return format_args(value, ctx, get(value.tuple)...); + std::tuple::type, Char>...> formatters_; + + template + FMT_CONSTEXPR auto do_parse(ParseContext& ctx, + std::integral_constant) + -> decltype(ctx.begin()) { + return ctx.begin(); + } + + template + FMT_CONSTEXPR auto do_parse(ParseContext& ctx, + std::integral_constant) + -> decltype(ctx.begin()) { + auto end = ctx.begin(); +#if FMT_TUPLE_JOIN_SPECIFIERS + end = std::get(formatters_).parse(ctx); + if (N > 1) { + auto end1 = do_parse(ctx, std::integral_constant()); + if (end != end1) + FMT_THROW(format_error("incompatible format specs for tuple elements")); + } +#endif + return end; } template - auto format_args(const tuple_join_view&, FormatContext& ctx) -> + auto do_format(const tuple_join_view&, FormatContext& ctx, + std::integral_constant) const -> typename FormatContext::iterator { - // NOTE: for compilers that support C++17, this empty function instantiation - // can be replaced with a constexpr branch in the variadic overload. return ctx.out(); } - template - auto format_args(const tuple_join_view& value, FormatContext& ctx, - const Arg& arg, const Args&... args) -> + template + auto do_format(const tuple_join_view& value, FormatContext& ctx, + std::integral_constant) const -> typename FormatContext::iterator { - using base = formatter::type, Char>; - auto out = base().format(arg, ctx); - if (sizeof...(Args) > 0) { + auto out = std::get(formatters_) + .format(std::get(value.tuple), ctx); + if (N > 1) { out = std::copy(value.sep.begin(), value.sep.end(), out); ctx.advance_to(out); - return format_args(value, ctx, args...); + return do_format(value, ctx, std::integral_constant()); } return out; } diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bundled/std.h b/Lumos/External/spdlog/include/spdlog/fmt/bundled/std.h new file mode 100644 index 000000000..41d2b2838 --- /dev/null +++ b/Lumos/External/spdlog/include/spdlog/fmt/bundled/std.h @@ -0,0 +1,171 @@ +// Formatting library for C++ - formatters for standard library types +// +// Copyright (c) 2012 - present, Victor Zverovich +// All rights reserved. +// +// For the license information refer to format.h. + +#ifndef FMT_STD_H_ +#define FMT_STD_H_ + +#include +#include +#include + +#include "ostream.h" + +#if FMT_HAS_INCLUDE() +# include +#endif +// Checking FMT_CPLUSPLUS for warning suppression in MSVC. +#if FMT_CPLUSPLUS >= 201703L +# if FMT_HAS_INCLUDE() +# include +# endif +# if FMT_HAS_INCLUDE() +# include +# endif +#endif + +#ifdef __cpp_lib_filesystem +FMT_BEGIN_NAMESPACE + +namespace detail { + +template +void write_escaped_path(basic_memory_buffer& quoted, + const std::filesystem::path& p) { + write_escaped_string(std::back_inserter(quoted), p.string()); +} +# ifdef _WIN32 +template <> +inline void write_escaped_path(basic_memory_buffer& quoted, + const std::filesystem::path& p) { + auto s = p.u8string(); + write_escaped_string( + std::back_inserter(quoted), + string_view(reinterpret_cast(s.c_str()), s.size())); +} +# endif +template <> +inline void write_escaped_path( + basic_memory_buffer& quoted, + const std::filesystem::path& p) { + write_escaped_string( + std::back_inserter(quoted), p.native()); +} + +} // namespace detail + +template +struct formatter + : formatter> { + template + auto format(const std::filesystem::path& p, FormatContext& ctx) const -> + typename FormatContext::iterator { + basic_memory_buffer quoted; + detail::write_escaped_path(quoted, p); + return formatter>::format( + basic_string_view(quoted.data(), quoted.size()), ctx); + } +}; +FMT_END_NAMESPACE +#endif + +FMT_BEGIN_NAMESPACE +template +struct formatter : basic_ostream_formatter {}; +FMT_END_NAMESPACE + +#ifdef __cpp_lib_variant +FMT_BEGIN_NAMESPACE +template struct formatter { + template + FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + template + auto format(const std::monostate&, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto out = ctx.out(); + out = detail::write(out, "monostate"); + return out; + } +}; + +namespace detail { + +template +using variant_index_sequence = + std::make_index_sequence::value>; + +// variant_size and variant_alternative check. +template +struct is_variant_like_ : std::false_type {}; +template +struct is_variant_like_::value)>> + : std::true_type {}; + +// formattable element check +template class is_variant_formattable_ { + template + static std::conjunction< + is_formattable, C>...> + check(std::index_sequence); + + public: + static constexpr const bool value = + decltype(check(variant_index_sequence{}))::value; +}; + +template +auto write_variant_alternative(OutputIt out, const T& v) -> OutputIt { + if constexpr (is_string::value) + return write_escaped_string(out, detail::to_string_view(v)); + else if constexpr (std::is_same_v) + return write_escaped_char(out, v); + else + return write(out, v); +} + +} // namespace detail + +template struct is_variant_like { + static constexpr const bool value = detail::is_variant_like_::value; +}; + +template struct is_variant_formattable { + static constexpr const bool value = + detail::is_variant_formattable_::value; +}; + +template +struct formatter< + Variant, Char, + std::enable_if_t, is_variant_formattable>>> { + template + FMT_CONSTEXPR auto parse(ParseContext& ctx) -> decltype(ctx.begin()) { + return ctx.begin(); + } + + template + auto format(const Variant& value, FormatContext& ctx) const + -> decltype(ctx.out()) { + auto out = ctx.out(); + + out = detail::write(out, "variant("); + std::visit( + [&](const auto& v) { + out = detail::write_variant_alternative(out, v); + }, + value); + *out++ = ')'; + return out; + } +}; +FMT_END_NAMESPACE +#endif + +#endif // FMT_STD_H_ diff --git a/Lumos/External/spdlog/include/spdlog/fmt/bundled/xchar.h b/Lumos/External/spdlog/include/spdlog/fmt/bundled/xchar.h index a0dd032f1..3b5bc15ca 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/bundled/xchar.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/bundled/xchar.h @@ -5,11 +5,10 @@ // // For the license information refer to format.h. -#ifndef FMT_WCHAR_H_ -#define FMT_WCHAR_H_ +#ifndef FMT_XCHAR_H_ +#define FMT_XCHAR_H_ #include -#include #include "format.h" @@ -30,9 +29,11 @@ using wmemory_buffer = basic_memory_buffer; #if FMT_GCC_VERSION && FMT_GCC_VERSION < 409 // Workaround broken conversion on older gcc. template using wformat_string = wstring_view; +inline auto runtime(wstring_view s) -> wstring_view { return s; } #else template using wformat_string = basic_format_string...>; +inline auto runtime(wstring_view s) -> basic_runtime { return {{s}}; } #endif template <> struct is_char : std::true_type {}; @@ -47,12 +48,7 @@ constexpr format_arg_store make_wformat_args( } inline namespace literals { -constexpr auto operator"" _format(const wchar_t* s, size_t n) - -> detail::udl_formatter { - return {{s, n}}; -} - -#if FMT_USE_USER_DEFINED_LITERALS && !FMT_USE_NONTYPE_TEMPLATE_PARAMETERS +#if FMT_USE_USER_DEFINED_LITERALS && !FMT_USE_NONTYPE_TEMPLATE_ARGS constexpr detail::udl_arg operator"" _a(const wchar_t* s, size_t) { return {s}; } @@ -87,13 +83,19 @@ auto vformat(basic_string_view format_str, return to_string(buffer); } +template +auto format(wformat_string fmt, T&&... args) -> std::wstring { + return vformat(fmt::wstring_view(fmt), fmt::make_wformat_args(args...)); +} + // Pass char_t as a default template parameter instead of using // std::basic_string> to reduce the symbol size. template , - FMT_ENABLE_IF(!std::is_same::value)> + FMT_ENABLE_IF(!std::is_same::value && + !std::is_same::value)> auto format(const S& format_str, Args&&... args) -> std::basic_string { - const auto& vargs = fmt::make_args_checked(format_str, args...); - return vformat(to_string_view(format_str), vargs); + return vformat(detail::to_string_view(format_str), + fmt::make_format_args>(args...)); } template , @@ -103,7 +105,7 @@ inline auto vformat( const Locale& loc, const S& format_str, basic_format_args>> args) -> std::basic_string { - return detail::vformat(loc, to_string_view(format_str), args); + return detail::vformat(loc, detail::to_string_view(format_str), args); } template ::value)> inline auto format(const Locale& loc, const S& format_str, Args&&... args) -> std::basic_string { - return detail::vformat(loc, to_string_view(format_str), - fmt::make_args_checked(format_str, args...)); + return detail::vformat(loc, detail::to_string_view(format_str), + fmt::make_format_args>(args...)); } template , @@ -123,7 +125,7 @@ auto vformat_to(OutputIt out, const S& format_str, basic_format_args>> args) -> OutputIt { auto&& buf = detail::get_buffer(out); - detail::vformat_to(buf, to_string_view(format_str), args); + detail::vformat_to(buf, detail::to_string_view(format_str), args); return detail::get_iterator(buf); } @@ -132,18 +134,8 @@ template ::value&& detail::is_exotic_char::value)> inline auto format_to(OutputIt out, const S& fmt, Args&&... args) -> OutputIt { - const auto& vargs = fmt::make_args_checked(fmt, args...); - return vformat_to(out, to_string_view(fmt), vargs); -} - -template ::value)> -FMT_DEPRECATED auto format_to(basic_memory_buffer& buf, - const S& format_str, Args&&... args) -> - typename buffer_context::iterator { - const auto& vargs = fmt::make_args_checked(format_str, args...); - detail::vformat_to(buf, to_string_view(format_str), vargs, {}); - return detail::buffer_appender(buf); + return vformat_to(out, detail::to_string_view(fmt), + fmt::make_format_args>(args...)); } template >> args) -> OutputIt { auto&& buf = detail::get_buffer(out); - vformat_to(buf, to_string_view(format_str), args, detail::locale_ref(loc)); + vformat_to(buf, detail::to_string_view(format_str), args, + detail::locale_ref(loc)); return detail::get_iterator(buf); } @@ -167,8 +160,8 @@ template < inline auto format_to(OutputIt out, const Locale& loc, const S& format_str, Args&&... args) -> typename std::enable_if::type { - const auto& vargs = fmt::make_args_checked(format_str, args...); - return vformat_to(out, loc, to_string_view(format_str), vargs); + return vformat_to(out, loc, to_string_view(format_str), + fmt::make_format_args>(args...)); } template ::value)> inline auto format_to_n(OutputIt out, size_t n, const S& fmt, const Args&... args) -> format_to_n_result { - const auto& vargs = fmt::make_args_checked(fmt, args...); - return vformat_to_n(out, n, to_string_view(fmt), vargs); + return vformat_to_n(out, n, detail::to_string_view(fmt), + fmt::make_format_args>(args...)); } template , FMT_ENABLE_IF(detail::is_exotic_char::value)> inline auto formatted_size(const S& fmt, Args&&... args) -> size_t { detail::counting_buffer buf; - const auto& vargs = fmt::make_args_checked(fmt, args...); - detail::vformat_to(buf, to_string_view(fmt), vargs); + detail::vformat_to(buf, detail::to_string_view(fmt), + fmt::make_format_args>(args...)); return buf.count(); } @@ -217,11 +210,11 @@ inline void vprint(wstring_view fmt, wformat_args args) { template void print(std::FILE* f, wformat_string fmt, T&&... args) { - return vprint(f, wstring_view(fmt), make_wformat_args(args...)); + return vprint(f, wstring_view(fmt), fmt::make_wformat_args(args...)); } template void print(wformat_string fmt, T&&... args) { - return vprint(wstring_view(fmt), make_wformat_args(args...)); + return vprint(wstring_view(fmt), fmt::make_wformat_args(args...)); } /** @@ -233,4 +226,4 @@ template inline auto to_wstring(const T& value) -> std::wstring { FMT_MODULE_EXPORT_END FMT_END_NAMESPACE -#endif // FMT_WCHAR_H_ +#endif // FMT_XCHAR_H_ diff --git a/Lumos/External/spdlog/include/spdlog/fmt/chrono.h b/Lumos/External/spdlog/include/spdlog/fmt/chrono.h index a0544bcaa..83fad2ff9 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/chrono.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/chrono.h @@ -8,13 +8,15 @@ // include bundled or external copy of fmtlib's chrono support // -#if !defined(SPDLOG_FMT_EXTERNAL) -# ifdef SPDLOG_HEADER_ONLY -# ifndef FMT_HEADER_ONLY -# define FMT_HEADER_ONLY +#if !defined(SPDLOG_USE_STD_FORMAT) +# if !defined(SPDLOG_FMT_EXTERNAL) +# ifdef SPDLOG_HEADER_ONLY +# ifndef FMT_HEADER_ONLY +# define FMT_HEADER_ONLY +# endif # endif +# include +# else +# include # endif -# include -#else -# include #endif diff --git a/Lumos/External/spdlog/include/spdlog/fmt/compile.h b/Lumos/External/spdlog/include/spdlog/fmt/compile.h index 6f3459350..906e9f57a 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/compile.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/compile.h @@ -5,16 +5,18 @@ #pragma once // -// include bundled or external copy of fmtlib's ostream support +// include bundled or external copy of fmtlib's compile-time support // -#if !defined(SPDLOG_FMT_EXTERNAL) -# ifdef SPDLOG_HEADER_ONLY -# ifndef FMT_HEADER_ONLY -# define FMT_HEADER_ONLY +#if !defined(SPDLOG_USE_STD_FORMAT) +# if !defined(SPDLOG_FMT_EXTERNAL) +# ifdef SPDLOG_HEADER_ONLY +# ifndef FMT_HEADER_ONLY +# define FMT_HEADER_ONLY +# endif # endif +# include +# else +# include # endif -# include -#else -# include #endif diff --git a/Lumos/External/spdlog/include/spdlog/fmt/fmt.h b/Lumos/External/spdlog/include/spdlog/fmt/fmt.h index 7aaeed814..90fcae0f0 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/fmt.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/fmt.h @@ -10,7 +10,9 @@ // By default spdlog include its own copy. // -#if !defined(SPDLOG_FMT_EXTERNAL) +#if defined(SPDLOG_USE_STD_FORMAT) // SPDLOG_USE_STD_FORMAT is defined - use std::format +# include +#elif !defined(SPDLOG_FMT_EXTERNAL) # if !defined(SPDLOG_COMPILED_LIB) && !defined(FMT_HEADER_ONLY) # define FMT_HEADER_ONLY # endif @@ -19,8 +21,12 @@ # endif // enable the 'n' flag in for backward compatibility with fmt 6.x # define FMT_DEPRECATED_N_SPECIFIER +// enable ostream formatting for backward compatibility with fmt 8.x +# define FMT_DEPRECATED_OSTREAM + # include # include + #else // SPDLOG_FMT_EXTERNAL is defined - use external fmtlib # include # include diff --git a/Lumos/External/spdlog/include/spdlog/fmt/ostr.h b/Lumos/External/spdlog/include/spdlog/fmt/ostr.h index 9d8efe38c..758803417 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/ostr.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/ostr.h @@ -8,13 +8,15 @@ // include bundled or external copy of fmtlib's ostream support // -#if !defined(SPDLOG_FMT_EXTERNAL) -# ifdef SPDLOG_HEADER_ONLY -# ifndef FMT_HEADER_ONLY -# define FMT_HEADER_ONLY +#if !defined(SPDLOG_USE_STD_FORMAT) +# if !defined(SPDLOG_FMT_EXTERNAL) +# ifdef SPDLOG_HEADER_ONLY +# ifndef FMT_HEADER_ONLY +# define FMT_HEADER_ONLY +# endif # endif +# include +# else +# include # endif -# include -#else -# include #endif diff --git a/Lumos/External/spdlog/include/spdlog/fmt/ranges.h b/Lumos/External/spdlog/include/spdlog/fmt/ranges.h new file mode 100644 index 000000000..9103a5f6a --- /dev/null +++ b/Lumos/External/spdlog/include/spdlog/fmt/ranges.h @@ -0,0 +1,22 @@ +// +// Copyright(c) 2016 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +#pragma once +// +// include bundled or external copy of fmtlib's ranges support +// + +#if !defined(SPDLOG_USE_STD_FORMAT) +# if !defined(SPDLOG_FMT_EXTERNAL) +# ifdef SPDLOG_HEADER_ONLY +# ifndef FMT_HEADER_ONLY +# define FMT_HEADER_ONLY +# endif +# endif +# include +# else +# include +# endif +#endif diff --git a/Lumos/External/spdlog/include/spdlog/fmt/std.h b/Lumos/External/spdlog/include/spdlog/fmt/std.h new file mode 100644 index 000000000..0490cab0b --- /dev/null +++ b/Lumos/External/spdlog/include/spdlog/fmt/std.h @@ -0,0 +1,23 @@ +// +// Copyright(c) 2016 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +#pragma once +// +// include bundled or external copy of fmtlib's std support (for formatting e.g. std::filesystem::path, std::thread::id, std::monostate, +// std::variant, ...) +// + +#if !defined(SPDLOG_USE_STD_FORMAT) +# if !defined(SPDLOG_FMT_EXTERNAL) +# ifdef SPDLOG_HEADER_ONLY +# ifndef FMT_HEADER_ONLY +# define FMT_HEADER_ONLY +# endif +# endif +# include +# else +# include +# endif +#endif diff --git a/Lumos/External/spdlog/include/spdlog/fmt/xchar.h b/Lumos/External/spdlog/include/spdlog/fmt/xchar.h index 616d8f5ba..9a766e5a0 100644 --- a/Lumos/External/spdlog/include/spdlog/fmt/xchar.h +++ b/Lumos/External/spdlog/include/spdlog/fmt/xchar.h @@ -5,16 +5,18 @@ #pragma once // -// include bundled or external copy of fmtlib's ostream support +// include bundled or external copy of fmtlib's xchar support // -#if !defined(SPDLOG_FMT_EXTERNAL) -# ifdef SPDLOG_HEADER_ONLY -# ifndef FMT_HEADER_ONLY -# define FMT_HEADER_ONLY +#if !defined(SPDLOG_USE_STD_FORMAT) +# if !defined(SPDLOG_FMT_EXTERNAL) +# ifdef SPDLOG_HEADER_ONLY +# ifndef FMT_HEADER_ONLY +# define FMT_HEADER_ONLY +# endif # endif +# include +# else +# include # endif -# include -#else -# include #endif diff --git a/Lumos/External/spdlog/include/spdlog/fwd.h b/Lumos/External/spdlog/include/spdlog/fwd.h index cc05ddd41..d25882572 100644 --- a/Lumos/External/spdlog/include/spdlog/fwd.h +++ b/Lumos/External/spdlog/include/spdlog/fwd.h @@ -11,4 +11,8 @@ namespace sinks { class sink; } +namespace level { +enum level_enum : int; +} + } // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/logger-inl.h b/Lumos/External/spdlog/include/spdlog/logger-inl.h index fd841657d..227cec439 100644 --- a/Lumos/External/spdlog/include/spdlog/logger-inl.h +++ b/Lumos/External/spdlog/include/spdlog/logger-inl.h @@ -185,7 +185,7 @@ SPDLOG_INLINE void logger::sink_it_(const details::log_msg &msg) { sink->log(msg); } - SPDLOG_LOGGER_CATCH() + SPDLOG_LOGGER_CATCH(msg.source) } } @@ -203,14 +203,14 @@ SPDLOG_INLINE void logger::flush_() { sink->flush(); } - SPDLOG_LOGGER_CATCH() + SPDLOG_LOGGER_CATCH(source_loc()) } } SPDLOG_INLINE void logger::dump_backtrace_() { using details::log_msg; - if (tracer_.enabled()) + if (tracer_.enabled() && !tracer_.empty()) { sink_it_(log_msg{name(), level::info, "****************** Backtrace Start ******************"}); tracer_.foreach_pop([this](const log_msg &msg) { this->sink_it_(msg); }); @@ -248,9 +248,9 @@ SPDLOG_INLINE void logger::err_handler_(const std::string &msg) char date_buf[64]; std::strftime(date_buf, sizeof(date_buf), "%Y-%m-%d %H:%M:%S", &tm_time); #if defined(USING_R) && defined(R_R_H) // if in R environment - REprintf("[*** LOG ERROR #%04zu ***] [%s] [%s] {%s}\n", err_counter, date_buf, name().c_str(), msg.c_str()); + REprintf("[*** LOG ERROR #%04zu ***] [%s] [%s] %s\n", err_counter, date_buf, name().c_str(), msg.c_str()); #else - std::fprintf(stderr, "[*** LOG ERROR #%04zu ***] [%s] [%s] {%s}\n", err_counter, date_buf, name().c_str(), msg.c_str()); + std::fprintf(stderr, "[*** LOG ERROR #%04zu ***] [%s] [%s] %s\n", err_counter, date_buf, name().c_str(), msg.c_str()); #endif } } diff --git a/Lumos/External/spdlog/include/spdlog/logger.h b/Lumos/External/spdlog/include/spdlog/logger.h index a69148b4d..1810cb2ac 100644 --- a/Lumos/External/spdlog/include/spdlog/logger.h +++ b/Lumos/External/spdlog/include/spdlog/logger.h @@ -28,10 +28,17 @@ #include #ifndef SPDLOG_NO_EXCEPTIONS -# define SPDLOG_LOGGER_CATCH() \ +# define SPDLOG_LOGGER_CATCH(location) \ catch (const std::exception &ex) \ { \ - err_handler_(ex.what()); \ + if (location.filename) \ + { \ + err_handler_(fmt_lib::format(SPDLOG_FMT_STRING("{} [{}({})]"), ex.what(), location.filename, location.line)); \ + } \ + else \ + { \ + err_handler_(ex.what()); \ + } \ } \ catch (...) \ { \ @@ -39,7 +46,7 @@ throw; \ } #else -# define SPDLOG_LOGGER_CATCH() +# define SPDLOG_LOGGER_CATCH(location) #endif namespace spdlog { @@ -77,14 +84,14 @@ class SPDLOG_API logger logger &operator=(logger other) SPDLOG_NOEXCEPT; void swap(spdlog::logger &other) SPDLOG_NOEXCEPT; - template - void log(source_loc loc, level::level_enum lvl, const FormatString &fmt, Args &&...args) + template + void log(source_loc loc, level::level_enum lvl, format_string_t fmt, Args &&...args) { - log_(loc, lvl, fmt, std::forward(args)...); + log_(loc, lvl, details::to_string_view(fmt), std::forward(args)...); } - template - void log(level::level_enum lvl, const FormatString &fmt, Args &&...args) + template + void log(level::level_enum lvl, format_string_t fmt, Args &&...args) { log(source_loc{}, lvl, fmt, std::forward(args)...); } @@ -95,11 +102,11 @@ class SPDLOG_API logger log(source_loc{}, lvl, msg); } - // T can be statically converted to string_view - template::value, int>::type = 0> + // T cannot be statically converted to format string (including string_view/wstring_view) + template::value, int>::type = 0> void log(source_loc loc, level::level_enum lvl, const T &msg) { - log(loc, lvl, string_view_t{msg}); + log(loc, lvl, "{}", msg); } void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, string_view_t msg) @@ -133,50 +140,126 @@ class SPDLOG_API logger log(source_loc{}, lvl, msg); } - // T cannot be statically converted to string_view or wstring_view - template::value && - !is_convertible_to_wstring_view::value, - int>::type = 0> - void log(source_loc loc, level::level_enum lvl, const T &msg) + template + void trace(format_string_t fmt, Args &&...args) { - log(loc, lvl, "{}", msg); + log(level::trace, fmt, std::forward(args)...); } - template - void trace(const FormatString &fmt, Args &&...args) + template + void debug(format_string_t fmt, Args &&...args) + { + log(level::debug, fmt, std::forward(args)...); + } + + template + void info(format_string_t fmt, Args &&...args) + { + log(level::info, fmt, std::forward(args)...); + } + + template + void warn(format_string_t fmt, Args &&...args) + { + log(level::warn, fmt, std::forward(args)...); + } + + template + void error(format_string_t fmt, Args &&...args) + { + log(level::err, fmt, std::forward(args)...); + } + + template + void critical(format_string_t fmt, Args &&...args) + { + log(level::critical, fmt, std::forward(args)...); + } + +#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT + template + void log(source_loc loc, level::level_enum lvl, wformat_string_t fmt, Args &&...args) + { + log_(loc, lvl, details::to_string_view(fmt), std::forward(args)...); + } + + template + void log(level::level_enum lvl, wformat_string_t fmt, Args &&...args) + { + log(source_loc{}, lvl, fmt, std::forward(args)...); + } + + void log(log_clock::time_point log_time, source_loc loc, level::level_enum lvl, wstring_view_t msg) + { + bool log_enabled = should_log(lvl); + bool traceback_enabled = tracer_.enabled(); + if (!log_enabled && !traceback_enabled) + { + return; + } + + memory_buf_t buf; + details::os::wstr_to_utf8buf(wstring_view_t(msg.data(), msg.size()), buf); + details::log_msg log_msg(log_time, loc, name_, lvl, string_view_t(buf.data(), buf.size())); + log_it_(log_msg, log_enabled, traceback_enabled); + } + + void log(source_loc loc, level::level_enum lvl, wstring_view_t msg) + { + bool log_enabled = should_log(lvl); + bool traceback_enabled = tracer_.enabled(); + if (!log_enabled && !traceback_enabled) + { + return; + } + + memory_buf_t buf; + details::os::wstr_to_utf8buf(wstring_view_t(msg.data(), msg.size()), buf); + details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size())); + log_it_(log_msg, log_enabled, traceback_enabled); + } + + void log(level::level_enum lvl, wstring_view_t msg) + { + log(source_loc{}, lvl, msg); + } + + template + void trace(wformat_string_t fmt, Args &&...args) { log(level::trace, fmt, std::forward(args)...); } - template - void debug(const FormatString &fmt, Args &&...args) + template + void debug(wformat_string_t fmt, Args &&...args) { log(level::debug, fmt, std::forward(args)...); } - template - void info(const FormatString &fmt, Args &&...args) + template + void info(wformat_string_t fmt, Args &&...args) { log(level::info, fmt, std::forward(args)...); } - template - void warn(const FormatString &fmt, Args &&...args) + template + void warn(wformat_string_t fmt, Args &&...args) { log(level::warn, fmt, std::forward(args)...); } - template - void error(const FormatString &fmt, Args &&...args) + template + void error(wformat_string_t fmt, Args &&...args) { log(level::err, fmt, std::forward(args)...); } - template - void critical(const FormatString &fmt, Args &&...args) + template + void critical(wformat_string_t fmt, Args &&...args) { log(level::critical, fmt, std::forward(args)...); } +#endif template void trace(const T &msg) @@ -236,6 +319,10 @@ class SPDLOG_API logger // each sink will get a separate instance of the formatter object. void set_formatter(std::unique_ptr f); + // set formatting for the sinks in this logger. + // equivalent to + // set_formatter(make_unique(pattern, time_type)) + // Note: each sink will get a new instance of a formatter object, replacing the old one. void set_pattern(std::string pattern, pattern_time_type time_type = pattern_time_type::local); // backtrace support. @@ -269,9 +356,8 @@ class SPDLOG_API logger details::backtracer tracer_; // common implementation for after templated public api has been resolved - template, - typename std::enable_if::value, Char>::type * = nullptr> - void log_(source_loc loc, level::level_enum lvl, const FormatString &fmt, Args &&...args) + template + void log_(source_loc loc, level::level_enum lvl, string_view_t fmt, Args &&...args) { bool log_enabled = should_log(lvl); bool traceback_enabled = tracer_.enabled(); @@ -282,16 +368,21 @@ class SPDLOG_API logger SPDLOG_TRY { memory_buf_t buf; - fmt::detail::vformat_to(buf, fmt::to_string_view(fmt), fmt::make_format_args(args...)); +#ifdef SPDLOG_USE_STD_FORMAT + fmt_lib::vformat_to(std::back_inserter(buf), fmt, fmt_lib::make_format_args(args...)); +#else + fmt::vformat_to(fmt::appender(buf), fmt, fmt::make_format_args(args...)); +#endif + details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size())); log_it_(log_msg, log_enabled, traceback_enabled); } - SPDLOG_LOGGER_CATCH() + SPDLOG_LOGGER_CATCH(loc) } #ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT template - void log_(source_loc loc, level::level_enum lvl, const wstring_view_t &fmt, Args &&...args) + void log_(source_loc loc, level::level_enum lvl, wstring_view_t fmt, Args &&...args) { bool log_enabled = should_log(lvl); bool traceback_enabled = tracer_.enabled(); @@ -302,36 +393,16 @@ class SPDLOG_API logger SPDLOG_TRY { // format to wmemory_buffer and convert to utf8 - fmt::wmemory_buffer wbuf; - fmt::format_to(std::back_inserter(wbuf), fmt, std::forward(args)...); - memory_buf_t buf; - details::os::wstr_to_utf8buf(wstring_view_t(wbuf.data(), wbuf.size()), buf); - details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size())); - log_it_(log_msg, log_enabled, traceback_enabled); - } - SPDLOG_LOGGER_CATCH() - } + wmemory_buf_t wbuf; + fmt_lib::vformat_to(std::back_inserter(wbuf), fmt, fmt_lib::make_format_args(args...)); - // T can be statically converted to wstring_view, and no formatting needed. - template::value, int>::type = 0> - void log_(source_loc loc, level::level_enum lvl, const T &msg) - { - bool log_enabled = should_log(lvl); - bool traceback_enabled = tracer_.enabled(); - if (!log_enabled && !traceback_enabled) - { - return; - } - SPDLOG_TRY - { memory_buf_t buf; - details::os::wstr_to_utf8buf(msg, buf); + details::os::wstr_to_utf8buf(wstring_view_t(wbuf.data(), wbuf.size()), buf); details::log_msg log_msg(loc, name_, lvl, string_view_t(buf.data(), buf.size())); log_it_(log_msg, log_enabled, traceback_enabled); } - SPDLOG_LOGGER_CATCH() + SPDLOG_LOGGER_CATCH(loc) } - #endif // SPDLOG_WCHAR_TO_UTF8_SUPPORT // log the given message (if the given log level is high enough), diff --git a/Lumos/External/spdlog/include/spdlog/pattern_formatter-inl.h b/Lumos/External/spdlog/include/spdlog/pattern_formatter-inl.h index ec727032b..01afbe6f0 100644 --- a/Lumos/External/spdlog/include/spdlog/pattern_formatter-inl.h +++ b/Lumos/External/spdlog/include/spdlog/pattern_formatter-inl.h @@ -766,6 +766,7 @@ class source_location_formatter final : public flag_formatter { if (msg.source.empty()) { + ScopedPadder p(0, padinfo_, dest); return; } @@ -800,6 +801,7 @@ class source_filename_formatter final : public flag_formatter { if (msg.source.empty()) { + ScopedPadder p(0, padinfo_, dest); return; } size_t text_size = padinfo_.enabled() ? std::char_traits::length(msg.source.filename) : 0; @@ -846,6 +848,7 @@ class short_filename_formatter final : public flag_formatter { if (msg.source.empty()) { + ScopedPadder p(0, padinfo_, dest); return; } auto filename = basename(msg.source.filename); @@ -867,6 +870,7 @@ class source_linenum_formatter final : public flag_formatter { if (msg.source.empty()) { + ScopedPadder p(0, padinfo_, dest); return; } @@ -889,6 +893,7 @@ class source_funcname_formatter final : public flag_formatter { if (msg.source.empty()) { + ScopedPadder p(0, padinfo_, dest); return; } size_t text_size = padinfo_.enabled() ? std::char_traits::length(msg.source.funcname) : 0; @@ -1019,6 +1024,7 @@ SPDLOG_INLINE pattern_formatter::pattern_formatter( : pattern_(std::move(pattern)) , eol_(std::move(eol)) , pattern_time_type_(time_type) + , need_localtime_(false) , last_log_secs_(0) , custom_handlers_(std::move(custom_user_flags)) { @@ -1031,6 +1037,7 @@ SPDLOG_INLINE pattern_formatter::pattern_formatter(pattern_time_type time_type, : pattern_("%+") , eol_(std::move(eol)) , pattern_time_type_(time_type) + , need_localtime_(true) , last_log_secs_(0) { std::memset(&cached_tm_, 0, sizeof(cached_tm_)); @@ -1044,16 +1051,25 @@ SPDLOG_INLINE std::unique_ptr pattern_formatter::clone() const { cloned_custom_formatters[it.first] = it.second->clone(); } - return details::make_unique(pattern_, pattern_time_type_, eol_, std::move(cloned_custom_formatters)); + auto cloned = details::make_unique(pattern_, pattern_time_type_, eol_, std::move(cloned_custom_formatters)); + cloned->need_localtime(need_localtime_); +#if defined(__GNUC__) && __GNUC__ < 5 + return std::move(cloned); +#else + return cloned; +#endif } SPDLOG_INLINE void pattern_formatter::format(const details::log_msg &msg, memory_buf_t &dest) { - auto secs = std::chrono::duration_cast(msg.time.time_since_epoch()); - if (secs != last_log_secs_) + if (need_localtime_) { - cached_tm_ = get_time_(msg); - last_log_secs_ = secs; + const auto secs = std::chrono::duration_cast(msg.time.time_since_epoch()); + if (secs != last_log_secs_) + { + cached_tm_ = get_time_(msg); + last_log_secs_ = secs; + } } for (auto &f : formatters_) @@ -1067,9 +1083,15 @@ SPDLOG_INLINE void pattern_formatter::format(const details::log_msg &msg, memory SPDLOG_INLINE void pattern_formatter::set_pattern(std::string pattern) { pattern_ = std::move(pattern); + need_localtime_ = false; compile_pattern_(pattern_); } +SPDLOG_INLINE void pattern_formatter::need_localtime(bool need) +{ + need_localtime_ = need; +} + SPDLOG_INLINE std::tm pattern_formatter::get_time_(const details::log_msg &msg) { if (pattern_time_type_ == pattern_time_type::local) @@ -1097,6 +1119,7 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i { case ('+'): // default formatter formatters_.push_back(details::make_unique(padding)); + need_localtime_ = true; break; case 'n': // logger name @@ -1121,60 +1144,74 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i case ('a'): // weekday formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('A'): // short weekday formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('b'): case ('h'): // month formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('B'): // short month formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('c'): // datetime formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('C'): // year 2 digits formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('Y'): // year 4 digits formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('D'): case ('x'): // datetime MM/DD/YY formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('m'): // month 1-12 formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('d'): // day of month 1-31 formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('H'): // hours 24 formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('I'): // hours 12 formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('M'): // minutes formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('S'): // seconds formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('e'): // milliseconds @@ -1195,23 +1232,28 @@ SPDLOG_INLINE void pattern_formatter::handle_flag_(char flag, details::padding_i case ('p'): // am/pm formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('r'): // 12 hour clock 02:55:02 pm formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('R'): // 24-hour HH:MM time formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('T'): case ('X'): // ISO 8601 time format (HH:MM:SS) formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('z'): // timezone formatters_.push_back(details::make_unique>(padding)); + need_localtime_ = true; break; case ('P'): // pid @@ -1342,7 +1384,6 @@ SPDLOG_INLINE details::padding_info pattern_formatter::handle_padspec_(std::stri { truncate = false; } - return details::padding_info{std::min(width, max_width), side, truncate}; } diff --git a/Lumos/External/spdlog/include/spdlog/pattern_formatter.h b/Lumos/External/spdlog/include/spdlog/pattern_formatter.h index e9ccfaa75..4c87b21ef 100644 --- a/Lumos/External/spdlog/include/spdlog/pattern_formatter.h +++ b/Lumos/External/spdlog/include/spdlog/pattern_formatter.h @@ -68,7 +68,7 @@ class SPDLOG_API custom_flag_formatter : public details::flag_formatter public: virtual std::unique_ptr clone() const = 0; - void set_padding_info(details::padding_info padding) + void set_padding_info(const details::padding_info &padding) { flag_formatter::padinfo_ = padding; } @@ -98,11 +98,13 @@ class SPDLOG_API pattern_formatter final : public formatter return *this; } void set_pattern(std::string pattern); + void need_localtime(bool need = true); private: std::string pattern_; std::string eol_; pattern_time_type pattern_time_type_; + bool need_localtime_; std::tm cached_tm_; std::chrono::seconds last_log_secs_; std::vector> formatters_; diff --git a/Lumos/External/spdlog/include/spdlog/sinks/android_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/android_sink.h index 42935a7cb..0087e9533 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/android_sink.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/android_sink.h @@ -16,6 +16,7 @@ # include # include # include +# include # if !defined(SPDLOG_ANDROID_RETRIES) # define SPDLOG_ANDROID_RETRIES 2 @@ -25,9 +26,10 @@ namespace spdlog { namespace sinks { /* - * Android sink (logging using __android_log_write) + * Android sink + * (logging using __android_log_write or __android_log_buf_write depending on the specified BufferID) */ -template +template class android_sink final : public base_sink { public: @@ -53,24 +55,43 @@ class android_sink final : public base_sink const char *msg_output = formatted.data(); // See system/core/liblog/logger_write.c for explanation of return value - int ret = __android_log_write(priority, tag_.c_str(), msg_output); + int ret = android_log(priority, tag_.c_str(), msg_output); + if (ret == -EPERM) + { + return; // !__android_log_is_loggable + } int retry_count = 0; while ((ret == -11 /*EAGAIN*/) && (retry_count < SPDLOG_ANDROID_RETRIES)) { details::os::sleep_for_millis(5); - ret = __android_log_write(priority, tag_.c_str(), msg_output); + ret = android_log(priority, tag_.c_str(), msg_output); retry_count++; } if (ret < 0) { - throw_spdlog_ex("__android_log_write() failed", ret); + throw_spdlog_ex("logging to Android failed", ret); } } void flush_() override {} private: + // There might be liblog versions used, that do not support __android_log_buf_write. So we only compile and link against + // __android_log_buf_write, if user explicitly provides a non-default log buffer. Otherwise, when using the default log buffer, always + // log via __android_log_write. + template + typename std::enable_if(log_id::LOG_ID_MAIN), int>::type android_log(int prio, const char *tag, const char *text) + { + return __android_log_write(prio, tag, text); + } + + template + typename std::enable_if(log_id::LOG_ID_MAIN), int>::type android_log(int prio, const char *tag, const char *text) + { + return __android_log_buf_write(ID, prio, tag, text); + } + static android_LogPriority convert_to_android_(spdlog::level::level_enum level) { switch (level) @@ -98,6 +119,12 @@ class android_sink final : public base_sink using android_sink_mt = android_sink; using android_sink_st = android_sink; + +template +using android_sink_buf_mt = android_sink; +template +using android_sink_buf_st = android_sink; + } // namespace sinks // Create and register android syslog logger @@ -116,4 +143,4 @@ inline std::shared_ptr android_logger_st(const std::string &logger_name, } // namespace spdlog -#endif // __ANDROID__ \ No newline at end of file +#endif // __ANDROID__ diff --git a/Lumos/External/spdlog/include/spdlog/sinks/ansicolor_sink-inl.h b/Lumos/External/spdlog/include/spdlog/sinks/ansicolor_sink-inl.h index d8db423ce..c924fc5bd 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/ansicolor_sink-inl.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/ansicolor_sink-inl.h @@ -21,20 +21,20 @@ SPDLOG_INLINE ansicolor_sink::ansicolor_sink(FILE *target_file, co { set_color_mode(mode); - colors_[level::trace] = to_string_(white); - colors_[level::debug] = to_string_(cyan); - colors_[level::info] = to_string_(green); - colors_[level::warn] = to_string_(yellow_bold); - colors_[level::err] = to_string_(red_bold); - colors_[level::critical] = to_string_(bold_on_red); - colors_[level::off] = to_string_(reset); + colors_.at(level::trace) = to_string_(white); + colors_.at(level::debug) = to_string_(cyan); + colors_.at(level::info) = to_string_(green); + colors_.at(level::warn) = to_string_(yellow_bold); + colors_.at(level::err) = to_string_(red_bold); + colors_.at(level::critical) = to_string_(bold_on_red); + colors_.at(level::off) = to_string_(reset); } template SPDLOG_INLINE void ansicolor_sink::set_color(level::level_enum color_level, string_view_t color) { std::lock_guard lock(mutex_); - colors_[color_level] = to_string_(color); + colors_.at(static_cast(color_level)) = to_string_(color); } template @@ -52,7 +52,7 @@ SPDLOG_INLINE void ansicolor_sink::log(const details::log_msg &msg // before color range print_range_(formatted, 0, msg.color_range_start); // in color range - print_ccode_(colors_[msg.level]); + print_ccode_(colors_.at(static_cast(msg.level))); print_range_(formatted, msg.color_range_start, msg.color_range_end); print_ccode_(reset); // after color range diff --git a/Lumos/External/spdlog/include/spdlog/sinks/base_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/base_sink.h index a0624e941..2e795f592 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/base_sink.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/base_sink.h @@ -16,7 +16,7 @@ namespace spdlog { namespace sinks { template -class base_sink : public sink +class SPDLOG_API base_sink : public sink { public: base_sink(); @@ -37,7 +37,7 @@ class base_sink : public sink protected: // sink formatter std::unique_ptr formatter_; - mutable Mutex mutex_; + Mutex mutex_; virtual void sink_it_(const details::log_msg &msg) = 0; virtual void flush_() = 0; diff --git a/Lumos/External/spdlog/include/spdlog/sinks/basic_file_sink-inl.h b/Lumos/External/spdlog/include/spdlog/sinks/basic_file_sink-inl.h index e903dd939..8d23f96df 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/basic_file_sink-inl.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/basic_file_sink-inl.h @@ -14,7 +14,8 @@ namespace spdlog { namespace sinks { template -SPDLOG_INLINE basic_file_sink::basic_file_sink(const filename_t &filename, bool truncate) +SPDLOG_INLINE basic_file_sink::basic_file_sink(const filename_t &filename, bool truncate, const file_event_handlers &event_handlers) + : file_helper_{event_handlers} { file_helper_.open(filename, truncate); } diff --git a/Lumos/External/spdlog/include/spdlog/sinks/basic_file_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/basic_file_sink.h index 047bc8ce5..aacc993bf 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/basic_file_sink.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/basic_file_sink.h @@ -20,7 +20,7 @@ template class basic_file_sink final : public base_sink { public: - explicit basic_file_sink(const filename_t &filename, bool truncate = false); + explicit basic_file_sink(const filename_t &filename, bool truncate = false, const file_event_handlers &event_handlers = {}); const filename_t &filename() const; protected: @@ -40,15 +40,17 @@ using basic_file_sink_st = basic_file_sink; // factory functions // template -inline std::shared_ptr basic_logger_mt(const std::string &logger_name, const filename_t &filename, bool truncate = false) +inline std::shared_ptr basic_logger_mt( + const std::string &logger_name, const filename_t &filename, bool truncate = false, const file_event_handlers &event_handlers = {}) { - return Factory::template create(logger_name, filename, truncate); + return Factory::template create(logger_name, filename, truncate, event_handlers); } template -inline std::shared_ptr basic_logger_st(const std::string &logger_name, const filename_t &filename, bool truncate = false) +inline std::shared_ptr basic_logger_st( + const std::string &logger_name, const filename_t &filename, bool truncate = false, const file_event_handlers &event_handlers = {}) { - return Factory::template create(logger_name, filename, truncate); + return Factory::template create(logger_name, filename, truncate, event_handlers); } } // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/sinks/callback_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/callback_sink.h new file mode 100644 index 000000000..bcd31383b --- /dev/null +++ b/Lumos/External/spdlog/include/spdlog/sinks/callback_sink.h @@ -0,0 +1,61 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#pragma once + +#include +#include +#include + +#include +#include + +namespace spdlog { + +// callbacks type +typedef std::function custom_log_callback; + +namespace sinks { +/* + * Trivial callback sink, gets a callback function and calls it on each log + */ +template +class callback_sink final : public base_sink +{ +public: + explicit callback_sink(const custom_log_callback &callback) + : callback_{callback} + {} + +protected: + void sink_it_(const details::log_msg &msg) override + { + callback_(msg); + } + void flush_() override{}; + +private: + custom_log_callback callback_; +}; + +using callback_sink_mt = callback_sink; +using callback_sink_st = callback_sink; + +} // namespace sinks + +// +// factory functions +// +template +inline std::shared_ptr callback_logger_mt(const std::string &logger_name, const custom_log_callback &callback) +{ + return Factory::template create(logger_name, callback); +} + +template +inline std::shared_ptr callback_logger_st(const std::string &logger_name, const custom_log_callback &callback) +{ + return Factory::template create(logger_name, callback); +} + +} // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/sinks/daily_file_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/daily_file_sink.h index d6a09f6bd..0770380c0 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/daily_file_sink.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/daily_file_sink.h @@ -13,9 +13,10 @@ #include #include +#include +#include #include #include -#include #include #include @@ -32,8 +33,8 @@ struct daily_filename_calculator { filename_t basename, ext; std::tie(basename, ext) = details::file_helper::split_by_extension(filename); - return fmt::format( - SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}{}"), basename, now_tm.tm_year + 1900, now_tm.tm_mon + 1, now_tm.tm_mday, ext); + return fmt_lib::format(SPDLOG_FMT_STRING(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}{}")), basename, now_tm.tm_year + 1900, + now_tm.tm_mon + 1, now_tm.tm_mday, ext); } }; @@ -46,15 +47,15 @@ struct daily_filename_calculator */ struct daily_filename_format_calculator { - static filename_t calc_filename(const filename_t &filename, const tm &now_tm) + static filename_t calc_filename(const filename_t &file_path, const tm &now_tm) { - // generate fmt datetime format string, e.g. {:%Y-%m-%d}. - filename_t fmt_filename = fmt::format(SPDLOG_FILENAME_T("{{:{}}}"), filename); -#if defined(_MSC_VER) && defined(SPDLOG_WCHAR_FILENAMES) // for some reason msvc doesnt allow fmt::runtime(..) with wchar here - return fmt::format(fmt_filename, now_tm); +#if defined(_WIN32) && defined(SPDLOG_WCHAR_FILENAMES) + std::wstringstream stream; #else - return fmt::format(SPDLOG_FMT_RUNTIME(fmt_filename), now_tm); + std::stringstream stream; #endif + stream << std::put_time(&now_tm, file_path.c_str()); + return stream.str(); } }; @@ -68,10 +69,12 @@ class daily_file_sink final : public base_sink { public: // create daily file sink which rotates on given time - daily_file_sink(filename_t base_filename, int rotation_hour, int rotation_minute, bool truncate = false, uint16_t max_files = 0) + daily_file_sink(filename_t base_filename, int rotation_hour, int rotation_minute, bool truncate = false, uint16_t max_files = 0, + const file_event_handlers &event_handlers = {}) : base_filename_(std::move(base_filename)) , rotation_h_(rotation_hour) , rotation_m_(rotation_minute) + , file_helper_{event_handlers} , truncate_(truncate) , max_files_(max_files) , filenames_q_() @@ -213,30 +216,32 @@ using daily_file_format_sink_st = daily_file_sink -inline std::shared_ptr daily_logger_mt( - const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0) +inline std::shared_ptr daily_logger_mt(const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, + bool truncate = false, uint16_t max_files = 0, const file_event_handlers &event_handlers = {}) { - return Factory::template create(logger_name, filename, hour, minute, truncate, max_files); + return Factory::template create(logger_name, filename, hour, minute, truncate, max_files, event_handlers); } template -inline std::shared_ptr daily_logger_format_mt( - const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0) +inline std::shared_ptr daily_logger_format_mt(const std::string &logger_name, const filename_t &filename, int hour = 0, + int minute = 0, bool truncate = false, uint16_t max_files = 0, const file_event_handlers &event_handlers = {}) { - return Factory::template create(logger_name, filename, hour, minute, truncate, max_files); + return Factory::template create( + logger_name, filename, hour, minute, truncate, max_files, event_handlers); } template -inline std::shared_ptr daily_logger_st( - const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0) +inline std::shared_ptr daily_logger_st(const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, + bool truncate = false, uint16_t max_files = 0, const file_event_handlers &event_handlers = {}) { - return Factory::template create(logger_name, filename, hour, minute, truncate, max_files); + return Factory::template create(logger_name, filename, hour, minute, truncate, max_files, event_handlers); } template -inline std::shared_ptr daily_logger_format_st( - const std::string &logger_name, const filename_t &filename, int hour = 0, int minute = 0, bool truncate = false, uint16_t max_files = 0) +inline std::shared_ptr daily_logger_format_st(const std::string &logger_name, const filename_t &filename, int hour = 0, + int minute = 0, bool truncate = false, uint16_t max_files = 0, const file_event_handlers &event_handlers = {}) { - return Factory::template create(logger_name, filename, hour, minute, truncate, max_files); + return Factory::template create( + logger_name, filename, hour, minute, truncate, max_files, event_handlers); } } // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/sinks/dist_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/dist_sink.h index 8fccb4ee5..7ec3a2ecf 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/dist_sink.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/dist_sink.h @@ -31,16 +31,16 @@ class dist_sink : public base_sink dist_sink(const dist_sink &) = delete; dist_sink &operator=(const dist_sink &) = delete; - void add_sink(std::shared_ptr sink) + void add_sink(std::shared_ptr sub_sink) { std::lock_guard lock(base_sink::mutex_); - sinks_.push_back(sink); + sinks_.push_back(sub_sink); } - void remove_sink(std::shared_ptr sink) + void remove_sink(std::shared_ptr sub_sink) { std::lock_guard lock(base_sink::mutex_); - sinks_.erase(std::remove(sinks_.begin(), sinks_.end(), sink), sinks_.end()); + sinks_.erase(std::remove(sinks_.begin(), sinks_.end(), sub_sink), sinks_.end()); } void set_sinks(std::vector> sinks) @@ -57,20 +57,20 @@ class dist_sink : public base_sink protected: void sink_it_(const details::log_msg &msg) override { - for (auto &sink : sinks_) + for (auto &sub_sink : sinks_) { - if (sink->should_log(msg.level)) + if (sub_sink->should_log(msg.level)) { - sink->log(msg); + sub_sink->log(msg); } } } void flush_() override { - for (auto &sink : sinks_) + for (auto &sub_sink : sinks_) { - sink->flush(); + sub_sink->flush(); } } @@ -82,9 +82,9 @@ class dist_sink : public base_sink void set_formatter_(std::unique_ptr sink_formatter) override { base_sink::formatter_ = std::move(sink_formatter); - for (auto &sink : sinks_) + for (auto &sub_sink : sinks_) { - sink->set_formatter(base_sink::formatter_->clone()); + sub_sink->set_formatter(base_sink::formatter_->clone()); } } std::vector> sinks_; diff --git a/Lumos/External/spdlog/include/spdlog/sinks/dup_filter_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/dup_filter_sink.h index 282163ae4..3c96549c5 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/dup_filter_sink.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/dup_filter_sink.h @@ -20,7 +20,7 @@ // #include // // int main() { -// auto dup_filter = std::make_shared(std::chrono::seconds(5)); +// auto dup_filter = std::make_shared(std::chrono::seconds(5), level::info); // dup_filter->add_sink(std::make_shared()); // spdlog::logger l("logger", dup_filter); // l.info("Hello"); @@ -41,8 +41,9 @@ class dup_filter_sink : public dist_sink { public: template - explicit dup_filter_sink(std::chrono::duration max_skip_duration) + explicit dup_filter_sink(std::chrono::duration max_skip_duration, level::level_enum notification_level = level::info) : max_skip_duration_{max_skip_duration} + , log_level_{notification_level} {} protected: @@ -50,6 +51,7 @@ class dup_filter_sink : public dist_sink log_clock::time_point last_msg_time_; std::string last_msg_payload_; size_t skip_counter_ = 0; + level::level_enum log_level_; void sink_it_(const details::log_msg &msg) override { @@ -67,7 +69,7 @@ class dup_filter_sink : public dist_sink auto msg_size = ::snprintf(buf, sizeof(buf), "Skipped %u duplicate messages..", static_cast(skip_counter_)); if (msg_size > 0 && static_cast(msg_size) < sizeof(buf)) { - details::log_msg skipped_msg{msg.logger_name, level::info, string_view_t{buf, static_cast(msg_size)}}; + details::log_msg skipped_msg{msg.source, msg.logger_name, log_level_, string_view_t{buf, static_cast(msg_size)}}; dist_sink::sink_it_(skipped_msg); } } diff --git a/Lumos/External/spdlog/include/spdlog/sinks/hourly_file_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/hourly_file_sink.h index e75ab4db0..33dd89483 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/hourly_file_sink.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/hourly_file_sink.h @@ -31,7 +31,7 @@ struct hourly_filename_calculator { filename_t basename, ext; std::tie(basename, ext) = details::file_helper::split_by_extension(filename); - return fmt::format(SPDLOG_FILENAME_T("{}_{:04d}{:02d}{:02d}_{:02d}{}"), basename, now_tm.tm_year + 1900, now_tm.tm_mon + 1, + return fmt_lib::format(SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}_{:02d}{}"), basename, now_tm.tm_year + 1900, now_tm.tm_mon + 1, now_tm.tm_mday, now_tm.tm_hour, ext); } }; @@ -46,8 +46,10 @@ class hourly_file_sink final : public base_sink { public: // create hourly file sink which rotates on given time - hourly_file_sink(filename_t base_filename, bool truncate = false, uint16_t max_files = 0) + hourly_file_sink( + filename_t base_filename, bool truncate = false, uint16_t max_files = 0, const file_event_handlers &event_handlers = {}) : base_filename_(std::move(base_filename)) + , file_helper_{event_handlers} , truncate_(truncate) , max_files_(max_files) , filenames_q_() @@ -55,6 +57,7 @@ class hourly_file_sink final : public base_sink auto now = log_clock::now(); auto filename = FileNameCalc::calc_filename(base_filename_, now_tm(now)); file_helper_.open(filename, truncate_); + remove_init_file_ = file_helper_.size() == 0; rotation_tp_ = next_rotation_tp_(); if (max_files_ > 0) @@ -76,10 +79,16 @@ class hourly_file_sink final : public base_sink bool should_rotate = time >= rotation_tp_; if (should_rotate) { + if (remove_init_file_) + { + file_helper_.close(); + details::os::remove(file_helper_.filename()); + } auto filename = FileNameCalc::calc_filename(base_filename_, now_tm(time)); file_helper_.open(filename, truncate_); rotation_tp_ = next_rotation_tp_(); } + remove_init_file_ = false; memory_buf_t formatted; base_sink::formatter_->format(msg, formatted); file_helper_.write(formatted); @@ -168,6 +177,7 @@ class hourly_file_sink final : public base_sink bool truncate_; uint16_t max_files_; details::circular_q filenames_q_; + bool remove_init_file_; }; using hourly_file_sink_mt = hourly_file_sink; @@ -179,16 +189,16 @@ using hourly_file_sink_st = hourly_file_sink; // factory functions // template -inline std::shared_ptr hourly_logger_mt( - const std::string &logger_name, const filename_t &filename, bool truncate = false, uint16_t max_files = 0) +inline std::shared_ptr hourly_logger_mt(const std::string &logger_name, const filename_t &filename, bool truncate = false, + uint16_t max_files = 0, const file_event_handlers &event_handlers = {}) { - return Factory::template create(logger_name, filename, truncate, max_files); + return Factory::template create(logger_name, filename, truncate, max_files, event_handlers); } template -inline std::shared_ptr hourly_logger_st( - const std::string &logger_name, const filename_t &filename, bool truncate = false, uint16_t max_files = 0) +inline std::shared_ptr hourly_logger_st(const std::string &logger_name, const filename_t &filename, bool truncate = false, + uint16_t max_files = 0, const file_event_handlers &event_handlers = {}) { - return Factory::template create(logger_name, filename, truncate, max_files); + return Factory::template create(logger_name, filename, truncate, max_files, event_handlers); } } // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/sinks/kafka_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/kafka_sink.h new file mode 100644 index 000000000..ce740efc0 --- /dev/null +++ b/Lumos/External/spdlog/include/spdlog/sinks/kafka_sink.h @@ -0,0 +1,133 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#pragma once + +// +// Custom sink for kafka +// Building and using requires librdkafka library. +// For building librdkafka library check the url below +// https://github.com/confluentinc/librdkafka +// + +#include +#include "spdlog/details/log_msg.h" +#include "spdlog/sinks/base_sink.h" +#include "spdlog/details/synchronous_factory.h" +#include "spdlog/details/null_mutex.h" +#include "spdlog/async.h" +#include + +// kafka header +#include + +namespace spdlog { +namespace sinks { + +struct kafka_sink_config +{ + std::string server_addr; + std::string produce_topic; + int32_t flush_timeout_ms = 1000; + + kafka_sink_config(std::string addr, std::string topic, int flush_timeout_ms = 1000) + : server_addr{std::move(addr)} + , produce_topic{std::move(topic)} + , flush_timeout_ms(flush_timeout_ms) + {} +}; + +template +class kafka_sink : public base_sink +{ +public: + kafka_sink(kafka_sink_config config) + : config_{std::move(config)} + { + try + { + std::string errstr; + conf_.reset(RdKafka::Conf::create(RdKafka::Conf::CONF_GLOBAL)); + RdKafka::Conf::ConfResult confRes = conf_->set("bootstrap.servers", config_.server_addr, errstr); + if (confRes != RdKafka::Conf::CONF_OK) + { + throw_spdlog_ex(fmt_lib::format("conf set bootstrap.servers failed err:{}", errstr)); + } + + tconf_.reset(RdKafka::Conf::create(RdKafka::Conf::CONF_TOPIC)); + if (tconf_ == nullptr) + { + throw_spdlog_ex(fmt_lib::format("create topic config failed")); + } + + producer_.reset(RdKafka::Producer::create(conf_.get(), errstr)); + if (producer_ == nullptr) + { + throw_spdlog_ex(fmt_lib::format("create producer failed err:{}", errstr)); + } + topic_.reset(RdKafka::Topic::create(producer_.get(), config_.produce_topic, tconf_.get(), errstr)); + if (topic_ == nullptr) + { + throw_spdlog_ex(fmt_lib::format("create topic failed err:{}", errstr)); + } + } + catch (const std::exception &e) + { + throw_spdlog_ex(fmt_lib::format("error create kafka instance: {}", e.what())); + } + } + + ~kafka_sink() + { + producer_->flush(config_.flush_timeout_ms); + } + +protected: + void sink_it_(const details::log_msg &msg) override + { + producer_->produce(topic_.get(), 0, RdKafka::Producer::RK_MSG_COPY, (void *)msg.payload.data(), msg.payload.size(), NULL, NULL); + } + + void flush_() override + { + producer_->flush(config_.flush_timeout_ms); + } + +private: + kafka_sink_config config_; + std::unique_ptr producer_ = nullptr; + std::unique_ptr conf_ = nullptr; + std::unique_ptr tconf_ = nullptr; + std::unique_ptr topic_ = nullptr; +}; + +using kafka_sink_mt = kafka_sink; +using kafka_sink_st = kafka_sink; + +} // namespace sinks + +template +inline std::shared_ptr kafka_logger_mt(const std::string &logger_name, spdlog::sinks::kafka_sink_config config) +{ + return Factory::template create(logger_name, config); +} + +template +inline std::shared_ptr kafka_logger_st(const std::string &logger_name, spdlog::sinks::kafka_sink_config config) +{ + return Factory::template create(logger_name, config); +} + +template +inline std::shared_ptr kafka_logger_async_mt(std::string logger_name, spdlog::sinks::kafka_sink_config config) +{ + return Factory::template create(logger_name, config); +} + +template +inline std::shared_ptr kafka_logger_async_st(std::string logger_name, spdlog::sinks::kafka_sink_config config) +{ + return Factory::template create(logger_name, config); +} + +} // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/sinks/mongo_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/mongo_sink.h index 048b457cf..6a8927f54 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/mongo_sink.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/mongo_sink.h @@ -30,16 +30,26 @@ class mongo_sink : public base_sink { public: mongo_sink(const std::string &db_name, const std::string &collection_name, const std::string &uri = "mongodb://localhost:27017") + try : mongo_sink(std::make_shared(), db_name, collection_name, uri) + {} + catch (const std::exception &e) + { + throw_spdlog_ex(fmt_lib::format("Error opening database: {}", e.what())); + } + + mongo_sink(std::shared_ptr instance, const std::string &db_name, const std::string &collection_name, + const std::string &uri = "mongodb://localhost:27017") + : instance_(std::move(instance)) + , db_name_(db_name) + , coll_name_(collection_name) { try { - client_ = std::make_unique(mongocxx::uri{uri}); - db_name_ = db_name; - coll_name_ = collection_name; + client_ = spdlog::details::make_unique(mongocxx::uri{uri}); } - catch (const std::exception) + catch (const std::exception &e) { - throw spdlog_ex("Error opening database"); + throw_spdlog_ex(fmt_lib::format("Error opening database: {}", e.what())); } } @@ -57,8 +67,8 @@ class mongo_sink : public base_sink if (client_ != nullptr) { auto doc = document{} << "timestamp" << bsoncxx::types::b_date(msg.time) << "level" << level::to_string_view(msg.level).data() - << "message" << std::string(msg.payload.begin(), msg.payload.end()) << "logger_name" - << std::string(msg.logger_name.begin(), msg.logger_name.end()) << "thread_id" + << "level_num" << msg.level << "message" << std::string(msg.payload.begin(), msg.payload.end()) + << "logger_name" << std::string(msg.logger_name.begin(), msg.logger_name.end()) << "thread_id" << static_cast(msg.thread_id) << finalize; client_->database(db_name_).collection(coll_name_).insert_one(doc.view()); } @@ -67,12 +77,11 @@ class mongo_sink : public base_sink void flush_() override {} private: - static mongocxx::instance instance_; + std::shared_ptr instance_; std::string db_name_; std::string coll_name_; std::unique_ptr client_ = nullptr; }; -mongocxx::instance mongo_sink::instance_{}; #include "spdlog/details/null_mutex.h" #include diff --git a/Lumos/External/spdlog/include/spdlog/sinks/msvc_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/msvc_sink.h index 2ac4a9659..bf68ae880 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/msvc_sink.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/msvc_sink.h @@ -1,4 +1,4 @@ -// Copyright(c) 2016 Alexander Dalshov. +// Copyright(c) 2016 Alexander Dalshov & spdlog contributors. // Distributed under the MIT License (http://opensource.org/licenses/MIT) #pragma once @@ -6,13 +6,21 @@ #if defined(_WIN32) # include +# if defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) +# include +# endif # include # include # include // Avoid including windows.h (https://stackoverflow.com/a/30741042) +# if defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) +extern "C" __declspec(dllimport) void __stdcall OutputDebugStringW(const wchar_t *lpOutputString); +# else extern "C" __declspec(dllimport) void __stdcall OutputDebugStringA(const char *lpOutputString); +# endif +extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); namespace spdlog { namespace sinks { @@ -24,16 +32,31 @@ class msvc_sink : public base_sink { public: msvc_sink() = default; + msvc_sink(bool check_debugger_present) + : check_debugger_present_{check_debugger_present} {}; protected: void sink_it_(const details::log_msg &msg) override { + if (check_debugger_present_ && !IsDebuggerPresent()) + { + return; + } memory_buf_t formatted; base_sink::formatter_->format(msg, formatted); - OutputDebugStringA(fmt::to_string(formatted).c_str()); + formatted.push_back('\0'); // add a null terminator for OutputDebugString +# if defined(SPDLOG_WCHAR_TO_UTF8_SUPPORT) + wmemory_buf_t wformatted; + details::os::utf8_to_wstrbuf(string_view_t(formatted.data(), formatted.size()), wformatted); + OutputDebugStringW(wformatted.data()); +# else + OutputDebugStringA(formatted.data()); +# endif } void flush_() override {} + + bool check_debugger_present_ = true; }; using msvc_sink_mt = msvc_sink; diff --git a/Lumos/External/spdlog/include/spdlog/sinks/qt_sinks.h b/Lumos/External/spdlog/include/spdlog/sinks/qt_sinks.h index 5a9a83da7..f801ac344 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/qt_sinks.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/qt_sinks.h @@ -4,197 +4,289 @@ #pragma once // -// Custom sink for QPlainTextEdit or QTextEdit and its children(QTextBrowser... +// Custom sink for QPlainTextEdit or QTextEdit and its childs(QTextBrowser... // etc) Building and using requires Qt library. // +// Warning: the qt_sink won't be notified if the target widget is destroyed. +// If the widget's lifetime can be shorter than the logger's one, you should provide some permanent QObject, +// and then use a standard signal/slot. +// #include "spdlog/common.h" #include "spdlog/details/log_msg.h" #include "spdlog/details/synchronous_factory.h" #include "spdlog/sinks/base_sink.h" +#include -#include -#include #include +#include -namespace _spdlog_p { -namespace _sinks_p { // -// Private class for QTextEdit and its derivatives +// qt_sink class // -class qtextedit_sink_p : public QObject +namespace spdlog { +namespace sinks { +template +class qt_sink : public base_sink { - Q_OBJECT public: - qtextedit_sink_p(QTextEdit *textedit = nullptr) + qt_sink(QObject *qt_object, std::string meta_method) + : qt_object_(qt_object) + , meta_method_(std::move(meta_method)) { - if (textedit != nullptr) + if (!qt_object_) { - textedit_ = textedit; - connect(this, &qtextedit_sink_p::append_text, textedit_, &QTextEdit::append); + throw_spdlog_ex("qt_sink: qt_object is null"); } } - ~qtextedit_sink_p() {} + ~qt_sink() + { + flush_(); + } - void append(const spdlog::string_view_t &str) +protected: + void sink_it_(const details::log_msg &msg) override { - emit append_text(QString::fromUtf8(str.data(), static_cast(str.size() - 2))); + memory_buf_t formatted; + base_sink::formatter_->format(msg, formatted); + const string_view_t str = string_view_t(formatted.data(), formatted.size()); + QMetaObject::invokeMethod(qt_object_, meta_method_.c_str(), Qt::AutoConnection, + Q_ARG(QString, QString::fromUtf8(str.data(), static_cast(str.size())).trimmed())); } -signals: - void append_text(const QString &); + void flush_() override {} private: - QTextEdit *textedit_ = nullptr; + QObject *qt_object_ = nullptr; + std::string meta_method_; }; -// -// Private class for QPlainTextEdit -// -class qplaintextedit_sink_p : public QObject +// QT color sink to QTextEdit. +// Color location is determined by the sink log pattern like in the rest of spdlog sinks. +// Colors can be modified if needed using sink->set_color(level, qtTextCharFormat). +// max_lines is the maximum number of lines that the sink will hold before removing the oldest lines. +// Note: Only ascii (latin1) is supported by this sink. +template +class qt_color_sink : public base_sink { - Q_OBJECT public: - qplaintextedit_sink_p(QPlainTextEdit *textedit = nullptr) + qt_color_sink(QTextEdit *qt_text_edit, int max_lines) + : qt_text_edit_(qt_text_edit) + , max_lines_(max_lines) { - if (textedit != nullptr) + if (!qt_text_edit_) { - textedit_ = textedit; - connect(this, &qplaintextedit_sink_p::append_text, textedit_, &QPlainTextEdit::appendPlainText); + throw_spdlog_ex("qt_color_text_sink: text_edit is null"); } - } - ~qplaintextedit_sink_p() {} + default_color_ = qt_text_edit_->currentCharFormat(); + // set colors + QTextCharFormat format; + // trace + format.setForeground(Qt::gray); + colors_.at(level::trace) = format; + // debug + format.setForeground(Qt::cyan); + colors_.at(level::debug) = format; + // info + format.setForeground(Qt::green); + colors_.at(level::info) = format; + // warn + format.setForeground(Qt::yellow); + colors_.at(level::warn) = format; + // err + format.setForeground(Qt::red); + colors_.at(level::err) = format; + // critical + format.setForeground(Qt::white); + format.setBackground(Qt::red); + colors_.at(level::critical) = format; + } - void append(const spdlog::string_view_t &str) + ~qt_color_sink() { - emit append_text(QString::fromUtf8(str.data(), static_cast(str.size() - 2))); + flush_(); } -signals: - void append_text(const QString &); + void set_default_color(QTextCharFormat format) + { + // std::lock_guard lock(base_sink::mutex_); + default_color_ = format; + } -private: - QPlainTextEdit *textedit_ = nullptr; -}; -} // namespace _sinks_p -} // namespace _spdlog_p + void set_level_color(level::level_enum color_level, QTextCharFormat format) + { + // std::lock_guard lock(base_sink::mutex_); + colors_.at(static_cast(color_level)) = format; + } -// -// qtextedit_sink class -// -namespace spdlog { -namespace sinks { -template -class qtextedit_sink : public base_sink -{ -public: - qtextedit_sink(QTextEdit *textedit = nullptr) + QTextCharFormat &get_level_color(level::level_enum color_level) { - if (textedit != nullptr) - { - textedit_p = std::make_shared<_spdlog_p::_sinks_p::qtextedit_sink_p>(textedit); - } - else - { - throw spdlog_ex("Error opening QTextEdit"); - } + std::lock_guard lock(base_sink::mutex_); + return colors_.at(static_cast(color_level)); } - ~qtextedit_sink() + QTextCharFormat &get_default_color() { - flush_(); + std::lock_guard lock(base_sink::mutex_); + return default_color_; } protected: + struct invoke_params + { + invoke_params(int max_lines, QTextEdit *q_text_edit, QString payload, QTextCharFormat default_color, QTextCharFormat level_color, + int color_range_start, int color_range_end) + : max_lines(max_lines) + , q_text_edit(q_text_edit) + , payload(std::move(payload)) + , default_color(default_color) + , level_color(level_color) + , color_range_start(color_range_start) + , color_range_end(color_range_end) + {} + int max_lines; + QTextEdit *q_text_edit; + QString payload; + QTextCharFormat default_color; + QTextCharFormat level_color; + int color_range_start; + int color_range_end; + }; + void sink_it_(const details::log_msg &msg) override { memory_buf_t formatted; base_sink::formatter_->format(msg, formatted); - string_view_t str_v = string_view_t(formatted.data(), formatted.size()); - textedit_p->append(str_v); + + const string_view_t str = string_view_t(formatted.data(), formatted.size()); + // apply the color to the color range in the formatted message. + auto payload = QString::fromLatin1(str.data(), static_cast(str.size())); + + invoke_params params{max_lines_, // max lines + qt_text_edit_, // text edit to append to + std::move(payload), // text to append + default_color_, // default color + colors_.at(msg.level), // color to apply + static_cast(msg.color_range_start), // color range start + static_cast(msg.color_range_end)}; // color range end + + QMetaObject::invokeMethod( + qt_text_edit_, [params]() { invoke_method_(params); }, Qt::AutoConnection); } void flush_() override {} -private: - std::shared_ptr<_spdlog_p::_sinks_p::qtextedit_sink_p> textedit_p = nullptr; -}; + // Add colored text to the text edit widget. This method is invoked in the GUI thread. + // It is a static method to ensure that it is handled correctly even if the sink is destroyed prematurely + // before it is invoked. -// -// qplaintextedit_sink class -// -template -class qplaintextedit_sink : public base_sink -{ -public: - qplaintextedit_sink(QPlainTextEdit *textedit = nullptr) + static void invoke_method_(invoke_params params) { - if (textedit != nullptr) + auto *document = params.q_text_edit->document(); + QTextCursor cursor(document); + + // remove first blocks if number of blocks exceeds max_lines + while (document->blockCount() > params.max_lines) { - textedit_p = std::make_shared<_spdlog_p::_sinks_p::qplaintextedit_sink_p>(textedit); + cursor.select(QTextCursor::BlockUnderCursor); + cursor.removeSelectedText(); + cursor.deleteChar(); // delete the newline after the block } - else + + cursor.movePosition(QTextCursor::End); + cursor.setCharFormat(params.default_color); + + // if color range not specified or not not valid, just append the text with default color + if (params.color_range_end <= params.color_range_start) { - throw spdlog_ex("Error opening QPlainTextEdit"); + cursor.insertText(params.payload); + return; } - } - ~qplaintextedit_sink() - { - flush_(); - } + // insert the text before the color range + cursor.insertText(params.payload.left(params.color_range_start)); -protected: - void sink_it_(const details::log_msg &msg) override - { - memory_buf_t formatted; - base_sink::formatter_->format(msg, formatted); - string_view_t str_v = string_view_t(formatted.data(), formatted.size()); - textedit_p->append(str_v); - } + // insert the colorized text + cursor.setCharFormat(params.level_color); + cursor.insertText(params.payload.mid(params.color_range_start, params.color_range_end - params.color_range_start)); - void flush_() override {} + // insert the text after the color range with default format + cursor.setCharFormat(params.default_color); + cursor.insertText(params.payload.mid(params.color_range_end)); + } -private: - std::shared_ptr<_spdlog_p::_sinks_p::qplaintextedit_sink_p> textedit_p = nullptr; + QTextEdit *qt_text_edit_; + int max_lines_; + QTextCharFormat default_color_; + std::array colors_; }; #include "spdlog/details/null_mutex.h" #include -using qtextedit_sink_mt = qtextedit_sink; -using qtextedit_sink_st = qtextedit_sink; - -using qplaintextedit_sink_mt = qplaintextedit_sink; -using qplaintextedit_sink_st = qplaintextedit_sink; +using qt_sink_mt = qt_sink; +using qt_sink_st = qt_sink; +using qt_color_sink_mt = qt_color_sink; +using qt_color_sink_st = qt_color_sink; } // namespace sinks // // Factory functions // + +// log to QTextEdit template -inline std::shared_ptr qtextedit_logger_mt(const std::string &logger_name, QTextEdit *qtextedit = nullptr) +inline std::shared_ptr qt_logger_mt(const std::string &logger_name, QTextEdit *qt_object, const std::string &meta_method = "append") { - return Factory::template create(logger_name, qtextedit); + return Factory::template create(logger_name, qt_object, meta_method); } template -inline std::shared_ptr qtextedit_logger_st(const std::string &logger_name, QTextEdit *qtextedit = nullptr) +inline std::shared_ptr qt_logger_st(const std::string &logger_name, QTextEdit *qt_object, const std::string &meta_method = "append") { - return Factory::template create(logger_name, qtextedit); + return Factory::template create(logger_name, qt_object, meta_method); } +// log to QPlainTextEdit template -inline std::shared_ptr qplaintextedit_logger_mt(const std::string &logger_name, QPlainTextEdit *qplaintextedit = nullptr) +inline std::shared_ptr qt_logger_mt( + const std::string &logger_name, QPlainTextEdit *qt_object, const std::string &meta_method = "appendPlainText") { - return Factory::template create(logger_name, qplaintextedit); + return Factory::template create(logger_name, qt_object, meta_method); } template -inline std::shared_ptr qplaintextedit_logger_st(const std::string &logger_name, QPlainTextEdit *qplaintextedit = nullptr) +inline std::shared_ptr qt_logger_st( + const std::string &logger_name, QPlainTextEdit *qt_object, const std::string &meta_method = "appendPlainText") { - return Factory::template create(logger_name, qplaintextedit); + return Factory::template create(logger_name, qt_object, meta_method); } +// log to QObject +template +inline std::shared_ptr qt_logger_mt(const std::string &logger_name, QObject *qt_object, const std::string &meta_method) +{ + return Factory::template create(logger_name, qt_object, meta_method); +} + +template +inline std::shared_ptr qt_logger_st(const std::string &logger_name, QObject *qt_object, const std::string &meta_method) +{ + return Factory::template create(logger_name, qt_object, meta_method); +} + +// log to QTextEdit with colorize output +template +inline std::shared_ptr qt_color_logger_mt(const std::string &logger_name, QTextEdit *qt_text_edit, int max_lines) +{ + return Factory::template create(logger_name, qt_text_edit, max_lines); +} + +template +inline std::shared_ptr qt_color_logger_st(const std::string &logger_name, QTextEdit *qt_text_edit, int max_lines) +{ + return Factory::template create(logger_name, qt_text_edit, max_lines); +} + } // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/sinks/ringbuffer_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/ringbuffer_sink.h index 1ee3f6916..3ca47c6f7 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/ringbuffer_sink.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/ringbuffer_sink.h @@ -50,7 +50,7 @@ class ringbuffer_sink final : public base_sink { memory_buf_t formatted; base_sink::formatter_->format(q_.at(i), formatted); - ret.push_back(fmt::to_string(formatted)); + ret.push_back(SPDLOG_BUF_TO_STRING(formatted)); } return ret; } diff --git a/Lumos/External/spdlog/include/spdlog/sinks/rotating_file_sink-inl.h b/Lumos/External/spdlog/include/spdlog/sinks/rotating_file_sink-inl.h index f31f53190..cf8b9d5c6 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/rotating_file_sink-inl.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/rotating_file_sink-inl.h @@ -25,16 +25,27 @@ namespace sinks { template SPDLOG_INLINE rotating_file_sink::rotating_file_sink( - filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open) + filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open, const file_event_handlers &event_handlers) : base_filename_(std::move(base_filename)) , max_size_(max_size) , max_files_(max_files) + , file_helper_{event_handlers} { + if (max_size == 0) + { + throw_spdlog_ex("rotating sink constructor: max_size arg cannot be zero"); + } + + if (max_files > 200000) + { + throw_spdlog_ex("rotating sink constructor: max_files arg cannot exceed 200000"); + } file_helper_.open(calc_filename(base_filename_, 0)); current_size_ = file_helper_.size(); // expensive. called only once if (rotate_on_open && current_size_ > 0) { rotate_(); + current_size_ = 0; } } @@ -50,7 +61,7 @@ SPDLOG_INLINE filename_t rotating_file_sink::calc_filename(const filename filename_t basename, ext; std::tie(basename, ext) = details::file_helper::split_by_extension(filename); - return fmt::format(SPDLOG_FILENAME_T("{}.{}{}"), basename, index, ext); + return fmt_lib::format(SPDLOG_FILENAME_T("{}.{}{}"), basename, index, ext); } template @@ -65,13 +76,22 @@ SPDLOG_INLINE void rotating_file_sink::sink_it_(const details::log_msg &m { memory_buf_t formatted; base_sink::formatter_->format(msg, formatted); - current_size_ += formatted.size(); - if (current_size_ > max_size_) + auto new_size = current_size_ + formatted.size(); + + // rotate if the new estimated file size exceeds max size. + // rotate only if the real size > 0 to better deal with full disk (see issue #2261). + // we only check the real size when new_size > max_size_ because it is relatively expensive. + if (new_size > max_size_) { - rotate_(); - current_size_ = formatted.size(); + file_helper_.flush(); + if (file_helper_.size() > 0) + { + rotate_(); + new_size = formatted.size(); + } } file_helper_.write(formatted); + current_size_ = new_size; } template @@ -90,6 +110,7 @@ SPDLOG_INLINE void rotating_file_sink::rotate_() { using details::os::filename_to_str; using details::os::path_exists; + file_helper_.close(); for (auto i = max_files_; i > 0; --i) { diff --git a/Lumos/External/spdlog/include/spdlog/sinks/rotating_file_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/rotating_file_sink.h index 842527ef7..ce0d7b1ef 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/rotating_file_sink.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/rotating_file_sink.h @@ -22,7 +22,8 @@ template class rotating_file_sink final : public base_sink { public: - rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open = false); + rotating_file_sink(filename_t base_filename, std::size_t max_size, std::size_t max_files, bool rotate_on_open = false, + const file_event_handlers &event_handlers = {}); static filename_t calc_filename(const filename_t &filename, std::size_t index); filename_t filename(); @@ -59,17 +60,19 @@ using rotating_file_sink_st = rotating_file_sink; // template -inline std::shared_ptr rotating_logger_mt( - const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false) +inline std::shared_ptr rotating_logger_mt(const std::string &logger_name, const filename_t &filename, size_t max_file_size, + size_t max_files, bool rotate_on_open = false, const file_event_handlers &event_handlers = {}) { - return Factory::template create(logger_name, filename, max_file_size, max_files, rotate_on_open); + return Factory::template create( + logger_name, filename, max_file_size, max_files, rotate_on_open, event_handlers); } template -inline std::shared_ptr rotating_logger_st( - const std::string &logger_name, const filename_t &filename, size_t max_file_size, size_t max_files, bool rotate_on_open = false) +inline std::shared_ptr rotating_logger_st(const std::string &logger_name, const filename_t &filename, size_t max_file_size, + size_t max_files, bool rotate_on_open = false, const file_event_handlers &event_handlers = {}) { - return Factory::template create(logger_name, filename, max_file_size, max_files, rotate_on_open); + return Factory::template create( + logger_name, filename, max_file_size, max_files, rotate_on_open, event_handlers); } } // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/sinks/stdout_sinks-inl.h b/Lumos/External/spdlog/include/spdlog/sinks/stdout_sinks-inl.h index c14066b9b..c1754370f 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/stdout_sinks-inl.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/stdout_sinks-inl.h @@ -16,7 +16,7 @@ // so instead we use ::FileWrite # include -# ifndef _USING_V110_SDK71_ // fileapi.h doesnt exist in winxp +# ifndef _USING_V110_SDK71_ // fileapi.h doesn't exist in winxp # include // WriteFile (..) # endif @@ -37,7 +37,7 @@ SPDLOG_INLINE stdout_sink_base::stdout_sink_base(FILE *file) #ifdef _WIN32 // get windows handle from the FILE* object - handle_ = (HANDLE)::_get_osfhandle(::_fileno(file_)); + handle_ = reinterpret_cast(::_get_osfhandle(::_fileno(file_))); // don't throw to support cases where no console is attached, // and let the log method to do nothing if (handle_ == INVALID_HANDLE_VALUE). @@ -60,7 +60,6 @@ SPDLOG_INLINE void stdout_sink_base::log(const details::log_msg &m std::lock_guard lock(mutex_); memory_buf_t formatted; formatter_->format(msg, formatted); - ::fflush(file_); // flush in case there is somthing in this file_ already auto size = static_cast(formatted.size()); DWORD bytes_written = 0; bool ok = ::WriteFile(handle_, formatted.data(), size, &bytes_written, nullptr) != 0; @@ -73,8 +72,8 @@ SPDLOG_INLINE void stdout_sink_base::log(const details::log_msg &m memory_buf_t formatted; formatter_->format(msg, formatted); ::fwrite(formatted.data(), sizeof(char), formatted.size(), file_); +#endif // WIN32 ::fflush(file_); // flush every line to terminal -#endif // WIN32 } template diff --git a/Lumos/External/spdlog/include/spdlog/sinks/systemd_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/systemd_sink.h index e3d513a0d..b00a95f29 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/systemd_sink.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/systemd_sink.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include @@ -18,16 +19,15 @@ namespace sinks { /** * Sink that write to systemd journal using the `sd_journal_send()` library call. - * - * Locking is not needed, as `sd_journal_send()` itself is thread-safe. */ template class systemd_sink : public base_sink { public: - // - systemd_sink() - : syslog_levels_{{/* spdlog::level::trace */ LOG_DEBUG, + systemd_sink(std::string ident = "", bool enable_formatting = false) + : ident_{std::move(ident)} + , enable_formatting_{enable_formatting} + , syslog_levels_{{/* spdlog::level::trace */ LOG_DEBUG, /* spdlog::level::debug */ LOG_DEBUG, /* spdlog::level::info */ LOG_INFO, /* spdlog::level::warn */ LOG_WARNING, @@ -42,31 +42,52 @@ class systemd_sink : public base_sink systemd_sink &operator=(const systemd_sink &) = delete; protected: + const std::string ident_; + bool enable_formatting_ = false; using levels_array = std::array; levels_array syslog_levels_; void sink_it_(const details::log_msg &msg) override { int err; + string_view_t payload; + memory_buf_t formatted; + if (enable_formatting_) + { + base_sink::formatter_->format(msg, formatted); + payload = string_view_t(formatted.data(), formatted.size()); + } + else + { + payload = msg.payload; + } - size_t length = msg.payload.size(); + size_t length = payload.size(); // limit to max int if (length > static_cast(std::numeric_limits::max())) { length = static_cast(std::numeric_limits::max()); } + const string_view_t syslog_identifier = ident_.empty() ? msg.logger_name : ident_; + // Do not send source location if not available if (msg.source.empty()) { // Note: function call inside '()' to avoid macro expansion - err = (sd_journal_send)("MESSAGE=%.*s", static_cast(length), msg.payload.data(), "PRIORITY=%d", syslog_level(msg.level), - "SYSLOG_IDENTIFIER=%.*s", static_cast(msg.logger_name.size()), msg.logger_name.data(), nullptr); + err = (sd_journal_send)("MESSAGE=%.*s", static_cast(length), payload.data(), "PRIORITY=%d", syslog_level(msg.level), +#ifndef SPDLOG_NO_THREAD_ID + "TID=%zu", details::os::thread_id(), +#endif + "SYSLOG_IDENTIFIER=%.*s", static_cast(syslog_identifier.size()), syslog_identifier.data(), nullptr); } else { - err = (sd_journal_send)("MESSAGE=%.*s", static_cast(length), msg.payload.data(), "PRIORITY=%d", syslog_level(msg.level), - "SYSLOG_IDENTIFIER=%.*s", static_cast(msg.logger_name.size()), msg.logger_name.data(), "CODE_FILE=%s", + err = (sd_journal_send)("MESSAGE=%.*s", static_cast(length), payload.data(), "PRIORITY=%d", syslog_level(msg.level), +#ifndef SPDLOG_NO_THREAD_ID + "TID=%zu", details::os::thread_id(), +#endif + "SYSLOG_IDENTIFIER=%.*s", static_cast(syslog_identifier.size()), syslog_identifier.data(), "CODE_FILE=%s", msg.source.filename, "CODE_LINE=%d", msg.source.line, "CODE_FUNC=%s", msg.source.funcname, nullptr); } @@ -90,14 +111,16 @@ using systemd_sink_st = systemd_sink; // Create and register a syslog logger template -inline std::shared_ptr systemd_logger_mt(const std::string &logger_name) +inline std::shared_ptr systemd_logger_mt( + const std::string &logger_name, const std::string &ident = "", bool enable_formatting = false) { - return Factory::template create(logger_name); + return Factory::template create(logger_name, ident, enable_formatting); } template -inline std::shared_ptr systemd_logger_st(const std::string &logger_name) +inline std::shared_ptr systemd_logger_st( + const std::string &logger_name, const std::string &ident = "", bool enable_formatting = false) { - return Factory::template create(logger_name); + return Factory::template create(logger_name, ident, enable_formatting); } } // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/sinks/udp_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/udp_sink.h new file mode 100644 index 000000000..ccbce2be3 --- /dev/null +++ b/Lumos/External/spdlog/include/spdlog/sinks/udp_sink.h @@ -0,0 +1,74 @@ +// Copyright(c) 2015-present, Gabi Melman & spdlog contributors. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) + +#pragma once + +#include +#include +#include +#ifdef _WIN32 +# include +#else +# include +#endif + +#include +#include +#include +#include + +// Simple udp client sink +// Sends formatted log via udp + +namespace spdlog { +namespace sinks { + +struct udp_sink_config +{ + std::string server_host; + uint16_t server_port; + + udp_sink_config(std::string host, uint16_t port) + : server_host{std::move(host)} + , server_port{port} + {} +}; + +template +class udp_sink : public spdlog::sinks::base_sink +{ +public: + // host can be hostname or ip address + explicit udp_sink(udp_sink_config sink_config) + : client_{sink_config.server_host, sink_config.server_port} + {} + + ~udp_sink() override = default; + +protected: + void sink_it_(const spdlog::details::log_msg &msg) override + { + spdlog::memory_buf_t formatted; + spdlog::sinks::base_sink::formatter_->format(msg, formatted); + client_.send(formatted.data(), formatted.size()); + } + + void flush_() override {} + details::udp_client client_; +}; + +using udp_sink_mt = udp_sink; +using udp_sink_st = udp_sink; + +} // namespace sinks + +// +// factory functions +// +template +inline std::shared_ptr udp_logger_mt(const std::string &logger_name, sinks::udp_sink_config skin_config) +{ + return Factory::template create(logger_name, skin_config); +} + +} // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/sinks/win_eventlog_sink.h b/Lumos/External/spdlog/include/spdlog/sinks/win_eventlog_sink.h index 5e70599a1..d23d00a8b 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/win_eventlog_sink.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/win_eventlog_sink.h @@ -47,6 +47,24 @@ namespace win_eventlog { namespace internal { +struct local_alloc_t +{ + HLOCAL hlocal_; + + SPDLOG_CONSTEXPR local_alloc_t() SPDLOG_NOEXCEPT : hlocal_(nullptr) {} + + local_alloc_t(local_alloc_t const &) = delete; + local_alloc_t &operator=(local_alloc_t const &) = delete; + + ~local_alloc_t() SPDLOG_NOEXCEPT + { + if (hlocal_) + { + LocalFree(hlocal_); + } + } +}; + /** Windows error */ struct win32_error : public spdlog_ex { @@ -55,22 +73,17 @@ struct win32_error : public spdlog_ex { std::string system_message; - LPSTR format_message_result{}; + local_alloc_t format_message_result{}; auto format_message_succeeded = ::FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, - error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&format_message_result, 0, nullptr); - - if (format_message_succeeded && format_message_result) - { - system_message = fmt::format(" ({})", format_message_result); - } + error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&format_message_result.hlocal_, 0, nullptr); - if (format_message_result) + if (format_message_succeeded && format_message_result.hlocal_) { - LocalFree((HLOCAL)format_message_result); + system_message = fmt_lib::format(" ({})", (LPSTR)format_message_result.hlocal_); } - return fmt::format("{}: {}{}", user_message, error_code, system_message); + return fmt_lib::format("{}: {}{}", user_message, error_code, system_message); } explicit win32_error(std::string const &func_name, DWORD error = GetLastError()) @@ -197,7 +210,7 @@ class win_eventlog_sink : public base_sink HANDLE hEventLog_{NULL}; internal::sid_t current_user_sid_; std::string source_; - WORD event_id_; + DWORD event_id_; HANDLE event_log_handle() { @@ -228,12 +241,12 @@ class win_eventlog_sink : public base_sink details::os::utf8_to_wstrbuf(string_view_t(formatted.data(), formatted.size()), buf); LPCWSTR lp_wstr = buf.data(); - succeeded = ::ReportEventW(event_log_handle(), eventlog::get_event_type(msg), eventlog::get_event_category(msg), event_id_, - current_user_sid_.as_sid(), 1, 0, &lp_wstr, nullptr); + succeeded = static_cast(::ReportEventW(event_log_handle(), eventlog::get_event_type(msg), eventlog::get_event_category(msg), + event_id_, current_user_sid_.as_sid(), 1, 0, &lp_wstr, nullptr)); #else LPCSTR lp_str = formatted.data(); - succeeded = ::ReportEventA(event_log_handle(), eventlog::get_event_type(msg), eventlog::get_event_category(msg), event_id_, - current_user_sid_.as_sid(), 1, 0, &lp_str, nullptr); + succeeded = static_cast(::ReportEventA(event_log_handle(), eventlog::get_event_type(msg), eventlog::get_event_category(msg), + event_id_, current_user_sid_.as_sid(), 1, 0, &lp_str, nullptr)); #endif if (!succeeded) @@ -245,7 +258,7 @@ class win_eventlog_sink : public base_sink void flush_() override {} public: - win_eventlog_sink(std::string const &source, WORD event_id = 1000 /* according to mscoree.dll */) + win_eventlog_sink(std::string const &source, DWORD event_id = 1000 /* according to mscoree.dll */) : source_(source) , event_id_(event_id) { diff --git a/Lumos/External/spdlog/include/spdlog/sinks/wincolor_sink-inl.h b/Lumos/External/spdlog/include/spdlog/sinks/wincolor_sink-inl.h index be3d80a20..8311929e4 100644 --- a/Lumos/External/spdlog/include/spdlog/sinks/wincolor_sink-inl.h +++ b/Lumos/External/spdlog/include/spdlog/sinks/wincolor_sink-inl.h @@ -45,7 +45,7 @@ template void SPDLOG_INLINE wincolor_sink::set_color(level::level_enum level, std::uint16_t color) { std::lock_guard lock(mutex_); - colors_[level] = color; + colors_[static_cast(level)] = color; } template @@ -66,7 +66,7 @@ void SPDLOG_INLINE wincolor_sink::log(const details::log_msg &msg) // before color range print_range_(formatted, 0, msg.color_range_start); // in color range - auto orig_attribs = static_cast(set_foreground_color_(colors_[msg.level])); + auto orig_attribs = static_cast(set_foreground_color_(colors_[static_cast(msg.level)])); print_range_(formatted, msg.color_range_start, msg.color_range_end); // reset to orig colors ::SetConsoleTextAttribute(static_cast(out_handle_), orig_attribs); diff --git a/Lumos/External/spdlog/include/spdlog/spdlog-inl.h b/Lumos/External/spdlog/include/spdlog/spdlog-inl.h index 2b875fae9..22ea22bb4 100644 --- a/Lumos/External/spdlog/include/spdlog/spdlog-inl.h +++ b/Lumos/External/spdlog/include/spdlog/spdlog-inl.h @@ -67,11 +67,6 @@ SPDLOG_INLINE void flush_on(level::level_enum log_level) details::registry::instance().flush_on(log_level); } -SPDLOG_INLINE void flush_every(std::chrono::seconds interval) -{ - details::registry::instance().flush_every(interval); -} - SPDLOG_INLINE void set_error_handler(void (*handler)(const std::string &msg)) { details::registry::instance().set_error_handler(handler); @@ -122,4 +117,9 @@ SPDLOG_INLINE void set_default_logger(std::shared_ptr default_lo details::registry::instance().set_default_logger(std::move(default_logger)); } +SPDLOG_INLINE void apply_logger_env_levels(std::shared_ptr logger) +{ + details::registry::instance().apply_logger_env_levels(std::move(logger)); +} + } // namespace spdlog diff --git a/Lumos/External/spdlog/include/spdlog/spdlog.h b/Lumos/External/spdlog/include/spdlog/spdlog.h index 41c6bbb81..fbfe5fb86 100644 --- a/Lumos/External/spdlog/include/spdlog/spdlog.h +++ b/Lumos/External/spdlog/include/spdlog/spdlog.h @@ -81,7 +81,11 @@ SPDLOG_API void flush_on(level::level_enum log_level); // Start/Restart a periodic flusher thread // Warning: Use only if all your loggers are thread safe! -SPDLOG_API void flush_every(std::chrono::seconds interval); +template +inline void flush_every(std::chrono::duration interval) +{ + details::registry::instance().flush_every(interval); +} // Set global error handler SPDLOG_API void set_error_handler(void (*handler)(const std::string &msg)); @@ -127,50 +131,59 @@ SPDLOG_API spdlog::logger *default_logger_raw(); SPDLOG_API void set_default_logger(std::shared_ptr default_logger); -template -inline void log(source_loc source, level::level_enum lvl, const FormatString &fmt, Args &&...args) +// Initialize logger level based on environment configs. +// +// Useful for applying SPDLOG_LEVEL to manually created loggers. +// +// Example: +// auto mylogger = std::make_shared("mylogger", ...); +// spdlog::apply_logger_env_levels(mylogger); +SPDLOG_API void apply_logger_env_levels(std::shared_ptr logger); + +template +inline void log(source_loc source, level::level_enum lvl, format_string_t fmt, Args &&...args) { default_logger_raw()->log(source, lvl, fmt, std::forward(args)...); } -template -inline void log(level::level_enum lvl, const FormatString &fmt, Args &&...args) +template +inline void log(level::level_enum lvl, format_string_t fmt, Args &&...args) { default_logger_raw()->log(source_loc{}, lvl, fmt, std::forward(args)...); } -template -inline void trace(const FormatString &fmt, Args &&...args) +template +inline void trace(format_string_t fmt, Args &&...args) { default_logger_raw()->trace(fmt, std::forward(args)...); } -template -inline void debug(const FormatString &fmt, Args &&...args) +template +inline void debug(format_string_t fmt, Args &&...args) { default_logger_raw()->debug(fmt, std::forward(args)...); } -template -inline void info(const FormatString &fmt, Args &&...args) +template +inline void info(format_string_t fmt, Args &&...args) { default_logger_raw()->info(fmt, std::forward(args)...); } -template -inline void warn(const FormatString &fmt, Args &&...args) +template +inline void warn(format_string_t fmt, Args &&...args) { default_logger_raw()->warn(fmt, std::forward(args)...); } -template -inline void error(const FormatString &fmt, Args &&...args) +template +inline void error(format_string_t fmt, Args &&...args) { default_logger_raw()->error(fmt, std::forward(args)...); } -template -inline void critical(const FormatString &fmt, Args &&...args) +template +inline void critical(format_string_t fmt, Args &&...args) { default_logger_raw()->critical(fmt, std::forward(args)...); } @@ -187,6 +200,56 @@ inline void log(level::level_enum lvl, const T &msg) default_logger_raw()->log(lvl, msg); } +#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT +template +inline void log(source_loc source, level::level_enum lvl, wformat_string_t fmt, Args &&...args) +{ + default_logger_raw()->log(source, lvl, fmt, std::forward(args)...); +} + +template +inline void log(level::level_enum lvl, wformat_string_t fmt, Args &&...args) +{ + default_logger_raw()->log(source_loc{}, lvl, fmt, std::forward(args)...); +} + +template +inline void trace(wformat_string_t fmt, Args &&...args) +{ + default_logger_raw()->trace(fmt, std::forward(args)...); +} + +template +inline void debug(wformat_string_t fmt, Args &&...args) +{ + default_logger_raw()->debug(fmt, std::forward(args)...); +} + +template +inline void info(wformat_string_t fmt, Args &&...args) +{ + default_logger_raw()->info(fmt, std::forward(args)...); +} + +template +inline void warn(wformat_string_t fmt, Args &&...args) +{ + default_logger_raw()->warn(fmt, std::forward(args)...); +} + +template +inline void error(wformat_string_t fmt, Args &&...args) +{ + default_logger_raw()->error(fmt, std::forward(args)...); +} + +template +inline void critical(wformat_string_t fmt, Args &&...args) +{ + default_logger_raw()->critical(fmt, std::forward(args)...); +} +#endif + template inline void trace(const T &msg) { @@ -238,7 +301,12 @@ inline void critical(const T &msg) // SPDLOG_LEVEL_OFF // -#define SPDLOG_LOGGER_CALL(logger, level, ...) (logger)->log(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__) +#ifndef SPDLOG_NO_SOURCE_LOC +# define SPDLOG_LOGGER_CALL(logger, level, ...) \ + (logger)->log(spdlog::source_loc{__FILE__, __LINE__, SPDLOG_FUNCTION}, level, __VA_ARGS__) +#else +# define SPDLOG_LOGGER_CALL(logger, level, ...) (logger)->log(spdlog::source_loc{}, level, __VA_ARGS__) +#endif #if SPDLOG_ACTIVE_LEVEL <= SPDLOG_LEVEL_TRACE # define SPDLOG_LOGGER_TRACE(logger, ...) SPDLOG_LOGGER_CALL(logger, spdlog::level::trace, __VA_ARGS__) diff --git a/Lumos/External/spdlog/include/spdlog/stopwatch.h b/Lumos/External/spdlog/include/spdlog/stopwatch.h index bb976b19c..bea7b8a74 100644 --- a/Lumos/External/spdlog/include/spdlog/stopwatch.h +++ b/Lumos/External/spdlog/include/spdlog/stopwatch.h @@ -4,6 +4,7 @@ #pragma once #include +#include // Stopwatch support for spdlog (using std::chrono::steady_clock). // Displays elapsed seconds since construction as double. @@ -42,20 +43,27 @@ class stopwatch void reset() { - start_tp_ = clock ::now(); + start_tp_ = clock::now(); } }; } // namespace spdlog // Support for fmt formatting (e.g. "{:012.9}" or just "{}") -namespace fmt { +namespace +#ifdef SPDLOG_USE_STD_FORMAT + std +#else + fmt +#endif +{ + template<> struct formatter : formatter { template - auto format(const spdlog::stopwatch &sw, FormatContext &ctx) -> decltype(ctx.out()) + auto format(const spdlog::stopwatch &sw, FormatContext &ctx) const -> decltype(ctx.out()) { return formatter::format(sw.elapsed().count(), ctx); } }; -} // namespace fmt +} // namespace std diff --git a/Lumos/External/spdlog/include/spdlog/tweakme.h b/Lumos/External/spdlog/include/spdlog/tweakme.h index 24361f303..5bcb5ff42 100644 --- a/Lumos/External/spdlog/include/spdlog/tweakme.h +++ b/Lumos/External/spdlog/include/spdlog/tweakme.h @@ -19,6 +19,13 @@ // #define SPDLOG_CLOCK_COARSE /////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// Uncomment if source location logging is not needed. +// This will prevent spdlog from using __FILE__, __LINE__ and SPDLOG_FUNCTION +// +// #define SPDLOG_NO_SOURCE_LOC +/////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////// // Uncomment if thread id logging is not needed (i.e. no %t in the log pattern). // This will prevent spdlog from querying the thread id on each log call. @@ -74,6 +81,12 @@ // #define SPDLOG_FMT_EXTERNAL /////////////////////////////////////////////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////////// +// Uncomment to use C++20 std::format instead of fmt. +// +// #define SPDLOG_USE_STD_FORMAT +/////////////////////////////////////////////////////////////////////////////// + /////////////////////////////////////////////////////////////////////////////// // Uncomment to enable wchar_t support (convert to utf8) // @@ -89,8 +102,7 @@ /////////////////////////////////////////////////////////////////////////////// // Uncomment to customize level names (e.g. "MY TRACE") // -// #define SPDLOG_LEVEL_NAMES { "MY TRACE", "MY DEBUG", "MY INFO", "MY WARNING", -// "MY ERROR", "MY CRITICAL", "OFF" } +// #define SPDLOG_LEVEL_NAMES { "MY TRACE", "MY DEBUG", "MY INFO", "MY WARNING", "MY ERROR", "MY CRITICAL", "OFF" } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// @@ -120,5 +132,9 @@ // __PRETTY_FUNCTION__ might be nicer in clang/gcc, and __FUNCTION__ in msvc. // Defaults to __FUNCTION__ (should work on all compilers) if not defined. // -// #define SPDLOG_FUNCTION __PRETTY_FUNCTION__ +// #ifdef __PRETTY_FUNCTION__ +// # define SPDLOG_FUNCTION __PRETTY_FUNCTION__ +// #else +// # define SPDLOG_FUNCTION __FUNCTION__ +// #endif /////////////////////////////////////////////////////////////////////////////// diff --git a/Lumos/External/spdlog/include/spdlog/version.h b/Lumos/External/spdlog/include/spdlog/version.h index e759a61e7..633cddc78 100644 --- a/Lumos/External/spdlog/include/spdlog/version.h +++ b/Lumos/External/spdlog/include/spdlog/version.h @@ -4,7 +4,7 @@ #pragma once #define SPDLOG_VER_MAJOR 1 -#define SPDLOG_VER_MINOR 9 +#define SPDLOG_VER_MINOR 12 #define SPDLOG_VER_PATCH 0 #define SPDLOG_VERSION (SPDLOG_VER_MAJOR * 10000 + SPDLOG_VER_MINOR * 100 + SPDLOG_VER_PATCH) diff --git a/Lumos/External/spdlog/logos/jetbrains-variant-4.svg b/Lumos/External/spdlog/logos/jetbrains-variant-4.svg new file mode 100644 index 000000000..e02b55951 --- /dev/null +++ b/Lumos/External/spdlog/logos/jetbrains-variant-4.svg @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Lumos/External/spdlog/scripts/ci_setup_clang.sh b/Lumos/External/spdlog/scripts/ci_setup_clang.sh new file mode 100644 index 000000000..140f9f9d0 --- /dev/null +++ b/Lumos/External/spdlog/scripts/ci_setup_clang.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +set -ex + +VERSION=$1 + +apt-get update +apt-get install -y libc++-${VERSION}-dev libc++abi-${VERSION}-dev + +if [[ "${VERSION}" -ge 12 ]]; then + apt-get install -y --no-install-recommends libunwind-${VERSION}-dev +fi diff --git a/Lumos/External/spdlog/scripts/extract_version.py b/Lumos/External/spdlog/scripts/extract_version.py new file mode 100644 index 000000000..79b5728a8 --- /dev/null +++ b/Lumos/External/spdlog/scripts/extract_version.py @@ -0,0 +1,17 @@ +#!/usr/bin/env python3 + +import os +import re + +base_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) +config_h = os.path.join(base_path, 'include', 'spdlog', 'version.h') +data = {'MAJOR': 0, 'MINOR': 0, 'PATCH': 0} +reg = re.compile(r'^\s*#define\s+SPDLOG_VER_([A-Z]+)\s+([0-9]+).*$') + +with open(config_h, 'r') as fp: + for l in fp: + m = reg.match(l) + if m: + data[m.group(1)] = int(m.group(2)) + +print(f"{data['MAJOR']}.{data['MINOR']}.{data['PATCH']}") diff --git a/Lumos/External/spdlog/scripts/format.sh b/Lumos/External/spdlog/scripts/format.sh new file mode 100644 index 000000000..bd5868ebc --- /dev/null +++ b/Lumos/External/spdlog/scripts/format.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +cd "$(dirname "$0")"/.. +pwd +echo -n "Running dos2unix " +find . -name "*\.h" -o -name "*\.cpp"|grep -v bundled|xargs -I {} sh -c "dos2unix '{}' 2>/dev/null; echo -n '.'" +echo +echo -n "Running clang-format " +find . -name "*\.h" -o -name "*\.cpp"|grep -v bundled|xargs -I {} sh -c "clang-format -i {}; echo -n '.'" +echo +echo -n "Running cmake-format " +find . -name "CMakeLists.txt" -o -name "*\.cmake"|grep -v bundled|xargs -I {} sh -c "cmake-format --line-width 120 --tab-size 4 --max-subgroups-hwrap 4 -i {}; echo -n '.'" +echo + + + diff --git a/Lumos/External/spdlog/src/async.cpp b/Lumos/External/spdlog/src/async.cpp index b7443dfc3..5ea8d8f40 100644 --- a/Lumos/External/spdlog/src/async.cpp +++ b/Lumos/External/spdlog/src/async.cpp @@ -9,5 +9,3 @@ #include #include #include - -template class SPDLOG_API spdlog::details::mpmc_blocking_queue; diff --git a/Lumos/External/spdlog/src/bundled_fmtlib_format.cpp b/Lumos/External/spdlog/src/bundled_fmtlib_format.cpp new file mode 100644 index 000000000..933918260 --- /dev/null +++ b/Lumos/External/spdlog/src/bundled_fmtlib_format.cpp @@ -0,0 +1,52 @@ +// Slightly modified version of fmt lib's format.cc (version 1.9.1) source file. +// Copyright (c) 2012 - 2016, Victor Zverovich +// All rights reserved. + +#ifndef SPDLOG_COMPILED_LIB +# error Please define SPDLOG_COMPILED_LIB to compile this file. +#endif + +#if !defined(SPDLOG_FMT_EXTERNAL) && !defined(SPDLOG_USE_STD_FORMAT) + +#include + +FMT_BEGIN_NAMESPACE +namespace detail { + +template FMT_API auto dragonbox::to_decimal(float x) noexcept + -> dragonbox::decimal_fp; +template FMT_API auto dragonbox::to_decimal(double x) noexcept + -> dragonbox::decimal_fp; + +#ifndef FMT_STATIC_THOUSANDS_SEPARATOR +template FMT_API locale_ref::locale_ref(const std::locale& loc); +template FMT_API auto locale_ref::get() const -> std::locale; +#endif + +// Explicit instantiations for char. + +template FMT_API auto thousands_sep_impl(locale_ref) + -> thousands_sep_result; +template FMT_API auto decimal_point_impl(locale_ref) -> char; + +template FMT_API void buffer::append(const char*, const char*); + +// DEPRECATED! +// There is no correspondent extern template in format.h because of +// incompatibility between clang and gcc (#2377). +template FMT_API void vformat_to(buffer&, string_view, + basic_format_args, + locale_ref); + +// Explicit instantiations for wchar_t. + +template FMT_API auto thousands_sep_impl(locale_ref) + -> thousands_sep_result; +template FMT_API auto decimal_point_impl(locale_ref) -> wchar_t; + +template FMT_API void buffer::append(const wchar_t*, const wchar_t*); + +} // namespace detail +FMT_END_NAMESPACE + +#endif // !SPDLOG_FMT_EXTERNAL diff --git a/Lumos/External/spdlog/src/fmt.cpp b/Lumos/External/spdlog/src/fmt.cpp deleted file mode 100644 index b3cd3cf13..000000000 --- a/Lumos/External/spdlog/src/fmt.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// Slightly modified version of fmt lib's format.cc source file. -// Copyright (c) 2012 - 2016, Victor Zverovich -// All rights reserved. - -#ifndef SPDLOG_COMPILED_LIB -# error Please define SPDLOG_COMPILED_LIB to compile this file. -#endif - -#if !defined(SPDLOG_FMT_EXTERNAL) -# include - -FMT_BEGIN_NAMESPACE -namespace detail { - -template -int format_float(char *buf, std::size_t size, const char *format, int precision, T value) -{ -# ifdef FMT_FUZZ - if (precision > 100000) - throw std::runtime_error("fuzz mode - avoid large allocation inside snprintf"); -# endif - // Suppress the warning about nonliteral format string. - int (*snprintf_ptr)(char *, size_t, const char *, ...) = FMT_SNPRINTF; - return precision < 0 ? snprintf_ptr(buf, size, format, value) : snprintf_ptr(buf, size, format, precision, value); -} - -template FMT_API dragonbox::decimal_fp dragonbox::to_decimal(float x) FMT_NOEXCEPT; -template FMT_API dragonbox::decimal_fp dragonbox::to_decimal(double x) FMT_NOEXCEPT; -} // namespace detail - -// Workaround a bug in MSVC2013 that prevents instantiation of format_float. -int (*instantiate_format_float)(double, int, detail::float_specs, detail::buffer &) = detail::format_float; - -# ifndef FMT_STATIC_THOUSANDS_SEPARATOR -template FMT_API detail::locale_ref::locale_ref(const std::locale &loc); -template FMT_API std::locale detail::locale_ref::get() const; -# endif - -// Explicit instantiations for char. - -template FMT_API auto detail::thousands_sep_impl(locale_ref) -> thousands_sep_result; -template FMT_API char detail::decimal_point_impl(locale_ref); - -template FMT_API void detail::buffer::append(const char *, const char *); - -// DEPRECATED! -// There is no correspondent extern template in format.h because of -// incompatibility between clang and gcc (#2377). -template FMT_API void detail::vformat_to( - detail::buffer &, string_view, basic_format_args, detail::locale_ref); - -template FMT_API int detail::snprintf_float(double, int, detail::float_specs, detail::buffer &); -template FMT_API int detail::snprintf_float(long double, int, detail::float_specs, detail::buffer &); -template FMT_API int detail::format_float(double, int, detail::float_specs, detail::buffer &); -template FMT_API int detail::format_float(long double, int, detail::float_specs, detail::buffer &); - -// Explicit instantiations for wchar_t. - -template FMT_API auto detail::thousands_sep_impl(locale_ref) -> thousands_sep_result; -template FMT_API wchar_t detail::decimal_point_impl(locale_ref); - -template FMT_API void detail::buffer::append(const wchar_t *, const wchar_t *); - -template struct detail::basic_data; - -FMT_END_NAMESPACE - -#endif // !SPDLOG_FMT_EXTERNAL diff --git a/Lumos/External/spdlog/tests/CMakeLists.txt b/Lumos/External/spdlog/tests/CMakeLists.txt new file mode 100644 index 000000000..176578ade --- /dev/null +++ b/Lumos/External/spdlog/tests/CMakeLists.txt @@ -0,0 +1,86 @@ +cmake_minimum_required(VERSION 3.10) +project(spdlog_utests CXX) + +if(NOT TARGET spdlog) + # Stand-alone build + find_package(spdlog REQUIRED) +endif() + +include(../cmake/utils.cmake) + +find_package(PkgConfig) +if(PkgConfig_FOUND) + pkg_check_modules(systemd libsystemd) +endif() + +find_package(Catch2 3 QUIET) +if(Catch2_FOUND) + message(STATUS "Packaged version of Catch will be used.") +else() + message(STATUS "Bundled version of Catch will be downloaded and used.") + include(FetchContent) + FetchContent_Declare(Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG v3.3.2) + FetchContent_MakeAvailable(Catch2) +endif() + +set(SPDLOG_UTESTS_SOURCES + test_file_helper.cpp + test_file_logging.cpp + test_daily_logger.cpp + test_misc.cpp + test_eventlog.cpp + test_pattern_formatter.cpp + test_async.cpp + test_registry.cpp + test_macros.cpp + utils.cpp + main.cpp + test_mpmc_q.cpp + test_dup_filter.cpp + test_fmt_helper.cpp + test_stdout_api.cpp + test_backtrace.cpp + test_create_dir.cpp + test_custom_callbacks.cpp + test_cfg.cpp + test_time_point.cpp + test_stopwatch.cpp) + +if(NOT SPDLOG_NO_EXCEPTIONS) + list(APPEND SPDLOG_UTESTS_SOURCES test_errors.cpp) +endif() + +if(systemd_FOUND) + list(APPEND SPDLOG_UTESTS_SOURCES test_systemd.cpp) +endif() + +if(NOT SPDLOG_USE_STD_FORMAT) + list(APPEND SPDLOG_UTESTS_SOURCES test_bin_to_hex.cpp) +endif() + +enable_testing() + +function(spdlog_prepare_test test_target spdlog_lib) + add_executable(${test_target} ${SPDLOG_UTESTS_SOURCES}) + spdlog_enable_warnings(${test_target}) + target_link_libraries(${test_target} PRIVATE ${spdlog_lib}) + if(systemd_FOUND) + target_link_libraries(${test_target} PRIVATE ${systemd_LIBRARIES}) + endif() + target_link_libraries(${test_target} PRIVATE Catch2::Catch2WithMain) + if(SPDLOG_SANITIZE_ADDRESS) + spdlog_enable_sanitizer(${test_target}) + endif() + add_test(NAME ${test_target} COMMAND ${test_target}) + set_tests_properties(${test_target} PROPERTIES RUN_SERIAL ON) +endfunction() + +# The compiled library tests +if(SPDLOG_BUILD_TESTS OR SPDLOG_BUILD_ALL) + spdlog_prepare_test(spdlog-utests spdlog::spdlog) +endif() + +# The header-only library version tests +if(SPDLOG_BUILD_TESTS_HO OR SPDLOG_BUILD_ALL) + spdlog_prepare_test(spdlog-utests-ho spdlog::spdlog_header_only) +endif() diff --git a/Lumos/External/spdlog/tests/includes.h b/Lumos/External/spdlog/tests/includes.h new file mode 100644 index 000000000..6e46992b5 --- /dev/null +++ b/Lumos/External/spdlog/tests/includes.h @@ -0,0 +1,36 @@ +#pragma once + +#if defined(__GNUC__) && __GNUC__ == 12 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // Workaround for GCC 12 +#endif +#include +#if defined(__GNUC__) && __GNUC__ == 12 +# pragma GCC diagnostic pop +#endif + +#include "utils.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SPDLOG_ACTIVE_LEVEL SPDLOG_LEVEL_DEBUG + +#include "spdlog/spdlog.h" +#include "spdlog/async.h" +#include "spdlog/details/fmt_helper.h" +#include "spdlog/sinks/basic_file_sink.h" +#include "spdlog/sinks/daily_file_sink.h" +#include "spdlog/sinks/null_sink.h" +#include "spdlog/sinks/ostream_sink.h" +#include "spdlog/sinks/rotating_file_sink.h" +#include "spdlog/sinks/stdout_color_sinks.h" +#include "spdlog/sinks/msvc_sink.h" +#include "spdlog/pattern_formatter.h" diff --git a/Lumos/External/spdlog/tests/main.cpp b/Lumos/External/spdlog/tests/main.cpp new file mode 100644 index 000000000..c8dca1936 --- /dev/null +++ b/Lumos/External/spdlog/tests/main.cpp @@ -0,0 +1,10 @@ +#if defined(__GNUC__) && __GNUC__ == 12 +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wmaybe-uninitialized" // Workaround for GCC 12 +#endif + +#include + +#if defined(__GNUC__) && __GNUC__ == 12 +# pragma GCC diagnostic pop +#endif diff --git a/Lumos/External/spdlog/tests/test_async.cpp b/Lumos/External/spdlog/tests/test_async.cpp new file mode 100644 index 000000000..06c5c9214 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_async.cpp @@ -0,0 +1,198 @@ +#include "includes.h" +#include "spdlog/async.h" +#include "spdlog/sinks/basic_file_sink.h" +#include "test_sink.h" + +#define TEST_FILENAME "test_logs/async_test.log" + +TEST_CASE("basic async test ", "[async]") +{ + auto test_sink = std::make_shared(); + size_t overrun_counter = 0; + size_t queue_size = 128; + size_t messages = 256; + { + auto tp = std::make_shared(queue_size, 1); + auto logger = std::make_shared("as", test_sink, tp, spdlog::async_overflow_policy::block); + for (size_t i = 0; i < messages; i++) + { + logger->info("Hello message #{}", i); + } + logger->flush(); + overrun_counter = tp->overrun_counter(); + } + REQUIRE(test_sink->msg_counter() == messages); + REQUIRE(test_sink->flush_counter() == 1); + REQUIRE(overrun_counter == 0); +} + +TEST_CASE("discard policy ", "[async]") +{ + auto test_sink = std::make_shared(); + test_sink->set_delay(std::chrono::milliseconds(1)); + size_t queue_size = 4; + size_t messages = 1024; + + auto tp = std::make_shared(queue_size, 1); + auto logger = std::make_shared("as", test_sink, tp, spdlog::async_overflow_policy::overrun_oldest); + for (size_t i = 0; i < messages; i++) + { + logger->info("Hello message"); + } + REQUIRE(test_sink->msg_counter() < messages); + REQUIRE(tp->overrun_counter() > 0); +} + +TEST_CASE("discard policy using factory ", "[async]") +{ + size_t queue_size = 4; + size_t messages = 1024; + spdlog::init_thread_pool(queue_size, 1); + + auto logger = spdlog::create_async_nb("as2"); + auto test_sink = std::static_pointer_cast(logger->sinks()[0]); + test_sink->set_delay(std::chrono::milliseconds(3)); + + for (size_t i = 0; i < messages; i++) + { + logger->info("Hello message"); + } + + REQUIRE(test_sink->msg_counter() < messages); + spdlog::drop_all(); +} + +TEST_CASE("flush", "[async]") +{ + auto test_sink = std::make_shared(); + size_t queue_size = 256; + size_t messages = 256; + { + auto tp = std::make_shared(queue_size, 1); + auto logger = std::make_shared("as", test_sink, tp, spdlog::async_overflow_policy::block); + for (size_t i = 0; i < messages; i++) + { + logger->info("Hello message #{}", i); + } + + logger->flush(); + } + // std::this_thread::sleep_for(std::chrono::milliseconds(250)); + REQUIRE(test_sink->msg_counter() == messages); + REQUIRE(test_sink->flush_counter() == 1); +} + +TEST_CASE("async periodic flush", "[async]") +{ + + auto logger = spdlog::create_async("as"); + auto test_sink = std::static_pointer_cast(logger->sinks()[0]); + + spdlog::flush_every(std::chrono::seconds(1)); + std::this_thread::sleep_for(std::chrono::milliseconds(1700)); + REQUIRE(test_sink->flush_counter() == 1); + spdlog::flush_every(std::chrono::seconds(0)); + spdlog::drop_all(); +} + +TEST_CASE("tp->wait_empty() ", "[async]") +{ + auto test_sink = std::make_shared(); + test_sink->set_delay(std::chrono::milliseconds(5)); + size_t messages = 100; + + auto tp = std::make_shared(messages, 2); + auto logger = std::make_shared("as", test_sink, tp, spdlog::async_overflow_policy::block); + for (size_t i = 0; i < messages; i++) + { + logger->info("Hello message #{}", i); + } + logger->flush(); + tp.reset(); + + REQUIRE(test_sink->msg_counter() == messages); + REQUIRE(test_sink->flush_counter() == 1); +} + +TEST_CASE("multi threads", "[async]") +{ + auto test_sink = std::make_shared(); + size_t queue_size = 128; + size_t messages = 256; + size_t n_threads = 10; + { + auto tp = std::make_shared(queue_size, 1); + auto logger = std::make_shared("as", test_sink, tp, spdlog::async_overflow_policy::block); + + std::vector threads; + for (size_t i = 0; i < n_threads; i++) + { + threads.emplace_back([logger, messages] { + for (size_t j = 0; j < messages; j++) + { + logger->info("Hello message #{}", j); + } + }); + logger->flush(); + } + + for (auto &t : threads) + { + t.join(); + } + } + + REQUIRE(test_sink->msg_counter() == messages * n_threads); + REQUIRE(test_sink->flush_counter() == n_threads); +} + +TEST_CASE("to_file", "[async]") +{ + prepare_logdir(); + size_t messages = 1024; + size_t tp_threads = 1; + spdlog::filename_t filename = SPDLOG_FILENAME_T(TEST_FILENAME); + { + auto file_sink = std::make_shared(filename, true); + auto tp = std::make_shared(messages, tp_threads); + auto logger = std::make_shared("as", std::move(file_sink), std::move(tp)); + + for (size_t j = 0; j < messages; j++) + { + logger->info("Hello message #{}", j); + } + } + + require_message_count(TEST_FILENAME, messages); + auto contents = file_contents(TEST_FILENAME); + using spdlog::details::os::default_eol; + REQUIRE(ends_with(contents, spdlog::fmt_lib::format("Hello message #1023{}", default_eol))); +} + +TEST_CASE("to_file multi-workers", "[async]") +{ + prepare_logdir(); + size_t messages = 1024 * 10; + size_t tp_threads = 10; + spdlog::filename_t filename = SPDLOG_FILENAME_T(TEST_FILENAME); + { + auto file_sink = std::make_shared(filename, true); + auto tp = std::make_shared(messages, tp_threads); + auto logger = std::make_shared("as", std::move(file_sink), std::move(tp)); + + for (size_t j = 0; j < messages; j++) + { + logger->info("Hello message #{}", j); + } + } + require_message_count(TEST_FILENAME, messages); +} + +TEST_CASE("bad_tp", "[async]") +{ + auto test_sink = std::make_shared(); + std::shared_ptr const empty_tp; + auto logger = std::make_shared("as", test_sink, empty_tp); + logger->info("Please throw an exception"); + REQUIRE(test_sink->msg_counter() == 0); +} diff --git a/Lumos/External/spdlog/tests/test_backtrace.cpp b/Lumos/External/spdlog/tests/test_backtrace.cpp new file mode 100644 index 000000000..6cf9ec550 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_backtrace.cpp @@ -0,0 +1,78 @@ +#include "includes.h" +#include "test_sink.h" +#include "spdlog/async.h" + +TEST_CASE("bactrace1", "[bactrace]") +{ + + using spdlog::sinks::test_sink_st; + auto test_sink = std::make_shared(); + size_t backtrace_size = 5; + + spdlog::logger logger("test-backtrace", test_sink); + logger.set_pattern("%v"); + logger.enable_backtrace(backtrace_size); + + logger.info("info message"); + for (int i = 0; i < 100; i++) + logger.debug("debug message {}", i); + + REQUIRE(test_sink->lines().size() == 1); + REQUIRE(test_sink->lines()[0] == "info message"); + + logger.dump_backtrace(); + REQUIRE(test_sink->lines().size() == backtrace_size + 3); + REQUIRE(test_sink->lines()[1] == "****************** Backtrace Start ******************"); + REQUIRE(test_sink->lines()[2] == "debug message 95"); + REQUIRE(test_sink->lines()[3] == "debug message 96"); + REQUIRE(test_sink->lines()[4] == "debug message 97"); + REQUIRE(test_sink->lines()[5] == "debug message 98"); + REQUIRE(test_sink->lines()[6] == "debug message 99"); + REQUIRE(test_sink->lines()[7] == "****************** Backtrace End ********************"); +} + +TEST_CASE("bactrace-empty", "[bactrace]") +{ + using spdlog::sinks::test_sink_st; + auto test_sink = std::make_shared(); + size_t backtrace_size = 5; + + spdlog::logger logger("test-backtrace", test_sink); + logger.set_pattern("%v"); + logger.enable_backtrace(backtrace_size); + logger.dump_backtrace(); + REQUIRE(test_sink->lines().size() == 0); +} + +TEST_CASE("bactrace-async", "[bactrace]") +{ + using spdlog::sinks::test_sink_mt; + auto test_sink = std::make_shared(); + using spdlog::details::os::sleep_for_millis; + + size_t backtrace_size = 5; + + spdlog::init_thread_pool(120, 1); + auto logger = std::make_shared("test-bactrace-async", test_sink, spdlog::thread_pool()); + logger->set_pattern("%v"); + logger->enable_backtrace(backtrace_size); + + logger->info("info message"); + for (int i = 0; i < 100; i++) + logger->debug("debug message {}", i); + + sleep_for_millis(100); + REQUIRE(test_sink->lines().size() == 1); + REQUIRE(test_sink->lines()[0] == "info message"); + + logger->dump_backtrace(); + sleep_for_millis(100); // give time for the async dump to complete + REQUIRE(test_sink->lines().size() == backtrace_size + 3); + REQUIRE(test_sink->lines()[1] == "****************** Backtrace Start ******************"); + REQUIRE(test_sink->lines()[2] == "debug message 95"); + REQUIRE(test_sink->lines()[3] == "debug message 96"); + REQUIRE(test_sink->lines()[4] == "debug message 97"); + REQUIRE(test_sink->lines()[5] == "debug message 98"); + REQUIRE(test_sink->lines()[6] == "debug message 99"); + REQUIRE(test_sink->lines()[7] == "****************** Backtrace End ********************"); +} diff --git a/Lumos/External/spdlog/tests/test_bin_to_hex.cpp b/Lumos/External/spdlog/tests/test_bin_to_hex.cpp new file mode 100644 index 000000000..3c50c74a9 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_bin_to_hex.cpp @@ -0,0 +1,93 @@ +#include "includes.h" +#include "test_sink.h" +#include "spdlog/fmt/bin_to_hex.h" + +TEST_CASE("to_hex", "[to_hex]") +{ + std::ostringstream oss; + auto oss_sink = std::make_shared(oss); + spdlog::logger oss_logger("oss", oss_sink); + + std::vector v{9, 0xa, 0xb, 0xc, 0xff, 0xff}; + oss_logger.info("{}", spdlog::to_hex(v)); + + auto output = oss.str(); + REQUIRE(ends_with(output, "0000: 09 0a 0b 0c ff ff" + std::string(spdlog::details::os::default_eol))); +} + +TEST_CASE("to_hex_upper", "[to_hex]") +{ + std::ostringstream oss; + auto oss_sink = std::make_shared(oss); + spdlog::logger oss_logger("oss", oss_sink); + + std::vector v{9, 0xa, 0xb, 0xc, 0xff, 0xff}; + oss_logger.info("{:X}", spdlog::to_hex(v)); + + auto output = oss.str(); + REQUIRE(ends_with(output, "0000: 09 0A 0B 0C FF FF" + std::string(spdlog::details::os::default_eol))); +} + +TEST_CASE("to_hex_no_delimiter", "[to_hex]") +{ + std::ostringstream oss; + auto oss_sink = std::make_shared(oss); + spdlog::logger oss_logger("oss", oss_sink); + + std::vector v{9, 0xa, 0xb, 0xc, 0xff, 0xff}; + oss_logger.info("{:sX}", spdlog::to_hex(v)); + + auto output = oss.str(); + REQUIRE(ends_with(output, "0000: 090A0B0CFFFF" + std::string(spdlog::details::os::default_eol))); +} + +TEST_CASE("to_hex_show_ascii", "[to_hex]") +{ + std::ostringstream oss; + auto oss_sink = std::make_shared(oss); + spdlog::logger oss_logger("oss", oss_sink); + + std::vector v{9, 0xa, 0xb, 0x41, 0xc, 0x4b, 0xff, 0xff}; + oss_logger.info("{:Xsa}", spdlog::to_hex(v, 8)); + + REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4BFFFF ...A.K.." + std::string(spdlog::details::os::default_eol))); +} + +TEST_CASE("to_hex_different_size_per_line", "[to_hex]") +{ + std::ostringstream oss; + auto oss_sink = std::make_shared(oss); + spdlog::logger oss_logger("oss", oss_sink); + + std::vector v{9, 0xa, 0xb, 0x41, 0xc, 0x4b, 0xff, 0xff}; + + oss_logger.info("{:Xsa}", spdlog::to_hex(v, 10)); + REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4BFFFF ...A.K.." + std::string(spdlog::details::os::default_eol))); + + oss_logger.info("{:Xs}", spdlog::to_hex(v, 10)); + REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4BFFFF" + std::string(spdlog::details::os::default_eol))); + + oss_logger.info("{:Xsa}", spdlog::to_hex(v, 6)); + REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4B ...A.K" + std::string(spdlog::details::os::default_eol) + "0006: FFFF .." + + std::string(spdlog::details::os::default_eol))); + + oss_logger.info("{:Xs}", spdlog::to_hex(v, 6)); + REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4B" + std::string(spdlog::details::os::default_eol) + "0006: FFFF" + + std::string(spdlog::details::os::default_eol))); +} + +TEST_CASE("to_hex_no_ascii", "[to_hex]") +{ + std::ostringstream oss; + auto oss_sink = std::make_shared(oss); + spdlog::logger oss_logger("oss", oss_sink); + + std::vector v{9, 0xa, 0xb, 0x41, 0xc, 0x4b, 0xff, 0xff}; + oss_logger.info("{:Xs}", spdlog::to_hex(v, 8)); + + REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4BFFFF" + std::string(spdlog::details::os::default_eol))); + + oss_logger.info("{:Xsna}", spdlog::to_hex(v, 8)); + + REQUIRE(ends_with(oss.str(), "090A0B410C4BFFFF" + std::string(spdlog::details::os::default_eol))); +} diff --git a/Lumos/External/spdlog/tests/test_cfg.cpp b/Lumos/External/spdlog/tests/test_cfg.cpp new file mode 100644 index 000000000..11aefa208 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_cfg.cpp @@ -0,0 +1,183 @@ + +#include "includes.h" +#include "test_sink.h" + +#include +#include + +using spdlog::cfg::load_argv_levels; +using spdlog::cfg::load_env_levels; +using spdlog::sinks::test_sink_st; + +TEST_CASE("env", "[cfg]") +{ + spdlog::drop("l1"); + auto l1 = spdlog::create("l1"); +#ifdef CATCH_PLATFORM_WINDOWS + _putenv_s("SPDLOG_LEVEL", "l1=warn"); +#else + setenv("SPDLOG_LEVEL", "l1=warn", 1); +#endif + load_env_levels(); + REQUIRE(l1->level() == spdlog::level::warn); + spdlog::set_default_logger(spdlog::create("cfg-default")); + REQUIRE(spdlog::default_logger()->level() == spdlog::level::info); +} + +TEST_CASE("argv1", "[cfg]") +{ + spdlog::drop("l1"); + const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn"}; + load_argv_levels(2, argv); + auto l1 = spdlog::create("l1"); + REQUIRE(l1->level() == spdlog::level::warn); + REQUIRE(spdlog::default_logger()->level() == spdlog::level::info); +} + +TEST_CASE("argv2", "[cfg]") +{ + spdlog::drop("l1"); + const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=warn,trace"}; + load_argv_levels(2, argv); + auto l1 = spdlog::create("l1"); + REQUIRE(l1->level() == spdlog::level::warn); + REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace); +} + +TEST_CASE("argv3", "[cfg]") +{ + spdlog::set_level(spdlog::level::trace); + + spdlog::drop("l1"); + const char *argv[] = {"ignore", "SPDLOG_LEVEL=junk_name=warn"}; + load_argv_levels(2, argv); + auto l1 = spdlog::create("l1"); + REQUIRE(l1->level() == spdlog::level::trace); + REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace); +} + +TEST_CASE("argv4", "[cfg]") +{ + spdlog::set_level(spdlog::level::info); + spdlog::drop("l1"); + const char *argv[] = {"ignore", "SPDLOG_LEVEL=junk"}; + load_argv_levels(2, argv); + auto l1 = spdlog::create("l1"); + REQUIRE(l1->level() == spdlog::level::info); +} + +TEST_CASE("argv5", "[cfg]") +{ + spdlog::set_level(spdlog::level::info); + spdlog::drop("l1"); + const char *argv[] = {"ignore", "ignore", "SPDLOG_LEVEL=l1=warn,trace"}; + load_argv_levels(3, argv); + auto l1 = spdlog::create("l1"); + REQUIRE(l1->level() == spdlog::level::warn); + REQUIRE(spdlog::default_logger()->level() == spdlog::level::trace); + spdlog::set_level(spdlog::level::info); +} + +TEST_CASE("argv6", "[cfg]") +{ + spdlog::set_level(spdlog::level::err); + const char *argv[] = {""}; + load_argv_levels(1, argv); + REQUIRE(spdlog::default_logger()->level() == spdlog::level::err); + spdlog::set_level(spdlog::level::info); +} + +TEST_CASE("argv7", "[cfg]") +{ + spdlog::set_level(spdlog::level::err); + const char *argv[] = {""}; + load_argv_levels(0, argv); + REQUIRE(spdlog::default_logger()->level() == spdlog::level::err); + spdlog::set_level(spdlog::level::info); +} + +TEST_CASE("level-not-set-test1", "[cfg]") +{ + spdlog::drop("l1"); + const char *argv[] = {"ignore", ""}; + load_argv_levels(2, argv); + auto l1 = spdlog::create("l1"); + l1->set_level(spdlog::level::trace); + REQUIRE(l1->level() == spdlog::level::trace); + REQUIRE(spdlog::default_logger()->level() == spdlog::level::info); +} + +TEST_CASE("level-not-set-test2", "[cfg]") +{ + spdlog::drop("l1"); + spdlog::drop("l2"); + const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace"}; + + auto l1 = spdlog::create("l1"); + l1->set_level(spdlog::level::warn); + auto l2 = spdlog::create("l2"); + l2->set_level(spdlog::level::warn); + + load_argv_levels(2, argv); + + REQUIRE(l1->level() == spdlog::level::trace); + REQUIRE(l2->level() == spdlog::level::warn); + REQUIRE(spdlog::default_logger()->level() == spdlog::level::info); +} + +TEST_CASE("level-not-set-test3", "[cfg]") +{ + spdlog::drop("l1"); + spdlog::drop("l2"); + const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace"}; + + load_argv_levels(2, argv); + + auto l1 = spdlog::create("l1"); + auto l2 = spdlog::create("l2"); + + REQUIRE(l1->level() == spdlog::level::trace); + REQUIRE(l2->level() == spdlog::level::info); + REQUIRE(spdlog::default_logger()->level() == spdlog::level::info); +} + +TEST_CASE("level-not-set-test4", "[cfg]") +{ + spdlog::drop("l1"); + spdlog::drop("l2"); + const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=trace,warn"}; + + load_argv_levels(2, argv); + + auto l1 = spdlog::create("l1"); + auto l2 = spdlog::create("l2"); + + REQUIRE(l1->level() == spdlog::level::trace); + REQUIRE(l2->level() == spdlog::level::warn); + REQUIRE(spdlog::default_logger()->level() == spdlog::level::warn); +} + +TEST_CASE("level-not-set-test5", "[cfg]") +{ + spdlog::drop("l1"); + spdlog::drop("l2"); + const char *argv[] = {"ignore", "SPDLOG_LEVEL=l1=junk,warn"}; + + load_argv_levels(2, argv); + + auto l1 = spdlog::create("l1"); + auto l2 = spdlog::create("l2"); + + REQUIRE(l1->level() == spdlog::level::warn); + REQUIRE(l2->level() == spdlog::level::warn); + REQUIRE(spdlog::default_logger()->level() == spdlog::level::warn); +} + +TEST_CASE("restore-to-default", "[cfg]") +{ + spdlog::drop("l1"); + spdlog::drop("l2"); + const char *argv[] = {"ignore", "SPDLOG_LEVEL=info"}; + load_argv_levels(2, argv); + REQUIRE(spdlog::default_logger()->level() == spdlog::level::info); +} diff --git a/Lumos/External/spdlog/tests/test_create_dir.cpp b/Lumos/External/spdlog/tests/test_create_dir.cpp new file mode 100644 index 000000000..f17126bc3 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_create_dir.cpp @@ -0,0 +1,75 @@ +/* + * This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE + */ +#include "includes.h" + +using spdlog::details::os::create_dir; +using spdlog::details::os::path_exists; + +bool try_create_dir(const spdlog::filename_t &path, const spdlog::filename_t &normalized_path) +{ + auto rv = create_dir(path); + REQUIRE(rv == true); + return path_exists(normalized_path); +} + +TEST_CASE("create_dir", "[create_dir]") +{ + prepare_logdir(); + + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/dir1/dir1"), SPDLOG_FILENAME_T("test_logs/dir1/dir1"))); + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/dir1/dir1"), SPDLOG_FILENAME_T("test_logs/dir1/dir1"))); // test existing + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/dir1///dir2//"), SPDLOG_FILENAME_T("test_logs/dir1/dir2"))); + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("./test_logs/dir1/dir3"), SPDLOG_FILENAME_T("test_logs/dir1/dir3"))); + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs/../test_logs/dir1/dir4"), SPDLOG_FILENAME_T("test_logs/dir1/dir4"))); + +#ifdef WIN32 + // test backslash folder separator + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs\\dir1\\dir222"), SPDLOG_FILENAME_T("test_logs\\dir1\\dir222"))); + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs\\dir1\\dir223\\"), SPDLOG_FILENAME_T("test_logs\\dir1\\dir223\\"))); + REQUIRE( + try_create_dir(SPDLOG_FILENAME_T(".\\test_logs\\dir1\\dir2\\dir99\\..\\dir23"), SPDLOG_FILENAME_T("test_logs\\dir1\\dir2\\dir23"))); + REQUIRE(try_create_dir(SPDLOG_FILENAME_T("test_logs\\..\\test_logs\\dir1\\dir5"), SPDLOG_FILENAME_T("test_logs\\dir1\\dir5"))); +#endif +} + +TEST_CASE("create_invalid_dir", "[create_dir]") +{ + REQUIRE(create_dir(SPDLOG_FILENAME_T("")) == false); + REQUIRE(create_dir(spdlog::filename_t{}) == false); +#ifdef __linux__ + REQUIRE(create_dir("/proc/spdlog-utest") == false); +#endif +} + +TEST_CASE("dir_name", "[create_dir]") +{ + using spdlog::details::os::dir_name; + REQUIRE(dir_name(SPDLOG_FILENAME_T("")).empty()); + REQUIRE(dir_name(SPDLOG_FILENAME_T("dir")).empty()); + +#ifdef WIN32 + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\)")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\\\)")) == SPDLOG_FILENAME_T(R"(dir\\)")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\file)")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir/file)")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\file.txt)")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir/file)")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(dir\file.txt\)")) == SPDLOG_FILENAME_T(R"(dir\file.txt)")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(\dir\file.txt)")) == SPDLOG_FILENAME_T(R"(\dir)")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(\\dir\file.txt)")) == SPDLOG_FILENAME_T(R"(\\dir)")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(..\file.txt)")) == SPDLOG_FILENAME_T("..")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(.\file.txt)")) == SPDLOG_FILENAME_T(".")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(c:\\a\b\c\d\file.txt)")) == SPDLOG_FILENAME_T(R"(c:\\a\b\c\d)")); + REQUIRE(dir_name(SPDLOG_FILENAME_T(R"(c://a/b/c/d/file.txt)")) == SPDLOG_FILENAME_T(R"(c://a/b/c/d)")); +#endif + REQUIRE(dir_name(SPDLOG_FILENAME_T("dir/")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("dir///")) == SPDLOG_FILENAME_T("dir//")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("dir/file")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("dir/file.txt")) == SPDLOG_FILENAME_T("dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("dir/file.txt/")) == SPDLOG_FILENAME_T("dir/file.txt")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("/dir/file.txt")) == SPDLOG_FILENAME_T("/dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("//dir/file.txt")) == SPDLOG_FILENAME_T("//dir")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("../file.txt")) == SPDLOG_FILENAME_T("..")); + REQUIRE(dir_name(SPDLOG_FILENAME_T("./file.txt")) == SPDLOG_FILENAME_T(".")); +} diff --git a/Lumos/External/spdlog/tests/test_custom_callbacks.cpp b/Lumos/External/spdlog/tests/test_custom_callbacks.cpp new file mode 100644 index 000000000..78babd790 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_custom_callbacks.cpp @@ -0,0 +1,34 @@ +/* + * This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE + */ +#include "includes.h" +#include "test_sink.h" +#include "spdlog/sinks/callback_sink.h" +#include "spdlog/async.h" +#include "spdlog/common.h" + +TEST_CASE("custom_callback_logger", "[custom_callback_logger]") +{ + std::vector lines; + spdlog::pattern_formatter formatter; + auto callback_logger = std::make_shared([&](const spdlog::details::log_msg &msg) { + spdlog::memory_buf_t formatted; + formatter.format(msg, formatted); + auto eol_len = strlen(spdlog::details::os::default_eol); + lines.emplace_back(formatted.begin(), formatted.end() - eol_len); + }); + std::shared_ptr test_sink(new spdlog::sinks::test_sink_st); + + spdlog::logger logger("test-callback", {callback_logger, test_sink}); + + logger.info("test message 1"); + logger.info("test message 2"); + logger.info("test message 3"); + + std::vector ref_lines = test_sink->lines(); + + REQUIRE(lines[0] == ref_lines[0]); + REQUIRE(lines[1] == ref_lines[1]); + REQUIRE(lines[2] == ref_lines[2]); + spdlog::drop_all(); +} diff --git a/Lumos/External/spdlog/tests/test_daily_logger.cpp b/Lumos/External/spdlog/tests/test_daily_logger.cpp new file mode 100644 index 000000000..82f289416 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_daily_logger.cpp @@ -0,0 +1,183 @@ +/* + * This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE + */ +#include "includes.h" + +#ifdef SPDLOG_USE_STD_FORMAT +using filename_memory_buf_t = std::basic_string; +#else +using filename_memory_buf_t = fmt::basic_memory_buffer; +#endif + +#ifdef SPDLOG_WCHAR_FILENAMES +std::string filename_buf_to_utf8string(const filename_memory_buf_t &w) +{ + spdlog::memory_buf_t buf; + spdlog::details::os::wstr_to_utf8buf(spdlog::wstring_view_t(w.data(), w.size()), buf); + return SPDLOG_BUF_TO_STRING(buf); +} +#else +std::string filename_buf_to_utf8string(const filename_memory_buf_t &w) +{ + return SPDLOG_BUF_TO_STRING(w); +} +#endif + +TEST_CASE("daily_logger with dateonly calculator", "[daily_logger]") +{ + using sink_type = spdlog::sinks::daily_file_sink; + + prepare_logdir(); + + // calculate filename (time based) + spdlog::filename_t basename = SPDLOG_FILENAME_T("test_logs/daily_dateonly"); + std::tm tm = spdlog::details::os::localtime(); + filename_memory_buf_t w; + spdlog::fmt_lib::format_to( + std::back_inserter(w), SPDLOG_FILENAME_T("{}_{:04d}-{:02d}-{:02d}"), basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); + + auto logger = spdlog::create("logger", basename, 0, 0); + for (int i = 0; i < 10; ++i) + { + + logger->info("Test message {}", i); + } + logger->flush(); + + require_message_count(filename_buf_to_utf8string(w), 10); +} + +struct custom_daily_file_name_calculator +{ + static spdlog::filename_t calc_filename(const spdlog::filename_t &basename, const tm &now_tm) + { + filename_memory_buf_t w; + spdlog::fmt_lib::format_to(std::back_inserter(w), SPDLOG_FILENAME_T("{}{:04d}{:02d}{:02d}"), basename, now_tm.tm_year + 1900, + now_tm.tm_mon + 1, now_tm.tm_mday); + + return SPDLOG_BUF_TO_STRING(w); + } +}; + +TEST_CASE("daily_logger with custom calculator", "[daily_logger]") +{ + using sink_type = spdlog::sinks::daily_file_sink; + + prepare_logdir(); + + // calculate filename (time based) + spdlog::filename_t basename = SPDLOG_FILENAME_T("test_logs/daily_dateonly"); + std::tm tm = spdlog::details::os::localtime(); + filename_memory_buf_t w; + spdlog::fmt_lib::format_to( + std::back_inserter(w), SPDLOG_FILENAME_T("{}{:04d}{:02d}{:02d}"), basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday); + + auto logger = spdlog::create("logger", basename, 0, 0); + for (int i = 0; i < 10; ++i) + { + logger->info("Test message {}", i); + } + + logger->flush(); + + require_message_count(filename_buf_to_utf8string(w), 10); +} + +/* + * File name calculations + */ + +TEST_CASE("rotating_file_sink::calc_filename1", "[rotating_file_sink]") +{ + auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename(SPDLOG_FILENAME_T("rotated.txt"), 3); + REQUIRE(filename == SPDLOG_FILENAME_T("rotated.3.txt")); +} + +TEST_CASE("rotating_file_sink::calc_filename2", "[rotating_file_sink]") +{ + auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename(SPDLOG_FILENAME_T("rotated"), 3); + REQUIRE(filename == SPDLOG_FILENAME_T("rotated.3")); +} + +TEST_CASE("rotating_file_sink::calc_filename3", "[rotating_file_sink]") +{ + auto filename = spdlog::sinks::rotating_file_sink_st::calc_filename(SPDLOG_FILENAME_T("rotated.txt"), 0); + REQUIRE(filename == SPDLOG_FILENAME_T("rotated.txt")); +} + +// regex supported only from gcc 4.9 and above +#if defined(_MSC_VER) || !(__GNUC__ <= 4 && __GNUC_MINOR__ < 9) + +# include + +TEST_CASE("daily_file_sink::daily_filename_calculator", "[daily_file_sink]") +{ + // daily_YYYY-MM-DD_hh-mm.txt + auto filename = + spdlog::sinks::daily_filename_calculator::calc_filename(SPDLOG_FILENAME_T("daily.txt"), spdlog::details::os::localtime()); + // date regex based on https://www.regular-expressions.info/dates.html + std::basic_regex re( + SPDLOG_FILENAME_T(R"(^daily_(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])\.txt$)")); + std::match_results match; + REQUIRE(std::regex_match(filename, match, re)); +} +#endif + +TEST_CASE("daily_file_sink::daily_filename_format_calculator", "[daily_file_sink]") +{ + std::tm tm = spdlog::details::os::localtime(); + // example-YYYY-MM-DD.log + auto filename = spdlog::sinks::daily_filename_format_calculator::calc_filename(SPDLOG_FILENAME_T("example-%Y-%m-%d.log"), tm); + + REQUIRE(filename == + spdlog::fmt_lib::format(SPDLOG_FILENAME_T("example-{:04d}-{:02d}-{:02d}.log"), tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday)); +} + +/* Test removal of old files */ +static spdlog::details::log_msg create_msg(std::chrono::seconds offset) +{ + using spdlog::log_clock; + spdlog::details::log_msg msg{"test", spdlog::level::info, "Hello Message"}; + msg.time = log_clock::now() + offset; + return msg; +} + +static void test_rotate(int days_to_run, uint16_t max_days, uint16_t expected_n_files) +{ + using spdlog::log_clock; + using spdlog::details::log_msg; + using spdlog::sinks::daily_file_sink_st; + + prepare_logdir(); + + spdlog::filename_t basename = SPDLOG_FILENAME_T("test_logs/daily_rotate.txt"); + daily_file_sink_st sink{basename, 2, 30, true, max_days}; + + // simulate messages with 24 intervals + + for (int i = 0; i < days_to_run; i++) + { + auto offset = std::chrono::seconds{24 * 3600 * i}; + sink.log(create_msg(offset)); + } + + REQUIRE(count_files("test_logs") == static_cast(expected_n_files)); +} + +TEST_CASE("daily_logger rotate", "[daily_file_sink]") +{ + int days_to_run = 1; + test_rotate(days_to_run, 0, 1); + test_rotate(days_to_run, 1, 1); + test_rotate(days_to_run, 3, 1); + test_rotate(days_to_run, 10, 1); + + days_to_run = 10; + test_rotate(days_to_run, 0, 10); + test_rotate(days_to_run, 1, 1); + test_rotate(days_to_run, 3, 3); + test_rotate(days_to_run, 9, 9); + test_rotate(days_to_run, 10, 10); + test_rotate(days_to_run, 11, 10); + test_rotate(days_to_run, 20, 10); +} diff --git a/Lumos/External/spdlog/tests/test_dup_filter.cpp b/Lumos/External/spdlog/tests/test_dup_filter.cpp new file mode 100644 index 000000000..8ae2ee60a --- /dev/null +++ b/Lumos/External/spdlog/tests/test_dup_filter.cpp @@ -0,0 +1,90 @@ +#include "includes.h" +#include "spdlog/sinks/dup_filter_sink.h" +#include "test_sink.h" + +TEST_CASE("dup_filter_test1", "[dup_filter_sink]") +{ + using spdlog::sinks::dup_filter_sink_st; + using spdlog::sinks::test_sink_mt; + + dup_filter_sink_st dup_sink{std::chrono::seconds{5}}; + auto test_sink = std::make_shared(); + dup_sink.add_sink(test_sink); + + for (int i = 0; i < 10; i++) + { + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); + } + + REQUIRE(test_sink->msg_counter() == 1); +} + +TEST_CASE("dup_filter_test2", "[dup_filter_sink]") +{ + using spdlog::sinks::dup_filter_sink_st; + using spdlog::sinks::test_sink_mt; + + dup_filter_sink_st dup_sink{std::chrono::seconds{0}}; + auto test_sink = std::make_shared(); + dup_sink.add_sink(test_sink); + + for (int i = 0; i < 10; i++) + { + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + } + + REQUIRE(test_sink->msg_counter() == 10); +} + +TEST_CASE("dup_filter_test3", "[dup_filter_sink]") +{ + using spdlog::sinks::dup_filter_sink_st; + using spdlog::sinks::test_sink_mt; + + dup_filter_sink_st dup_sink{std::chrono::seconds{1}}; + auto test_sink = std::make_shared(); + dup_sink.add_sink(test_sink); + + for (int i = 0; i < 10; i++) + { + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2"}); + } + + REQUIRE(test_sink->msg_counter() == 20); +} + +TEST_CASE("dup_filter_test4", "[dup_filter_sink]") +{ + using spdlog::sinks::dup_filter_sink_mt; + using spdlog::sinks::test_sink_mt; + + dup_filter_sink_mt dup_sink{std::chrono::milliseconds{10}}; + auto test_sink = std::make_shared(); + dup_sink.add_sink(test_sink); + + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message"}); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message"}); + REQUIRE(test_sink->msg_counter() == 2); +} + +TEST_CASE("dup_filter_test5", "[dup_filter_sink]") +{ + using spdlog::sinks::dup_filter_sink_mt; + using spdlog::sinks::test_sink_mt; + + dup_filter_sink_mt dup_sink{std::chrono::seconds{5}}; + auto test_sink = std::make_shared(); + test_sink->set_pattern("%v"); + dup_sink.add_sink(test_sink); + + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message1"}); + dup_sink.log(spdlog::details::log_msg{"test", spdlog::level::info, "message2"}); + + REQUIRE(test_sink->msg_counter() == 3); // skip 2 messages but log the "skipped.." message before message2 + REQUIRE(test_sink->lines()[1] == "Skipped 2 duplicate messages.."); +} diff --git a/Lumos/External/spdlog/tests/test_errors.cpp b/Lumos/External/spdlog/tests/test_errors.cpp new file mode 100644 index 000000000..780324822 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_errors.cpp @@ -0,0 +1,124 @@ +/* + * This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE + */ +#include "includes.h" + +#include + +#define SIMPLE_LOG "test_logs/simple_log.txt" +#define SIMPLE_ASYNC_LOG "test_logs/simple_async_log.txt" + +class failing_sink : public spdlog::sinks::base_sink +{ +protected: + void sink_it_(const spdlog::details::log_msg &) final + { + throw std::runtime_error("some error happened during log"); + } + + void flush_() final + { + throw std::runtime_error("some error happened during flush"); + } +}; +struct custom_ex +{}; + +#if !defined(SPDLOG_USE_STD_FORMAT) // std formt doesn't fully support tuntime strings +TEST_CASE("default_error_handler", "[errors]") +{ + prepare_logdir(); + spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG); + + auto logger = spdlog::create("test-error", filename, true); + logger->set_pattern("%v"); + logger->info(SPDLOG_FMT_RUNTIME("Test message {} {}"), 1); + logger->info("Test message {}", 2); + logger->flush(); + using spdlog::details::os::default_eol; + REQUIRE(file_contents(SIMPLE_LOG) == spdlog::fmt_lib::format("Test message 2{}", default_eol)); + REQUIRE(count_lines(SIMPLE_LOG) == 1); +} + +TEST_CASE("custom_error_handler", "[errors]") +{ + prepare_logdir(); + spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG); + auto logger = spdlog::create("logger", filename, true); + logger->flush_on(spdlog::level::info); + logger->set_error_handler([=](const std::string &) { throw custom_ex(); }); + logger->info("Good message #1"); + + REQUIRE_THROWS_AS(logger->info(SPDLOG_FMT_RUNTIME("Bad format msg {} {}"), "xxx"), custom_ex); + logger->info("Good message #2"); + require_message_count(SIMPLE_LOG, 2); +} +#endif + +TEST_CASE("default_error_handler2", "[errors]") +{ + spdlog::drop_all(); + auto logger = spdlog::create("failed_logger"); + logger->set_error_handler([=](const std::string &) { throw custom_ex(); }); + REQUIRE_THROWS_AS(logger->info("Some message"), custom_ex); +} + +TEST_CASE("flush_error_handler", "[errors]") +{ + spdlog::drop_all(); + auto logger = spdlog::create("failed_logger"); + logger->set_error_handler([=](const std::string &) { throw custom_ex(); }); + REQUIRE_THROWS_AS(logger->flush(), custom_ex); +} + +#if !defined(SPDLOG_USE_STD_FORMAT) +TEST_CASE("async_error_handler", "[errors]") +{ + prepare_logdir(); + std::string err_msg("log failed with some msg"); + + spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_ASYNC_LOG); + { + spdlog::init_thread_pool(128, 1); + auto logger = spdlog::create_async("logger", filename, true); + logger->set_error_handler([=](const std::string &) { + std::ofstream ofs("test_logs/custom_err.txt"); + if (!ofs) + { + throw std::runtime_error("Failed open test_logs/custom_err.txt"); + } + ofs << err_msg; + }); + logger->info("Good message #1"); + logger->info(SPDLOG_FMT_RUNTIME("Bad format msg {} {}"), "xxx"); + logger->info("Good message #2"); + spdlog::drop("logger"); // force logger to drain the queue and shutdown + } + spdlog::init_thread_pool(128, 1); + require_message_count(SIMPLE_ASYNC_LOG, 2); + REQUIRE(file_contents("test_logs/custom_err.txt") == err_msg); +} +#endif + +// Make sure async error handler is executed +TEST_CASE("async_error_handler2", "[errors]") +{ + prepare_logdir(); + std::string err_msg("This is async handler error message"); + { + spdlog::details::os::create_dir(SPDLOG_FILENAME_T("test_logs")); + spdlog::init_thread_pool(128, 1); + auto logger = spdlog::create_async("failed_logger"); + logger->set_error_handler([=](const std::string &) { + std::ofstream ofs("test_logs/custom_err2.txt"); + if (!ofs) + throw std::runtime_error("Failed open test_logs/custom_err2.txt"); + ofs << err_msg; + }); + logger->info("Hello failure"); + spdlog::drop("failed_logger"); // force logger to drain the queue and shutdown + } + + spdlog::init_thread_pool(128, 1); + REQUIRE(file_contents("test_logs/custom_err2.txt") == err_msg); +} diff --git a/Lumos/External/spdlog/tests/test_eventlog.cpp b/Lumos/External/spdlog/tests/test_eventlog.cpp new file mode 100644 index 000000000..5253c5a7e --- /dev/null +++ b/Lumos/External/spdlog/tests/test_eventlog.cpp @@ -0,0 +1,71 @@ +#if _WIN32 + +# include "includes.h" +# include "test_sink.h" + +# include "spdlog/sinks/win_eventlog_sink.h" + +static const LPCSTR TEST_SOURCE = "spdlog_test"; + +static void test_single_print(std::function do_log, std::string const &expected_contents, WORD expected_ev_type) +{ + using namespace std::chrono; + do_log(expected_contents); + const auto expected_time_generated = duration_cast(system_clock::now().time_since_epoch()).count(); + + struct handle_t + { + HANDLE handle_; + + ~handle_t() + { + if (handle_) + { + REQUIRE(CloseEventLog(handle_)); + } + } + } event_log{::OpenEventLogA(nullptr, TEST_SOURCE)}; + + REQUIRE(event_log.handle_); + + DWORD read_bytes{}, size_needed{}; + auto ok = ::ReadEventLogA( + event_log.handle_, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 0, &read_bytes, 0, &read_bytes, &size_needed); + REQUIRE(!ok); + REQUIRE(::GetLastError() == ERROR_INSUFFICIENT_BUFFER); + + std::vector record_buffer(size_needed); + PEVENTLOGRECORD record = (PEVENTLOGRECORD)record_buffer.data(); + + ok = ::ReadEventLogA( + event_log.handle_, EVENTLOG_SEQUENTIAL_READ | EVENTLOG_BACKWARDS_READ, 0, record, size_needed, &read_bytes, &size_needed); + REQUIRE(ok); + + REQUIRE(record->NumStrings == 1); + REQUIRE(record->EventType == expected_ev_type); + REQUIRE((expected_time_generated - record->TimeGenerated) <= 3u); + + std::string message_in_log(((char *)record + record->StringOffset)); + REQUIRE(message_in_log == expected_contents + spdlog::details::os::default_eol); +} + +TEST_CASE("eventlog", "[eventlog]") +{ + using namespace spdlog; + + auto test_sink = std::make_shared(TEST_SOURCE); + + spdlog::logger test_logger("eventlog", test_sink); + test_logger.set_level(level::trace); + + test_sink->set_pattern("%v"); + + test_single_print([&test_logger](std::string const &msg) { test_logger.trace(msg); }, "my trace message", EVENTLOG_SUCCESS); + test_single_print([&test_logger](std::string const &msg) { test_logger.debug(msg); }, "my debug message", EVENTLOG_SUCCESS); + test_single_print([&test_logger](std::string const &msg) { test_logger.info(msg); }, "my info message", EVENTLOG_INFORMATION_TYPE); + test_single_print([&test_logger](std::string const &msg) { test_logger.warn(msg); }, "my warn message", EVENTLOG_WARNING_TYPE); + test_single_print([&test_logger](std::string const &msg) { test_logger.error(msg); }, "my error message", EVENTLOG_ERROR_TYPE); + test_single_print([&test_logger](std::string const &msg) { test_logger.critical(msg); }, "my critical message", EVENTLOG_ERROR_TYPE); +} + +#endif //_WIN32 diff --git a/Lumos/External/spdlog/tests/test_file_helper.cpp b/Lumos/External/spdlog/tests/test_file_helper.cpp new file mode 100644 index 000000000..dd3ca4f8a --- /dev/null +++ b/Lumos/External/spdlog/tests/test_file_helper.cpp @@ -0,0 +1,168 @@ +/* + * This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE + */ +#include "includes.h" + +#define TEST_FILENAME "test_logs/file_helper_test.txt" + +using spdlog::details::file_helper; + +static void write_with_helper(file_helper &helper, size_t howmany) +{ + spdlog::memory_buf_t formatted; + spdlog::fmt_lib::format_to(std::back_inserter(formatted), "{}", std::string(howmany, '1')); + helper.write(formatted); + helper.flush(); +} + +TEST_CASE("file_helper_filename", "[file_helper::filename()]") +{ + prepare_logdir(); + + file_helper helper; + spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME); + helper.open(target_filename); + REQUIRE(helper.filename() == target_filename); +} + +TEST_CASE("file_helper_size", "[file_helper::size()]") +{ + prepare_logdir(); + spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME); + size_t expected_size = 123; + { + file_helper helper; + helper.open(target_filename); + write_with_helper(helper, expected_size); + REQUIRE(static_cast(helper.size()) == expected_size); + } + REQUIRE(get_filesize(TEST_FILENAME) == expected_size); +} + +TEST_CASE("file_helper_reopen", "[file_helper::reopen()]") +{ + prepare_logdir(); + spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME); + file_helper helper; + helper.open(target_filename); + write_with_helper(helper, 12); + REQUIRE(helper.size() == 12); + helper.reopen(true); + REQUIRE(helper.size() == 0); +} + +TEST_CASE("file_helper_reopen2", "[file_helper::reopen(false)]") +{ + prepare_logdir(); + spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME); + size_t expected_size = 14; + file_helper helper; + helper.open(target_filename); + write_with_helper(helper, expected_size); + REQUIRE(helper.size() == expected_size); + helper.reopen(false); + REQUIRE(helper.size() == expected_size); +} + +static void test_split_ext(const spdlog::filename_t::value_type *fname, const spdlog::filename_t::value_type *expect_base, + const spdlog::filename_t::value_type *expect_ext) +{ + spdlog::filename_t filename(fname); + spdlog::filename_t expected_base(expect_base); + spdlog::filename_t expected_ext(expect_ext); + + spdlog::filename_t basename; + spdlog::filename_t ext; + std::tie(basename, ext) = file_helper::split_by_extension(filename); + REQUIRE(basename == expected_base); + REQUIRE(ext == expected_ext); +} + +TEST_CASE("file_helper_split_by_extension", "[file_helper::split_by_extension()]") +{ + test_split_ext(SPDLOG_FILENAME_T("mylog.txt"), SPDLOG_FILENAME_T("mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T(".mylog.txt"), SPDLOG_FILENAME_T(".mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T(".mylog"), SPDLOG_FILENAME_T(".mylog"), SPDLOG_FILENAME_T("")); + test_split_ext(SPDLOG_FILENAME_T("/aaa/bb.d/mylog"), SPDLOG_FILENAME_T("/aaa/bb.d/mylog"), SPDLOG_FILENAME_T("")); + test_split_ext(SPDLOG_FILENAME_T("/aaa/bb.d/mylog.txt"), SPDLOG_FILENAME_T("/aaa/bb.d/mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog.txt"), SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog."), SPDLOG_FILENAME_T("aaa/bbb/ccc/mylog."), SPDLOG_FILENAME_T("")); + test_split_ext(SPDLOG_FILENAME_T("aaa/bbb/ccc/.mylog.txt"), SPDLOG_FILENAME_T("aaa/bbb/ccc/.mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T("/aaa/bbb/ccc/mylog.txt"), SPDLOG_FILENAME_T("/aaa/bbb/ccc/mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T("/aaa/bbb/ccc/.mylog"), SPDLOG_FILENAME_T("/aaa/bbb/ccc/.mylog"), SPDLOG_FILENAME_T("")); + test_split_ext(SPDLOG_FILENAME_T("../mylog.txt"), SPDLOG_FILENAME_T("../mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T(".././mylog.txt"), SPDLOG_FILENAME_T(".././mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T(".././mylog.txt/xxx"), SPDLOG_FILENAME_T(".././mylog.txt/xxx"), SPDLOG_FILENAME_T("")); + test_split_ext(SPDLOG_FILENAME_T("/mylog.txt"), SPDLOG_FILENAME_T("/mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T("//mylog.txt"), SPDLOG_FILENAME_T("//mylog"), SPDLOG_FILENAME_T(".txt")); + test_split_ext(SPDLOG_FILENAME_T(""), SPDLOG_FILENAME_T(""), SPDLOG_FILENAME_T("")); + test_split_ext(SPDLOG_FILENAME_T("."), SPDLOG_FILENAME_T("."), SPDLOG_FILENAME_T("")); + test_split_ext(SPDLOG_FILENAME_T("..txt"), SPDLOG_FILENAME_T("."), SPDLOG_FILENAME_T(".txt")); +} + +TEST_CASE("file_event_handlers", "[file_helper]") +{ + enum class flags + { + before_open, + after_open, + before_close, + after_close + }; + prepare_logdir(); + + spdlog::filename_t test_filename = SPDLOG_FILENAME_T(TEST_FILENAME); + // define event handles that update vector of flags when called + std::vector events; + spdlog::file_event_handlers handlers; + handlers.before_open = [&](spdlog::filename_t filename) { + REQUIRE(filename == test_filename); + events.push_back(flags::before_open); + }; + handlers.after_open = [&](spdlog::filename_t filename, std::FILE *fstream) { + REQUIRE(filename == test_filename); + REQUIRE(fstream); + fputs("after_open\n", fstream); + events.push_back(flags::after_open); + }; + handlers.before_close = [&](spdlog::filename_t filename, std::FILE *fstream) { + REQUIRE(filename == test_filename); + REQUIRE(fstream); + fputs("before_close\n", fstream); + events.push_back(flags::before_close); + }; + handlers.after_close = [&](spdlog::filename_t filename) { + REQUIRE(filename == test_filename); + events.push_back(flags::after_close); + }; + { + spdlog::details::file_helper helper{handlers}; + REQUIRE(events.empty()); + + helper.open(test_filename); + REQUIRE(events == std::vector{flags::before_open, flags::after_open}); + + events.clear(); + helper.close(); + REQUIRE(events == std::vector{flags::before_close, flags::after_close}); + REQUIRE(file_contents(TEST_FILENAME) == "after_open\nbefore_close\n"); + + helper.reopen(true); + events.clear(); + } + // make sure that the file_helper destrcutor calls the close callbacks if needed + REQUIRE(events == std::vector{flags::before_close, flags::after_close}); + REQUIRE(file_contents(TEST_FILENAME) == "after_open\nbefore_close\n"); +} + +TEST_CASE("file_helper_open", "[file_helper]") +{ + prepare_logdir(); + spdlog::filename_t target_filename = SPDLOG_FILENAME_T(TEST_FILENAME); + file_helper helper; + helper.open(target_filename); + helper.close(); + + target_filename += SPDLOG_FILENAME_T("/invalid"); + REQUIRE_THROWS_AS(helper.open(target_filename), spdlog::spdlog_ex); +} diff --git a/Lumos/External/spdlog/tests/test_file_logging.cpp b/Lumos/External/spdlog/tests/test_file_logging.cpp new file mode 100644 index 000000000..7a7119ad8 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_file_logging.cpp @@ -0,0 +1,109 @@ +/* + * This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE + */ +#include "includes.h" + +#define SIMPLE_LOG "test_logs/simple_log" +#define ROTATING_LOG "test_logs/rotating_log" + +TEST_CASE("simple_file_logger", "[simple_logger]") +{ + prepare_logdir(); + spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG); + + auto logger = spdlog::create("logger", filename); + logger->set_pattern("%v"); + + logger->info("Test message {}", 1); + logger->info("Test message {}", 2); + + logger->flush(); + require_message_count(SIMPLE_LOG, 2); + using spdlog::details::os::default_eol; + REQUIRE(file_contents(SIMPLE_LOG) == spdlog::fmt_lib::format("Test message 1{}Test message 2{}", default_eol, default_eol)); +} + +TEST_CASE("flush_on", "[flush_on]") +{ + prepare_logdir(); + spdlog::filename_t filename = SPDLOG_FILENAME_T(SIMPLE_LOG); + + auto logger = spdlog::create("logger", filename); + logger->set_pattern("%v"); + logger->set_level(spdlog::level::trace); + logger->flush_on(spdlog::level::info); + logger->trace("Should not be flushed"); + REQUIRE(count_lines(SIMPLE_LOG) == 0); + + logger->info("Test message {}", 1); + logger->info("Test message {}", 2); + + require_message_count(SIMPLE_LOG, 3); + using spdlog::details::os::default_eol; + REQUIRE(file_contents(SIMPLE_LOG) == + spdlog::fmt_lib::format("Should not be flushed{}Test message 1{}Test message 2{}", default_eol, default_eol, default_eol)); +} + +TEST_CASE("rotating_file_logger1", "[rotating_logger]") +{ + prepare_logdir(); + size_t max_size = 1024 * 10; + spdlog::filename_t basename = SPDLOG_FILENAME_T(ROTATING_LOG); + auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 0); + + for (int i = 0; i < 10; ++i) + { + logger->info("Test message {}", i); + } + + logger->flush(); + require_message_count(ROTATING_LOG, 10); +} + +TEST_CASE("rotating_file_logger2", "[rotating_logger]") +{ + prepare_logdir(); + size_t max_size = 1024 * 10; + spdlog::filename_t basename = SPDLOG_FILENAME_T(ROTATING_LOG); + + { + // make an initial logger to create the first output file + auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 2, true); + for (int i = 0; i < 10; ++i) + { + logger->info("Test message {}", i); + } + // drop causes the logger destructor to be called, which is required so the + // next logger can rename the first output file. + spdlog::drop(logger->name()); + } + + auto logger = spdlog::rotating_logger_mt("logger", basename, max_size, 2, true); + for (int i = 0; i < 10; ++i) + { + logger->info("Test message {}", i); + } + + logger->flush(); + + require_message_count(ROTATING_LOG, 10); + + for (int i = 0; i < 1000; i++) + { + + logger->info("Test message {}", i); + } + + logger->flush(); + REQUIRE(get_filesize(ROTATING_LOG) <= max_size); + REQUIRE(get_filesize(ROTATING_LOG ".1") <= max_size); +} + +// test that passing max_size=0 throws +TEST_CASE("rotating_file_logger3", "[rotating_logger]") +{ + prepare_logdir(); + size_t max_size = 0; + spdlog::filename_t basename = SPDLOG_FILENAME_T(ROTATING_LOG); + REQUIRE_THROWS_AS(spdlog::rotating_logger_mt("logger", basename, max_size, 0), spdlog::spdlog_ex); +} diff --git a/Lumos/External/spdlog/tests/test_fmt_helper.cpp b/Lumos/External/spdlog/tests/test_fmt_helper.cpp new file mode 100644 index 000000000..521419024 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_fmt_helper.cpp @@ -0,0 +1,90 @@ + +#include "includes.h" + +using spdlog::memory_buf_t; +using spdlog::details::to_string_view; + +void test_pad2(int n, const char *expected) +{ + memory_buf_t buf; + spdlog::details::fmt_helper::pad2(n, buf); + + REQUIRE(to_string_view(buf) == expected); +} + +void test_pad3(uint32_t n, const char *expected) +{ + memory_buf_t buf; + spdlog::details::fmt_helper::pad3(n, buf); + + REQUIRE(to_string_view(buf) == expected); +} + +void test_pad6(std::size_t n, const char *expected) +{ + memory_buf_t buf; + spdlog::details::fmt_helper::pad6(n, buf); + + REQUIRE(to_string_view(buf) == expected); +} + +void test_pad9(std::size_t n, const char *expected) +{ + memory_buf_t buf; + spdlog::details::fmt_helper::pad9(n, buf); + + REQUIRE(to_string_view(buf) == expected); +} + +TEST_CASE("pad2", "[fmt_helper]") +{ + test_pad2(0, "00"); + test_pad2(3, "03"); + test_pad2(10, "10"); + test_pad2(23, "23"); + test_pad2(99, "99"); + test_pad2(100, "100"); + test_pad2(123, "123"); + test_pad2(1234, "1234"); + test_pad2(-5, "-5"); +} + +TEST_CASE("pad3", "[fmt_helper]") +{ + test_pad3(0, "000"); + test_pad3(3, "003"); + test_pad3(10, "010"); + test_pad3(23, "023"); + test_pad3(99, "099"); + test_pad3(100, "100"); + test_pad3(123, "123"); + test_pad3(999, "999"); + test_pad3(1000, "1000"); + test_pad3(1234, "1234"); +} + +TEST_CASE("pad6", "[fmt_helper]") +{ + test_pad6(0, "000000"); + test_pad6(3, "000003"); + test_pad6(23, "000023"); + test_pad6(123, "000123"); + test_pad6(1234, "001234"); + test_pad6(12345, "012345"); + test_pad6(123456, "123456"); +} + +TEST_CASE("pad9", "[fmt_helper]") +{ + test_pad9(0, "000000000"); + test_pad9(3, "000000003"); + test_pad9(23, "000000023"); + test_pad9(123, "000000123"); + test_pad9(1234, "000001234"); + test_pad9(12345, "000012345"); + test_pad9(123456, "000123456"); + test_pad9(1234567, "001234567"); + test_pad9(12345678, "012345678"); + test_pad9(123456789, "123456789"); + test_pad9(1234567891, "1234567891"); +} diff --git a/Lumos/External/spdlog/tests/test_macros.cpp b/Lumos/External/spdlog/tests/test_macros.cpp new file mode 100644 index 000000000..36537958b --- /dev/null +++ b/Lumos/External/spdlog/tests/test_macros.cpp @@ -0,0 +1,54 @@ +/* + * This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE + */ + +#include "includes.h" + +#if SPDLOG_ACTIVE_LEVEL != SPDLOG_LEVEL_DEBUG +# error "Invalid SPDLOG_ACTIVE_LEVEL in test. Should be SPDLOG_LEVEL_DEBUG" +#endif + +#define TEST_FILENAME "test_logs/simple_log" + +TEST_CASE("debug and trace w/o format string", "[macros]") +{ + + prepare_logdir(); + spdlog::filename_t filename = SPDLOG_FILENAME_T(TEST_FILENAME); + + auto logger = spdlog::create("logger", filename); + logger->set_pattern("%v"); + logger->set_level(spdlog::level::trace); + + SPDLOG_LOGGER_TRACE(logger, "Test message 1"); + SPDLOG_LOGGER_DEBUG(logger, "Test message 2"); + logger->flush(); + + using spdlog::details::os::default_eol; + REQUIRE(ends_with(file_contents(TEST_FILENAME), spdlog::fmt_lib::format("Test message 2{}", default_eol))); + REQUIRE(count_lines(TEST_FILENAME) == 1); + + auto orig_default_logger = spdlog::default_logger(); + spdlog::set_default_logger(logger); + + SPDLOG_TRACE("Test message 3"); + SPDLOG_DEBUG("Test message {}", 4); + logger->flush(); + + require_message_count(TEST_FILENAME, 2); + REQUIRE(ends_with(file_contents(TEST_FILENAME), spdlog::fmt_lib::format("Test message 4{}", default_eol))); + spdlog::set_default_logger(std::move(orig_default_logger)); +} + +TEST_CASE("disable param evaluation", "[macros]") +{ + SPDLOG_TRACE("Test message {}", throw std::runtime_error("Should not be evaluated")); +} + +TEST_CASE("pass logger pointer", "[macros]") +{ + auto logger = spdlog::create("refmacro"); + auto &ref = *logger; + SPDLOG_LOGGER_TRACE(&ref, "Test message 1"); + SPDLOG_LOGGER_DEBUG(&ref, "Test message 2"); +} diff --git a/Lumos/External/spdlog/tests/test_misc.cpp b/Lumos/External/spdlog/tests/test_misc.cpp new file mode 100644 index 000000000..9f3cb1744 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_misc.cpp @@ -0,0 +1,180 @@ +#include "includes.h" +#include "test_sink.h" + +template +std::string log_info(const T &what, spdlog::level::level_enum logger_level = spdlog::level::info) +{ + + std::ostringstream oss; + auto oss_sink = std::make_shared(oss); + + spdlog::logger oss_logger("oss", oss_sink); + oss_logger.set_level(logger_level); + oss_logger.set_pattern("%v"); + oss_logger.info(what); + + return oss.str().substr(0, oss.str().length() - strlen(spdlog::details::os::default_eol)); +} + +TEST_CASE("basic_logging ", "[basic_logging]") +{ + // const char + REQUIRE(log_info("Hello") == "Hello"); + REQUIRE(log_info("").empty()); + + // std::string + REQUIRE(log_info(std::string("Hello")) == "Hello"); + REQUIRE(log_info(std::string()).empty()); + + // Numbers + REQUIRE(log_info(5) == "5"); + REQUIRE(log_info(5.6) == "5.6"); + + // User defined class + // REQUIRE(log_info(some_logged_class("some_val")) == "some_val"); +} + +TEST_CASE("log_levels", "[log_levels]") +{ + REQUIRE(log_info("Hello", spdlog::level::err).empty()); + REQUIRE(log_info("Hello", spdlog::level::critical).empty()); + REQUIRE(log_info("Hello", spdlog::level::info) == "Hello"); + REQUIRE(log_info("Hello", spdlog::level::debug) == "Hello"); + REQUIRE(log_info("Hello", spdlog::level::trace) == "Hello"); +} + +TEST_CASE("level_to_string_view", "[convert_to_string_view") +{ + REQUIRE(spdlog::level::to_string_view(spdlog::level::trace) == "trace"); + REQUIRE(spdlog::level::to_string_view(spdlog::level::debug) == "debug"); + REQUIRE(spdlog::level::to_string_view(spdlog::level::info) == "info"); + REQUIRE(spdlog::level::to_string_view(spdlog::level::warn) == "warning"); + REQUIRE(spdlog::level::to_string_view(spdlog::level::err) == "error"); + REQUIRE(spdlog::level::to_string_view(spdlog::level::critical) == "critical"); + REQUIRE(spdlog::level::to_string_view(spdlog::level::off) == "off"); +} + +TEST_CASE("to_short_c_str", "[convert_to_short_c_str]") +{ + REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::trace)) == "T"); + REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::debug)) == "D"); + REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::info)) == "I"); + REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::warn)) == "W"); + REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::err)) == "E"); + REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::critical)) == "C"); + REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::off)) == "O"); +} + +TEST_CASE("to_level_enum", "[convert_to_level_enum]") +{ + REQUIRE(spdlog::level::from_str("trace") == spdlog::level::trace); + REQUIRE(spdlog::level::from_str("debug") == spdlog::level::debug); + REQUIRE(spdlog::level::from_str("info") == spdlog::level::info); + REQUIRE(spdlog::level::from_str("warning") == spdlog::level::warn); + REQUIRE(spdlog::level::from_str("warn") == spdlog::level::warn); + REQUIRE(spdlog::level::from_str("error") == spdlog::level::err); + REQUIRE(spdlog::level::from_str("critical") == spdlog::level::critical); + REQUIRE(spdlog::level::from_str("off") == spdlog::level::off); + REQUIRE(spdlog::level::from_str("null") == spdlog::level::off); +} + +TEST_CASE("periodic flush", "[periodic_flush]") +{ + using spdlog::sinks::test_sink_mt; + auto logger = spdlog::create("periodic_flush"); + auto test_sink = std::static_pointer_cast(logger->sinks()[0]); + + spdlog::flush_every(std::chrono::seconds(1)); + std::this_thread::sleep_for(std::chrono::milliseconds(1250)); + REQUIRE(test_sink->flush_counter() == 1); + spdlog::flush_every(std::chrono::seconds(0)); + spdlog::drop_all(); +} + +TEST_CASE("clone-logger", "[clone]") +{ + using spdlog::sinks::test_sink_mt; + auto test_sink = std::make_shared(); + auto logger = std::make_shared("orig", test_sink); + logger->set_pattern("%v"); + auto cloned = logger->clone("clone"); + + REQUIRE(cloned->name() == "clone"); + REQUIRE(logger->sinks() == cloned->sinks()); + REQUIRE(logger->level() == cloned->level()); + REQUIRE(logger->flush_level() == cloned->flush_level()); + logger->info("Some message 1"); + cloned->info("Some message 2"); + + REQUIRE(test_sink->lines().size() == 2); + REQUIRE(test_sink->lines()[0] == "Some message 1"); + REQUIRE(test_sink->lines()[1] == "Some message 2"); + + spdlog::drop_all(); +} + +TEST_CASE("clone async", "[clone]") +{ + using spdlog::sinks::test_sink_st; + spdlog::init_thread_pool(4, 1); + auto test_sink = std::make_shared(); + auto logger = std::make_shared("orig", test_sink, spdlog::thread_pool()); + logger->set_pattern("%v"); + auto cloned = logger->clone("clone"); + + REQUIRE(cloned->name() == "clone"); + REQUIRE(logger->sinks() == cloned->sinks()); + REQUIRE(logger->level() == cloned->level()); + REQUIRE(logger->flush_level() == cloned->flush_level()); + + logger->info("Some message 1"); + cloned->info("Some message 2"); + + spdlog::details::os::sleep_for_millis(100); + + REQUIRE(test_sink->lines().size() == 2); + REQUIRE(test_sink->lines()[0] == "Some message 1"); + REQUIRE(test_sink->lines()[1] == "Some message 2"); + + spdlog::drop_all(); +} + +TEST_CASE("default logger API", "[default logger]") +{ + std::ostringstream oss; + auto oss_sink = std::make_shared(oss); + + spdlog::set_default_logger(std::make_shared("oss", oss_sink)); + spdlog::set_pattern("*** %v"); + + spdlog::default_logger()->set_level(spdlog::level::trace); + spdlog::trace("hello trace"); + REQUIRE(oss.str() == "*** hello trace" + std::string(spdlog::details::os::default_eol)); + + oss.str(""); + spdlog::debug("hello debug"); + REQUIRE(oss.str() == "*** hello debug" + std::string(spdlog::details::os::default_eol)); + + oss.str(""); + spdlog::info("Hello"); + REQUIRE(oss.str() == "*** Hello" + std::string(spdlog::details::os::default_eol)); + + oss.str(""); + spdlog::warn("Hello again {}", 2); + REQUIRE(oss.str() == "*** Hello again 2" + std::string(spdlog::details::os::default_eol)); + + oss.str(""); + spdlog::error(123); + REQUIRE(oss.str() == "*** 123" + std::string(spdlog::details::os::default_eol)); + + oss.str(""); + spdlog::critical(std::string("some string")); + REQUIRE(oss.str() == "*** some string" + std::string(spdlog::details::os::default_eol)); + + oss.str(""); + spdlog::set_level(spdlog::level::info); + spdlog::debug("should not be logged"); + REQUIRE(oss.str().empty()); + spdlog::drop_all(); + spdlog::set_pattern("%v"); +} diff --git a/Lumos/External/spdlog/tests/test_mpmc_q.cpp b/Lumos/External/spdlog/tests/test_mpmc_q.cpp new file mode 100644 index 000000000..1540dcc89 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_mpmc_q.cpp @@ -0,0 +1,126 @@ +#include "includes.h" + +using std::chrono::milliseconds; +using test_clock = std::chrono::high_resolution_clock; + +static milliseconds millis_from(const test_clock::time_point &tp0) +{ + return std::chrono::duration_cast(test_clock::now() - tp0); +} +TEST_CASE("dequeue-empty-nowait", "[mpmc_blocking_q]") +{ + size_t q_size = 100; + milliseconds tolerance_wait(20); + spdlog::details::mpmc_blocking_queue q(q_size); + int popped_item = 0; + + auto start = test_clock::now(); + auto rv = q.dequeue_for(popped_item, milliseconds::zero()); + auto delta_ms = millis_from(start); + + REQUIRE(rv == false); + INFO("Delta " << delta_ms.count() << " millis"); + REQUIRE(delta_ms <= tolerance_wait); +} + +TEST_CASE("dequeue-empty-wait", "[mpmc_blocking_q]") +{ + + size_t q_size = 100; + milliseconds wait_ms(250); + milliseconds tolerance_wait(250); + + spdlog::details::mpmc_blocking_queue q(q_size); + int popped_item = 0; + auto start = test_clock::now(); + auto rv = q.dequeue_for(popped_item, wait_ms); + auto delta_ms = millis_from(start); + + REQUIRE(rv == false); + + INFO("Delta " << delta_ms.count() << " millis"); + REQUIRE(delta_ms >= wait_ms - tolerance_wait); + REQUIRE(delta_ms <= wait_ms + tolerance_wait); +} + +TEST_CASE("dequeue-full-nowait", "[mpmc_blocking_q]") +{ + spdlog::details::mpmc_blocking_queue q(1); + q.enqueue(42); + + int item = 0; + q.dequeue_for(item, milliseconds::zero()); + REQUIRE(item == 42); +} + +TEST_CASE("dequeue-full-wait", "[mpmc_blocking_q]") +{ + spdlog::details::mpmc_blocking_queue q(1); + q.enqueue(42); + + int item = 0; + q.dequeue(item); + REQUIRE(item == 42); +} + +TEST_CASE("enqueue_nowait", "[mpmc_blocking_q]") +{ + + size_t q_size = 1; + spdlog::details::mpmc_blocking_queue q(q_size); + milliseconds tolerance_wait(10); + + q.enqueue(1); + REQUIRE(q.overrun_counter() == 0); + + auto start = test_clock::now(); + q.enqueue_nowait(2); + auto delta_ms = millis_from(start); + + INFO("Delta " << delta_ms.count() << " millis"); + REQUIRE(delta_ms <= tolerance_wait); + REQUIRE(q.overrun_counter() == 1); +} + +TEST_CASE("bad_queue", "[mpmc_blocking_q]") +{ + size_t q_size = 0; + spdlog::details::mpmc_blocking_queue q(q_size); + q.enqueue_nowait(1); + REQUIRE(q.overrun_counter() == 1); + int i = 0; + REQUIRE(q.dequeue_for(i, milliseconds(0)) == false); +} + +TEST_CASE("empty_queue", "[mpmc_blocking_q]") +{ + size_t q_size = 10; + spdlog::details::mpmc_blocking_queue q(q_size); + int i = 0; + REQUIRE(q.dequeue_for(i, milliseconds(10)) == false); +} + +TEST_CASE("full_queue", "[mpmc_blocking_q]") +{ + size_t q_size = 100; + spdlog::details::mpmc_blocking_queue q(q_size); + for (int i = 0; i < static_cast(q_size); i++) + { + q.enqueue(i + 0); // i+0 to force rvalue and avoid tidy warnings on the same time if we std::move(i) instead + } + + q.enqueue_nowait(123456); + REQUIRE(q.overrun_counter() == 1); + + for (int i = 1; i < static_cast(q_size); i++) + { + int item = -1; + q.dequeue(item); + REQUIRE(item == i); + } + + // last item pushed has overridden the oldest. + int item = -1; + q.dequeue(item); + REQUIRE(item == 123456); +} diff --git a/Lumos/External/spdlog/tests/test_pattern_formatter.cpp b/Lumos/External/spdlog/tests/test_pattern_formatter.cpp new file mode 100644 index 000000000..bafea8842 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_pattern_formatter.cpp @@ -0,0 +1,501 @@ +#include "includes.h" +#include "test_sink.h" + +using spdlog::memory_buf_t; +using spdlog::details::to_string_view; + +// log to str and return it +template +static std::string log_to_str(const std::string &msg, const Args &...args) +{ + std::ostringstream oss; + auto oss_sink = std::make_shared(oss); + spdlog::logger oss_logger("pattern_tester", oss_sink); + oss_logger.set_level(spdlog::level::info); + + oss_logger.set_formatter(std::unique_ptr(new spdlog::pattern_formatter(args...))); + + oss_logger.info(msg); + return oss.str(); +} + +TEST_CASE("custom eol", "[pattern_formatter]") +{ + std::string msg = "Hello custom eol test"; + std::string eol = ";)"; + REQUIRE(log_to_str(msg, "%v", spdlog::pattern_time_type::local, ";)") == msg + eol); +} + +TEST_CASE("empty format", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "", spdlog::pattern_time_type::local, "").empty()); +} + +TEST_CASE("empty format2", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "", spdlog::pattern_time_type::local, "\n") == "\n"); +} + +TEST_CASE("level", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "[%l] %v", spdlog::pattern_time_type::local, "\n") == "[info] Some message\n"); +} + +TEST_CASE("short level", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "[%L] %v", spdlog::pattern_time_type::local, "\n") == "[I] Some message\n"); +} + +TEST_CASE("name", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "[%n] %v", spdlog::pattern_time_type::local, "\n") == "[pattern_tester] Some message\n"); +} + +TEST_CASE("date MM/DD/YY ", "[pattern_formatter]") +{ + auto now_tm = spdlog::details::os::localtime(); + std::stringstream oss; + oss << std::setfill('0') << std::setw(2) << now_tm.tm_mon + 1 << "/" << std::setw(2) << now_tm.tm_mday << "/" << std::setw(2) + << (now_tm.tm_year + 1900) % 1000 << " Some message\n"; + REQUIRE(log_to_str("Some message", "%D %v", spdlog::pattern_time_type::local, "\n") == oss.str()); +} + +TEST_CASE("color range test1", "[pattern_formatter]") +{ + auto formatter = std::make_shared("%^%v%$", spdlog::pattern_time_type::local, "\n"); + + memory_buf_t buf; + spdlog::fmt_lib::format_to(std::back_inserter(buf), "Hello"); + memory_buf_t formatted; + std::string logger_name = "test"; + spdlog::details::log_msg msg(logger_name, spdlog::level::info, spdlog::string_view_t(buf.data(), buf.size())); + formatter->format(msg, formatted); + REQUIRE(msg.color_range_start == 0); + REQUIRE(msg.color_range_end == 5); + REQUIRE(log_to_str("hello", "%^%v%$", spdlog::pattern_time_type::local, "\n") == "hello\n"); +} + +TEST_CASE("color range test2", "[pattern_formatter]") +{ + auto formatter = std::make_shared("%^%$", spdlog::pattern_time_type::local, "\n"); + std::string logger_name = "test"; + spdlog::details::log_msg msg(logger_name, spdlog::level::info, ""); + memory_buf_t formatted; + formatter->format(msg, formatted); + REQUIRE(msg.color_range_start == 0); + REQUIRE(msg.color_range_end == 0); + REQUIRE(log_to_str("", "%^%$", spdlog::pattern_time_type::local, "\n") == "\n"); +} + +TEST_CASE("color range test3", "[pattern_formatter]") +{ + auto formatter = std::make_shared("%^***%$"); + std::string logger_name = "test"; + spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored"); + memory_buf_t formatted; + formatter->format(msg, formatted); + REQUIRE(msg.color_range_start == 0); + REQUIRE(msg.color_range_end == 3); +} + +TEST_CASE("color range test4", "[pattern_formatter]") +{ + auto formatter = std::make_shared("XX%^YYY%$", spdlog::pattern_time_type::local, "\n"); + std::string logger_name = "test"; + spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored"); + + memory_buf_t formatted; + formatter->format(msg, formatted); + REQUIRE(msg.color_range_start == 2); + REQUIRE(msg.color_range_end == 5); + REQUIRE(log_to_str("ignored", "XX%^YYY%$", spdlog::pattern_time_type::local, "\n") == "XXYYY\n"); +} + +TEST_CASE("color range test5", "[pattern_formatter]") +{ + auto formatter = std::make_shared("**%^"); + std::string logger_name = "test"; + spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored"); + memory_buf_t formatted; + formatter->format(msg, formatted); + REQUIRE(msg.color_range_start == 2); + REQUIRE(msg.color_range_end == 0); +} + +TEST_CASE("color range test6", "[pattern_formatter]") +{ + auto formatter = std::make_shared("**%$"); + std::string logger_name = "test"; + spdlog::details::log_msg msg(logger_name, spdlog::level::info, "ignored"); + memory_buf_t formatted; + formatter->format(msg, formatted); + REQUIRE(msg.color_range_start == 0); + REQUIRE(msg.color_range_end == 2); +} + +// +// Test padding +// + +TEST_CASE("level_left_padded", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "[%8l] %v", spdlog::pattern_time_type::local, "\n") == "[ info] Some message\n"); + REQUIRE(log_to_str("Some message", "[%8!l] %v", spdlog::pattern_time_type::local, "\n") == "[ info] Some message\n"); +} + +TEST_CASE("level_right_padded", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "[%-8l] %v", spdlog::pattern_time_type::local, "\n") == "[info ] Some message\n"); + REQUIRE(log_to_str("Some message", "[%-8!l] %v", spdlog::pattern_time_type::local, "\n") == "[info ] Some message\n"); +} + +TEST_CASE("level_center_padded", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "[%=8l] %v", spdlog::pattern_time_type::local, "\n") == "[ info ] Some message\n"); + REQUIRE(log_to_str("Some message", "[%=8!l] %v", spdlog::pattern_time_type::local, "\n") == "[ info ] Some message\n"); +} + +TEST_CASE("short level_left_padded", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "[%3L] %v", spdlog::pattern_time_type::local, "\n") == "[ I] Some message\n"); + REQUIRE(log_to_str("Some message", "[%3!L] %v", spdlog::pattern_time_type::local, "\n") == "[ I] Some message\n"); +} + +TEST_CASE("short level_right_padded", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "[%-3L] %v", spdlog::pattern_time_type::local, "\n") == "[I ] Some message\n"); + REQUIRE(log_to_str("Some message", "[%-3!L] %v", spdlog::pattern_time_type::local, "\n") == "[I ] Some message\n"); +} + +TEST_CASE("short level_center_padded", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "[%=3L] %v", spdlog::pattern_time_type::local, "\n") == "[ I ] Some message\n"); + REQUIRE(log_to_str("Some message", "[%=3!L] %v", spdlog::pattern_time_type::local, "\n") == "[ I ] Some message\n"); +} + +TEST_CASE("left_padded_short", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "[%3n] %v", spdlog::pattern_time_type::local, "\n") == "[pattern_tester] Some message\n"); + REQUIRE(log_to_str("Some message", "[%3!n] %v", spdlog::pattern_time_type::local, "\n") == "[pat] Some message\n"); +} + +TEST_CASE("right_padded_short", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "[%-3n] %v", spdlog::pattern_time_type::local, "\n") == "[pattern_tester] Some message\n"); + REQUIRE(log_to_str("Some message", "[%-3!n] %v", spdlog::pattern_time_type::local, "\n") == "[pat] Some message\n"); +} + +TEST_CASE("center_padded_short", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "[%=3n] %v", spdlog::pattern_time_type::local, "\n") == "[pattern_tester] Some message\n"); + REQUIRE(log_to_str("Some message", "[%=3!n] %v", spdlog::pattern_time_type::local, "\n") == "[pat] Some message\n"); +} + +TEST_CASE("left_padded_huge", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "[%-300n] %v", spdlog::pattern_time_type::local, "\n") == + "[pattern_tester ] Some message\n"); + + REQUIRE(log_to_str("Some message", "[%-300!n] %v", spdlog::pattern_time_type::local, "\n") == + "[pattern_tester ] Some message\n"); +} + +TEST_CASE("left_padded_max", "[pattern_formatter]") +{ + REQUIRE(log_to_str("Some message", "[%-64n] %v", spdlog::pattern_time_type::local, "\n") == + "[pattern_tester ] Some message\n"); + + REQUIRE(log_to_str("Some message", "[%-64!n] %v", spdlog::pattern_time_type::local, "\n") == + "[pattern_tester ] Some message\n"); +} + +// Test padding + truncate flag + +TEST_CASE("paddinng_truncate", "[pattern_formatter]") +{ + REQUIRE(log_to_str("123456", "%6!v", spdlog::pattern_time_type::local, "\n") == "123456\n"); + REQUIRE(log_to_str("123456", "%5!v", spdlog::pattern_time_type::local, "\n") == "12345\n"); + REQUIRE(log_to_str("123456", "%7!v", spdlog::pattern_time_type::local, "\n") == " 123456\n"); + + REQUIRE(log_to_str("123456", "%-6!v", spdlog::pattern_time_type::local, "\n") == "123456\n"); + REQUIRE(log_to_str("123456", "%-5!v", spdlog::pattern_time_type::local, "\n") == "12345\n"); + REQUIRE(log_to_str("123456", "%-7!v", spdlog::pattern_time_type::local, "\n") == "123456 \n"); + + REQUIRE(log_to_str("123456", "%=6!v", spdlog::pattern_time_type::local, "\n") == "123456\n"); + REQUIRE(log_to_str("123456", "%=5!v", spdlog::pattern_time_type::local, "\n") == "12345\n"); + REQUIRE(log_to_str("123456", "%=7!v", spdlog::pattern_time_type::local, "\n") == "123456 \n"); + + REQUIRE(log_to_str("123456", "%0!v", spdlog::pattern_time_type::local, "\n") == "\n"); +} + +TEST_CASE("padding_truncate_funcname", "[pattern_formatter]") +{ + spdlog::sinks::test_sink_st test_sink; + + const char *pattern = "%v [%5!!]"; + auto formatter = std::unique_ptr(new spdlog::pattern_formatter(pattern)); + test_sink.set_formatter(std::move(formatter)); + + spdlog::details::log_msg msg1{spdlog::source_loc{"ignored", 1, "func"}, "test_logger", spdlog::level::info, "message"}; + test_sink.log(msg1); + REQUIRE(test_sink.lines()[0] == "message [ func]"); + + spdlog::details::log_msg msg2{spdlog::source_loc{"ignored", 1, "function"}, "test_logger", spdlog::level::info, "message"}; + test_sink.log(msg2); + REQUIRE(test_sink.lines()[1] == "message [funct]"); +} + +TEST_CASE("padding_funcname", "[pattern_formatter]") +{ + spdlog::sinks::test_sink_st test_sink; + + const char *pattern = "%v [%10!]"; + auto formatter = std::unique_ptr(new spdlog::pattern_formatter(pattern)); + test_sink.set_formatter(std::move(formatter)); + + spdlog::details::log_msg msg1{spdlog::source_loc{"ignored", 1, "func"}, "test_logger", spdlog::level::info, "message"}; + test_sink.log(msg1); + REQUIRE(test_sink.lines()[0] == "message [ func]"); + + spdlog::details::log_msg msg2{spdlog::source_loc{"ignored", 1, "func567890123"}, "test_logger", spdlog::level::info, "message"}; + test_sink.log(msg2); + REQUIRE(test_sink.lines()[1] == "message [func567890123]"); +} + +TEST_CASE("clone-default-formatter", "[pattern_formatter]") +{ + auto formatter_1 = std::make_shared(); + auto formatter_2 = formatter_1->clone(); + std::string logger_name = "test"; + spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message"); + + memory_buf_t formatted_1; + memory_buf_t formatted_2; + formatter_1->format(msg, formatted_1); + formatter_2->format(msg, formatted_2); + + REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2)); +} + +TEST_CASE("clone-default-formatter2", "[pattern_formatter]") +{ + auto formatter_1 = std::make_shared("%+"); + auto formatter_2 = formatter_1->clone(); + std::string logger_name = "test"; + spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message"); + + memory_buf_t formatted_1; + memory_buf_t formatted_2; + formatter_1->format(msg, formatted_1); + formatter_2->format(msg, formatted_2); + + REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2)); +} + +TEST_CASE("clone-formatter", "[pattern_formatter]") +{ + auto formatter_1 = std::make_shared("%D %X [%] [%n] %v"); + auto formatter_2 = formatter_1->clone(); + std::string logger_name = "test"; + spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message"); + + memory_buf_t formatted_1; + memory_buf_t formatted_2; + formatter_1->format(msg, formatted_1); + formatter_2->format(msg, formatted_2); + + REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2)); +} + +TEST_CASE("clone-formatter-2", "[pattern_formatter]") +{ + using spdlog::pattern_time_type; + auto formatter_1 = std::make_shared("%D %X [%] [%n] %v", pattern_time_type::utc, "xxxxxx\n"); + auto formatter_2 = formatter_1->clone(); + std::string logger_name = "test2"; + spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message"); + + memory_buf_t formatted_1; + memory_buf_t formatted_2; + formatter_1->format(msg, formatted_1); + formatter_2->format(msg, formatted_2); + + REQUIRE(to_string_view(formatted_1) == to_string_view(formatted_2)); +} + +class custom_test_flag : public spdlog::custom_flag_formatter +{ +public: + explicit custom_test_flag(std::string txt) + : some_txt{std::move(txt)} + {} + + void format(const spdlog::details::log_msg &, const std::tm &tm, spdlog::memory_buf_t &dest) override + { + if (some_txt == "throw_me") + { + throw spdlog::spdlog_ex("custom_flag_exception_test"); + } + else if (some_txt == "time") + { + auto formatted = spdlog::fmt_lib::format("{:d}:{:02d}{:s}", tm.tm_hour % 12, tm.tm_min, tm.tm_hour / 12 ? "PM" : "AM"); + dest.append(formatted.data(), formatted.data() + formatted.size()); + return; + } + some_txt = std::string(padinfo_.width_, ' ') + some_txt; + dest.append(some_txt.data(), some_txt.data() + some_txt.size()); + } + spdlog::details::padding_info get_padding_info() + { + return padinfo_; + } + + std::string some_txt; + + std::unique_ptr clone() const override + { + return spdlog::details::make_unique(some_txt); + } +}; +// test clone with custom flag formatters +TEST_CASE("clone-custom_formatter", "[pattern_formatter]") +{ + auto formatter_1 = std::make_shared(); + formatter_1->add_flag('t', "custom_output").set_pattern("[%n] [%t] %v"); + auto formatter_2 = formatter_1->clone(); + std::string logger_name = "logger-name"; + spdlog::details::log_msg msg(logger_name, spdlog::level::info, "some message"); + + memory_buf_t formatted_1; + memory_buf_t formatted_2; + formatter_1->format(msg, formatted_1); + formatter_2->format(msg, formatted_2); + + auto expected = spdlog::fmt_lib::format("[logger-name] [custom_output] some message{}", spdlog::details::os::default_eol); + + REQUIRE(to_string_view(formatted_1) == expected); + REQUIRE(to_string_view(formatted_2) == expected); +} + +// +// Test source location formatting +// + +#ifdef _WIN32 +static const char *const test_path = "\\a\\b\\c/myfile.cpp"; +#else +static const char *const test_path = "/a/b//myfile.cpp"; +#endif + +TEST_CASE("short filename formatter-1", "[pattern_formatter]") +{ + spdlog::pattern_formatter formatter("%s", spdlog::pattern_time_type::local, ""); + memory_buf_t formatted; + std::string logger_name = "logger-name"; + spdlog::source_loc source_loc{test_path, 123, "some_func()"}; + spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello"); + formatter.format(msg, formatted); + + REQUIRE(to_string_view(formatted) == "myfile.cpp"); +} + +TEST_CASE("short filename formatter-2", "[pattern_formatter]") +{ + spdlog::pattern_formatter formatter("%s:%#", spdlog::pattern_time_type::local, ""); + memory_buf_t formatted; + std::string logger_name = "logger-name"; + spdlog::source_loc source_loc{"myfile.cpp", 123, "some_func()"}; + spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello"); + formatter.format(msg, formatted); + + REQUIRE(to_string_view(formatted) == "myfile.cpp:123"); +} + +TEST_CASE("short filename formatter-3", "[pattern_formatter]") +{ + spdlog::pattern_formatter formatter("%s %v", spdlog::pattern_time_type::local, ""); + memory_buf_t formatted; + std::string logger_name = "logger-name"; + spdlog::source_loc source_loc{"", 123, "some_func()"}; + spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello"); + formatter.format(msg, formatted); + + REQUIRE(to_string_view(formatted) == " Hello"); +} + +TEST_CASE("full filename formatter", "[pattern_formatter]") +{ + spdlog::pattern_formatter formatter("%g", spdlog::pattern_time_type::local, ""); + memory_buf_t formatted; + std::string logger_name = "logger-name"; + spdlog::source_loc source_loc{test_path, 123, "some_func()"}; + spdlog::details::log_msg msg(source_loc, "logger-name", spdlog::level::info, "Hello"); + formatter.format(msg, formatted); + + REQUIRE(to_string_view(formatted) == test_path); +} + +TEST_CASE("custom flags", "[pattern_formatter]") +{ + auto formatter = std::make_shared(); + formatter->add_flag('t', "custom1").add_flag('u', "custom2").set_pattern("[%n] [%t] [%u] %v"); + + memory_buf_t formatted; + + spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, "some message"); + formatter->format(msg, formatted); + auto expected = spdlog::fmt_lib::format("[logger-name] [custom1] [custom2] some message{}", spdlog::details::os::default_eol); + + REQUIRE(to_string_view(formatted) == expected); +} + +TEST_CASE("custom flags-padding", "[pattern_formatter]") +{ + auto formatter = std::make_shared(); + formatter->add_flag('t', "custom1").add_flag('u', "custom2").set_pattern("[%n] [%t] [%5u] %v"); + + memory_buf_t formatted; + + spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, "some message"); + formatter->format(msg, formatted); + auto expected = spdlog::fmt_lib::format("[logger-name] [custom1] [ custom2] some message{}", spdlog::details::os::default_eol); + + REQUIRE(to_string_view(formatted) == expected); +} + +TEST_CASE("custom flags-exception", "[pattern_formatter]") +{ + auto formatter = std::make_shared(); + formatter->add_flag('t', "throw_me").add_flag('u', "custom2").set_pattern("[%n] [%t] [%u] %v"); + + memory_buf_t formatted; + spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, "some message"); + CHECK_THROWS_AS(formatter->format(msg, formatted), spdlog::spdlog_ex); +} + +TEST_CASE("override need_localtime", "[pattern_formatter]") +{ + auto formatter = std::make_shared(spdlog::pattern_time_type::local, "\n"); + formatter->add_flag('t', "time").set_pattern("%t> %v"); + + { + memory_buf_t formatted; + spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, "some message"); + formatter->format(msg, formatted); + REQUIRE(to_string_view(formatted) == "0:00AM> some message\n"); + } + + { + formatter->need_localtime(); + + auto now_tm = spdlog::details::os::localtime(); + std::stringstream oss; + oss << (now_tm.tm_hour % 12) << ":" << std::setfill('0') << std::setw(2) << now_tm.tm_min << (now_tm.tm_hour / 12 ? "PM" : "AM") + << "> some message\n"; + + memory_buf_t formatted; + spdlog::details::log_msg msg(spdlog::source_loc{}, "logger-name", spdlog::level::info, "some message"); + formatter->format(msg, formatted); + REQUIRE(to_string_view(formatted) == oss.str()); + } +} diff --git a/Lumos/External/spdlog/tests/test_registry.cpp b/Lumos/External/spdlog/tests/test_registry.cpp new file mode 100644 index 000000000..8e632cc64 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_registry.cpp @@ -0,0 +1,116 @@ +#include "includes.h" + +static const char *const tested_logger_name = "null_logger"; +static const char *const tested_logger_name2 = "null_logger2"; + +#ifndef SPDLOG_NO_EXCEPTIONS +TEST_CASE("register_drop", "[registry]") +{ + spdlog::drop_all(); + spdlog::create(tested_logger_name); + REQUIRE(spdlog::get(tested_logger_name) != nullptr); + // Throw if registering existing name + REQUIRE_THROWS_AS(spdlog::create(tested_logger_name), spdlog::spdlog_ex); +} + +TEST_CASE("explicit register", "[registry]") +{ + spdlog::drop_all(); + auto logger = std::make_shared(tested_logger_name, std::make_shared()); + spdlog::register_logger(logger); + REQUIRE(spdlog::get(tested_logger_name) != nullptr); + // Throw if registering existing name + REQUIRE_THROWS_AS(spdlog::create(tested_logger_name), spdlog::spdlog_ex); +} +#endif + +TEST_CASE("apply_all", "[registry]") +{ + spdlog::drop_all(); + auto logger = std::make_shared(tested_logger_name, std::make_shared()); + spdlog::register_logger(logger); + auto logger2 = std::make_shared(tested_logger_name2, std::make_shared()); + spdlog::register_logger(logger2); + + int counter = 0; + spdlog::apply_all([&counter](std::shared_ptr) { counter++; }); + REQUIRE(counter == 2); + + counter = 0; + spdlog::drop(tested_logger_name2); + spdlog::apply_all([&counter](std::shared_ptr l) { + REQUIRE(l->name() == tested_logger_name); + counter++; + }); + REQUIRE(counter == 1); +} + +TEST_CASE("drop", "[registry]") +{ + spdlog::drop_all(); + spdlog::create(tested_logger_name); + spdlog::drop(tested_logger_name); + REQUIRE_FALSE(spdlog::get(tested_logger_name)); +} + +TEST_CASE("drop-default", "[registry]") +{ + spdlog::set_default_logger(spdlog::null_logger_st(tested_logger_name)); + spdlog::drop(tested_logger_name); + REQUIRE_FALSE(spdlog::default_logger()); + REQUIRE_FALSE(spdlog::get(tested_logger_name)); +} + +TEST_CASE("drop_all", "[registry]") +{ + spdlog::drop_all(); + spdlog::create(tested_logger_name); + spdlog::create(tested_logger_name2); + spdlog::drop_all(); + REQUIRE_FALSE(spdlog::get(tested_logger_name)); + REQUIRE_FALSE(spdlog::get(tested_logger_name2)); + REQUIRE_FALSE(spdlog::default_logger()); +} + +TEST_CASE("drop non existing", "[registry]") +{ + spdlog::drop_all(); + spdlog::create(tested_logger_name); + spdlog::drop("some_name"); + REQUIRE_FALSE(spdlog::get("some_name")); + REQUIRE(spdlog::get(tested_logger_name)); + spdlog::drop_all(); +} + +TEST_CASE("default logger", "[registry]") +{ + spdlog::drop_all(); + spdlog::set_default_logger(spdlog::null_logger_st(tested_logger_name)); + REQUIRE(spdlog::get(tested_logger_name) == spdlog::default_logger()); + spdlog::drop_all(); +} + +TEST_CASE("set_default_logger(nullptr)", "[registry]") +{ + spdlog::set_default_logger(nullptr); + REQUIRE_FALSE(spdlog::default_logger()); +} + +TEST_CASE("disable automatic registration", "[registry]") +{ + // set some global parameters + spdlog::level::level_enum log_level = spdlog::level::level_enum::warn; + spdlog::set_level(log_level); + // but disable automatic registration + spdlog::set_automatic_registration(false); + auto logger1 = spdlog::create(tested_logger_name, SPDLOG_FILENAME_T("filename"), 11, 59); + auto logger2 = spdlog::create_async(tested_logger_name2); + // loggers should not be part of the registry + REQUIRE_FALSE(spdlog::get(tested_logger_name)); + REQUIRE_FALSE(spdlog::get(tested_logger_name2)); + // but make sure they are still initialized according to global defaults + REQUIRE(logger1->level() == log_level); + REQUIRE(logger2->level() == log_level); + spdlog::set_level(spdlog::level::info); + spdlog::set_automatic_registration(true); +} diff --git a/Lumos/External/spdlog/tests/test_sink.h b/Lumos/External/spdlog/tests/test_sink.h new file mode 100644 index 000000000..57db65c10 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_sink.h @@ -0,0 +1,79 @@ +// +// Copyright(c) 2018 Gabi Melman. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +#pragma once + +#include "spdlog/details/null_mutex.h" +#include "spdlog/sinks/base_sink.h" +#include "spdlog/fmt/fmt.h" +#include +#include +#include + +namespace spdlog { +namespace sinks { + +template +class test_sink : public base_sink +{ + const size_t lines_to_save = 100; + +public: + size_t msg_counter() + { + std::lock_guard lock(base_sink::mutex_); + return msg_counter_; + } + + size_t flush_counter() + { + std::lock_guard lock(base_sink::mutex_); + return flush_counter_; + } + + void set_delay(std::chrono::milliseconds delay) + { + std::lock_guard lock(base_sink::mutex_); + delay_ = delay; + } + + // return last output without the eol + std::vector lines() + { + std::lock_guard lock(base_sink::mutex_); + return lines_; + } + +protected: + void sink_it_(const details::log_msg &msg) override + { + memory_buf_t formatted; + base_sink::formatter_->format(msg, formatted); + // save the line without the eol + auto eol_len = strlen(details::os::default_eol); + if (lines_.size() < lines_to_save) + { + lines_.emplace_back(formatted.begin(), formatted.end() - eol_len); + } + msg_counter_++; + std::this_thread::sleep_for(delay_); + } + + void flush_() override + { + flush_counter_++; + } + + size_t msg_counter_{0}; + size_t flush_counter_{0}; + std::chrono::milliseconds delay_{std::chrono::milliseconds::zero()}; + std::vector lines_; +}; + +using test_sink_mt = test_sink; +using test_sink_st = test_sink; + +} // namespace sinks +} // namespace spdlog diff --git a/Lumos/External/spdlog/tests/test_stdout_api.cpp b/Lumos/External/spdlog/tests/test_stdout_api.cpp new file mode 100644 index 000000000..d55223fff --- /dev/null +++ b/Lumos/External/spdlog/tests/test_stdout_api.cpp @@ -0,0 +1,98 @@ +/* + * This content is released under the MIT License as specified in https://raw.githubusercontent.com/gabime/spdlog/master/LICENSE + */ +#include "includes.h" +#include "spdlog/sinks/stdout_sinks.h" +#include "spdlog/sinks/stdout_color_sinks.h" +TEST_CASE("stdout_st", "[stdout]") +{ + auto l = spdlog::stdout_logger_st("test"); + l->set_pattern("%+"); + l->set_level(spdlog::level::trace); + l->trace("Test stdout_st"); + spdlog::drop_all(); +} + +TEST_CASE("stdout_mt", "[stdout]") +{ + auto l = spdlog::stdout_logger_mt("test"); + l->set_pattern("%+"); + l->set_level(spdlog::level::debug); + l->debug("Test stdout_mt"); + spdlog::drop_all(); +} + +TEST_CASE("stderr_st", "[stderr]") +{ + auto l = spdlog::stderr_logger_st("test"); + l->set_pattern("%+"); + l->info("Test stderr_st"); + spdlog::drop_all(); +} + +TEST_CASE("stderr_mt", "[stderr]") +{ + auto l = spdlog::stderr_logger_mt("test"); + l->set_pattern("%+"); + l->info("Test stderr_mt"); + l->warn("Test stderr_mt"); + l->error("Test stderr_mt"); + l->critical("Test stderr_mt"); + spdlog::drop_all(); +} + +// color loggers +TEST_CASE("stdout_color_st", "[stdout]") +{ + auto l = spdlog::stdout_color_st("test"); + l->set_pattern("%+"); + l->info("Test stdout_color_st"); + spdlog::drop_all(); +} + +TEST_CASE("stdout_color_mt", "[stdout]") +{ + auto l = spdlog::stdout_color_mt("test"); + l->set_pattern("%+"); + l->set_level(spdlog::level::trace); + l->trace("Test stdout_color_mt"); + spdlog::drop_all(); +} + +TEST_CASE("stderr_color_st", "[stderr]") +{ + auto l = spdlog::stderr_color_st("test"); + l->set_pattern("%+"); + l->set_level(spdlog::level::debug); + l->debug("Test stderr_color_st"); + spdlog::drop_all(); +} + +TEST_CASE("stderr_color_mt", "[stderr]") +{ + auto l = spdlog::stderr_color_mt("test"); + l->set_pattern("%+"); + l->info("Test stderr_color_mt"); + l->warn("Test stderr_color_mt"); + l->error("Test stderr_color_mt"); + l->critical("Test stderr_color_mt"); + spdlog::drop_all(); +} + +#ifdef SPDLOG_WCHAR_TO_UTF8_SUPPORT + +TEST_CASE("wchar_api", "[stdout]") +{ + auto l = spdlog::stdout_logger_st("wchar_logger"); + l->set_pattern("%+"); + l->set_level(spdlog::level::trace); + l->trace(L"Test wchar_api"); + l->trace(L"Test wchar_api {}", L"param"); + l->trace(L"Test wchar_api {}", 1); + l->trace(L"Test wchar_api {}", std::wstring{L"wstring param"}); + l->trace(std::wstring{L"Test wchar_api wstring"}); + SPDLOG_LOGGER_DEBUG(l, L"Test SPDLOG_LOGGER_DEBUG {}", L"param"); + spdlog::drop_all(); +} + +#endif diff --git a/Lumos/External/spdlog/tests/test_stopwatch.cpp b/Lumos/External/spdlog/tests/test_stopwatch.cpp new file mode 100644 index 000000000..81827b87e --- /dev/null +++ b/Lumos/External/spdlog/tests/test_stopwatch.cpp @@ -0,0 +1,44 @@ +#include "includes.h" +#include "test_sink.h" +#include "spdlog/stopwatch.h" + +TEST_CASE("stopwatch1", "[stopwatch]") +{ + using std::chrono::milliseconds; + using clock = std::chrono::steady_clock; + milliseconds wait_ms(200); + milliseconds tolerance_ms(250); + auto start = clock::now(); + spdlog::stopwatch sw; + std::this_thread::sleep_for(wait_ms); + auto stop = clock::now(); + auto diff_ms = std::chrono::duration_cast(stop - start); + REQUIRE(sw.elapsed() >= diff_ms); + REQUIRE(sw.elapsed() <= diff_ms + tolerance_ms); +} + +TEST_CASE("stopwatch2", "[stopwatch]") +{ + using spdlog::sinks::test_sink_st; + using std::chrono::duration_cast; + using std::chrono::milliseconds; + using clock = std::chrono::steady_clock; + + clock::duration wait_duration(milliseconds(200)); + clock::duration tolerance_duration(milliseconds(250)); + + auto test_sink = std::make_shared(); + + auto start = clock::now(); + spdlog::stopwatch sw; + spdlog::logger logger("test-stopwatch", test_sink); + logger.set_pattern("%v"); + std::this_thread::sleep_for(wait_duration); + auto stop = clock::now(); + logger.info("{}", sw); + auto val = std::stod(test_sink->lines()[0]); + auto diff_duration = duration_cast>(stop - start); + + REQUIRE(val >= (diff_duration).count() - 0.001); + REQUIRE(val <= (diff_duration + tolerance_duration).count()); +} diff --git a/Lumos/External/spdlog/tests/test_systemd.cpp b/Lumos/External/spdlog/tests/test_systemd.cpp new file mode 100644 index 000000000..8688f41d5 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_systemd.cpp @@ -0,0 +1,15 @@ +#include "includes.h" +#include "spdlog/sinks/systemd_sink.h" + +TEST_CASE("systemd", "[all]") +{ + auto systemd_sink = std::make_shared(); + spdlog::logger logger("spdlog_systemd_test", systemd_sink); + logger.set_level(spdlog::level::trace); + logger.trace("test spdlog trace"); + logger.debug("test spdlog debug"); + SPDLOG_LOGGER_INFO((&logger), "test spdlog info"); + SPDLOG_LOGGER_WARN((&logger), "test spdlog warn"); + SPDLOG_LOGGER_ERROR((&logger), "test spdlog error"); + SPDLOG_LOGGER_CRITICAL((&logger), "test spdlog critical"); +} diff --git a/Lumos/External/spdlog/tests/test_time_point.cpp b/Lumos/External/spdlog/tests/test_time_point.cpp new file mode 100644 index 000000000..bacff69a4 --- /dev/null +++ b/Lumos/External/spdlog/tests/test_time_point.cpp @@ -0,0 +1,36 @@ +#include "includes.h" +#include "test_sink.h" +#include "spdlog/async.h" + +TEST_CASE("time_point1", "[time_point log_msg]") +{ + std::shared_ptr test_sink(new spdlog::sinks::test_sink_st); + spdlog::logger logger("test-time_point", test_sink); + + spdlog::source_loc source{}; + std::chrono::system_clock::time_point tp{std::chrono::system_clock::now()}; + test_sink->set_pattern("%T.%F"); // interested in the time_point + + // all the following should have the same time + test_sink->set_delay(std::chrono::milliseconds(10)); + for (int i = 0; i < 5; i++) + { + spdlog::details::log_msg msg{tp, source, "test_logger", spdlog::level::info, "message"}; + test_sink->log(msg); + } + + logger.log(tp, source, spdlog::level::info, "formatted message"); + logger.log(tp, source, spdlog::level::info, "formatted message"); + logger.log(tp, source, spdlog::level::info, "formatted message"); + logger.log(tp, source, spdlog::level::info, "formatted message"); + logger.log(source, spdlog::level::info, "formatted message"); // last line has different time_point + + // now the real test... that the times are the same. + std::vector lines = test_sink->lines(); + REQUIRE(lines[0] == lines[1]); + REQUIRE(lines[2] == lines[3]); + REQUIRE(lines[4] == lines[5]); + REQUIRE(lines[6] == lines[7]); + REQUIRE(lines[8] != lines[9]); + spdlog::drop_all(); +} diff --git a/Lumos/External/spdlog/tests/utils.cpp b/Lumos/External/spdlog/tests/utils.cpp new file mode 100644 index 000000000..6d027797b --- /dev/null +++ b/Lumos/External/spdlog/tests/utils.cpp @@ -0,0 +1,127 @@ +#include "includes.h" + +#ifdef _WIN32 +# include +#else +# include +# include +#endif + +void prepare_logdir() +{ + spdlog::drop_all(); +#ifdef _WIN32 + system("rmdir /S /Q test_logs"); +#else + auto rv = system("rm -rf test_logs"); + if (rv != 0) + { + throw std::runtime_error("Failed to rm -rf test_logs"); + } +#endif +} + +std::string file_contents(const std::string &filename) +{ + std::ifstream ifs(filename, std::ios_base::binary); + if (!ifs) + { + throw std::runtime_error("Failed open file "); + } + return std::string((std::istreambuf_iterator(ifs)), (std::istreambuf_iterator())); +} + +std::size_t count_lines(const std::string &filename) +{ + std::ifstream ifs(filename); + if (!ifs) + { + throw std::runtime_error("Failed open file "); + } + + std::string line; + size_t counter = 0; + while (std::getline(ifs, line)) + counter++; + return counter; +} + +void require_message_count(const std::string &filename, const std::size_t messages) +{ + if (strlen(spdlog::details::os::default_eol) == 0) + { + REQUIRE(count_lines(filename) == 1); + } + else + { + REQUIRE(count_lines(filename) == messages); + } +} + +std::size_t get_filesize(const std::string &filename) +{ + std::ifstream ifs(filename, std::ifstream::ate | std::ifstream::binary); + if (!ifs) + { + throw std::runtime_error("Failed open file "); + } + + return static_cast(ifs.tellg()); +} + +// source: https://stackoverflow.com/a/2072890/192001 +bool ends_with(std::string const &value, std::string const &ending) +{ + if (ending.size() > value.size()) + { + return false; + } + return std::equal(ending.rbegin(), ending.rend(), value.rbegin()); +} + +#ifdef _WIN32 +// Based on: https://stackoverflow.com/a/37416569/192001 +std::size_t count_files(const std::string &folder) +{ + size_t counter = 0; + WIN32_FIND_DATAA ffd; + + // Start iterating over the files in the folder directory. + HANDLE hFind = ::FindFirstFileA((folder + "\\*").c_str(), &ffd); + if (hFind != INVALID_HANDLE_VALUE) + { + do // Managed to locate and create an handle to that folder. + { + if (ffd.cFileName[0] != '.') + counter++; + } while (::FindNextFileA(hFind, &ffd) != 0); + ::FindClose(hFind); + } + else + { + throw std::runtime_error("Failed open folder " + folder); + } + + return counter; +} +#else +// Based on: https://stackoverflow.com/a/2802255/192001 +std::size_t count_files(const std::string &folder) +{ + size_t counter = 0; + DIR *dp = opendir(folder.c_str()); + if (dp == nullptr) + { + throw std::runtime_error("Failed open folder " + folder); + } + + struct dirent *ep = nullptr; + while ((ep = readdir(dp)) != nullptr) + { + if (ep->d_name[0] != '.') + counter++; + } + (void)closedir(dp); + return counter; +} +#endif diff --git a/Lumos/External/spdlog/tests/utils.h b/Lumos/External/spdlog/tests/utils.h new file mode 100644 index 000000000..53c09b469 --- /dev/null +++ b/Lumos/External/spdlog/tests/utils.h @@ -0,0 +1,18 @@ +#pragma once + +#include +#include + +std::size_t count_files(const std::string &folder); + +void prepare_logdir(); + +std::string file_contents(const std::string &filename); + +std::size_t count_lines(const std::string &filename); + +void require_message_count(const std::string &filename, const std::size_t messages); + +std::size_t get_filesize(const std::string &filename); + +bool ends_with(std::string const &value, std::string const &ending); \ No newline at end of file diff --git a/Lumos/Source/Lumos/Core/CommandLine.h b/Lumos/Source/Lumos/Core/CommandLine.h index a19dfc746..914fe134a 100644 --- a/Lumos/Source/Lumos/Core/CommandLine.h +++ b/Lumos/Source/Lumos/Core/CommandLine.h @@ -20,7 +20,7 @@ namespace Lumos { NONE = 0, REQUIRE = 1, - OPTIONAL = 2 + OPT = 2 }; #if 0 struct option_t diff --git a/Lumos/Source/Lumos/Core/OS/Allocators/PoolAllocator.h b/Lumos/Source/Lumos/Core/OS/Allocators/PoolAllocator.h new file mode 100644 index 000000000..1d11b24b1 --- /dev/null +++ b/Lumos/Source/Lumos/Core/OS/Allocators/PoolAllocator.h @@ -0,0 +1,97 @@ +#pragma once +#include "Memory.h" + +namespace Lumos +{ +// Pool Allocator +template +class PoolAllocator +{ + public: + explicit PoolAllocator(Arena* arena = nullptr, size_t poolSize = Megabytes(50)) + : m_Arena(arena) + , m_PoolSize(poolSize) + , m_NextAvailable(nullptr) + { + if(!arena) + { + m_ArenaOwned = true; + m_Arena = ArenaAlloc(Megabytes(51)); + } + + assert(m_Arena); + assert(m_PoolSize >= sizeof(Node)); + + m_AlignSize = (sizeof(T) + alignof(T) - 1) & ~(alignof(T) - 1); + + // Calculate the number of elements that fit in a pool + m_ElementsPerPool = (m_PoolSize - sizeof(Node)) / m_AlignSize; + + AllocateNewPool(); + } + + ~PoolAllocator() + { + while(m_HeadPool) + { + Node* nextPool = m_HeadPool->next; + m_Arena->Position = reinterpret_cast(m_HeadPool); + m_HeadPool = nextPool; + } + + if(m_ArenaOwned) + ArenaRelease(m_Arena); + } + + T* Allocate() + { + if(!m_NextAvailable) + { + AllocateNewPool(); + } + + Node* node = m_NextAvailable; + m_NextAvailable = m_NextAvailable->next; + + return reinterpret_cast(node); + } + + void Deallocate(T* ptr) + { + Node* node = reinterpret_cast(ptr); + node->next = m_NextAvailable; + m_NextAvailable = node; + } + + private: + struct Node + { + Node* next; + }; + + Arena* m_Arena; + size_t m_PoolSize; + size_t m_AlignSize; + size_t m_ElementsPerPool; + Node* m_HeadPool; + Node* m_NextAvailable; + bool m_ArenaOwned = false; + + void AllocateNewPool() + { + void* poolMemory = ArenaPush(m_Arena, m_PoolSize); + Node* pool = reinterpret_cast(poolMemory); + m_HeadPool = pool; + + // Create the linked list of available nodes in the pool + for(size_t i = 0; i < m_ElementsPerPool - 1; ++i) + { + pool->next = reinterpret_cast(reinterpret_cast(pool) + m_AlignSize); + pool = pool->next; + } + + pool->next = nullptr; + m_NextAvailable = m_HeadPool; + } +}; +} \ No newline at end of file diff --git a/Lumos/Source/Lumos/Core/OS/Memory.h b/Lumos/Source/Lumos/Core/OS/Memory.h index deddaedb7..b44593018 100644 --- a/Lumos/Source/Lumos/Core/OS/Memory.h +++ b/Lumos/Source/Lumos/Core/OS/Memory.h @@ -55,99 +55,6 @@ namespace Lumos #define ArenaTempBlock(arena, name) \ ArenaTemp name = { 0 }; \ DeferLoop(name = ArenaTempBegin(arena), ArenaTempEnd(name)) - - // Pool Allocator - template - class PoolAllocator - { - public: - explicit PoolAllocator(Arena* arena = nullptr, size_t poolSize = Megabytes(50)) - : m_Arena(arena) - , m_PoolSize(poolSize) - , m_NextAvailable(nullptr) - { - if(!arena) - { - m_ArenaOwned = true; - m_Arena = ArenaAlloc(Megabytes(51)); - } - - assert(m_Arena); - assert(m_PoolSize >= sizeof(Node)); - - m_AlignSize = (sizeof(T) + alignof(T) - 1) & ~(alignof(T) - 1); - - // Calculate the number of elements that fit in a pool - m_ElementsPerPool = (m_PoolSize - sizeof(Node)) / m_AlignSize; - - AllocateNewPool(); - } - - ~PoolAllocator() - { - while(m_HeadPool) - { - Node* nextPool = m_HeadPool->next; - m_Arena->Position = reinterpret_cast(m_HeadPool); - m_HeadPool = nextPool; - } - - if(m_ArenaOwned) - ArenaRelease(m_Arena); - } - - T* Allocate() - { - if(!m_NextAvailable) - { - AllocateNewPool(); - } - - Node* node = m_NextAvailable; - m_NextAvailable = m_NextAvailable->next; - - return reinterpret_cast(node); - } - - void Deallocate(T* ptr) - { - Node* node = reinterpret_cast(ptr); - node->next = m_NextAvailable; - m_NextAvailable = node; - } - - private: - struct Node - { - Node* next; - }; - - Arena* m_Arena; - size_t m_PoolSize; - size_t m_AlignSize; - size_t m_ElementsPerPool; - Node* m_HeadPool; - Node* m_NextAvailable; - bool m_ArenaOwned = false; - - void AllocateNewPool() - { - void* poolMemory = ArenaPush(m_Arena, m_PoolSize); - Node* pool = reinterpret_cast(poolMemory); - m_HeadPool = pool; - - // Create the linked list of available nodes in the pool - for(size_t i = 0; i < m_ElementsPerPool - 1; ++i) - { - pool->next = reinterpret_cast(reinterpret_cast(pool) + m_AlignSize); - pool = pool->next; - } - - pool->next = nullptr; - m_NextAvailable = m_HeadPool; - } - }; - } #define CUSTOM_MEMORY_ALLOCATOR diff --git a/Lumos/Source/Lumos/Core/OS/Window.h b/Lumos/Source/Lumos/Core/OS/Window.h index 5b4b69181..63b690911 100644 --- a/Lumos/Source/Lumos/Core/OS/Window.h +++ b/Lumos/Source/Lumos/Core/OS/Window.h @@ -1,10 +1,13 @@ #pragma once +#include "Core/Reference.h" #include "Events/Event.h" #include "Graphics/RHI/SwapChain.h" #include "Graphics/RHI/GraphicsContext.h" #include #include +#include +#include namespace Lumos { diff --git a/Lumos/Source/Lumos/Graphics/Camera/Camera.cpp b/Lumos/Source/Lumos/Graphics/Camera/Camera.cpp index e51a56281..7d23fd9ef 100644 --- a/Lumos/Source/Lumos/Graphics/Camera/Camera.cpp +++ b/Lumos/Source/Lumos/Graphics/Camera/Camera.cpp @@ -104,14 +104,14 @@ namespace Lumos if(flipY) y *= -1.0f; - glm::vec4 near = viewProjInverse * glm::vec4(x, y, 0.0f, 1.0f); - near /= near.w; + glm::vec4 n = viewProjInverse * glm::vec4(x, y, 0.0f, 1.0f); + n /= n.w; - glm::vec4 far = viewProjInverse * glm::vec4(x, y, 1.0f, 1.0f); - far /= far.w; + glm::vec4 f = viewProjInverse * glm::vec4(x, y, 1.0f, 1.0f); + f /= f.w; - ret.Origin = glm::vec3(near); - ret.Direction = glm::normalize(glm::vec3(far) - ret.Origin); + ret.Origin = glm::vec3(n); + ret.Direction = glm::normalize(glm::vec3(f) - ret.Origin); return ret; } diff --git a/Lumos/Source/Lumos/Graphics/ModelLoader/GLTFLoader.cpp b/Lumos/Source/Lumos/Graphics/ModelLoader/GLTFLoader.cpp index 08795ad0d..734064435 100644 --- a/Lumos/Source/Lumos/Graphics/ModelLoader/GLTFLoader.cpp +++ b/Lumos/Source/Lumos/Graphics/ModelLoader/GLTFLoader.cpp @@ -320,8 +320,8 @@ namespace Lumos::Graphics Maths::Vector3Simple* normals = reinterpret_cast(data.data()); for(auto p = 0; p < normalCount; ++p) { - vertices[p].Normal = (parentTransform.GetWorldMatrix() * Maths::ToVector4(normals[p])); - + //vertices[p].Normal = (parentTransform.GetWorldMatrix() * Maths::ToVector4(normals[p])); + vertices[p].Normal = glm::transpose(glm::inverse(glm::mat3(parentTransform.GetWorldMatrix()))) * (glm::vec3(Maths::ToVector4(normals[p]))); vertices[p].Normal = glm::normalize(vertices[p].Normal); } } diff --git a/Lumos/Source/Lumos/Graphics/RHI/Definitions.h b/Lumos/Source/Lumos/Graphics/RHI/Definitions.h index 6c2816518..000305d47 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/Definitions.h +++ b/Lumos/Source/Lumos/Graphics/RHI/Definitions.h @@ -1,4 +1,6 @@ #pragma once +#include "Core/LMLog.h" +#include namespace Lumos { diff --git a/Lumos/Source/Lumos/Graphics/RHI/Renderer.cpp b/Lumos/Source/Lumos/Graphics/RHI/Renderer.cpp index 2dda2fdb7..db65c3780 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/Renderer.cpp +++ b/Lumos/Source/Lumos/Graphics/RHI/Renderer.cpp @@ -152,6 +152,9 @@ namespace Lumos } } + GraphicsContext* Renderer::GetGraphicsContext() { return Application::Get().GetWindow()->GetGraphicsContext(); } + SwapChain* Renderer::GetMainSwapChain() { return Application::Get().GetWindow()->GetSwapChain(); } + void Renderer::DrawMesh(CommandBuffer* commandBuffer, Graphics::Pipeline* pipeline, Graphics::Mesh* mesh) { mesh->GetVertexBuffer()->Bind(commandBuffer, pipeline); diff --git a/Lumos/Source/Lumos/Graphics/RHI/Renderer.h b/Lumos/Source/Lumos/Graphics/RHI/Renderer.h index cdd27e1ae..376e03d78 100644 --- a/Lumos/Source/Lumos/Graphics/RHI/Renderer.h +++ b/Lumos/Source/Lumos/Graphics/RHI/Renderer.h @@ -1,5 +1,4 @@ #pragma once -#include "Core/Application.h" #include "Core/OS/Window.h" #include "Graphics/RHI/Definitions.h" #include @@ -88,8 +87,8 @@ namespace Lumos return capabilities; } - static GraphicsContext* GetGraphicsContext() { return Application::Get().GetWindow()->GetGraphicsContext(); } - static SwapChain* GetMainSwapChain() { return Application::Get().GetWindow()->GetSwapChain(); } + static GraphicsContext* GetGraphicsContext(); + static SwapChain* GetMainSwapChain(); static void DrawMesh(CommandBuffer* commandBuffer, Graphics::Pipeline* pipeline, Graphics::Mesh* mesh); protected: diff --git a/Lumos/Source/Lumos/Graphics/Renderers/RenderPasses.h b/Lumos/Source/Lumos/Graphics/Renderers/RenderPasses.h index 492cfc250..6265739a4 100644 --- a/Lumos/Source/Lumos/Graphics/Renderers/RenderPasses.h +++ b/Lumos/Source/Lumos/Graphics/Renderers/RenderPasses.h @@ -7,6 +7,9 @@ namespace Lumos { class Scene; + class TimeStep; + class WindowResizeEvent; + namespace Maths { class Transform; diff --git a/Lumos/Source/Lumos/ImGui/ImGuiUtilities.cpp b/Lumos/Source/Lumos/ImGui/ImGuiUtilities.cpp index 5132e9c00..6c4af3487 100644 --- a/Lumos/Source/Lumos/ImGui/ImGuiUtilities.cpp +++ b/Lumos/Source/Lumos/ImGui/ImGuiUtilities.cpp @@ -939,9 +939,9 @@ namespace Lumos colours[ImGuiCol_Border] = foreground; colours[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.24f); - colours[ImGuiCol_FrameBg] = background; - colours[ImGuiCol_FrameBgHovered] = background; - colours[ImGuiCol_FrameBgActive] = background; + colours[ImGuiCol_FrameBg] = foreground; + colours[ImGuiCol_FrameBgHovered] = foreground; + colours[ImGuiCol_FrameBgActive] = foreground; colours[ImGuiCol_TitleBg] = foreground; colours[ImGuiCol_TitleBgActive] = foreground; diff --git a/Lumos/Source/Lumos/Maths/Frustum.cpp b/Lumos/Source/Lumos/Maths/Frustum.cpp index bd123f144..3f5d92953 100644 --- a/Lumos/Source/Lumos/Maths/Frustum.cpp +++ b/Lumos/Source/Lumos/Maths/Frustum.cpp @@ -73,21 +73,21 @@ namespace Lumos CalculateVertices(transform); } - void Frustum::DefineOrtho(float scale, float aspectRatio, float near, float far, const glm::mat4& viewMatrix) + void Frustum::DefineOrtho(float scale, float aspectRatio, float n, float f, const glm::mat4& viewMatrix) { LUMOS_PROFILE_FUNCTION_LOW(); - glm::mat4 m = glm::ortho(-scale * aspectRatio, scale * aspectRatio, -scale, scale, near, far); + glm::mat4 m = glm::ortho(-scale * aspectRatio, scale * aspectRatio, -scale, scale, n, f); m = m * viewMatrix; Define(m); } - void Frustum::Define(float fov, float aspectRatio, float near, float far, const glm::mat4& viewMatrix) + void Frustum::Define(float fov, float aspectRatio, float n, float f, const glm::mat4& viewMatrix) { LUMOS_PROFILE_FUNCTION_LOW(); float tangent = tan(fov * 0.5f); - float height = near * tangent; + float height = n * tangent; float width = height * aspectRatio; - glm::mat4 m = glm::frustum(-width, width, -height, height, near, far); + glm::mat4 m = glm::frustum(-width, width, -height, height, n, f); m = m * viewMatrix; Define(m); } diff --git a/Lumos/Source/Lumos/Maths/Frustum.h b/Lumos/Source/Lumos/Maths/Frustum.h index 26a12c2c1..139d957c3 100644 --- a/Lumos/Source/Lumos/Maths/Frustum.h +++ b/Lumos/Source/Lumos/Maths/Frustum.h @@ -32,8 +32,8 @@ namespace Lumos void Transform(const glm::mat4& transform); void Define(const glm::mat4& projection, const glm::mat4& view); void Define(const glm::mat4& transform); - void DefineOrtho(float scale, float aspectRatio, float near, float far, const glm::mat4& viewMatrix); - void Define(float fov, float aspectRatio, float near, float far, const glm::mat4& viewMatrix); + void DefineOrtho(float scale, float aspectRatio, float n, float f, const glm::mat4& viewMatrix); + void Define(float fov, float aspectRatio, float n, float f, const glm::mat4& viewMatrix); bool IsInside(const glm::vec3& point) const; bool IsInside(const BoundingSphere& sphere) const; diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/LumosPhysicsEngine.h b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/LumosPhysicsEngine.h index b2930e7eb..72f2e5c5d 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/LumosPhysicsEngine.h +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/LumosPhysicsEngine.h @@ -5,6 +5,7 @@ #include "Narrowphase/Manifold.h" #include "Broadphase/Broadphase.h" #include "Scene/ISystem.h" +#include "Core/OS/Allocators/PoolAllocator.h" namespace Lumos { @@ -111,7 +112,7 @@ namespace Lumos uint32_t GetPositionIterations() const { return m_PositionIterations; } void SetPositionIterations(uint32_t iterations) { m_PositionIterations = iterations; } - RigidBody3D* CreateBody(const RigidBody3DProperties& properties); + RigidBody3D* CreateBody(const RigidBody3DProperties& properties = {}); void DestroyBody(RigidBody3D* body); const PhysicsStats3D& GetStats() const { return m_Stats; } diff --git a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Narrowphase/CollisionDetection.cpp b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Narrowphase/CollisionDetection.cpp index 2694a5cba..ce45c9166 100644 --- a/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Narrowphase/CollisionDetection.cpp +++ b/Lumos/Source/Lumos/Physics/LumosPhysicsEngine/Narrowphase/CollisionDetection.cpp @@ -35,7 +35,7 @@ namespace Lumos bool CollisionDetection::CheckCollision(RigidBody3D* obj1, RigidBody3D* obj2, CollisionShape* shape1, CollisionShape* shape2, CollisionData* out_coldata) { LUMOS_PROFILE_FUNCTION_LOW(); - LUMOS_ASSERT(((shape1->GetType() | shape2->GetType()) < m_MaxSize), "Invalid collision func {0}, {1}, {2}, {3}", shape1->GetType(), shape2->GetType(), shape2->GetType() | shape2->GetType(), m_MaxSize); + LUMOS_ASSERT(((shape1->GetType() | shape2->GetType()) < m_MaxSize), "Invalid collision func {0}, {1}, {2}, {3}", (int)shape1->GetType(), (int)shape2->GetType(), (int)shape2->GetType() | (int)shape2->GetType(), m_MaxSize); return CALL_MEMBER_FN(*this, m_CollisionCheckFunctions[shape1->GetType() | shape2->GetType()])(obj1, obj2, shape1, shape2, out_coldata); } diff --git a/Lumos/Source/Lumos/Platform/OpenGL/GLContext.cpp b/Lumos/Source/Lumos/Platform/OpenGL/GLContext.cpp index 8fc10d1a7..5df433edf 100644 --- a/Lumos/Source/Lumos/Platform/OpenGL/GLContext.cpp +++ b/Lumos/Source/Lumos/Platform/OpenGL/GLContext.cpp @@ -127,9 +127,9 @@ namespace Lumos { LUMOS_LOG_INFO("----------------------------------"); LUMOS_LOG_INFO(OPENGLLOG); - LUMOS_LOG_INFO(glGetString(GL_VERSION)); - LUMOS_LOG_INFO(glGetString(GL_VENDOR)); - LUMOS_LOG_INFO(glGetString(GL_RENDERER)); + LUMOS_LOG_INFO((const char*)(glGetString(GL_VERSION))); + LUMOS_LOG_INFO((const char*)(glGetString(GL_VENDOR))); + LUMOS_LOG_INFO((const char*)(glGetString(GL_RENDERER))); LUMOS_LOG_INFO("----------------------------------"); #if LUMOS_DEBUG diff --git a/Lumos/Source/Lumos/Platform/Vulkan/VKShader.cpp b/Lumos/Source/Lumos/Platform/Vulkan/VKShader.cpp index 4d2553282..8b7a975b5 100644 --- a/Lumos/Source/Lumos/Platform/Vulkan/VKShader.cpp +++ b/Lumos/Source/Lumos/Platform/Vulkan/VKShader.cpp @@ -374,7 +374,7 @@ namespace Lumos case VK_FORMAT_R32G32B32A32_UINT: return sizeof(glm::ivec4); // Need uintvec? default: - LUMOS_LOG_ERROR("Unsupported Format {0}", format); + LUMOS_LOG_ERROR("Unsupported Format {0}", (int)format); return 0; } diff --git a/Lumos/Source/Lumos/Scene/Component/RigidBody3DComponent.cpp b/Lumos/Source/Lumos/Scene/Component/RigidBody3DComponent.cpp index cebbc5872..3df0ee764 100644 --- a/Lumos/Source/Lumos/Scene/Component/RigidBody3DComponent.cpp +++ b/Lumos/Source/Lumos/Scene/Component/RigidBody3DComponent.cpp @@ -18,6 +18,12 @@ namespace Lumos { } + RigidBody3DComponent::RigidBody3DComponent(const RigidBody3DProperties& properties) + { + m_RigidBody = Application::Get().GetSystem()->CreateBody(properties); + + } + RigidBody3DComponent::RigidBody3DComponent(const RigidBody3DComponent& other) { m_RigidBody = other.m_RigidBody; diff --git a/Lumos/Source/Lumos/Scene/Component/RigidBody3DComponent.h b/Lumos/Source/Lumos/Scene/Component/RigidBody3DComponent.h index 9991d7f2b..d27dd2b0c 100644 --- a/Lumos/Source/Lumos/Scene/Component/RigidBody3DComponent.h +++ b/Lumos/Source/Lumos/Scene/Component/RigidBody3DComponent.h @@ -106,7 +106,8 @@ namespace Lumos RigidBody3DComponent(); RigidBody3DComponent(const RigidBody3DComponent& other); - explicit RigidBody3DComponent(RigidBody3D* physics); + RigidBody3DComponent(RigidBody3D* physics); + RigidBody3DComponent(const RigidBody3DProperties& params); ~RigidBody3DComponent() = default; diff --git a/Lumos/Source/Lumos/Scripting/Lua/LuaManager.cpp b/Lumos/Source/Lumos/Scripting/Lua/LuaManager.cpp index 858159bb0..51e9c220f 100644 --- a/Lumos/Source/Lumos/Scripting/Lua/LuaManager.cpp +++ b/Lumos/Source/Lumos/Scripting/Lua/LuaManager.cpp @@ -25,6 +25,7 @@ #include "Scene/EntityManager.h" #include "Scene/EntityFactory.h" #include "Physics/LumosPhysicsEngine/LumosPhysicsEngine.h" +#include "Physics/LumosPhysicsEngine/RigidBody3D.h" #include "ImGuiLua.h" #include "PhysicsLua.h" @@ -614,9 +615,11 @@ namespace Lumos REGISTER_COMPONENT_WITH_ECS(state, Camera, static_cast(&Entity::AddComponent)); - sol::usertype RigidBody3DComponent_type = state.new_usertype("RigidBody3DComponent" /*, sol::constructors&>>()*/); + sol::usertype RigidBody3DComponent_type = state.new_usertype("RigidBody3DComponent", sol::constructors>()); RigidBody3DComponent_type.set_function("GetRigidBody", &RigidBody3DComponent::GetRigidBody); - REGISTER_COMPONENT_WITH_ECS(state, RigidBody3DComponent, static_cast&)>(&Entity::AddComponent)); //, SharedPtr&>)); + + REGISTER_COMPONENT_WITH_ECS(state, RigidBody3DComponent, static_cast(&Entity::AddComponent)); + //REGISTER_COMPONENT_WITH_ECS(state, RigidBody3DComponent, static_cast(&Entity::AddComponent RigidBody2DComponent_type = state.new_usertype("RigidBody2DComponent", sol::constructors>()); RigidBody2DComponent_type.set_function("GetRigidBody", &RigidBody2DComponent::GetRigidBody); diff --git a/Lumos/Source/Lumos/Scripting/Lua/PhysicsLua.cpp b/Lumos/Source/Lumos/Scripting/Lua/PhysicsLua.cpp index 526f2b157..d5ecc94ca 100644 --- a/Lumos/Source/Lumos/Scripting/Lua/PhysicsLua.cpp +++ b/Lumos/Source/Lumos/Scripting/Lua/PhysicsLua.cpp @@ -334,6 +334,15 @@ namespace Lumos physicsObjectParameters_type["scale"] = &RigidBodyParameters::scale; physicsObjectParameters_type["isStatic"] = &RigidBodyParameters::isStatic; physicsObjectParameters_type["customShapePositions"] = &RigidBodyParameters::custumShapePositions; + + + sol::usertype physicsObjectParameters3D_type = state.new_usertype("RigidBodyParameters3D"); + physicsObjectParameters3D_type["mass"] = &RigidBody3DProperties::Mass; + //physicsObjectParameters3D_type["shape"] = &RigidBody3DProperties::Shape; + physicsObjectParameters3D_type["position"] = &RigidBody3DProperties::Position; + //physicsObjectParameters3D_type["scale"] = &RigidBody3DProperties::Scale; + physicsObjectParameters3D_type["isStatic"] = &RigidBody3DProperties::Static; + //physicsObjectParameters3D_type["customShapePositions"] = &RigidBody3DProperties::custumShapePositions; sol::usertype physics3D_type = state.new_usertype("RigidBody3D"); //, sol::constructors()); //;const RigidBodyParameters&)>()); physics3D_type.set_function("SetForce", &RigidBody3D::SetForce); diff --git a/Lumos/Source/Precompiled.h b/Lumos/Source/Precompiled.h index 0913fba5c..5fc449752 100644 --- a/Lumos/Source/Precompiled.h +++ b/Lumos/Source/Precompiled.h @@ -27,4 +27,11 @@ #include "Core/LMLog.h" #include "Core/Core.h" #include "Core/Profiler.h" + +#include +#include + +#ifdef LUMOS_PLATFORM_WINDOWS +#include +#endif #endif diff --git a/README.md b/README.md index f2e329ea9..7f876c2cb 100755 --- a/README.md +++ b/README.md @@ -9,14 +9,13 @@ Dependencies

-Build +Build platforms -license +license
-Issues -size -stars -Discord +stars +release +Discord

diff --git a/Resources/Screenshot 2023-09-04 100048.png b/Resources/Screenshot 2023-09-04 100048.png new file mode 100644 index 0000000000000000000000000000000000000000..4d32f61a8fd04f82da52c0a6462eb8387dcd20c0 GIT binary patch literal 953503 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

KU^IRe1jg?^x37qUwL0g(q<(Ttz2 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

`A()N((+JR_- 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%0DeqJ)U&0Ua17=rO9AN4gotYE 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

4Zen08wJ%STS2zqhYJs}| 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 VfUYnJ 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 z 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 literal 0 HcmV?d00001