From ddfeccb6b7ce9442e66771abfdbe87689d60362e Mon Sep 17 00:00:00 2001 From: halx99 Date: Sun, 30 Nov 2025 22:12:17 +0800 Subject: [PATCH 01/17] Improve tlx --- 1k/platforms.cmake | 4 + 3rdparty/yasio/yasio/bindings/lyasio.cpp | 70 +- 3rdparty/yasio/yasio/bindings/yasio_axlua.cpp | 17 +- 3rdparty/yasio/yasio/bindings/yasio_sol.hpp | 14 +- 3rdparty/yasio/yasio/buffer_alloc.hpp | 119 -- .../yasio/yasio/compiler/feature_test.hpp | 36 +- 3rdparty/yasio/yasio/config.hpp | 6 - 3rdparty/yasio/yasio/ibstream.hpp | 36 +- 3rdparty/yasio/yasio/impl/mbedtls.hpp | 2 +- 3rdparty/yasio/yasio/impl/poll_io_watcher.hpp | 8 +- 3rdparty/yasio/yasio/impl/socket.hpp | 2 +- 3rdparty/yasio/yasio/io_service.cpp | 70 +- 3rdparty/yasio/yasio/io_service.hpp | 96 +- 3rdparty/yasio/yasio/io_watcher.hpp | 9 +- 3rdparty/yasio/yasio/memory.hpp | 45 - 3rdparty/yasio/yasio/object_pool.hpp | 4 +- 3rdparty/yasio/yasio/obstream.hpp | 32 +- 3rdparty/yasio/yasio/pod_vector.hpp | 516 ----- 3rdparty/yasio/yasio/ref_ptr.hpp | 211 --- 3rdparty/yasio/yasio/split.hpp | 2 +- 3rdparty/yasio/yasio/string_view.hpp | 1287 ------------- 3rdparty/yasio/yasio/tlx/array_buffer.hpp | 12 + 3rdparty/yasio/yasio/tlx/buffer_alloc.hpp | 87 + .../yasio/yasio/{ => tlx}/byte_buffer.hpp | 12 +- .../yasio/yasio/{utils.hpp => tlx/chrono.hpp} | 27 +- .../yasio/yasio/{file.hpp => tlx/file_io.hpp} | 21 +- 3rdparty/yasio/yasio/tlx/memory.hpp | 463 +++++ .../yasio/yasio/{ => tlx}/shared_mutex.hpp | 14 +- 3rdparty/yasio/yasio/{ => tlx}/singleton.hpp | 4 +- 3rdparty/yasio/yasio/{ => tlx}/string.hpp | 345 ++-- 3rdparty/yasio/yasio/tlx/string_view.hpp | 240 +++ .../yasio/yasio/{ => tlx}/type_traits.hpp | 2 +- 3rdparty/yasio/yasio/tlx/vector.hpp | 1680 +++++++++++++++++ 3rdparty/yasio/yasio/wtimer_hres.hpp | 3 +- 3rdparty/yasio/yasio/xxsocket.cpp | 31 +- 3rdparty/yasio/yasio/xxsocket.hpp | 6 +- 3rdparty/yasio/yasio/yasio.natvis | 110 +- axmol/2d/ActionCoroutine.h | 16 +- axmol/2d/AutoPolygon.cpp | 8 +- axmol/2d/ComponentContainer.cpp | 2 +- axmol/2d/ComponentContainer.h | 2 +- axmol/2d/DrawNode.cpp | 24 +- axmol/2d/DrawNode.h | 10 +- axmol/2d/FontAtlas.cpp | 4 +- axmol/2d/FontAtlas.h | 4 +- axmol/2d/FontAtlasCache.cpp | 2 +- axmol/2d/FontAtlasCache.h | 2 +- axmol/2d/FontFreeType.cpp | 2 +- axmol/2d/MotionStreak.h | 4 +- axmol/2d/ParticleSystem.cpp | 4 +- axmol/2d/ProgressTimer.h | 6 +- axmol/2d/SpriteFrameCache.cpp | 4 +- axmol/2d/SpriteFrameCache.h | 4 +- axmol/2d/SpriteSheetLoader.h | 2 +- axmol/2d/TMXXMLParser.cpp | 14 +- axmol/3d/Animation3D.cpp | 26 +- axmol/3d/Animation3D.h | 6 +- axmol/3d/Bundle3DData.h | 21 +- axmol/3d/Mesh.cpp | 4 +- axmol/3d/Mesh.h | 6 +- axmol/3d/MeshDataCache.h | 2 +- axmol/3d/MeshMaterial.h | 2 +- axmol/3d/MeshRenderer.cpp | 2 +- axmol/3d/MeshRenderer.h | 2 +- axmol/3d/MeshVertexIndexData.h | 2 +- axmol/3d/ObjLoader.cpp | 6 +- axmol/3d/ObjLoader.h | 6 +- axmol/3d/Terrain.cpp | 6 +- axmol/3d/VertexInputBinding.cpp | 4 +- axmol/audio/AudioDecoderManager.cpp | 8 +- axmol/audio/AudioEngine.cpp | 4 +- axmol/audio/AudioEngine.h | 4 +- axmol/audio/AudioEngineImpl.h | 2 +- axmol/axmol.natvis | 10 +- axmol/base/Console.cpp | 8 +- axmol/base/Console.h | 6 +- axmol/base/Data.cpp | 5 +- axmol/base/Data.h | 4 +- axmol/base/Director.cpp | 4 +- axmol/base/Environment.cpp | 2 +- axmol/base/EventDispatcher.h | 4 +- axmol/base/JsonWriter.h | 6 +- axmol/base/Logging.cpp | 4 +- axmol/base/Map.h | 2 +- axmol/base/ObjectFactory.h | 2 +- axmol/base/Properties.cpp | 4 +- axmol/base/RefPtr.h | 2 +- axmol/base/Scheduler.cpp | 16 +- axmol/base/Scheduler.h | 20 +- axmol/base/SimpleTimer.cpp | 6 +- axmol/base/UserDefault.cpp | 6 +- axmol/base/UserDefault.h | 7 +- axmol/base/Utils.cpp | 18 +- axmol/base/Utils.h | 4 +- axmol/base/Value.h | 2 +- axmol/base/Vector.h | 8 +- axmol/base/ZipUtils.cpp | 26 +- axmol/base/ZipUtils.h | 8 +- axmol/base/astc.cpp | 8 +- axmol/media/AndroidMediaEngine.h | 4 +- axmol/media/AvfMediaEngine.mm | 2 +- axmol/media/MediaEngine.cpp | 16 +- axmol/media/MediaEngine.h | 4 +- axmol/media/VlcMediaEngine.h | 4 +- axmol/media/WmfMediaEngine.h | 6 +- axmol/network/HttpClient-wasm.cpp | 4 +- axmol/network/HttpClient.cpp | 9 +- axmol/network/HttpCookie.cpp | 41 +- axmol/network/HttpRequest.h | 4 +- axmol/network/HttpResponse.h | 6 +- axmol/network/WebSocket-wasm.h | 2 +- axmol/network/WebSocket.cpp | 4 +- axmol/network/WebSocket.h | 12 +- axmol/physics/PhysicsCollider.h | 4 +- axmol/physics3d/PhysicsMeshRenderer.cpp | 4 +- axmol/platform/FileUtils.cpp | 11 +- axmol/platform/FileUtils.h | 14 +- axmol/platform/Image.cpp | 2 +- axmol/platform/android/Device-android.cpp | 3 +- axmol/platform/android/FileUtils-android.cpp | 2 +- .../android/RenderViewImpl-android.cpp | 4 +- axmol/platform/android/jni/JniHelper.h | 14 +- axmol/platform/desktop/RenderViewImpl.h | 8 +- axmol/platform/wasm/FileUtils-wasm.cpp | 2 +- axmol/platform/win32/Application-win32.cpp | 5 +- axmol/platform/win32/FileUtils-win32.cpp | 2 +- axmol/platform/winrt/FileUtilsWinRT.cpp | 2 +- axmol/renderer/Material.h | 2 +- axmol/renderer/TextureCache.h | 2 +- axmol/renderer/VertexLayoutManager.cpp | 6 +- axmol/renderer/VertexLayoutManager.h | 6 +- axmol/rhi/Program.h | 4 +- axmol/rhi/ProgramState.cpp | 4 +- axmol/rhi/ProgramState.h | 17 +- axmol/rhi/SamplerCache.cpp | 6 +- axmol/rhi/SamplerCache.h | 8 +- axmol/rhi/Texture.cpp | 2 +- axmol/rhi/d3d11/Buffer11.h | 2 +- axmol/rhi/d3d11/DepthStencilState11.h | 2 +- axmol/rhi/d3d11/Program11.cpp | 4 +- axmol/rhi/d3d11/Program11.h | 4 +- axmol/rhi/d3d11/RenderContext11.h | 2 +- axmol/rhi/d3d11/RenderPipeline11.h | 2 +- axmol/rhi/d3d11/ShaderModule11.h | 8 +- axmol/rhi/d3d11/VertexLayout11.cpp | 2 +- axmol/rhi/d3d12/Buffer12.h | 2 +- axmol/rhi/d3d12/DepthStencilState12.cpp | 4 +- axmol/rhi/d3d12/Driver12.cpp | 6 +- axmol/rhi/d3d12/Program12.cpp | 4 +- axmol/rhi/d3d12/Program12.h | 4 +- axmol/rhi/d3d12/RenderPipeline12.cpp | 8 +- axmol/rhi/d3d12/RenderPipeline12.h | 4 +- axmol/rhi/d3d12/ShaderModule12.h | 8 +- axmol/rhi/d3d12/Texture12.h | 4 +- axmol/rhi/metal/ProgramMTL.h | 4 +- axmol/rhi/metal/ProgramMTL.mm | 4 +- axmol/rhi/metal/RenderPipelineMTL.h | 2 +- axmol/rhi/metal/ShaderModuleMTL.h | 8 +- axmol/rhi/opengl/DriverGL.cpp | 6 +- axmol/rhi/opengl/ProgramGL.cpp | 14 +- axmol/rhi/opengl/ProgramGL.h | 12 +- axmol/rhi/opengl/RenderContextGL.cpp | 4 +- axmol/rhi/opengl/ShaderModuleGL.cpp | 2 +- axmol/rhi/vulkan/BufferVK.h | 2 +- axmol/rhi/vulkan/DepthStencilStateVK.cpp | 4 +- axmol/rhi/vulkan/DriverVK.cpp | 12 +- axmol/rhi/vulkan/DriverVK.h | 8 +- axmol/rhi/vulkan/ProgramVK.cpp | 4 +- axmol/rhi/vulkan/ProgramVK.h | 4 +- axmol/rhi/vulkan/RenderContextVK.cpp | 2 +- axmol/rhi/vulkan/RenderContextVK.h | 14 +- axmol/rhi/vulkan/RenderPipelineVK.cpp | 10 +- axmol/rhi/vulkan/RenderPipelineVK.h | 12 +- axmol/rhi/vulkan/RenderTargetVK.cpp | 16 +- axmol/rhi/vulkan/RenderTargetVK.h | 6 +- axmol/rhi/vulkan/SemaphorePoolVK.h | 4 +- axmol/rhi/vulkan/ShaderModuleVK.h | 8 +- axmol/rhi/vulkan/TextureVK.h | 4 +- axmol/tlx/byte_buffer.hpp | 8 +- axmol/tlx/charconv.hpp | 8 +- axmol/tlx/filesystem.hpp | 12 +- axmol/tlx/flat_map.hpp | 52 +- axmol/tlx/flat_map_base.hpp | 284 +++ axmol/tlx/flat_multimap.hpp | 41 +- axmol/tlx/flat_multiset.hpp | 29 +- axmol/tlx/flat_set.hpp | 29 +- axmol/tlx/flat_set_base.hpp | 217 +++ axmol/tlx/hash.hpp | 4 +- axmol/tlx/hlookup.hpp | 13 +- axmol/tlx/memory.hpp | 130 +- axmol/tlx/singleton.hpp | 25 + axmol/tlx/sorted_vector.hpp | 235 --- axmol/tlx/type_traits.hpp | 4 +- axmol/tlx/utility.hpp | 4 +- axmol/tlx/{pod_vector.hpp => vector.hpp} | 13 +- axmol/ui/UIEditBox/UIEditBoxImpl-android.cpp | 3 +- axmol/ui/UIMediaPlayer.cpp | 2 +- axmol/ui/UIRichText.cpp | 6 +- axmol/ui/UIWebView/UIWebViewImpl-android.cpp | 5 +- .../src/DragonBones/animation/Animation.cpp | 2 +- .../src/DragonBones/animation/Animation.h | 6 +- .../DragonBones/animation/AnimationState.cpp | 6 +- .../DragonBones/animation/AnimationState.h | 2 +- .../src/DragonBones/factory/BaseFactory.cpp | 2 +- .../src/DragonBones/factory/BaseFactory.h | 8 +- .../src/DragonBones/model/AnimationData.h | 10 +- .../src/DragonBones/model/ArmatureData.h | 10 +- .../src/DragonBones/model/DragonBonesData.h | 2 +- .../src/DragonBones/model/SkinData.h | 4 +- .../src/DragonBones/model/TextureAtlasData.h | 4 +- .../src/DragonBones/parser/JSONDataParser.h | 8 +- extensions/ImGui/src/ImGui/ImGuiPresenter.h | 2 +- .../JSONDefault/src/JSONDefault/JSONDefault.h | 4 +- .../src/Particle3D/PU/PUMaterialManager.cpp | 2 - .../src/Particle3D/PU/PUParticleSystem3D.h | 2 +- .../src/Particle3D/PU/PUScriptCompiler.cpp | 8 +- .../src/Particle3D/PU/PUScriptCompiler.h | 8 +- extensions/SDFGen/src/SDFGen/SDFGen.cpp | 12 +- .../src/assets-manager/AssetsManagerEx.cpp | 2 +- .../src/assets-manager/AssetsManagerEx.h | 4 +- .../src/assets-manager/Manifest.cpp | 10 +- .../src/assets-manager/Manifest.h | 12 +- .../ActionTimeline/ActionTimeline.h | 4 +- .../ActionTimeline/ActionTimelineCache.h | 2 +- .../cocostudio/ActionTimeline/CSLoader.cpp | 2 +- .../ActionTimeline/SkeletonNode.cpp | 4 +- .../cocostudio/ActionTimeline/SkeletonNode.h | 6 +- .../src/cocostudio/ArmatureDataManager.h | 2 +- extensions/cocostudio/src/cocostudio/Bone.cpp | 2 +- .../cocostudio/src/cocostudio/SGUIReader.cpp | 4 +- .../cocostudio/src/cocostudio/SGUIReader.h | 4 +- .../src/cocostudio/SpineSkeletonDataCache.h | 4 +- .../src/cocostudio/SpriteFrameCacheHelper.h | 2 +- .../src/fairygui/TranslationHelper.cpp | 2 +- .../fairygui/src/fairygui/TranslationHelper.h | 2 +- .../src/physics-nodes/PhysicsDebugNode.cpp | 2 +- .../lua-bindings/auto/axlua_studio_auto.cpp | 4 +- .../lua-bindings/manual/AxluaLoader.cpp | 1 - .../manual/LuaBasicConversions.cpp | 10 +- .../lua-bindings/manual/LuaBasicConversions.h | 11 +- .../lua-bindings/manual/LuaStack.cpp | 9 +- .../manual/network/lua_xml_http_request.cpp | 4 +- .../Box2DTestBed/Box2DTestDebugDrawNode.h | 6 +- .../Source/MeshRendererTest/DrawNode3D.h | 2 +- .../Source/RendererTest/RendererTest.cpp | 2 +- tests/cpp-tests/proj.linux/main.cpp | 1 - tests/unit-tests/CMakeLists.txt | 1 + .../Source/axmol/base/UTF8Tests.cpp | 4 +- .../Source/axmol/platform/FileUtilsTests.cpp | 2 +- .../Source/axmol/tlx/ContainerTests.cpp | 181 ++ 250 files changed, 4425 insertions(+), 3659 deletions(-) delete mode 100644 3rdparty/yasio/yasio/buffer_alloc.hpp delete mode 100644 3rdparty/yasio/yasio/memory.hpp delete mode 100644 3rdparty/yasio/yasio/pod_vector.hpp delete mode 100644 3rdparty/yasio/yasio/ref_ptr.hpp delete mode 100644 3rdparty/yasio/yasio/string_view.hpp create mode 100644 3rdparty/yasio/yasio/tlx/array_buffer.hpp create mode 100644 3rdparty/yasio/yasio/tlx/buffer_alloc.hpp rename 3rdparty/yasio/yasio/{ => tlx}/byte_buffer.hpp (83%) rename 3rdparty/yasio/yasio/{utils.hpp => tlx/chrono.hpp} (85%) rename 3rdparty/yasio/yasio/{file.hpp => tlx/file_io.hpp} (84%) create mode 100644 3rdparty/yasio/yasio/tlx/memory.hpp rename 3rdparty/yasio/yasio/{ => tlx}/shared_mutex.hpp (95%) rename 3rdparty/yasio/yasio/{ => tlx}/singleton.hpp (99%) rename 3rdparty/yasio/yasio/{ => tlx}/string.hpp (63%) create mode 100644 3rdparty/yasio/yasio/tlx/string_view.hpp rename 3rdparty/yasio/yasio/{ => tlx}/type_traits.hpp (99%) create mode 100644 3rdparty/yasio/yasio/tlx/vector.hpp create mode 100644 axmol/tlx/flat_map_base.hpp create mode 100644 axmol/tlx/flat_set_base.hpp create mode 100644 axmol/tlx/singleton.hpp delete mode 100644 axmol/tlx/sorted_vector.hpp rename axmol/tlx/{pod_vector.hpp => vector.hpp} (82%) create mode 100644 tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp diff --git a/1k/platforms.cmake b/1k/platforms.cmake index 9af2514b88c3..3af5cb984c91 100644 --- a/1k/platforms.cmake +++ b/1k/platforms.cmake @@ -97,6 +97,10 @@ endif() # compiler id +if(NOT WIN32 AND CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(FULL_CLANG TRUE) +endif() + # generators that are capable of organizing into a hierarchy of folders set_property(GLOBAL PROPERTY USE_FOLDERS ON) diff --git a/3rdparty/yasio/yasio/bindings/lyasio.cpp b/3rdparty/yasio/yasio/bindings/lyasio.cpp index 080a7d458e36..8c053f5b4039 100644 --- a/3rdparty/yasio/yasio/bindings/lyasio.cpp +++ b/3rdparty/yasio/yasio/bindings/lyasio.cpp @@ -39,7 +39,7 @@ enum }; template -static void obstream_write_v(_Stream* obs, cxx17::string_view val, int length_field_bits) +static void obstream_write_v(_Stream* obs, std::string_view val, int length_field_bits) { // default: Use variant length of length field, just like .net BinaryWriter.Write(String), // see: @@ -58,7 +58,7 @@ static void obstream_write_v(_Stream* obs, cxx17::string_view val, int length_fi } }; template -static cxx17::string_view ibstream_read_v(_Stream* ibs, int length_field_bits) +static std::string_view ibstream_read_v(_Stream* ibs, int length_field_bits) { // default: Use variant length of length field, just like .net BinaryReader.ReadString, // see: @@ -113,21 +113,21 @@ static void register_obstream(sol::table& lib, const char* usertype) "write_f16", &_Stream::template write, # endif "write_f", &_Stream::template write, "write_lf", &_Stream::template write, "write_v", - [](_Stream* obs, cxx17::string_view sv, sol::variadic_args args) { + [](_Stream* obs, std::string_view sv, sol::variadic_args args) { int lfl = -1; if (args.size() > 0) lfl = static_cast(args[0]); return obstream_write_v<_Stream>(obs, sv, lfl); }, - "write_bytes", static_cast(&_Stream::write_bytes), "length", &_Stream::length, "to_string", - [](_Stream* obs) { return cxx17::string_view(obs->data(), obs->length()); }, "save", &_Stream::save); + "write_bytes", static_cast(&_Stream::write_bytes), "length", &_Stream::length, "to_string", + [](_Stream* obs) { return std::string_view(obs->data(), obs->length()); }, "save", &_Stream::save); } template static void register_ibstream(sol::table& lib, const char* usertype) { lib.new_usertype<_Stream>( - usertype, sol::constructors<_Stream(), _Stream(yasio::sbyte_buffer), _Stream(const _OStream*)>(), "load", &_Stream::load, "read_ix", + usertype, sol::constructors<_Stream(), _Stream(tlx::sbyte_buffer), _Stream(const _OStream*)>(), "load", &_Stream::load, "read_ix", &_Stream::template read_ix, "read_bool", &_Stream::template read, "read_i8", &_Stream::template read, "read_i16", &_Stream::template read, "read_i32", &_Stream::template read, "read_i64", &_Stream::template read, "read_u8", &_Stream::template read, "read_u16", &_Stream::template read, "read_u32", &_Stream::template read, "read_u64", @@ -142,8 +142,8 @@ static void register_ibstream(sol::table& lib, const char* usertype) lfl = static_cast(args[0]); return ibstream_read_v<_Stream>(ibs, lfl); }, - "read_bytes", static_cast(&_Stream::read_bytes), "seek", &_StreamView::seek, "length", &_StreamView::length, - "to_string", [](_Stream* ibs) { return cxx17::string_view(ibs->data(), ibs->length()); }); + "read_bytes", static_cast(&_Stream::read_bytes), "seek", &_StreamView::seek, "length", &_StreamView::length, + "to_string", [](_Stream* ibs) { return std::string_view(ibs->data(), ibs->length()); }); } } // namespace lyasio @@ -170,11 +170,11 @@ YASIO_LUA_API int luaopen_yasio(lua_State* L) switch (buffer_type) { case lyasio::BUFFER_RAW: - return sol::make_object(L, cxx17::string_view{packet_data(pkt), packet_len(pkt)}); + return sol::make_object(L, std::string_view{packet_data(pkt), packet_len(pkt)}); case lyasio::BUFFER_FAST: - return sol::make_object(L, cxx14::make_unique(forward_packet((packet_t &&) pkt))); + return sol::make_object(L, std::make_unique(forward_packet((packet_t &&) pkt))); default: - return sol::make_object(L, cxx14::make_unique(forward_packet((packet_t &&) pkt))); + return sol::make_object(L, std::make_unique(forward_packet((packet_t &&) pkt))); } }, "cindex", &io_event::cindex, "transport", &io_event::transport @@ -192,13 +192,13 @@ YASIO_LUA_API int luaopen_yasio(lua_State* L) std::vector hosts; auto host = channel_eps["host"]; if (host.valid()) - hosts.push_back(io_hostent(host.get(), channel_eps["port"])); + hosts.push_back(io_hostent(host.get(), channel_eps["port"])); else { for (auto item : channel_eps) { auto ep = item.second.as(); - hosts.push_back(io_hostent(ep["host"].get(), ep["port"])); + hosts.push_back(io_hostent(ep["host"].get(), ep["port"])); } } return new (&uninitialized_memory) @@ -258,16 +258,16 @@ YASIO_LUA_API int luaopen_yasio(lua_State* L) sol::overload(static_cast(&io_service::close), static_cast(&io_service::close)), "write", sol::overload( - [](io_service* service, transport_handle_t transport, cxx17::string_view s) { - return service->write(transport, yasio::sbyte_buffer{s.data(), s.data() + s.length()}); + [](io_service* service, transport_handle_t transport, std::string_view s) { + return service->write(transport, tlx::sbyte_buffer{s.data(), s.data() + s.length()}); }, [](io_service* service, transport_handle_t transport, yasio::obstream* obs) { return service->write(transport, std::move(obs->buffer())); }), "write_to", sol::overload( - [](io_service* service, transport_handle_t transport, cxx17::string_view s, cxx17::string_view ip, u_short port) { - return service->write_to(transport, yasio::sbyte_buffer{s.data(), s.data() + s.length()}, ip::endpoint{ip.data(), port}); + [](io_service* service, transport_handle_t transport, std::string_view s, std::string_view ip, u_short port) { + return service->write_to(transport, tlx::sbyte_buffer{s.data(), s.data() + s.length()}, ip::endpoint{ip.data(), port}); }, - [](io_service* service, transport_handle_t transport, yasio::obstream* obs, cxx17::string_view ip, u_short port) { + [](io_service* service, transport_handle_t transport, yasio::obstream* obs, std::string_view ip, u_short port) { return service->write_to(transport, std::move(obs->buffer()), ip::endpoint{ip.data(), port}); }), "native_ptr", [](io_service* service) { return (void*)service; }); @@ -280,8 +280,8 @@ YASIO_LUA_API int luaopen_yasio(lua_State* L) lyasio::register_ibstream(yasio_lib, "ibstream"); lyasio::register_ibstream(yasio_lib, "fast_ibstream"); - yasio_lib["highp_clock"] = &highp_clock; - yasio_lib["highp_time"] = &highp_clock; + yasio_lib["highp_clock"] = &tlx::highp_clock; + yasio_lib["highp_time"] = &tlx::highp_clock; yasio_lib["unwrap_ptr"] = [](lua_State* L) -> int { auto& pkt = *(packet_t*)lua_touserdata(L, 1); @@ -371,11 +371,11 @@ YASIO_LUA_API int luaopen_yasio(lua_State* L) /// customize the type conversion from/to lua namespace kaguya { -// cxx17::string_view +// std::string_view template <> -struct lua_type_traits { - typedef cxx17::string_view get_type; - typedef cxx17::string_view push_type; +struct lua_type_traits { + typedef std::string_view get_type; + typedef std::string_view push_type; static bool strictCheckType(lua_State* l, int index) { return lua_type(l, index) == LUA_TSTRING; } static bool checkType(lua_State* l, int index) { return lua_isstring(l, index) != 0; } @@ -383,7 +383,7 @@ struct lua_type_traits { { size_t size = 0; const char* buffer = lua_tolstring(l, index, &size); - return cxx17::string_view(buffer, size); + return std::string_view(buffer, size); } static int push(lua_State* l, push_type s) { @@ -527,15 +527,15 @@ static void register_obstream(kaguya::LuaTable& lib, const char* usertype, const .addFunction("write_f", &_BaseStream::template write) .addFunction("write_lf", &_BaseStream::template write) .addStaticFunction("write_v", - [](_BaseStream* obs, cxx17::string_view sv, kaguya::VariadicArgType args) { + [](_BaseStream* obs, std::string_view sv, kaguya::VariadicArgType args) { int lfl = -1; if (args.size() > 0) lfl = static_cast(args[0]); return lyasio::obstream_write_v(obs, sv, lfl); }) - .addFunction("write_bytes", static_cast(&_BaseStream::write_bytes)) + .addFunction("write_bytes", static_cast(&_BaseStream::write_bytes)) .addFunction("length", &_BaseStream::length) - .addStaticFunction("to_string", [](_BaseStream* obs) { return cxx17::string_view(obs->data(), obs->length()); })); + .addStaticFunction("to_string", [](_BaseStream* obs) { return std::string_view(obs->data(), obs->length()); })); // ##-- obstream lib[usertype].setClass(userclass); } @@ -565,10 +565,10 @@ static void register_ibstream(kaguya::LuaTable& lib, const char* usertype, const length_field_bits = static_cast(args[0]); return lyasio::ibstream_read_v(ibs, length_field_bits); }) - .addFunction("read_bytes", static_cast(&_StreamView::read_bytes)) + .addFunction("read_bytes", static_cast(&_StreamView::read_bytes)) .addFunction("seek", &_StreamView::seek) .addFunction("length", &_StreamView::length) - .addStaticFunction("to_string", [](_StreamView* ibs) { return cxx17::string_view(ibs->data(), ibs->length()); })); + .addStaticFunction("to_string", [](_StreamView* ibs) { return std::string_view(ibs->data(), ibs->length()); })); // ##-- ibstream lib[usertype].setClass(userclass); @@ -602,8 +602,8 @@ YASIO_LUA_API int luaopen_yasio(lua_State* L) [](io_event* ev) { auto& pkt = ev->packet(); if (is_packet_empty(pkt)) - return cxx17::string_view{""}; - return cxx17::string_view{packet_data(pkt), packet_len(pkt)}; + return std::string_view{""}; + return std::string_view{packet_data(pkt), packet_len(pkt)}; }) .addStaticFunction("fast_packet", [](io_event* ev) { @@ -652,16 +652,16 @@ end static_cast(&io_service::close)) .addOverloadedFunctions( "write", - [](io_service* service, transport_handle_t transport, cxx17::string_view s) { + [](io_service* service, transport_handle_t transport, std::string_view s) { return service->write(transport, yasio::sbyte_buffer(s.data(), s.data() + s.length())); }, [](io_service* service, transport_handle_t transport, yasio::obstream* obs) { return service->write(transport, std::move(obs->buffer())); }) .addOverloadedFunctions( "write_to", - [](io_service* service, transport_handle_t transport, cxx17::string_view s, cxx17::string_view ip, u_short port) { + [](io_service* service, transport_handle_t transport, std::string_view s, std::string_view ip, u_short port) { return service->write_to(transport, yasio::sbyte_buffer(s.data(), s.data() + s.length()), ip::endpoint{ip.data(), port}); }, - [](io_service* service, transport_handle_t transport, yasio::obstream* obs, cxx17::string_view ip, u_short port) { + [](io_service* service, transport_handle_t transport, yasio::obstream* obs, std::string_view ip, u_short port) { return service->write_to(transport, std::move(obs->buffer()), ip::endpoint{ip.data(), port}); }) .addStaticFunction("set_option", diff --git a/3rdparty/yasio/yasio/bindings/yasio_axlua.cpp b/3rdparty/yasio/yasio/bindings/yasio_axlua.cpp index 208f2b4ad653..4f4970657bc2 100644 --- a/3rdparty/yasio/yasio/bindings/yasio_axlua.cpp +++ b/3rdparty/yasio/yasio/bindings/yasio_axlua.cpp @@ -30,8 +30,6 @@ SOFTWARE. #include "yasio/bindings/yasio_axlua.hpp" #include "yasio/bindings/lyasio.hpp" #include "yasio/object_pool.hpp" -#include "yasio/ref_ptr.hpp" -#include "yasio/string_view.hpp" // A workaround to fix compile issue caused by `CCPlatformMacros.h` doesn't handle `__has_attribute` it properly # if !__has_attribute(format) @@ -40,6 +38,7 @@ SOFTWARE. #include "axmol/base/Director.h" #include "axmol/base/Scheduler.h" +#include "axmol/tlx/memory.hpp" using namespace ax; @@ -63,7 +62,15 @@ struct TimerObject static uintptr_t s_timerId; DEFINE_FAST_OBJECT_POOL_ALLOCATION(TimerObject, 128) - YASIO__DEFINE_REFERENCE_CLASS + + void retain() { ++_referenceCount; } + void release() + { + if (--_referenceCount == 0) + delete this; + } + + uint32_t _referenceCount{1}; }; uintptr_t TimerObject::s_timerId = 0; @@ -71,7 +78,7 @@ static TIMER_ID loop(unsigned int n, float interval, vcallback_t callback) { if (n > 0 && interval >= 0) { - yasio::ref_ptr timerObj(new TimerObject(std::move(callback))); + tlx::retain_ptr timerObj(new TimerObject(std::move(callback)), tlx::adopt_object); auto timerId = reinterpret_cast(++TimerObject::s_timerId); @@ -93,7 +100,7 @@ static TIMER_ID delay(float delay, vcallback_t callback) { if (delay > 0) { - yasio::ref_ptr timerObj(new TimerObject(std::move(callback))); + tlx::retain_ptr timerObj(new TimerObject(std::move(callback)), tlx::adopt_object); auto timerId = reinterpret_cast(++TimerObject::s_timerId); std::string key = fmt::format("LSTMR#{}", fmt::ptr(timerId)); diff --git a/3rdparty/yasio/yasio/bindings/yasio_sol.hpp b/3rdparty/yasio/yasio/bindings/yasio_sol.hpp index 604056ca11dc..70d51851d997 100644 --- a/3rdparty/yasio/yasio/bindings/yasio_sol.hpp +++ b/3rdparty/yasio/yasio/bindings/yasio_sol.hpp @@ -31,33 +31,33 @@ SOFTWARE. # include "sol2/sol.hpp" // sol2-2.x #endif -// use cxx17::string_view workaround with std::string_view +// use std::string_view workaround with std::string_view #if !YASIO__HAS_CXX17 namespace sol { namespace stack { template <> -struct pusher { - static int push(lua_State* L, const cxx17::string_view& str) +struct pusher { + static int push(lua_State* L, const std::string_view& str) { lua_pushlstring(L, !str.empty() ? str.c_str() : "", str.length()); return 1; } }; template <> -struct getter { - static cxx17::string_view get(lua_State* L, int index, record& tracking) +struct getter { + static std::string_view get(lua_State* L, int index, record& tracking) { tracking.use(1); // THIS IS THE ONLY BIT THAT CHANGES size_t len = 0; const char* s = lua_tolstring(L, index, &len); - return cxx17::string_view(s, len); + return std::string_view(s, len); } }; } // namespace stack template <> -struct lua_type_of : std::integral_constant {}; +struct lua_type_of : std::integral_constant {}; } // namespace sol #endif diff --git a/3rdparty/yasio/yasio/buffer_alloc.hpp b/3rdparty/yasio/yasio/buffer_alloc.hpp deleted file mode 100644 index 9a4981b30d67..000000000000 --- a/3rdparty/yasio/yasio/buffer_alloc.hpp +++ /dev/null @@ -1,119 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////////// -// A multi-platform support c++11 library with focus on asynchronous socket I/O for any -// client application. -////////////////////////////////////////////////////////////////////////////////////////// -/* -The MIT License (MIT) - -Copyright (c) 2012-2025 HALX99 - -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. -*/ - -#ifndef YASIO__BUFFER_ALLOC_HPP -#define YASIO__BUFFER_ALLOC_HPP -#include -#include -#include -#include -#include -#include "yasio/compiler/feature_test.hpp" -#include "yasio/type_traits.hpp" - -#define _YASIO_VERIFY_RANGE(cond, mesg) \ - do \ - { \ - if (cond) \ - ; /* contextually convertible to bool paranoia */ \ - else \ - { \ - throw std::out_of_range(mesg); \ - } \ - \ - } while (false) - -namespace yasio -{ -template -struct buffer_allocator_traits { - using value_type = typename _Alty::value_type; - using size_type = size_t; - static YASIO__CONSTEXPR size_type max_size() { return static_cast(-1) / sizeof(value_type); } - static value_type* reallocate(void* block, size_t size, size_t new_size) - { - return static_cast(_Alty::reallocate(block, size, new_size * sizeof(value_type))); - } - static void deallocate(void* block, size_t size) { _Alty::deallocate(block, size); } -}; -template ::value, int> = 0> -struct buffer_allocator { - using value_type = _Ty; - static value_type* reallocate(void* block, size_t /*size*/, size_t new_size) - { - return static_cast(::realloc(block, new_size * sizeof(value_type))); - } - static void deallocate(void* block, size_t /*size*/) { ::free(block); } -}; -template ::value, int> = 0> -struct std_buffer_allocator { - using value_type = _Ty; - static value_type* reallocate(void* block, size_t size, size_t new_size) - { - if (!block) - return new (std::nothrow) value_type[new_size]; - void* new_block = nullptr; - if (new_size) - { - if (new_size <= size) - return block; - new_block = new (std::nothrow) value_type[new_size]; - if (new_block) - memcpy(new_block, block, size); - } - delete[] (value_type*)block; - return (value_type*)new_block; - } - static void deallocate(void* block, size_t /*size*/) { delete[] (value_type*)block; } -}; -template -struct construct_helper { - template - static _Ty* construct_at(_Ty* p, Args&&... args) - { - return ::new (static_cast(p)) _Ty(std::forward(args)...); - } -}; -template -struct construct_helper<_Ty, false> { - template - static _Ty* construct_at(_Ty* p, Args&&... args) - { - return ::new (static_cast(p)) _Ty{std::forward(args)...}; - } -}; - -template -inline _Ty* construct_at(_Ty* p, Args&&... args) -{ - return construct_helper<_Ty, std::is_constructible<_Ty, Args&&...>::value>::construct_at(p, std::forward(args)...); -} - -} // namespace yasio - -#endif diff --git a/3rdparty/yasio/yasio/compiler/feature_test.hpp b/3rdparty/yasio/yasio/compiler/feature_test.hpp index c74cce335eab..fa4e839d486d 100644 --- a/3rdparty/yasio/yasio/compiler/feature_test.hpp +++ b/3rdparty/yasio/yasio/compiler/feature_test.hpp @@ -119,8 +119,21 @@ SOFTWARE. # define YASIO__OS_BSD_LIKE 0 #endif +#if !defined(_WIN32) || (defined(NTDDI_VERSION) && NTDDI_VERSION >= NTDDI_VISTA) || (defined(_WIN32_WINNT) && _WIN32_WINNT >= 0x0600) +# define YASIO__OS_NT6 1 +#else +# define YASIO__OS_NT6 0 +#endif + /// Tests multiplex io model of current OS +// poll +#if YASIO__OS_NT6 +# define YASIO__HAS_POLL 1 +#else +# define YASIO__HAS_POLL 0 +#endif + // ppoll #if defined(__linux__) && !defined(__ANDROID__) || (defined(__ANDROID_API__) && __ANDROID_API__ >= 21) # define YASIO__HAS_PPOLL 1 @@ -170,12 +183,18 @@ SOFTWARE. # define YASIO__HAS_SA_LEN 0 #endif -#if !defined(_WIN32) || defined(NTDDI_VISTA) +#if YASIO__OS_NT6 # define YASIO__HAS_NTOP 1 #else # define YASIO__HAS_NTOP 0 #endif +#if defined(NTDDI_WIN10_RS2) && NTDDI_VERSION >= NTDDI_WIN10_RS2 +# define YASIO__OS_NT10_RS2 1 +#else +# define YASIO__OS_NT10_RS2 0 +#endif + #if defined(_WIN32) && (!defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_APP)) && !defined(__MINGW64__) && !defined(__MINGW32__) # define YASIO__HAS_WIN32_TIMEAPI 1 #else @@ -240,18 +259,7 @@ SOFTWARE. #define YASIO__STD ::std:: -#if YASIO__HAS_CXX14 -namespace cxx14 -{ -using namespace std; -}; -#endif - -#if YASIO__HAS_CXX17 -namespace cxx17 -{ -using namespace std; -}; -#endif +// The yasio is the original tlx provider +#define _TLX ::tlx:: #endif diff --git a/3rdparty/yasio/yasio/config.hpp b/3rdparty/yasio/yasio/config.hpp index 7935b7aaf164..58ede2be06f7 100644 --- a/3rdparty/yasio/yasio/config.hpp +++ b/3rdparty/yasio/yasio/config.hpp @@ -87,12 +87,6 @@ SOFTWARE. */ // #define YASIO_ENABLE_UDS 1 -/* -** Uncomment or add compiler flag -DYASIO_NT_COMPAT_GAI for compatible with Windows XP -** see: https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfo -*/ -// #define YASIO_NT_COMPAT_GAI 1 - /* ** Uncomment or add compiler flag -DYASIO_NT_XHRES_TIMER to forcing use undocumented NT API to setup high-resolution timer */ diff --git a/3rdparty/yasio/yasio/ibstream.hpp b/3rdparty/yasio/yasio/ibstream.hpp index 9f7bb6361f61..b5ff39301e54 100644 --- a/3rdparty/yasio/yasio/ibstream.hpp +++ b/3rdparty/yasio/yasio/ibstream.hpp @@ -123,8 +123,8 @@ class binary_reader_impl { using convert_traits_type = _Traits; using this_type = binary_reader_impl<_Traits>; binary_reader_impl() { this->reset("", 0); } - binary_reader_impl(const sbyte_buffer& d) { this->reset(d); } - binary_reader_impl(const cxx17::string_view& d) { this->reset(d); } + binary_reader_impl(const tlx::sbyte_buffer& d) { this->reset(d); } + binary_reader_impl(const std::string_view& d) { this->reset(d); } binary_reader_impl(const void* data, size_t size) { this->reset(data, size); } template binary_reader_impl(const binary_writer_impl<_Traits, _BufferType>* obs) @@ -143,8 +143,8 @@ class binary_reader_impl { ~binary_reader_impl() {} - void reset(const sbyte_buffer& d) { reset(d.data(), d.size()); } - void reset(const cxx17::string_view& d) { reset(d.data(), d.length()); } + void reset(const tlx::sbyte_buffer& d) { reset(d.data(), d.size()); } + void reset(const std::string_view& d) { reset(d.data(), d.length()); } void reset(const void* data, size_t size) { first_ = ptr_ = static_cast(data); @@ -165,7 +165,7 @@ class binary_reader_impl { int read_varint(int size) { - size = yasio::clamp(size, 1, YASIO_SSIZEOF(int)); + size = std::clamp(size, 1, YASIO_SSIZEOF(int)); int value = 0; ::memcpy(&value, consume(size), size); @@ -173,7 +173,7 @@ class binary_reader_impl { } /* read blob data with '7bit encoded int' length field */ - cxx17::string_view read_v() + std::string_view read_v() { int count = read_ix(); return read_bytes(count); @@ -210,15 +210,15 @@ class binary_reader_impl { ::memcpy(oav, consume(len), len); } - cxx17::string_view read_v32() { return read_v_fx(); } - cxx17::string_view read_v16() { return read_v_fx(); } - cxx17::string_view read_v8() { return read_v_fx(); } + std::string_view read_v32() { return read_v_fx(); } + std::string_view read_v16() { return read_v_fx(); } + std::string_view read_v8() { return read_v_fx(); } - cxx17::string_view read_bytes(int len) + std::string_view read_bytes(int len) { if (len > 0) - return cxx17::string_view(consume(len), len); - return cxx17::string_view{}; + return std::string_view(consume(len), len); + return std::string_view{}; } bool empty() const { return first_ == last_; } @@ -264,7 +264,7 @@ class binary_reader_impl { } template - inline cxx17::string_view read_v_fx() + inline std::string_view read_v_fx() { _LenT n = this->read<_LenT>(); if (n > 0) @@ -272,11 +272,11 @@ class binary_reader_impl { return {}; } - cxx17::string_view range_view(size_t start, size_t end) + std::string_view range_view(size_t start, size_t end) { if (start <= end && (first_ + end) <= last_) - return cxx17::string_view{first_ + start, end - start}; - return cxx17::string_view{}; + return std::string_view{first_ + start, end - start}; + return std::string_view{}; } bool eof() const { return ptr_ == last_; } @@ -305,7 +305,7 @@ template class basic_ibstream : public binary_reader_impl<_Traits> { public: basic_ibstream() {} - basic_ibstream(sbyte_buffer blob) : binary_reader_impl<_Traits>(), blob_(std::move(blob)) { this->reset(blob_.data(), static_cast(blob_.size())); } + basic_ibstream(tlx::sbyte_buffer blob) : binary_reader_impl<_Traits>(), blob_(std::move(blob)) { this->reset(blob_.data(), static_cast(blob_.size())); } basic_ibstream(const basic_obstream<_Traits>* obs) : binary_reader_impl<_Traits>(), blob_(obs->buffer()) { this->reset(blob_.data(), static_cast(blob_.size())); @@ -332,7 +332,7 @@ class basic_ibstream : public binary_reader_impl<_Traits> { } protected: - sbyte_buffer blob_; + tlx::sbyte_buffer blob_; }; using ibstream_view = binary_reader_impl>; diff --git a/3rdparty/yasio/yasio/impl/mbedtls.hpp b/3rdparty/yasio/yasio/impl/mbedtls.hpp index 0bce89117844..450a4057532f 100644 --- a/3rdparty/yasio/yasio/impl/mbedtls.hpp +++ b/3rdparty/yasio/yasio/impl/mbedtls.hpp @@ -51,7 +51,7 @@ YASIO__DECL yssl_ctx_st* yssl_ctx_new(const yssl_options& opts) YASIO_LOG("mbedtls_ssl_config_defaults fail with ret=%d", ret); // rgn engine - cxx17::string_view pers = opts.client ? cxx17::string_view{YASIO_SSL_PIN, YASIO_SSL_PIN_LEN} : cxx17::string_view{YASIO_SSL_PON, YASIO_SSL_PON_LEN}; + std::string_view pers = opts.client ? std::string_view{YASIO_SSL_PIN, YASIO_SSL_PIN_LEN} : std::string_view{YASIO_SSL_PON, YASIO_SSL_PON_LEN}; ret = ::mbedtls_ctr_drbg_seed(&ctx->ctr_drbg, ::mbedtls_entropy_func, &ctx->entropy, (const unsigned char*)pers.data(), pers.length()); if (ret != 0) { diff --git a/3rdparty/yasio/yasio/impl/poll_io_watcher.hpp b/3rdparty/yasio/yasio/impl/poll_io_watcher.hpp index 7c65fd99d97c..bc41a1506b35 100644 --- a/3rdparty/yasio/yasio/impl/poll_io_watcher.hpp +++ b/3rdparty/yasio/yasio/impl/poll_io_watcher.hpp @@ -6,7 +6,7 @@ // Copyright (c) 2012-2025 HALX99 (halx99 at live dot com) #ifndef YASIO__POLL_IO_WATCHER_HPP #define YASIO__POLL_IO_WATCHER_HPP -#include "yasio/pod_vector.hpp" +#include "yasio/tlx/vector.hpp" #include "yasio/impl/socket.hpp" #include "yasio/impl/select_interrupter.hpp" @@ -77,7 +77,7 @@ class poll_io_watcher { } return underlying_events; } - static void pollfd_mod(yasio::pod_vector& fdset, socket_native_type fd, int add_events, int remove_events) + static void pollfd_mod(tlx::vector& fdset, socket_native_type fd, int add_events, int remove_events) { auto it = std::find_if(fdset.begin(), fdset.end(), [fd](const pollfd& pfd) { return pfd.fd == fd; }); if (it != fdset.end()) @@ -96,8 +96,8 @@ class poll_io_watcher { } protected: - yasio::pod_vector events_; - yasio::pod_vector revents_; + tlx::vector events_; + tlx::vector revents_; select_interrupter interrupter_; }; diff --git a/3rdparty/yasio/yasio/impl/socket.hpp b/3rdparty/yasio/yasio/impl/socket.hpp index 5b58b536befe..5cb51e35a40e 100644 --- a/3rdparty/yasio/yasio/impl/socket.hpp +++ b/3rdparty/yasio/yasio/impl/socket.hpp @@ -47,7 +47,7 @@ SOFTWARE. # include # include # include -# if defined(YASIO_NT_COMPAT_GAI) +# if NTDDI_VERSION < NTDDI_VISTA # include # endif # if YASIO__HAS_UDS diff --git a/3rdparty/yasio/yasio/io_service.cpp b/3rdparty/yasio/yasio/io_service.cpp index 615689c41476..3c1675a3c1b6 100644 --- a/3rdparty/yasio/yasio/io_service.cpp +++ b/3rdparty/yasio/yasio/io_service.cpp @@ -73,7 +73,7 @@ struct yasio_kcp_options { do \ { \ auto& __cprint = __get_cprint(); \ - auto __msg = ::yasio::strfmt(127, "[yasio][%lld]" format "\n", ::yasio::clock(), ##__VA_ARGS__); \ + auto __msg = ::yasio::strfmt(127, "[yasio][%lld]" format "\n", ::tlx::clock<::tlx::system_clock_t>(), ##__VA_ARGS__); \ if (__cprint) \ __cprint(level, __msg.c_str()); \ else { \ @@ -320,11 +320,11 @@ int io_channel::configure_multicast_group(bool onoff) return socket_->set_optval(IPPROTO_IPV6, onoff ? IPV6_JOIN_GROUP : IPV6_LEAVE_GROUP, &mreq_v6, (int)sizeof(mreq_v6)); } } -void io_channel::set_host(cxx17::string_view host) +void io_channel::set_host(std::string_view host) { if (this->remote_host_ != host) { - cxx17::assign(this->remote_host_, host); + this->remote_host_ = host; yasio__setbits(properties_, YCPF_HOST_DIRTY); } } @@ -360,7 +360,7 @@ int io_channel::__builtin_decode_len(void* d, int n) return n; } // -------------------- io_transport --------------------- -io_transport::io_transport(io_channel* ctx, xxsocket_ptr&& s) : ctx_(ctx) +io_transport::io_transport(io_channel* ctx, xxsocket_ptr&& s) : ctx_(ctx), buffer_(yasio__max_rcvbuf) { this->state_ = io_base::state::OPENED; this->socket_ = std::move(s); @@ -372,15 +372,15 @@ const print_fn2_t& io_transport::__get_cprint() const { return ctx_->get_service int io_transport::write(io_send_buffer&& buffer, completion_cb_t&& handler) { int n = static_cast(buffer.size()); - send_queue_.emplace(cxx14::make_unique(std::move(buffer), std::move(handler))); + send_queue_.emplace(std::make_unique(std::move(buffer), std::move(handler))); get_service().wakeup(); return n; } -int io_transport::do_read(int revent, int& error, highp_time_t&) +int io_transport::do_read(int revent, int& error, tlx::highp_time_t&) { return this->call_read(buffer_.data() + offset_, static_cast(buffer_.size() - offset_), revent, error); } -bool io_transport::do_write(highp_time_t& wait_duration) +bool io_transport::do_write(tlx::highp_time_t& wait_duration) { bool ret = false; do @@ -623,7 +623,7 @@ int io_transport_udp::write(io_send_buffer&& buffer, completion_cb_t&& handler) int io_transport_udp::write_to(io_send_buffer&& buffer, const ip::endpoint& to, completion_cb_t&& handler) { int n = static_cast(buffer.size()); - send_queue_.emplace(cxx14::make_unique(std::move(buffer), std::move(handler), to)); + send_queue_.emplace(std::make_unique(std::move(buffer), std::move(handler), to)); get_service().wakeup(); return n; } @@ -660,7 +660,7 @@ void io_transport_udp::set_primitives() }; } } -int io_transport_udp::handle_input(char* data, int bytes_transferred, int& /*error*/, highp_time_t&) +int io_transport_udp::handle_input(char* data, int bytes_transferred, int& /*error*/, tlx::highp_time_t&) { // pure udp, dispatch to upper layer directly auto& service = get_service(); if (!service.options_.forward_packet_) @@ -707,7 +707,7 @@ void io_transport_kcp::set_primitives() return nsent; }; } -bool io_transport_kcp::do_write(highp_time_t& wait_duration) +bool io_transport_kcp::do_write(tlx::highp_time_t& wait_duration) { bool ret = io_transport_udp::do_write(wait_duration); @@ -720,7 +720,7 @@ bool io_transport_kcp::do_write(highp_time_t& wait_duration) return ret; } -int io_transport_kcp::do_read(int revent, int& error, highp_time_t& wait_duration) +int io_transport_kcp::do_read(int revent, int& error, tlx::highp_time_t& wait_duration) { int n = this->call_read(&rawbuf_.front(), static_cast(rawbuf_.size()), revent, error); if (n > 0) @@ -742,7 +742,7 @@ int io_transport_kcp::do_read(int revent, int& error, highp_time_t& wait_duratio } return n; } -int io_transport_kcp::handle_input(char* buf, int len, int& error, highp_time_t& wait_duration) +int io_transport_kcp::handle_input(char* buf, int len, int& error, tlx::highp_time_t& wait_duration) { // ikcp in event always in service thread, so no need to lock if (0 == ::ikcp_input(kcp_, buf, len)) @@ -867,7 +867,7 @@ void io_service::initialize(const io_hostent* channel_eps, int channel_count) create_channels(channel_eps, channel_count); #if !defined(YASIO_USE_CARES) - life_mutex_ = std::make_shared(); + life_mutex_ = std::make_shared(); life_token_ = std::make_shared(); #endif this->state_ = io_service::state::IDLE; @@ -877,7 +877,7 @@ void io_service::finalize() if (this->state_ == io_service::state::IDLE) { #if !defined(YASIO_USE_CARES) - std::unique_lock lck(*life_mutex_); + std::unique_lock lck(*life_mutex_); life_token_.reset(); #endif destroy_channels(); @@ -919,7 +919,7 @@ void io_service::clear_transports() for (auto transport : transports_) { cleanup_io(transport); - yasio::invoke_dtor(transport); + tlx::invoke_dtor(transport); this->tpool_.push_back(transport); } transports_.clear(); @@ -972,7 +972,7 @@ void io_service::run() do { - this->current_time_ = yasio::steady_clock_t::now(); + this->current_time_ = tlx::steady_clock_t::now(); auto waitd_usec = get_timeout(this->wait_duration_); // Gets current wait duration #if defined(YASIO_USE_CARES) @@ -1188,7 +1188,7 @@ void io_service::handle_close(transport_handle_t thandle) cleanup_channel(ctx, false); } } -int io_service::write(transport_handle_t transport, sbyte_buffer buffer, completion_cb_t handler) +int io_service::write(transport_handle_t transport, tlx::sbyte_buffer buffer, completion_cb_t handler) { if (transport && transport->is_open()) return !buffer.empty() ? transport->write(io_send_buffer{std::move(buffer)}, std::move(handler)) : 0; @@ -1208,7 +1208,7 @@ int io_service::forward(transport_handle_t transport, const void* buf, size_t le return -1; } } -int io_service::write_to(transport_handle_t transport, sbyte_buffer buffer, const ip::endpoint& to, completion_cb_t handler) +int io_service::write_to(transport_handle_t transport, tlx::sbyte_buffer buffer, const ip::endpoint& to, completion_cb_t handler) { if (transport && transport->is_open()) return !buffer.empty() ? transport->write_to(io_send_buffer{std::move(buffer)}, to, std::move(handler)) : 0; @@ -1760,7 +1760,7 @@ void io_service::deallocate_transport(transport_handle_t t) { if (t->is_valid()) { - yasio::invoke_dtor(t); + tlx::invoke_dtor(t); this->tpool_.push_back(t); } } @@ -1814,7 +1814,7 @@ bool io_service::do_read(transport_handle_t transport) } else if (n > 0) { // forward packet, don't perform unpack, it's useful for implement streaming based protocol, like http, websocket and ... - this->forward_packet(transport->cindex(), io_packet_view{transport->buffer_.data(), n}, transport); + this->forward_packet(transport->cindex(), io_packet_view(transport->buffer_.data(), n), transport); } } else @@ -1959,7 +1959,7 @@ void io_service::process_deferred_events() if (!options_.no_dispatch_ && dispatch() > 0) this->wait_duration_ = 0; } -highp_time_t io_service::get_timeout(highp_time_t usec) +tlx::highp_time_t io_service::get_timeout(tlx::highp_time_t usec) { this->wait_duration_ = this->sched_freq_; // Reset next wait duration per frame @@ -2062,10 +2062,10 @@ void io_service::start_query(io_channel* ctx) #endif #if !defined(YASIO_USE_CARES) // init async name query thread state - auto resolving_host = ctx->remote_host_; - auto resolving_port = ctx->remote_port_; - std::weak_ptr weak_mutex = life_mutex_; - std::weak_ptr life_token = life_token_; + auto resolving_host = ctx->remote_host_; + auto resolving_port = ctx->remote_port_; + std::weak_ptr weak_mutex = life_mutex_; + std::weak_ptr life_token = life_token_; std::thread async_resolv_thread([this, life_token, weak_mutex, resolving_host, resolving_port, ctx] { // check life token if (life_token.use_count() < 1) @@ -2079,7 +2079,7 @@ void io_service::start_query(io_channel* ctx) auto pmtx = weak_mutex.lock(); if (!pmtx) return; - cxx17::shared_lock lck(*pmtx); + std::shared_lock lck(*pmtx); // check life token again, when io_service cleanup done, life_token's use_count will be 0, // otherwise, we can safe to do follow assignments. @@ -2088,7 +2088,7 @@ void io_service::start_query(io_channel* ctx) if (error == 0) { ctx->remote_eps_ = std::move(remote_eps); - ctx->query_success_time_ = highp_clock(); + ctx->query_success_time_ = tlx::highp_clock(); # if defined(YASIO_ENABLE_ARES_PROFILER) YASIO_KLOGD("[index: %d] query %s succeed, cost: %g(ms)", ctx->index_, ctx->remote_host_.c_str(), (ctx->query_success_time_ - ctx->query_start_time_) / 1000.0); @@ -2209,22 +2209,22 @@ void io_service::set_option_internal(int opt, va_list ap) // lgtm [cpp/poorly-do break; #endif case YOPT_S_CONNECT_TIMEOUT: - options_.connect_timeout_ = static_cast(va_arg(ap, int)) * std::micro::den; + options_.connect_timeout_ = static_cast(va_arg(ap, int)) * std::micro::den; break; case YOPT_S_CONNECT_TIMEOUTMS: - options_.connect_timeout_ = static_cast(va_arg(ap, int)) * std::milli::den; + options_.connect_timeout_ = static_cast(va_arg(ap, int)) * std::milli::den; break; case YOPT_S_DNS_CACHE_TIMEOUT: - options_.dns_cache_timeout_ = static_cast(va_arg(ap, int)) * std::micro::den; + options_.dns_cache_timeout_ = static_cast(va_arg(ap, int)) * std::micro::den; break; case YOPT_S_DNS_CACHE_TIMEOUTMS: - options_.dns_cache_timeout_ = static_cast(va_arg(ap, int)) * std::milli::den; + options_.dns_cache_timeout_ = static_cast(va_arg(ap, int)) * std::milli::den; break; case YOPT_S_DNS_QUERIES_TIMEOUT: - options_.dns_queries_timeout_ = static_cast(va_arg(ap, int)) * std::micro::den; + options_.dns_queries_timeout_ = static_cast(va_arg(ap, int)) * std::micro::den; break; case YOPT_S_DNS_QUERIES_TIMEOUTMS: - options_.dns_queries_timeout_ = static_cast(va_arg(ap, int)) * std::milli::den; + options_.dns_queries_timeout_ = static_cast(va_arg(ap, int)) * std::milli::den; break; case YOPT_S_DNS_QUERIES_TRIES: options_.dns_queries_tries_ = va_arg(ap, int); @@ -2264,7 +2264,7 @@ void io_service::set_option_internal(int opt, va_list ap) // lgtm [cpp/poorly-do { channel->uparams_.max_frame_length = va_arg(ap, int); channel->uparams_.length_field_offset = va_arg(ap, int); - channel->uparams_.length_field_length = yasio::clamp(va_arg(ap, int), YASIO_SSIZEOF(int8_t), YASIO_SSIZEOF(int)); + channel->uparams_.length_field_length = std::clamp(va_arg(ap, int), YASIO_SSIZEOF(int8_t), YASIO_SSIZEOF(int)); channel->uparams_.length_adjustment = va_arg(ap, int); } break; @@ -2272,7 +2272,7 @@ void io_service::set_option_internal(int opt, va_list ap) // lgtm [cpp/poorly-do case YOPT_C_UNPACK_STRIP: { auto channel = channel_at(static_cast(va_arg(ap, int))); if (channel) - channel->uparams_.initial_bytes_to_strip = yasio::clamp(va_arg(ap, int), 0, YASIO_UNPACK_MAX_STRIP); + channel->uparams_.initial_bytes_to_strip = std::clamp(va_arg(ap, int), 0, YASIO_UNPACK_MAX_STRIP); break; } case YOPT_C_UNPACK_NO_BSWAP: { diff --git a/3rdparty/yasio/yasio/io_service.hpp b/3rdparty/yasio/yasio/io_service.hpp index 3040df174679..70112ba51ece 100644 --- a/3rdparty/yasio/yasio/io_service.hpp +++ b/3rdparty/yasio/yasio/io_service.hpp @@ -39,19 +39,19 @@ SOFTWARE. #include #include "yasio/sz.hpp" #include "yasio/config.hpp" -#include "yasio/singleton.hpp" #include "yasio/impl/concurrent_queue.hpp" -#include "yasio/utils.hpp" +#include "yasio/tlx/singleton.hpp" +#include "yasio/tlx/chrono.hpp" #include "yasio/errc.hpp" -#include "yasio/memory.hpp" -#include "yasio/string_view.hpp" +#include "yasio/tlx/memory.hpp" +#include "yasio/tlx/string_view.hpp" #include "yasio/object_pool.hpp" -#include "yasio/byte_buffer.hpp" +#include "yasio/tlx/byte_buffer.hpp" #include "yasio/xxsocket.hpp" #include "yasio/io_watcher.hpp" #if !defined(YASIO_USE_CARES) -# include "yasio/shared_mutex.hpp" +# include "yasio/tlx/shared_mutex.hpp" #endif #if defined(YASIO_ENABLE_KCP) @@ -400,7 +400,7 @@ typedef completion_cb_t io_completion_cb_t; namespace { -static const int yasio__max_rcvbuf = YASIO_SZ(64, k); +static const size_t yasio__max_rcvbuf = YASIO_SZ(64, k); } // namespace // the ssl role @@ -412,10 +412,10 @@ enum ssl_role struct io_hostent { io_hostent() = default; - io_hostent(cxx17::string_view ip, u_short port) : host_(cxx17::svtos(ip)), port_(port) {} + io_hostent(std::string_view ip, u_short port) : host_(ip), port_(port) {} io_hostent(io_hostent&& rhs) YASIO__NOEXCEPT : host_(std::move(rhs.host_)), port_(rhs.port_) {} io_hostent(const io_hostent& rhs) : host_(rhs.host_), port_(rhs.port_) {} - void set_ip(cxx17::string_view ip) { cxx17::assign(host_, ip); } + void set_ip(std::string_view ip) { host_ = ip; } const std::string& get_ip() const { return host_; } void set_port(u_short port) { port_ = port; } u_short get_port() const { return port_; } @@ -425,17 +425,17 @@ struct io_hostent { class YASIO_API highp_timer { public: - highp_timer(io_service& service) : service_(service){}; + highp_timer(io_service& service) : service_(service) {}; highp_timer(const highp_timer&) = delete; highp_timer(highp_timer&&) = delete; highp_timer& operator=(const highp_timer&) = delete; void expires_from_now(const std::chrono::microseconds& duration) { this->duration_ = duration; - this->expire_time_ = yasio::steady_clock_t::now() + this->duration_; + this->expire_time_ = tlx::steady_clock_t::now() + this->duration_; } - void expires_from_now() { this->expire_time_ = yasio::steady_clock_t::now() + this->duration_; } + void expires_from_now() { this->expire_time_ = tlx::steady_clock_t::now() + this->duration_; } // Wait timer timeout once. void async_wait_once(timerv_cb_t cb) @@ -466,8 +466,8 @@ class YASIO_API highp_timer { YASIO__DECL std::chrono::microseconds wait_duration() const; io_service& service_; - std::chrono::microseconds duration_ = {}; - std::chrono::time_point expire_time_ = {}; + std::chrono::microseconds duration_ = {}; + std::chrono::time_point expire_time_ = {}; }; struct YASIO_API io_base { @@ -561,13 +561,13 @@ class YASIO_API io_channel : public io_base { private: YASIO__DECL io_channel(io_service& service, int index); - void set_address(cxx17::string_view host, u_short port) + void set_address(std::string_view host, u_short port) { set_host(host); set_port(port); } - YASIO__DECL void set_host(cxx17::string_view host); + YASIO__DECL void set_host(std::string_view host); YASIO__DECL void set_port(u_short port); void clear_mutable_flags() { properties_ &= 0x00ffffff; } @@ -598,7 +598,7 @@ class YASIO_API io_channel : public io_base { u_short remote_port_ = 0; // The last query success time in microseconds for dns cache support - highp_time_t query_success_time_ = 0; + tlx::highp_time_t query_success_time_ = 0; #if defined(YASIO_ENABLE_ARES_PROFILER) highp_time_t query_start_time_; @@ -642,7 +642,7 @@ class YASIO_API io_channel : public io_base { ip::endpoint multiaddr_, multiif_; // Current it's only for UDP - sbyte_buffer buffer_; + tlx::sbyte_buffer buffer_; // The bytes transferred from socket low layer, currently, only works for client channel long long bytes_transferred_ = 0; @@ -655,7 +655,7 @@ class YASIO_API io_channel : public io_base { class io_send_buffer { public: - explicit io_send_buffer(yasio::sbyte_buffer&& mutable_buffer) + explicit io_send_buffer(tlx::sbyte_buffer&& mutable_buffer) { mutable_buffer_ = std::move(mutable_buffer); data_ = mutable_buffer_.data(); @@ -680,7 +680,7 @@ class io_send_buffer { size_t size() const { return size_; } private: - yasio::sbyte_buffer mutable_buffer_; + tlx::sbyte_buffer mutable_buffer_; const char* data_; size_t size_; @@ -742,7 +742,7 @@ class io_transport : public io_base { protected: io_service& get_service() const { return ctx_->get_service(); } bool is_open() const { return state_ == state::OPENED && socket_ && socket_->is_open(); } - sbyte_buffer fetch_packet() + tlx::sbyte_buffer fetch_packet() { expected_size_ = -1; return std::move(expected_packet_); @@ -766,10 +766,10 @@ class io_transport : public io_base { YASIO__DECL void complete_op(io_send_op*, int error); // Call at io_service - YASIO__DECL virtual int do_read(int revent, int& error, highp_time_t& wait_duration); + YASIO__DECL virtual int do_read(int revent, int& error, tlx::highp_time_t& wait_duration); // Call at io_service, try flush pending packet - YASIO__DECL virtual bool do_write(highp_time_t& wait_duration); + YASIO__DECL virtual bool do_write(tlx::highp_time_t& wait_duration); // Sets the underlying layer socket io primitives. YASIO__DECL virtual void set_primitives(); @@ -778,11 +778,11 @@ class io_transport : public io_base { bool is_valid() const { return ctx_ != nullptr; } - yasio::sbyte_buffer buffer_{static_cast(yasio__max_rcvbuf)}; - int offset_ = 0; // recv buffer offset + tlx::sbyte_buffer buffer_; + int offset_ = 0; // recv buffer offset int expected_size_ = -1; - sbyte_buffer expected_packet_; + tlx::sbyte_buffer expected_packet_; io_channel* ctx_; @@ -838,7 +838,7 @@ class YASIO_API io_transport_udp : public io_transport { YASIO__DECL void confgure_remote(const ip::endpoint& peer); // process received data from low level - YASIO__DECL virtual int handle_input(char* data, int bytes_transferred, int& error, highp_time_t& wait_duration); + YASIO__DECL virtual int handle_input(char* data, int bytes_transferred, int& error, tlx::highp_time_t& wait_duration); ip::endpoint peer_; // for recv only, unstable mutable ip::endpoint destination_; // for sendto only, stable @@ -856,11 +856,11 @@ class io_transport_kcp : public io_transport_udp { protected: YASIO__DECL void set_primitives() override; - YASIO__DECL int do_read(int revent, int& error, highp_time_t& wait_duration) override; + YASIO__DECL int do_read(int revent, int& error, tlx::highp_time_t& wait_duration) override; YASIO__DECL bool do_write(highp_time_t& wait_duration) override; - YASIO__DECL int handle_input(char* buf, int len, int& error, highp_time_t& wait_duration) override; + YASIO__DECL int handle_input(char* buf, int len, int& error, tlx::highp_time_t& wait_duration) override; int interval() const { return kcp_->interval * std::milli::den; } @@ -873,7 +873,7 @@ class io_transport_kcp : public io_transport_udp { class io_transport_kcp {}; #endif -using io_packet = sbyte_buffer; +using io_packet = tlx::sbyte_buffer; #if !defined(YASIO_USE_SHARED_PACKET) using packet_t = io_packet; inline packet_t wrap_packet(io_packet& raw_packet) { return std::move(raw_packet); } @@ -977,7 +977,7 @@ class io_event final { if (t) t->ud_.ptr = (void*)(uintptr_t)uval; } - highp_time_t timestamp() const { return timestamp_; } + tlx::highp_time_t timestamp() const { return timestamp_; } #endif #if !defined(YASIO_DISABLE_OBJECT_POOL) DEFINE_CONCURRENT_OBJECT_POOL_ALLOCATION(io_event, 128) @@ -997,7 +997,7 @@ class io_event final { io_packet_view packet_view_; #if !defined(YASIO_MINIFY_EVENT) void* source_ud_; - highp_time_t timestamp_ = highp_clock(); + tlx::highp_time_t timestamp_ = tlx::highp_clock(); #endif }; @@ -1097,9 +1097,9 @@ class YASIO_API io_service // lgtm [cpp/class-many-fields] */ int write(transport_handle_t thandle, const void* buf, size_t len, completion_cb_t completion_handler = nullptr) { - return write(thandle, sbyte_buffer{(const char*)buf, (const char*)buf + len}, std::move(completion_handler)); + return write(thandle, tlx::sbyte_buffer{(const char*)buf, (const char*)buf + len}, std::move(completion_handler)); } - YASIO__DECL int write(transport_handle_t thandle, sbyte_buffer buffer, completion_cb_t completion_handler = nullptr); + YASIO__DECL int write(transport_handle_t thandle, tlx::sbyte_buffer buffer, completion_cb_t completion_handler = nullptr); YASIO__DECL int forward(transport_handle_t thandle, const void* buf, size_t len, completion_cb_t completion_handler); /* @@ -1111,9 +1111,9 @@ class YASIO_API io_service // lgtm [cpp/class-many-fields] */ int write_to(transport_handle_t thandle, const void* buf, size_t len, const ip::endpoint& to, completion_cb_t completion_handler = nullptr) { - return write_to(thandle, sbyte_buffer{(const char*)buf, (const char*)buf + len}, to, std::move(completion_handler)); + return write_to(thandle, tlx::sbyte_buffer{(const char*)buf, (const char*)buf + len}, to, std::move(completion_handler)); } - YASIO__DECL int write_to(transport_handle_t thandle, sbyte_buffer buffer, const ip::endpoint& to, completion_cb_t completion_handler = nullptr); + YASIO__DECL int write_to(transport_handle_t thandle, tlx::sbyte_buffer buffer, const ip::endpoint& to, completion_cb_t completion_handler = nullptr); YASIO__DECL int forward_to(transport_handle_t thandle, const void* buf, size_t len, const ip::endpoint& to, completion_cb_t completion_handler); // The highp_timer support, !important, the callback is called on the thread of io_service @@ -1159,7 +1159,7 @@ class YASIO_API io_service // lgtm [cpp/class-many-fields] YASIO__DECL void wakeup(); - YASIO__DECL highp_time_t get_timeout(highp_time_t usec); + YASIO__DECL tlx::highp_time_t get_timeout(tlx::highp_time_t usec); YASIO__DECL int do_resolve(io_channel* ctx); YASIO__DECL void do_connect(io_channel*); @@ -1207,7 +1207,7 @@ class YASIO_API io_service // lgtm [cpp/class-many-fields] template inline void fire_event(_Types&&... args) { - auto event = cxx14::make_unique(std::forward<_Types>(args)...); + auto event = std::make_unique(std::forward<_Types>(args)...); if (options_.on_defer_event_ && options_.on_defer_event_(event)) return; events_.emplace(std::move(event)); @@ -1215,7 +1215,7 @@ class YASIO_API io_service // lgtm [cpp/class-many-fields] template inline void forward_packet(_Types&&... args) { - options_.on_event_(cxx14::make_unique(std::forward<_Types>(args)...)); + options_.on_event_(std::make_unique(std::forward<_Types>(args)...)); } // new/delete client socket connection channel @@ -1239,7 +1239,7 @@ class YASIO_API io_service // lgtm [cpp/class-many-fields] YASIO__DECL void update_dns_status(); - bool address_expired(io_channel* ctx) const { return (highp_clock() - ctx->query_success_time_) > options_.dns_cache_timeout_; } + bool address_expired(io_channel* ctx) const { return (tlx::highp_clock() - ctx->query_success_time_) > options_.dns_cache_timeout_; } /* For log macro only */ inline const print_fn2_t& __get_cprint() const { return options_.print_; } @@ -1250,7 +1250,7 @@ class YASIO_API io_service // lgtm [cpp/class-many-fields] std::thread::id worker_id_; /* The current time according to the event loop. in msecs. */ - std::chrono::time_point current_time_; + std::chrono::time_point current_time_; privacy::concurrent_queue events_; @@ -1268,7 +1268,7 @@ class YASIO_API io_service // lgtm [cpp/class-many-fields] std::recursive_mutex timer_queue_mtx_; // the next wait duration for socket.select - highp_time_t wait_duration_; + tlx::highp_time_t wait_duration_; io_watcher io_watcher_; @@ -1277,10 +1277,10 @@ class YASIO_API io_service // lgtm [cpp/class-many-fields] // options struct __unnamed_options { - highp_time_t connect_timeout_ = 10LL * std::micro::den; - highp_time_t dns_cache_timeout_ = 600LL * std::micro::den; - highp_time_t dns_queries_timeout_ = 5LL * std::micro::den; - int dns_queries_tries_ = 5; + tlx::highp_time_t connect_timeout_ = 10LL * std::micro::den; + tlx::highp_time_t dns_cache_timeout_ = 600LL * std::micro::den; + tlx::highp_time_t dns_queries_timeout_ = 5LL * std::micro::den; + int dns_queries_tries_ = 5; bool dns_dirty_ = false; @@ -1339,7 +1339,7 @@ class YASIO_API io_service // lgtm [cpp/class-many-fields] // we need life_token + life_mutex struct life_token {}; std::shared_ptr life_token_; - std::shared_ptr life_mutex_; + std::shared_ptr life_mutex_; #endif }; // io_service @@ -1349,7 +1349,7 @@ using namespace yasio::inet; #endif } /* namespace yasio */ -#define yasio_shared_service yasio::singleton::instance +#define yasio_shared_service (_TLX singleton::instance) #if defined(YASIO_HEADER_ONLY) # include "yasio/io_service.cpp" // lgtm [cpp/include-non-header] diff --git a/3rdparty/yasio/yasio/io_watcher.hpp b/3rdparty/yasio/yasio/io_watcher.hpp index 074b8aed90c1..8e77067d51e3 100644 --- a/3rdparty/yasio/yasio/io_watcher.hpp +++ b/3rdparty/yasio/yasio/io_watcher.hpp @@ -17,7 +17,12 @@ #elif YASIO__HAS_EVPORT && defined(YASIO_ENABLE_HPERF_IO) # include "yasio/impl/evport_io_watcher.hpp" #elif !defined(YASIO_DISABLE_POLL) -# include "yasio/impl/poll_io_watcher.hpp" +# if YASIO__HAS_POLL +# include "yasio/impl/poll_io_watcher.hpp" +# else +# pragma message("Falling back to select_io_watcher due to target OS(NT < 6.0) not support poll") +# include "yasio/impl/select_io_watcher.hpp" +# endif #else # include "yasio/impl/select_io_watcher.hpp" #endif @@ -33,7 +38,7 @@ using io_watcher = kqueue_io_watcher; using io_watcher = epoll_io_watcher; #elif defined(YASIO__EVPORT_IO_WATCHER_HPP) using io_watcher = evport_io_watcher; -#elif !defined(YASIO_DISABLE_POLL) +#elif !defined(YASIO_DISABLE_POLL) && YASIO__HAS_POLL using io_watcher = poll_io_watcher; #else using io_watcher = select_io_watcher; diff --git a/3rdparty/yasio/yasio/memory.hpp b/3rdparty/yasio/yasio/memory.hpp deleted file mode 100644 index 830f76702fd9..000000000000 --- a/3rdparty/yasio/yasio/memory.hpp +++ /dev/null @@ -1,45 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////////// -// A multi-platform support c++11 library with focus on asynchronous socket I/O for any -// client application. -////////////////////////////////////////////////////////////////////////////////////////// -/* -The MIT License (MIT) - -Copyright (c) 2012-2025 HALX99 - -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. -*/ -#ifndef YASIO__MEMORY -#define YASIO__MEMORY -#include - -#include "yasio/compiler/feature_test.hpp" - -/// The make_unique workaround on c++11 -#if !YASIO__HAS_CXX14 -namespace cxx14 -{ -template std::unique_ptr<_Ty> make_unique(_Args&&... args) -{ - return std::unique_ptr<_Ty>(new _Ty(std::forward<_Args>(args)...)); -} -} // namespace cxx14 -#endif - -#endif diff --git a/3rdparty/yasio/yasio/object_pool.hpp b/3rdparty/yasio/yasio/object_pool.hpp index 7ac86283adc4..f3ee68247e00 100644 --- a/3rdparty/yasio/yasio/object_pool.hpp +++ b/3rdparty/yasio/yasio/object_pool.hpp @@ -28,7 +28,7 @@ SOFTWARE. #ifndef YASIO__OBJECT_POOL_HPP #define YASIO__OBJECT_POOL_HPP -#include "yasio/type_traits.hpp" +#include "yasio/tlx/type_traits.hpp" #include "yasio/impl/object_pool.hpp" namespace yasio @@ -40,7 +40,7 @@ struct null_mutex { template class object_pool : public detail::object_pool { public: - object_pool(size_t _ElemCount = 128) : detail::object_pool(::yasio::aligned_storage_size<_Ty>::value, _ElemCount) {} + object_pool(size_t _ElemCount = 128) : detail::object_pool(::tlx::aligned_storage_size<_Ty>::value, _ElemCount) {} template _Ty* create(_Types&&... args) diff --git a/3rdparty/yasio/yasio/obstream.hpp b/3rdparty/yasio/yasio/obstream.hpp index caea2f73a102..9c03bc3f80ed 100644 --- a/3rdparty/yasio/yasio/obstream.hpp +++ b/3rdparty/yasio/yasio/obstream.hpp @@ -33,10 +33,10 @@ SOFTWARE. #include #include #include -#include "yasio/string_view.hpp" +#include +#include "yasio/tlx/string_view.hpp" #include "yasio/endian_portable.hpp" -#include "yasio/utils.hpp" -#include "yasio/byte_buffer.hpp" +#include "yasio/tlx/byte_buffer.hpp" namespace yasio { enum : size_t @@ -143,7 +143,7 @@ class fixed_buffer : public fixed_buffer_span { std::array impl_; }; -template +template class dynamic_buffer_span { public: using implementation_type = _Cont; @@ -179,7 +179,7 @@ class dynamic_buffer_span { implementation_type* outs_; }; -template +template class dynamic_buffer : public dynamic_buffer_span<_Cont> { public: using super_type = dynamic_buffer_span<_Cont>; @@ -271,7 +271,7 @@ class binary_writer_impl { void push(int size) { - size = yasio::clamp(size, 1, YASIO_SSIZEOF(int)); + size = std::clamp(size, 1, YASIO_SSIZEOF(int)); auto bufsize = outs_->length(); offset_stack_.push(bufsize); @@ -280,7 +280,7 @@ class binary_writer_impl { void pop(int size) { - size = yasio::clamp(size, 1, YASIO_SSIZEOF(int)); + size = std::clamp(size, 1, YASIO_SSIZEOF(int)); auto offset = offset_stack_.top(); auto value = static_cast(outs_->length() - offset - size); @@ -291,7 +291,7 @@ class binary_writer_impl { void pop(int value, int size) { - size = yasio::clamp(size, 1, YASIO_SSIZEOF(int)); + size = std::clamp(size, 1, YASIO_SSIZEOF(int)); auto offset = offset_stack_.top(); value = convert_traits_type::toint(value, size); @@ -319,7 +319,7 @@ class binary_writer_impl { #endif /* write blob data with '7bit encoded int' length field */ - void write_v(cxx17::string_view value) + void write_v(std::string_view value) { int len = static_cast(value.length()); write_ix(len); @@ -327,15 +327,15 @@ class binary_writer_impl { } /* 32 bits length field */ - void write_v32(cxx17::string_view value) { write_v_fx(value); } + void write_v32(std::string_view value) { write_v_fx(value); } /* 16 bits length field */ - void write_v16(cxx17::string_view value) { write_v_fx(value); } + void write_v16(std::string_view value) { write_v_fx(value); } /* 8 bits length field */ - void write_v8(cxx17::string_view value) { write_v_fx(value); } + void write_v8(std::string_view value) { write_v_fx(value); } void write_byte(uint8_t value) { outs_->write_byte(value); } - void write_bytes(cxx17::string_view v) { return write_bytes(v.data(), static_cast(v.size())); } + void write_bytes(std::string_view v) { return write_bytes(v.data(), static_cast(v.size())); } void write_bytes(const void* d, int n) { outs_->write_bytes(d, n); } void write_bytes(size_t offset, const void* d, int n) { outs_->write_bytes(offset, d, n); } void fill_bytes(int n, uint8_t val = 0) { outs_->fill_bytes(n, val); } @@ -373,7 +373,7 @@ class binary_writer_impl { void write_varint(int value, int size) { - size = yasio::clamp(size, 1, YASIO_SSIZEOF(int)); + size = std::clamp(size, 1, YASIO_SSIZEOF(int)); value = convert_traits_type::toint(value, size); write_bytes(&value, size); @@ -401,7 +401,7 @@ class binary_writer_impl { private: template - inline void write_v_fx(cxx17::string_view value) + inline void write_v_fx(std::string_view value) { int size = static_cast(value.size()); this->write<_LenT>(static_cast<_LenT>(size)); @@ -500,7 +500,7 @@ using obstream = obstream_any; using fast_obstream = fast_obstream_any; //-------- basic_obstream_span -template +template class basic_obstream_span; template diff --git a/3rdparty/yasio/yasio/pod_vector.hpp b/3rdparty/yasio/yasio/pod_vector.hpp deleted file mode 100644 index 901c1e6a35e4..000000000000 --- a/3rdparty/yasio/yasio/pod_vector.hpp +++ /dev/null @@ -1,516 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////////// -// A multi-platform support c++11 library with focus on asynchronous socket I/O for any -// client application. -////////////////////////////////////////////////////////////////////////////////////////// -/* -The MIT License (MIT) - -Copyright (c) 2012-2025 HALX99 - -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. - -Version: 4.3.2 - -The pod_vector aka array_buffer concepts: - a. The memory model is similar to to std::vector, but only accept trivially_copyable(no destructor & no custom copy constructor) types - b. The resize behavior differrent stl, always allocate exactly - c. By default resize without fill (uninitialized and for overwrite), - use insert/append insetad if you want fill memory inside container - d. Support release internal buffer ownership with `release_pointer` - e. Transparent iterator - f. expand/append/insert/push_back will trigger memory allocate growth strategy MSVC - g. resize_and_overwrite (c++23) -*/ -#ifndef YASIO__POD_VECTOR_HPP -#define YASIO__POD_VECTOR_HPP -#include -#include -#include -#include -#include -#include "yasio/buffer_alloc.hpp" -#include "yasio/compiler/feature_test.hpp" - -namespace yasio -{ -template > -class pod_vector { -public: - using pointer = _Ty*; - using const_pointer = const _Ty*; - using reference = _Ty&; - using const_reference = const _Ty&; - using _Alloc_traits = buffer_allocator_traits<_Alloc>; - using size_type = typename _Alloc_traits::size_type; - using value_type = _Ty; - using iterator = _Ty*; // transparent iterator - using const_iterator = const _Ty*; - using allocator_type = _Alloc; - pod_vector() {} - explicit pod_vector(size_type count) { resize(static_cast(count)); } - pod_vector(size_type count, const_reference val) { resize(static_cast(count), val); } - template ::value, int> = 0> - pod_vector(_Iter first, _Iter last) - { - assign(first, last); - } - pod_vector(const pod_vector& rhs) { assign(rhs); }; - pod_vector(pod_vector&& rhs) YASIO__NOEXCEPT { assign(std::move(rhs)); } - /*pod_vector(std::initializer_list rhs) { _Assign_range(rhs.begin(), rhs.end()); }*/ - ~pod_vector() { _Tidy(); } - pod_vector& operator=(const pod_vector& rhs) - { - assign(rhs); - return *this; - } - pod_vector& operator=(pod_vector&& rhs) YASIO__NOEXCEPT - { - this->swap(rhs); - return *this; - } - template - pod_vector& operator+=(const _Cont& rhs) - { - return this->append(std::begin(rhs), std::end(rhs)); - } - pod_vector& operator+=(const_reference rhs) - { - this->push_back(rhs); - return *this; - } - template ::value, int> = 0> - void assign(_Iter first, _Iter last) - { - _Assign_range(first, last); - } - void assign(const pod_vector& rhs) { _Assign_range(rhs.begin(), rhs.end()); } - void assign(pod_vector&& rhs) { _Assign_rv(std::move(rhs)); } - void swap(pod_vector& rhs) YASIO__NOEXCEPT - { - std::swap(_Myfirst, rhs._Myfirst); - std::swap(_Mysize, rhs._Mysize); - std::swap(_Myres, rhs._Myres); - } - template ::value, int> = 0> - iterator insert(iterator pos, _Iter first, _Iter last) - { - auto mlast = _Myfirst + _Mysize; - _YASIO_VERIFY_RANGE(pos >= _Myfirst && pos <= mlast && first <= last, "pod_vector: out of range!"); - if (first != last) - { - auto insertion_off = static_cast(std::distance(_Myfirst, pos)); - if (pos == mlast) - append(first, last); - else - { - auto ifirst = std::addressof(*first); - static_assert(sizeof(*ifirst) == sizeof(value_type), "pod_vector: iterator type incompatible!"); - auto count = static_cast(std::distance(first, last)); - if (insertion_off >= 0) - { - expand(count); - pos = _Myfirst + insertion_off; - mlast = _Myfirst + _Mysize; - auto move_to = pos + count; - std::copy_n(pos, mlast - move_to, move_to); - std::copy_n((iterator)ifirst, count, pos); - } - } - return _Myfirst + insertion_off; - } - return pos; - } - iterator insert(iterator pos, size_type count, const_reference val) - { - auto mlast = _Myfirst + _Mysize; - _YASIO_VERIFY_RANGE(pos >= _Myfirst && pos <= mlast, "pod_vector: out of range!"); - if (count) - { - auto insertion_off = std::distance(_Myfirst, pos); - if (pos == mlast) - append(count, val); - else - { - if (insertion_off >= 0) - { - const auto old_size = _Mysize; - expand(count); - pos = _Myfirst + insertion_off; - mlast = _Myfirst + _Mysize; - auto move_to = pos + count; - std::copy_n(pos, mlast - move_to, move_to); - std::fill_n(pos, count, val); - } - } - return _Myfirst + insertion_off; - } - return pos; - } - iterator insert(iterator pos, const value_type& val) - { // insert val at pos - return emplace(pos, val); - } - iterator insert(iterator pos, value_type&& val) - { // insert by moving val at pos - return emplace(pos, std::move(val)); - } - template - iterator emplace(iterator pos, _Valty&&... val) - { - auto insertion_off = std::distance(_Myfirst, pos); - _YASIO_VERIFY_RANGE(insertion_off <= _Mysize, "pod_vector: out of range!"); -#if YASIO__HAS_CXX20 - emplace_back(std::forward<_Valty>(val)...); - std::rotate(begin() + insertion_off, end() - 1, end()); - return (begin() + insertion_off); -#else - auto mlast = _Myfirst + _Mysize; - if (pos == mlast) - emplace_back(std::forward<_Valty>(val)...); - else - { - if (insertion_off >= 0) - { - expand(1); - pos = _Myfirst + insertion_off; - mlast = _Myfirst + _Mysize; - auto move_to = pos + 1; - std::copy_n(pos, mlast - move_to, move_to); - ::yasio::construct_at(pos, std::forward<_Valty>(val)...); - } - } - return _Myfirst + insertion_off; -#endif - } - template ::value, int> = 0> - pod_vector& append(_Iter first, const _Iter last) - { - if (first != last) - { - auto ifirst = std::addressof(*first); - static_assert(sizeof(*ifirst) == sizeof(value_type), "pod_vector: iterator type incompatible!"); - auto count = static_cast(std::distance(first, last)); - if (count > 1) - { - const auto old_size = _Mysize; - expand(count); - std::copy_n((iterator)ifirst, count, _Myfirst + old_size); - } - else if (count == 1) - push_back(static_cast(*(iterator)ifirst)); - } - return *this; - } - pod_vector& append(size_type count, const_reference val) - { - expand(count, val); - return *this; - } - void push_back(value_type&& val) { push_back(val); } - void push_back(const value_type& val) { emplace_back(val); } - void pop_back() - { - if (!empty()) - _Eos(size() - 1); - } - template - inline value_type& emplace_back(_Valty&&... val) - { - if (_Mysize < _Myres) - return *::yasio::construct_at(_Myfirst + _Mysize++, std::forward<_Valty>(val)...); - return *_Emplace_back_reallocate(std::forward<_Valty>(val)...); - } - iterator erase(iterator pos) - { - const auto mlast = _Myfirst + _Mysize; - _YASIO_VERIFY_RANGE(pos >= _Myfirst && pos < mlast, "pod_vector: out of range!"); - _Mysize = static_cast(std::move(pos + 1, mlast, pos) - _Myfirst); - return pos; - } - iterator erase(iterator first, iterator last) - { - const auto mlast = _Myfirst + _Mysize; - _YASIO_VERIFY_RANGE((first <= last) && first >= _Myfirst && last <= mlast, "pod_vector: out of range!"); - _Mysize = static_cast(std::move(last, mlast, first) - _Myfirst); - return first; - } - value_type& front() - { - _YASIO_VERIFY_RANGE(!empty(), "pod_vector: out of range!"); - return *_Myfirst; - } - const value_type& front() const - { - _YASIO_VERIFY_RANGE(!empty(), "pod_vector: out of range!"); - return *_Myfirst; - } - value_type& back() - { - _YASIO_VERIFY_RANGE(!empty(), "pod_vector: out of range!"); - return _Myfirst[_Mysize - 1]; - } - const value_type& back() const - { - _YASIO_VERIFY_RANGE(!empty(), "pod_vector: out of range!"); - return _Myfirst[_Mysize - 1]; - } - static YASIO__CONSTEXPR size_type max_size() YASIO__NOEXCEPT { return _Alloc_traits::max_size(); } - iterator begin() YASIO__NOEXCEPT { return _Myfirst; } - iterator end() YASIO__NOEXCEPT { return _Myfirst + _Mysize; } - const_iterator begin() const YASIO__NOEXCEPT { return _Myfirst; } - const_iterator end() const YASIO__NOEXCEPT { return _Myfirst + _Mysize; } - pointer data() YASIO__NOEXCEPT { return _Myfirst; } - const_pointer data() const YASIO__NOEXCEPT { return _Myfirst; } - size_type capacity() const YASIO__NOEXCEPT { return _Myres; } - size_type size() const YASIO__NOEXCEPT { return _Mysize; } - size_type length() const YASIO__NOEXCEPT { return _Mysize; } - void clear() YASIO__NOEXCEPT { _Mysize = 0; } - bool empty() const YASIO__NOEXCEPT { return _Mysize == 0; } - - const_reference operator[](size_type index) const { return this->at(index); } - reference operator[](size_type index) { return this->at(index); } - const_reference at(size_type index) const - { - _YASIO_VERIFY_RANGE(index < this->size(), "pod_vector: out of range!"); - return _Myfirst[index]; - } - reference at(size_type index) - { - _YASIO_VERIFY_RANGE(index < this->size(), "pod_vector: out of range!"); - return _Myfirst[index]; - } -#pragma region modify size and capacity - void resize(size_type new_size) - { - if (this->capacity() < new_size) - _Resize_reallocate<_Reallocation_policy::_Exactly>(new_size); - else - _Eos(new_size); - } - void expand(size_type count) - { - const auto new_size = this->size() + count; - if (this->capacity() < new_size) - _Resize_reallocate<_Reallocation_policy::_At_least>(new_size); - else - _Eos(new_size); - } - void shrink_to_fit() - { // reduce capacity to size, provide strong guarantee - if (_Mysize != _Myres) - { // something to do - if (!_Mysize) - _Tidy(); - else - _Reallocate<_Reallocation_policy::_Exactly>(_Mysize); - } - } - void reserve(size_type new_cap) - { - if (this->capacity() < new_cap) - _Reallocate<_Reallocation_policy::_Exactly>(new_cap); - } - template - void resize_and_overwrite(const size_type new_size, _Operation op) - { - _Reallocate<_Reallocation_policy::_Exactly>(new_size); - _Eos(std::move(op)(_Myfirst, new_size)); - } -#pragma endregion - void resize(size_type new_size, const_reference val) - { - auto old_size = this->size(); - if (old_size != new_size) - { - resize(new_size); - if (old_size < new_size) - std::fill_n(_Myfirst + old_size, new_size - old_size, val); - } - } - void expand(size_type count, const_reference val) - { - if (count) - { - auto old_size = this->size(); - expand(count); - if (count) - std::fill_n(_Myfirst + old_size, count, val); - } - } - ptrdiff_t index_of(const_reference val) const YASIO__NOEXCEPT - { - auto it = std::find(begin(), end(), val); - if (it != this->end()) - return std::distance(begin(), it); - return -1; - } - void reset(size_type new_size) - { - resize(new_size); - memset(_Myfirst, 0x0, size_bytes()); - } - size_t size_bytes() const YASIO__NOEXCEPT { return this->size() * sizeof(value_type); } - template - pointer detach_abi(_Intty& len) YASIO__NOEXCEPT - { - len = static_cast<_Intty>(this->size()); - auto ptr = _Myfirst; - _Myfirst = nullptr; - _Mysize = _Myres = 0; - return ptr; - } - pointer detach_abi() YASIO__NOEXCEPT - { - size_type ignored_len; - return this->detach_abi(ignored_len); - } - void attach_abi(pointer ptr, size_type len) - { - _Tidy(); - _Myfirst = ptr; - _Mysize = _Myres = len; - } - pointer release_pointer() YASIO__NOEXCEPT { return detach_abi(); } - -private: - void _Eos(size_type size) YASIO__NOEXCEPT { _Mysize = size; } - template - pointer _Emplace_back_reallocate(_Valty&&... val) - { - const auto _Oldsize = _Mysize; - - if (_Oldsize == max_size()) - throw std::length_error("pod_vector too long"); - - const size_type _Newsize = _Oldsize + 1; - _Resize_reallocate<_Reallocation_policy::_At_least>(_Newsize); - const pointer _Newptr = ::yasio::construct_at(_Myfirst + _Oldsize, std::forward<_Valty>(val)...); - return _Newptr; - } - template ::value, int> = 0> - void _Assign_range(_Iter first, _Iter last) - { - auto ifirst = std::addressof(*first); - static_assert(sizeof(*ifirst) == sizeof(value_type), "pod_vector: iterator type incompatible!"); - if (ifirst != _Myfirst) - { - _Mysize = 0; - if (last > first) - { - const auto count = static_cast(std::distance(first, last)); - resize(count); - std::copy_n((iterator)ifirst, count, _Myfirst); - } - } - } - void _Assign_rv(pod_vector&& rhs) - { - memcpy((void*)this, &rhs, sizeof(rhs)); - memset((void*)&rhs, 0, sizeof(rhs)); - } - enum class _Reallocation_policy - { - _At_least, - _Exactly - }; - template <_Reallocation_policy _Policy> - void _Resize_reallocate(size_type size) - { - _Reallocate<_Policy>(size); - _Eos(size); - } - template <_Reallocation_policy _Policy> - void _Reallocate(size_type size) - { - size_type new_cap; - if YASIO__CONSTEXPR (_Policy == _Reallocation_policy::_Exactly) - new_cap = size; - else - new_cap = _Calculate_growth(size); - auto _Newvec = _Alloc::reallocate(_Myfirst, _Myres, new_cap); - if (_Newvec) - { - _Myfirst = _Newvec; - _Myres = new_cap; - } - else - throw std::bad_alloc{}; - } - size_type _Calculate_growth(const size_type new_size) const - { - // given _Oldcapacity and _Newsize, calculate geometric growth - const size_type old_cap = capacity(); - YASIO__CONSTEXPR auto max_cap = max_size(); - - if (old_cap > max_cap - old_cap / 2) - return max_cap; // geometric growth would overflow - - const size_type geometric = old_cap + (old_cap >> 1); - - if (geometric < new_size) - return new_size; // geometric growth would be insufficient - - return geometric; // geometric growth is sufficient - } - void _Tidy() YASIO__NOEXCEPT - { // free all storage - if (_Myfirst) - { - _Alloc::deallocate(_Myfirst, _Myres); - _Myfirst = nullptr; - _Mysize = _Myres = 0; - } - } - - pointer _Myfirst = nullptr; - size_type _Mysize = 0; - size_type _Myres = 0; -}; - -#pragma region c++20 like std::erase -template -void erase(pod_vector<_Ty, _Alloc>& cont, const _Ty& val) -{ - cont.erase(std::remove(cont.begin(), cont.end(), val), cont.end()); -} -template -void erase_if(pod_vector<_Ty, _Alloc>& cont, _Pr pred) -{ - cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); -} -#pragma endregion - -template -inline typename _Cont::iterator insert_sorted(_Cont& vec, typename _Cont::value_type const& val) -{ - return vec.insert(std::upper_bound(vec.begin(), vec.end(), val), val); -} - -template -inline typename _Cont::iterator insert_sorted(_Cont& vec, typename _Cont::value_type const& val, _Pred pred) -{ - return vec.insert(std::upper_bound(vec.begin(), vec.end(), val, pred), val); -} - -// alias: array_buffer -template > -using array_buffer = pod_vector<_Ty, _Alloc>; - -} // namespace yasio -#endif diff --git a/3rdparty/yasio/yasio/ref_ptr.hpp b/3rdparty/yasio/yasio/ref_ptr.hpp deleted file mode 100644 index ed64743dd733..000000000000 --- a/3rdparty/yasio/yasio/ref_ptr.hpp +++ /dev/null @@ -1,211 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////////// -// A multi-platform support c++11 library with focus on asynchronous socket I/O for any -// client application. -////////////////////////////////////////////////////////////////////////////////////////// -/* -The MIT License (MIT) - -Copyright (c) 2012-2025 HALX99 - -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. -*/ -#ifndef YASIO__REF_PTR_HPP -#define YASIO__REF_PTR_HPP -#include "yasio/config.hpp" - -// clang-format off -#define YASIO__DEFINE_REFERENCE_CLASS \ -private: \ - unsigned int __strong_refs = 1; \ - \ -public: \ - void retain() { ++__strong_refs; } \ - void release() \ - { \ - --__strong_refs; \ - if (__strong_refs == 0) \ - delete this; \ - } \ - \ -private: - -#define YASIO__SAFE_RELEASE(p) \ - if (p) \ - (p)->release() - -#define YASIO__SAFE_RELEASE_NULL(p) \ - do \ - { \ - if (p) \ - { \ - (p)->release(); \ - (p) = nullptr; \ - } \ - } while (0) - -#define YASIO__SAFE_RETAIN(p) \ - if (p) \ - (p)->retain() -// clang-format on - -namespace yasio -{ -struct own_ref_t {}; - -// TEMPLATE CLASS ref_ptr, allow any time with functions 'retain' and 'release' -template -class ref_ptr; - -template -class ref_ptr { // wrap an object pointer to ensure destruction -public: - typedef ref_ptr<_Ty> _Myt; - typedef _Ty element_type; - - explicit ref_ptr(_Ty* _Ptr = nullptr) throw() : ptr_(_Ptr) - { // construct from object pointer - } - - ref_ptr(_Ty* _Ptr, own_ref_t) throw() : ptr_(_Ptr) - { // construct from object pointer - YASIO__SAFE_RETAIN(ptr_); - } - - ref_ptr(std::nullptr_t) throw() : ptr_(nullptr) {} - - ref_ptr(const _Myt& _Right) throw() - { // construct by assuming pointer from _Right ref_ptr - ptr_ = _Right.get(); - YASIO__SAFE_RETAIN(ptr_); - } - - template - ref_ptr(const ref_ptr<_Other>& _Right) throw() - { // construct by assuming pointer from _Right - ptr_ = (_Ty*)_Right.get(); - YASIO__SAFE_RETAIN(ptr_); - } - - ref_ptr(_Myt&& _Right) throw() : ptr_(_Right.release()) {} - - template - ref_ptr(ref_ptr<_Other>&& _Right) throw() : ptr_((_Ty*)_Right.release()) - {} - - _Myt& operator=(const _Myt& _Right) throw() - { // assign compatible _Right (assume pointer) - if (this == &_Right) - return *this; - - reset(_Right.get()); - YASIO__SAFE_RETAIN(ptr_); - return (*this); - } - - _Myt& operator=(_Myt&& _Right) throw() - { // assign compatible _Right (assume pointer) - reset(_Right.release()); - return (*this); - } - - // release ownership - _Ty* release() - { - auto tmp = ptr_; - ptr_ = nullptr; - return tmp; - } - - template - _Myt& operator=(const ref_ptr<_Other>& _Right) throw() - { // assign compatible _Right (assume pointer) - if (this == &_Right) - return *this; - - reset((_Ty*)_Right.get()); - YASIO__SAFE_RETAIN(ptr_); - return (*this); - } - - template - _Myt& operator=(ref_ptr<_Other>&& _Right) throw() - { // assign compatible _Right (assume pointer) - reset((_Ty*)_Right.release()); - return (*this); - } - - _Myt& operator=(std::nullptr_t) throw() - { - reset(); - return (*this); - } - - ~ref_ptr() - { // release the object - YASIO__SAFE_RELEASE(ptr_); - } - - _Ty& operator*() const throw() - { // return designated value - return (*ptr_); // return (*get()); - } - - _Ty** operator&() throw() { return &(ptr_); } - - _Ty* operator->() const throw() - { // return pointer to class object - return (ptr_); // return (get()); - } - - template - _Ty& operator[](_Int index) const throw() - { - return (ptr_[index]); - } - - _Ty* get() const throw() - { // return wrapped pointer - return (ptr_); - } - - operator _Ty*() const throw() - { // convert to basic type - return (ptr_); - } - - /* - ** if already have a valid pointer, will call release firstly - */ - void reset(_Ty* _Ptr = nullptr) - { // relese designated object and store new pointer - if (ptr_ != _Ptr) - { - if (ptr_ != nullptr) - YASIO__SAFE_RELEASE(ptr_); - ptr_ = _Ptr; - } - } - -private: - _Ty* ptr_; // the wrapped object pointer -}; - -}; // namespace yasio - -#endif diff --git a/3rdparty/yasio/yasio/split.hpp b/3rdparty/yasio/yasio/split.hpp index 7fd4c99ccbe6..c6f505aba412 100644 --- a/3rdparty/yasio/yasio/split.hpp +++ b/3rdparty/yasio/yasio/split.hpp @@ -37,7 +37,7 @@ SOFTWARE. #pragma once -#include "yasio/string_view.hpp" +#include "yasio/tlx/string_view.hpp" #include #if defined(_MSC_VER) diff --git a/3rdparty/yasio/yasio/string_view.hpp b/3rdparty/yasio/yasio/string_view.hpp deleted file mode 100644 index 2e51323e62e4..000000000000 --- a/3rdparty/yasio/yasio/string_view.hpp +++ /dev/null @@ -1,1287 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////////// -// A multi-platform support c++11 library with focus on asynchronous socket I/O for any -// client application. -////////////////////////////////////////////////////////////////////////////////////////// -/* -The MIT License (MIT) - -Copyright (c) 2012-2025 HALX99 -Copyright (c) 2016 Matthew Rodusek(matthew.rodusek@gmail.com) - -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. -See: https://github.com/bitwizeshift/string_view-standalone -*/ -#ifndef YASIO__STRING_VIEW_HPP -#define YASIO__STRING_VIEW_HPP -#include -#include -#include -#include -#include "yasio/impl/char_traits.hpp" -#include "yasio/compiler/feature_test.hpp" - -/// wcsncasecmp workaround for android API level < 23, copy from msvc ucrt 10.0.18362.0 'wcsnicmp' -#if (defined(__ANDROID_API__) && __ANDROID_API__ < 23) || defined(__MINGW32__) -inline int wcsncasecmp(wchar_t const* const lhs, wchar_t const* const rhs, size_t const count) -{ - if (count == 0) - { - return 0; - } - - wchar_t const* lhs_ptr = reinterpret_cast(lhs); - wchar_t const* rhs_ptr = reinterpret_cast(rhs); - - int result; - int lhs_value; - int rhs_value; - size_t remaining = count; - do - { - lhs_value = ::towlower(*lhs_ptr++); - rhs_value = ::towlower(*rhs_ptr++); - result = lhs_value - rhs_value; - } while (result == 0 && lhs_value != 0 && --remaining != 0); - - return result; -} -#endif - -/// string_view workaround on c++11 -#if YASIO__HAS_CXX17 -# if __has_include() -# include -# endif -#else -# include -# include -# include -namespace cxx17 -{ -//////////////////////////////////////////////////////////////////////////// -/// \brief A wrapper around non-owned strings. -/// -/// This is an implementation of the C++17 string_view proposal -/// -/// \ingroup core -//////////////////////////////////////////////////////////////////////////// -template > -class basic_string_view; - -template -class basic_string_view { - //------------------------------------------------------------------------ - // Public Member Types - //------------------------------------------------------------------------ -public: - using char_type = _CharT; - using traits_type = _Traits; - using size_type = size_t; - - using value_type = _CharT; - using reference = value_type&; - using const_reference = const value_type&; - using pointer = value_type*; - using const_pointer = const value_type*; - - using iterator = const _CharT*; - using const_iterator = const _CharT*; - - //------------------------------------------------------------------------ - // Public Members - //------------------------------------------------------------------------ -public: - static const size_type npos = size_type(-1); - - //------------------------------------------------------------------------ - // Constructors - //------------------------------------------------------------------------ -public: - /// \brief Default constructs a basic_string_view without any content - basic_string_view(); - - /// \brief Constructs a basic_string_view from a std::basic_string - /// - /// \param str the string to view - template - basic_string_view(const std::basic_string<_CharT, _Traits, Allocator>& str); - - /// \brief Constructs a basic_string_view from an ansi-string - /// - /// \param str the string to view - basic_string_view(const char_type* str); - - /// \brief Constructs a basic_string_view from an ansi string of a given size - /// - /// \param str the string to view - /// \param count the size of the string - basic_string_view(const char_type* str, size_type count); - - //------------------------------------------------------------------------ - // Assignment - //------------------------------------------------------------------------ -public: - //------------------------------------------------------------------------ - // Capacity - //------------------------------------------------------------------------ -public: - /// \brief Returns the length of the string, in terms of bytes - /// - /// \return the length of the string, in terms of bytes - size_type size() const; - - /// \copydoc basic_string_view::size - size_type length() const; - - /// \brief The largest possible number of char-like objects that can be - /// referred to by a basic_string_view. - /// \return Maximum number of characters - size_type max_size() const; - - /// \brief Returns whether the basic_string_view is empty - /// (i.e. whether its length is 0). - /// - /// \return whether the basic_string_view is empty - bool empty() const; - - //------------------------------------------------------------------------ - // Element Access - //------------------------------------------------------------------------ -public: - /// \brief Gets the ansi-string of the current basic_string_view - /// - /// \return the ansi-string pointer - const char_type* c_str() const; - - /// \brief Gets the data of the current basic_string_view - /// - /// \note This is an alias of #c_str - /// - /// \return the data this basic_string_view contains - const char_type* data() const; - - /// \brief Accesses the element at index \p pos - /// - /// \param pos the index to access - /// \return const reference to the character - const_reference operator[](size_t pos) const; - - /// \brief Accesses the element at index \p pos - /// - /// \param pos the index to access - /// \return const reference to the character - const_reference at(size_t pos) const; - - /// \brief Access the first character of the string - /// - /// \note Undefined behavior if basic_string_view is empty - /// - /// \return reference to the first character of the string - const_reference front() const; - - /// \brief References the last character of the string - /// - /// \note Undefined behavior if basic_string_view is empty - /// - /// \return reference to the last character of the string - const_reference back() const; - - //------------------------------------------------------------------------ - // Modifiers - //------------------------------------------------------------------------ -public: - /// \brief Moves the start of the view forward by n characters. - /// - /// The behavior is undefined if n > size(). - /// - /// \param n number of characters to remove from the start of the view - void remove_prefix(size_type n); - - /// \brief Moves the end of the view back by n characters. - /// - /// The behavior is undefined if n > size(). - /// - /// \param n number of characters to remove from the end of the view - void remove_suffix(size_type n); - - /// \brief Exchanges the view with that of v. - /// - /// \param v view to swap with - void swap(basic_string_view& v); - - //------------------------------------------------------------------------ - // Conversions - //------------------------------------------------------------------------ -public: - /// \brief Creates a basic_string with a copy of the content of the current - /// view. - /// - /// \tparam Allocator type used to allocate internal storage - /// \param a Allocator instance to use for allocating the new string - /// - /// \return A basic_string containing a copy of the characters of the current - /// view. - template > - std::basic_string<_CharT, _Traits, Allocator> to_string(const Allocator& a = Allocator()) const; - - /// \copydoc basic_string_view::to_string - template - explicit operator std::basic_string<_CharT, _Traits, Allocator>() const; - - //------------------------------------------------------------------------ - // Operations - //------------------------------------------------------------------------ -public: - /// \brief Copies the substring [pos, pos + rcount) to the character string - /// pointed - /// to by dest, where rcount is the smaller of count and size() - pos. - /// - /// \param dest pointer to the destination character string - /// \param count requested substring length - /// \param pos position of the first character - size_type copy(char_type* dest, size_type count = npos, size_type pos = 0) const; - - /// \brief Returns a substring of this viewed string - /// - /// \param pos the position of the first character in the substring - /// \param len the length of the substring - /// \return the created substring - basic_string_view substr(size_t pos = 0, size_t len = npos) const; - - //------------------------------------------------------------------------ - - /// \brief Compares two character sequences - /// - /// \param v view to compare - /// \return negative value if this view is less than the other character - /// sequence, zero if the both character sequences are equal, positive - /// value if this view is greater than the other character sequence. - int compare(basic_string_view v) const; - - /// \brief Compares two character sequences - /// - /// \param pos position of the first character in this view to compare - /// \param count number of characters of this view to compare - /// \param v view to compare - /// \return negative value if this view is less than the other character - /// sequence, zero if the both character sequences are equal, positive - /// value if this view is greater than the other character sequence. - int compare(size_type pos, size_type count, basic_string_view v) const; - - /// \brief Compares two character sequences - /// - /// \param pos1 position of the first character in this view to compare - /// \param count1 number of characters of this view to compare - /// \param v view to compare - /// \param pos2 position of the second character in this view to compare - /// \param count2 number of characters of the given view to compare - /// \return negative value if this view is less than the other character - /// sequence, zero if the both character sequences are equal, positive - /// value if this view is greater than the other character sequence. - int compare(size_type pos1, size_type count1, basic_string_view v, size_type pos2, size_type count2) const; - - /// \brief Compares two character sequences - /// - /// \param s pointer to the character string to compare to - /// \return negative value if this view is less than the other character - /// sequence, zero if the both character sequences are equal, positive - /// value if this view is greater than the other character sequence. - int compare(const char_type* s) const; - - /// \brief Compares two character sequences - /// - /// \param pos position of the first character in this view to compare - /// \param count number of characters of this view to compare - /// \param s pointer to the character string to compare to - /// \return negative value if this view is less than the other character - /// sequence, zero if the both character sequences are equal, positive - /// value if this view is greater than the other character sequence. - int compare(size_type pos, size_type count, const char_type* s) const; - - /// \brief Compares two character sequences - /// - /// \param pos position of the first character in this view to compare - /// \param count1 number of characters of this view to compare - /// \param s pointer to the character string to compare to - /// \param count2 number of characters of the given view to compare - /// \return negative value if this view is less than the other character - /// sequence, zero if the both character sequences are equal, positive - /// value if this view is greater than the other character sequence. - int compare(size_type pos, size_type count1, const char_type* s, size_type count2) const; - - //------------------------------------------------------------------------ - - size_type find(basic_string_view v, size_type pos = 0) const; - - size_type find(char_type c, size_type pos = 0) const; - - size_type find(const char_type* s, size_type pos, size_type count) const; - - size_type find(const char_type* s, size_type pos = 0) const; - - //------------------------------------------------------------------------ - - size_type rfind(basic_string_view v, size_type pos = npos) const; - - size_type rfind(char_type c, size_type pos = npos) const; - - size_type rfind(const char_type* s, size_type pos, size_type count) const; - - size_type rfind(const char_type* s, size_type pos = npos) const; - - //------------------------------------------------------------------------ - - size_type find_first_of(basic_string_view v, size_type pos = 0) const; - - size_type find_first_of(char_type c, size_type pos = 0) const; - - size_type find_first_of(const char_type* s, size_type pos, size_type count) const; - - size_type find_first_of(const char_type* s, size_type pos = 0) const; - - //------------------------------------------------------------------------ - - size_type find_last_of(basic_string_view v, size_type pos = npos) const; - - size_type find_last_of(char_type c, size_type pos = npos) const; - - size_type find_last_of(const char_type* s, size_type pos, size_type count) const; - - size_type find_last_of(const char_type* s, size_type pos = npos) const; - - //------------------------------------------------------------------------ - - size_type find_first_not_of(basic_string_view v, size_type pos = 0) const; - - size_type find_first_not_of(char_type c, size_type pos = 0) const; - - size_type find_first_not_of(const char_type* s, size_type pos, size_type count) const; - - size_type find_first_not_of(const char_type* s, size_type pos = 0) const; - - //------------------------------------------------------------------------ - - size_type find_last_not_of(basic_string_view v, size_type pos = npos) const; - - size_type find_last_not_of(char_type c, size_type pos = npos) const; - - size_type find_last_not_of(const char_type* s, size_type pos, size_type count) const; - - size_type find_last_not_of(const char_type* s, size_type pos = npos) const; - - //------------------------------------------------------------------------ - // Iterators - //------------------------------------------------------------------------ -public: - /// \brief Retrieves the begin iterator for this basic_string_view - /// - /// \return the begin iterator - const_iterator begin() const; - - /// \brief Retrieves the end iterator for this basic_string_view - /// - /// \return the end iterator - const_iterator end() const; - - /// \copydoc basic_string_view::begin() - const_iterator cbegin() const; - - /// \copydoc basic_string_view::end() - const_iterator cend() const; - - //------------------------------------------------------------------------ - // Private Member - //------------------------------------------------------------------------ -private: - const char_type* m_str; ///< The internal string type - size_type m_size; ///< The size of this string -}; - -//-------------------------------------------------------------------------- -// Type Aliases -//-------------------------------------------------------------------------- - -using string_view = basic_string_view; -# if defined(__cpp_lib_char8_t) -using u8string_view = basic_string_view; -# endif -using wstring_view = basic_string_view; -using u16string_view = basic_string_view; -using u32string_view = basic_string_view; - -//-------------------------------------------------------------------------- -// Inline Definitions -//-------------------------------------------------------------------------- - -//-------------------------------------------------------------------------- -// Constructor -//-------------------------------------------------------------------------- - -template -inline basic_string_view<_CharT, _Traits>::basic_string_view() : m_str(nullptr), m_size(0) -{} - -template -template -inline basic_string_view<_CharT, _Traits>::basic_string_view(const std::basic_string<_CharT, _Traits, Allocator>& str) : m_str(str.c_str()), m_size(str.size()) -{} - -template -inline basic_string_view<_CharT, _Traits>::basic_string_view(const char_type* str) : m_str(str), m_size(traits_type::length(str)) -{} - -template -inline basic_string_view<_CharT, _Traits>::basic_string_view(const char_type* str, size_type count) : m_str(str), m_size(count) -{} - -//-------------------------------------------------------------------------- -// Capacity -//-------------------------------------------------------------------------- - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::size() const -{ - return m_size; -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::length() const -{ - return size(); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::max_size() const -{ - return npos - 1; -} - -template -inline bool basic_string_view<_CharT, _Traits>::empty() const -{ - return m_size == 0; -} - -//-------------------------------------------------------------------------- -// Element Access -//-------------------------------------------------------------------------- - -template -inline const typename basic_string_view<_CharT, _Traits>::char_type* basic_string_view<_CharT, _Traits>::c_str() const -{ - return m_str; -} - -template -inline const typename basic_string_view<_CharT, _Traits>::char_type* basic_string_view<_CharT, _Traits>::data() const -{ - return m_str; -} - -template -inline typename basic_string_view<_CharT, _Traits>::const_reference basic_string_view<_CharT, _Traits>::operator[](size_t pos) const -{ - return m_str[pos]; -} - -template -inline typename basic_string_view<_CharT, _Traits>::const_reference basic_string_view<_CharT, _Traits>::at(size_t pos) const -{ - if (yasio__unlikely(pos >= m_size)) - YASIO__THROW(std::out_of_range("Input out of range in basic_string_view::at"), 0); - return m_str[pos]; -} - -template -inline typename basic_string_view<_CharT, _Traits>::const_reference basic_string_view<_CharT, _Traits>::front() const -{ - return *m_str; -} - -template -inline typename basic_string_view<_CharT, _Traits>::const_reference basic_string_view<_CharT, _Traits>::back() const -{ - return m_str[m_size - 1]; -} - -//-------------------------------------------------------------------------- -// Modifiers -//-------------------------------------------------------------------------- - -template -inline void basic_string_view<_CharT, _Traits>::remove_prefix(size_type n) -{ - m_str += n, m_size -= n; -} - -template -inline void basic_string_view<_CharT, _Traits>::remove_suffix(size_type n) -{ - m_size -= n; -} - -template -inline void basic_string_view<_CharT, _Traits>::swap(basic_string_view& v) -{ - using std::swap; - swap(m_size, v.m_size); - swap(m_str, v.m_str); -} - -//-------------------------------------------------------------------------- -// Conversions -//-------------------------------------------------------------------------- - -template -template -inline std::basic_string<_CharT, _Traits, Allocator> basic_string_view<_CharT, _Traits>::to_string(const Allocator& a) const -{ - return std::basic_string<_CharT, _Traits, Allocator>(m_str, m_size, a); -} - -template -template -inline basic_string_view<_CharT, _Traits>::operator std::basic_string<_CharT, _Traits, Allocator>() const -{ - return std::basic_string<_CharT, _Traits, Allocator>(m_str, m_size); -} - -//-------------------------------------------------------------------------- -// String Operations -//-------------------------------------------------------------------------- - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::copy(char_type* dest, size_type count, size_type pos) const -{ - if (yasio__unlikely(pos >= m_size)) - YASIO__THROW(std::out_of_range("Index out of range in basic_string_view::copy"), 0); - - const size_type rcount = (std::min)(m_size - pos, count + 1); - std::copy(m_str + pos, m_str + pos + rcount, dest); - return rcount; -} - -template -inline basic_string_view<_CharT, _Traits> basic_string_view<_CharT, _Traits>::substr(size_t pos, size_t len) const -{ - const size_type max_length = pos > m_size ? 0 : m_size - pos; - if (yasio__unlikely(pos >= m_size)) - YASIO__THROW(std::out_of_range("Index out of range in basic_string_view::substr"), (basic_string_view<_CharT, _Traits>{})); - return basic_string_view<_CharT, _Traits>(m_str + pos, len > max_length ? max_length : len); -} - -//-------------------------------------------------------------------------- - -template -inline int basic_string_view<_CharT, _Traits>::compare(basic_string_view v) const -{ - const size_type rlen = (std::min)(m_size, v.m_size); - const int compare = _Traits::compare(m_str, v.m_str, rlen); - - return (compare ? compare : (m_size < v.m_size ? -1 : (m_size > v.m_size ? 1 : 0))); -} - -template -inline int basic_string_view<_CharT, _Traits>::compare(size_type pos, size_type count, basic_string_view v) const -{ - return substr(pos, count).compare(v); -} - -template -inline int basic_string_view<_CharT, _Traits>::compare(size_type pos1, size_type count1, basic_string_view v, size_type pos2, size_type count2) const -{ - return substr(pos1, count1).compare(v.substr(pos2, count2)); -} - -template -inline int basic_string_view<_CharT, _Traits>::compare(const char_type* s) const -{ - return compare(basic_string_view<_CharT, _Traits>(s)); -} - -template -inline int basic_string_view<_CharT, _Traits>::compare(size_type pos, size_type count, const char_type* s) const -{ - return substr(pos, count).compare(basic_string_view<_CharT, _Traits>(s)); -} - -template -inline int basic_string_view<_CharT, _Traits>::compare(size_type pos, size_type count1, const char_type* s, size_type count2) const -{ - return substr(pos, count1).compare(basic_string_view<_CharT, _Traits>(s, count2)); -} - -//-------------------------------------------------------------------------- - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find(basic_string_view v, size_type pos) const -{ - return __xxtraits_find<_Traits>(m_str, m_size, pos, v.m_str, v.m_size); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find(char_type c, size_type pos) const -{ - return find(basic_string_view<_CharT, _Traits>(&c, 1), pos); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find(const char_type* s, size_type pos, size_type count) const -{ - return find(basic_string_view<_CharT, _Traits>(s, count), pos); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find(const char_type* s, size_type pos) const -{ - return find(basic_string_view<_CharT, _Traits>(s), pos); -} - -//-------------------------------------------------------------------------- - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::rfind(basic_string_view v, size_type pos) const -{ - return __xxtraits_rfind<_Traits>(m_str, m_size, pos, v.m_str, v.m_size); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::rfind(char_type c, size_type pos) const -{ - return rfind(basic_string_view<_CharT, _Traits>(&c, 1), pos); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::rfind(const char_type* s, size_type pos, - size_type count) const -{ - return rfind(basic_string_view<_CharT, _Traits>(s, count), pos); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::rfind(const char_type* s, size_type pos) const -{ - return rfind(basic_string_view<_CharT, _Traits>(s), pos); -} - -//-------------------------------------------------------------------------- - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_first_of(basic_string_view v, size_type pos) const -{ - return __xxtraits_find_first_of<_Traits>(m_str, m_size, pos, v.m_str, v.m_size); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_first_of(char_type c, size_type pos) const -{ - return __xxtraits_find_ch<_Traits>(m_str, m_size, pos, c); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_first_of(const char_type* s, size_type pos, - size_type count) const -{ - return find_first_of(basic_string_view<_CharT, _Traits>(s, count), pos); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_first_of(const char_type* s, size_type pos) const -{ - return find_first_of(basic_string_view<_CharT, _Traits>(s), pos); -} - -//-------------------------------------------------------------------------- - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_last_of(basic_string_view v, size_type pos) const -{ - return __xxtraits_find_last_of<_Traits>(m_str, m_size, pos, v.m_str, v.m_size); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_last_of(char_type c, size_type pos) const -{ - return __xxtraits_rfind_ch<_Traits>(m_str, m_size, pos, c); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_last_of(const char_type* s, size_type pos, - size_type count) const -{ - return find_last_of(basic_string_view<_CharT, _Traits>(s, count), pos); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_last_of(const char_type* s, size_type pos) const -{ - return find_last_of(basic_string_view<_CharT, _Traits>(s), pos); -} - -//-------------------------------------------------------------------------- - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_first_not_of(basic_string_view v, size_type pos) const -{ - return __xxtraits_find_first_not_of<_Traits>(m_str, m_size, pos, v.m_str, v.m_size, pos); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_first_not_of(char_type c, size_type pos) const -{ - return __xxtraits_find_not_ch<_Traits>(m_str, m_size, pos, c); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_first_not_of(const char_type* s, size_type pos, - size_type count) const -{ - return find_first_not_of(basic_string_view<_CharT, _Traits>(s, count), pos); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_first_not_of(const char_type* s, size_type pos) const -{ - return find_first_not_of(basic_string_view<_CharT, _Traits>(s), pos); -} - -//-------------------------------------------------------------------------- - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_last_not_of(basic_string_view v, size_type pos) const -{ - return __xxtraits_find_last_not_of<_Traits>(m_str, m_size, pos, v.m_str, v.m_size); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_last_not_of(char_type c, size_type pos) const -{ - return __xxtraits_rfind_not_ch<_Traits>(m_str, m_size, pos, c); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_last_not_of(const char_type* s, size_type pos, - size_type count) const -{ - return find_last_not_of(basic_string_view<_CharT, _Traits>(s, count), pos); -} - -template -inline typename basic_string_view<_CharT, _Traits>::size_type basic_string_view<_CharT, _Traits>::find_last_not_of(const char_type* s, size_type pos) const -{ - return find_last_not_of(basic_string_view<_CharT, _Traits>(s), pos); -} - -//-------------------------------------------------------------------------- -// Iterator -//-------------------------------------------------------------------------- - -template -inline typename basic_string_view<_CharT, _Traits>::const_iterator basic_string_view<_CharT, _Traits>::begin() const -{ - return m_str; -} - -template -inline typename basic_string_view<_CharT, _Traits>::const_iterator basic_string_view<_CharT, _Traits>::end() const -{ - return m_str + m_size; -} - -template -inline typename basic_string_view<_CharT, _Traits>::const_iterator basic_string_view<_CharT, _Traits>::cbegin() const -{ - return m_str; -} - -template -inline typename basic_string_view<_CharT, _Traits>::const_iterator basic_string_view<_CharT, _Traits>::cend() const -{ - return m_str + m_size; -} - -//-------------------------------------------------------------------------- -// Public Functions -//-------------------------------------------------------------------------- - -template -std::basic_ostream<_CharT, _Traits>& operator<<(std::basic_ostream<_CharT, _Traits>& o, const basic_string_view<_CharT, _Traits>& str) -{ - o.write(str.data(), str.size()); - return o; -} - -template -inline void swap(basic_string_view<_CharT, _Traits>& lhs, basic_string_view<_CharT, _Traits>& rhs) -{ - lhs.swap(rhs); -} - -//-------------------------------------------------------------------------- -// Comparison Functions -//-------------------------------------------------------------------------- - -template -inline bool operator==(const basic_string_view<_CharT, _Traits>& lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return lhs.compare(rhs) == 0; -} - -template -inline bool operator==(basic_string_view<_CharT, _Traits> lhs, const _CharT* rhs) -{ - return lhs == basic_string_view<_CharT, _Traits>(rhs); -} - -template -inline bool operator==(const _CharT* lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return basic_string_view<_CharT, _Traits>(lhs) == rhs; -} - -template -inline bool operator==(const std::basic_string<_CharT, _Traits, Allocator>& lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return basic_string_view<_CharT, _Traits>(lhs) == rhs; -} - -template -inline bool operator==(const basic_string_view<_CharT, _Traits>& lhs, const std::basic_string<_CharT, _Traits, Allocator>& rhs) -{ - return lhs == basic_string_view<_CharT, _Traits>(rhs); -} - -//-------------------------------------------------------------------------- - -template -inline bool operator!=(const basic_string_view<_CharT, _Traits>& lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return lhs.compare(rhs) != 0; -} - -template -inline bool operator!=(const basic_string_view<_CharT, _Traits>& lhs, const _CharT* rhs) -{ - return lhs != basic_string_view<_CharT, _Traits>(rhs); -} - -template -inline bool operator!=(const _CharT* lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return basic_string_view<_CharT, _Traits>(lhs) != rhs; -} - -template -inline bool operator!=(const std::basic_string<_CharT, _Traits, Allocator>& lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return basic_string_view<_CharT, _Traits>(lhs) != rhs; -} - -template -inline bool operator!=(const basic_string_view<_CharT, _Traits>& lhs, const std::basic_string<_CharT, _Traits, Allocator>& rhs) -{ - return lhs != basic_string_view<_CharT, _Traits>(rhs); -} -//-------------------------------------------------------------------------- - -template -inline bool operator<(const basic_string_view<_CharT, _Traits>& lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return lhs.compare(rhs) < 0; -} - -template -inline bool operator<(const basic_string_view<_CharT, _Traits>& lhs, const _CharT* rhs) -{ - return lhs < basic_string_view<_CharT, _Traits>(rhs); -} - -template -inline bool operator<(const _CharT* lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return basic_string_view<_CharT, _Traits>(lhs) < rhs; -} - -template -inline bool operator<(const std::basic_string<_CharT, _Traits, Allocator>& lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return basic_string_view<_CharT, _Traits>(lhs) < rhs; -} - -template -inline bool operator<(const basic_string_view<_CharT, _Traits>& lhs, const std::basic_string<_CharT, _Traits, Allocator>& rhs) -{ - return lhs < basic_string_view<_CharT, _Traits>(rhs); -} - -//-------------------------------------------------------------------------- - -template -inline bool operator>(const basic_string_view<_CharT, _Traits>& lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return lhs.compare(rhs) > 0; -} - -template -inline bool operator>(const basic_string_view<_CharT, _Traits>& lhs, const _CharT* rhs) -{ - return lhs > basic_string_view<_CharT, _Traits>(rhs); -} - -template -inline bool operator>(const _CharT* lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return basic_string_view<_CharT, _Traits>(lhs) > rhs; -} - -template -inline bool operator>(const std::basic_string<_CharT, _Traits, Allocator>& lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return basic_string_view<_CharT, _Traits>(lhs) > rhs; -} - -template -inline bool operator>(const basic_string_view<_CharT, _Traits>& lhs, const std::basic_string<_CharT, _Traits, Allocator>& rhs) -{ - return lhs > basic_string_view<_CharT, _Traits>(rhs); -} - -//-------------------------------------------------------------------------- - -template -inline bool operator<=(const basic_string_view<_CharT, _Traits>& lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return lhs.compare(rhs) <= 0; -} - -template -inline bool operator<=(const basic_string_view<_CharT, _Traits>& lhs, const _CharT* rhs) -{ - return lhs <= basic_string_view<_CharT, _Traits>(rhs); -} - -template -inline bool operator<=(const _CharT* lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return basic_string_view<_CharT, _Traits>(lhs) <= rhs; -} - -template -inline bool operator<=(const std::basic_string<_CharT, _Traits, Allocator>& lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return basic_string_view<_CharT, _Traits>(lhs) <= rhs; -} - -template -inline bool operator<=(const basic_string_view<_CharT, _Traits>& lhs, const std::basic_string<_CharT, _Traits, Allocator>& rhs) -{ - return lhs <= basic_string_view<_CharT, _Traits>(rhs); -} - -//-------------------------------------------------------------------------- - -template -inline bool operator>=(const basic_string_view<_CharT, _Traits>& lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return lhs.compare(rhs) >= 0; -} - -template -inline bool operator>=(const basic_string_view<_CharT, _Traits>& lhs, const _CharT* rhs) -{ - return lhs >= basic_string_view<_CharT, _Traits>(rhs); -} - -template -inline bool operator>=(const _CharT* lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return basic_string_view<_CharT, _Traits>(lhs) >= rhs; -} - -template -inline bool operator>=(const std::basic_string<_CharT, _Traits, Allocator>& lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - return basic_string_view<_CharT, _Traits>(lhs) >= rhs; -} - -template -inline bool operator>=(const basic_string_view<_CharT, _Traits>& lhs, const std::basic_string<_CharT, _Traits, Allocator>& rhs) -{ - return lhs >= basic_string_view<_CharT, _Traits>(rhs); -} -//----------------------------------------------------------------- -// FNV1a hash from msvc++ -# if YASIO__64BITS -static const size_t _FNV_offset_basis = 14695981039346656037ULL; -static const size_t _FNV_prime = 1099511628211ULL; -# else /* defined(_M_X64), etc. */ -static const size_t _FNV_offset_basis = 2166136261U; -static const size_t _FNV_prime = 16777619U; -# endif /* defined(_M_X64), etc. */ -inline size_t _FNV1a_hash(const void* _First, size_t _Count) -{ // FNV-1a hash function for bytes in [_First, _First+_Count) - size_t _Val = _FNV_offset_basis; - for (size_t _Next = 0; _Next < _Count; ++_Next) - { // fold in another byte - _Val ^= (size_t) static_cast(_First)[_Next]; - _Val *= _FNV_prime; - } - - return (_Val); -} -} // namespace cxx17 -namespace std -{ -template -struct hash> { // hash functor for basic_string_view - typedef cxx17::basic_string_view<_Elem> _Kty; - - size_t operator()(const _Kty& _Keyval) const - { // hash _Keyval to size_t value by pseudorandomizing transform -# if defined(_LIBCPP_VERSION) - return __do_string_hash(_Keyval.data(), _Keyval.data() + _Keyval.size()); -# elif defined(__GLIBCXX__) - return _Hash_impl::hash(_Keyval.data(), _Keyval.size() * sizeof(_Elem)); -# else // msvc++ or other compiler without stable hash bytes function exists - return ::cxx17::_FNV1a_hash(_Keyval.data(), _Keyval.size() * sizeof(_Elem)); -# endif - } -}; -} // namespace std -#endif - -#if YASIO__HAS_CXX14 -namespace cxx17 -{ -// basic_string_view LITERALS -inline namespace literals -{ -inline namespace string_view_literals -{ -inline cxx17::string_view operator""_sv(const char* _Str, size_t _Len) { return cxx17::string_view(_Str, _Len); } -inline cxx17::wstring_view operator""_sv(const wchar_t* _Str, size_t _Len) { return cxx17::wstring_view(_Str, _Len); } -inline cxx17::u16string_view operator""_sv(const char16_t* _Str, size_t _Len) { return cxx17::u16string_view(_Str, _Len); } -inline cxx17::u32string_view operator""_sv(const char32_t* _Str, size_t _Len) { return cxx17::u32string_view(_Str, _Len); } -} // namespace string_view_literals -} // namespace literals -} // namespace cxx17 -#endif - -namespace cxx17 -{ -template -inline std::basic_string<_CharT, _Traits, Allocator>& assign(std::basic_string<_CharT, _Traits, Allocator>& lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - if (!rhs.empty()) - lhs.assign(rhs.data(), rhs.size()); - else - lhs.clear(); - return lhs; -} -template -inline std::basic_string<_CharT, _Traits, Allocator>& append(std::basic_string<_CharT, _Traits, Allocator>& lhs, const basic_string_view<_CharT, _Traits>& rhs) -{ - if (!rhs.empty()) - lhs.append(rhs.data(), rhs.size()); - else - lhs.clear(); - return lhs; -} -template > -inline std::basic_string<_CharT, _Traits, Allocator> svtos(const basic_string_view<_CharT, _Traits>& value) -{ - using string_type = std::basic_string<_CharT, _Traits, Allocator>; - return !value.empty() ? string_type(value.data(), value.size()) : string_type{}; -} -} // namespace cxx17 - -namespace cxx20 -{ -template -using decay_t = typename std::decay::type; -template -using remove_const_t = typename std::remove_const::type; -namespace char_ranges -{ // allow get char type from char*, wchar_t*, std::string, std::wstring -template -struct value_type { - using type = typename _Ty::value_type; -}; - -template -struct value_type<_Ty&> { - using type = remove_const_t<_Ty>; -}; - -template -struct value_type<_Ty*> { - using type = remove_const_t<_Ty>; -}; -} // namespace char_ranges - -// starts_with(), since C++20: -template -inline bool starts_with(cxx17::basic_string_view<_CharT> lhs, - cxx17::basic_string_view<_CharT> v) // (1) -{ - return lhs.size() >= v.size() && lhs.compare(0, v.size(), v) == 0; -} - -template -inline bool starts_with(_T1&& lhs, _T2&& v) // (2) -{ - using char_type = typename char_ranges::value_type>::type; - return starts_with(cxx17::basic_string_view{lhs}, cxx17::basic_string_view{v}); -} - -template -inline bool starts_with(cxx17::basic_string_view<_CharT> lhs, int c) // (3) -{ - return !lhs.empty() && lhs.front() == c; -} - -template -inline bool starts_with(_Ty&& lhs, int c) // (4) -{ - using char_type = typename char_ranges::value_type>::type; - return starts_with(cxx17::basic_string_view{lhs}, c); -} - -// ends_with(), since C++20: -template -inline bool ends_with(cxx17::basic_string_view<_CharT> lhs, - cxx17::basic_string_view<_CharT> v) // (1) -{ - auto offset = lhs.size() - v.size(); - return lhs.size() >= v.size() && lhs.compare(offset, v.size(), v) == 0; -} - -template -inline bool ends_with(_T1&& lhs, _T2&& v) // (2) -{ - using char_type = typename char_ranges::value_type>::type; - return ends_with(cxx17::basic_string_view{lhs}, cxx17::basic_string_view{v}); -} - -template -inline bool ends_with(cxx17::basic_string_view<_CharT> lhs, int c) // (3) -{ - return !lhs.empty() && lhs.back() == c; -} - -template -inline bool ends_with(_Ty&& lhs, int c) // (4) -{ - using char_type = typename char_ranges::value_type>::type; - return ends_with(cxx17::basic_string_view{lhs}, c); -} - -/// The case insensitive implementation of starts_with, ends_with -namespace ic -{ -template -inline bool iequals(cxx17::basic_string_view<_CharT> lhs, cxx17::basic_string_view<_CharT> v); -#if defined(_MSC_VER) -template <> -inline bool iequals(cxx17::basic_string_view lhs, cxx17::basic_string_view v) -{ - return lhs.size() == v.size() && ::_strnicmp(lhs.data(), v.data(), v.size()) == 0; -} -template <> -inline bool iequals(cxx17::basic_string_view lhs, cxx17::basic_string_view v) -{ - return lhs.size() == v.size() && ::_wcsnicmp(lhs.data(), v.data(), v.size()) == 0; -} -#else -template <> -inline bool iequals(cxx17::basic_string_view lhs, cxx17::basic_string_view v) -{ - return lhs.size() == v.size() && ::strncasecmp(lhs.data(), v.data(), v.size()) == 0; -} -template <> -inline bool iequals(cxx17::basic_string_view lhs, cxx17::basic_string_view v) -{ - return lhs.size() == v.size() && ::wcsncasecmp(lhs.data(), v.data(), v.size()) == 0; -} -#endif -template -inline bool iequals(_T1&& lhs, _T2&& v) -{ - using char_type = typename char_ranges::value_type>::type; - return iequals(cxx17::basic_string_view{lhs}, cxx17::basic_string_view{v}); -} -// starts_with(), since C++20: -template -inline bool starts_with(cxx17::basic_string_view<_CharT> lhs, - cxx17::basic_string_view<_CharT> v) // (1) -{ - return lhs.size() >= v.size() && iequals(lhs.substr(0, v.size()), v); -} - -template -inline bool starts_with(_T1&& lhs, _T2&& v) // (2) -{ - using char_type = typename char_ranges::value_type>::type; - return starts_with(cxx17::basic_string_view{lhs}, cxx17::basic_string_view{v}); -} - -template -inline bool starts_with(cxx17::basic_string_view<_CharT> lhs, int c) // (3) -{ - return !lhs.empty() && ::tolower(lhs.front()) == ::tolower(c); -} - -template -inline bool starts_with(_Ty&& lhs, int c) // (4) -{ - using char_type = typename char_ranges::value_type>::type; - return starts_with(cxx17::basic_string_view{lhs}, c); -} - -// ends_with(), since C++20: -template -inline bool ends_with(cxx17::basic_string_view<_CharT> lhs, - cxx17::basic_string_view<_CharT> v) // (1) -{ - return lhs.size() >= v.size() && iequals(lhs.substr(lhs.size() - v.size(), lhs.npos), v); -} - -template -inline bool ends_with(_T1&& lhs, _T2&& v) // (2) -{ - using char_type = typename char_ranges::value_type>::type; - return ends_with(cxx17::basic_string_view{lhs}, cxx17::basic_string_view{v}); -} - -template -inline bool ends_with(cxx17::basic_string_view<_CharT> lhs, int c) // (3) -{ - return !lhs.empty() && ::tolower(lhs.back()) == ::tolower(c); -} - -template -inline bool ends_with(_Ty&& lhs, int c) // (4) -{ - using char_type = typename char_ranges::value_type>::type; - return ends_with(cxx17::basic_string_view{lhs}, c); -} -} // namespace ic -} // namespace cxx20 - -#endif diff --git a/3rdparty/yasio/yasio/tlx/array_buffer.hpp b/3rdparty/yasio/yasio/tlx/array_buffer.hpp new file mode 100644 index 000000000000..4c78d9e142ed --- /dev/null +++ b/3rdparty/yasio/yasio/tlx/array_buffer.hpp @@ -0,0 +1,12 @@ +#pragma once + +#include "yasio/tlx/vector.hpp" +#include "yasio/tlx/buffer_alloc.hpp" +#include + +namespace tlx +{ +// alias: array_buffer +template > +using array_buffer = typename std::enable_if::value, ::tlx::vector<_Ty, _Alloc>>::type; +} // namespace tlx diff --git a/3rdparty/yasio/yasio/tlx/buffer_alloc.hpp b/3rdparty/yasio/yasio/tlx/buffer_alloc.hpp new file mode 100644 index 000000000000..33823124bb1f --- /dev/null +++ b/3rdparty/yasio/yasio/tlx/buffer_alloc.hpp @@ -0,0 +1,87 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// A multi-platform support c++11 library with focus on asynchronous socket I/O for any +// client application. +////////////////////////////////////////////////////////////////////////////////////////// +/* +The MIT License (MIT) + +Copyright (c) 2012-2025 HALX99 + +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. +*/ + +#ifndef YASIO__BUFFER_ALLOC_HPP +#define YASIO__BUFFER_ALLOC_HPP +#include +#include +#include +#include +#include +#include "yasio/compiler/feature_test.hpp" +#include "yasio/tlx/type_traits.hpp" + +namespace tlx +{ +template +struct crt_buffer_allocator { + using value_type = T; + using pointer = T*; + using const_pointer = const T*; + using size_type = std::size_t; + using difference_type = std::ptrdiff_t; + + // allocate n elements using CRT malloc + pointer allocate(size_type n) + { + if (n > max_size()) + throw std::bad_alloc(); + void* p = ::malloc(n * sizeof(T)); + if (!p) + throw std::bad_alloc(); + return static_cast(p); + } + + // deallocate memory using CRT free + void deallocate(pointer p, size_type /*n*/) noexcept { ::free(p); } + + // optional reallocate (non-standard, but useful for vector) + pointer reallocate(pointer p, size_type old_count, size_type new_count) + { + void* np = ::realloc(p, new_count * sizeof(T)); + if (!np) + throw std::bad_alloc(); + return static_cast(np); + } + + // max_size consistent with std::allocator + size_type max_size() const noexcept { return static_cast(-1) / sizeof(T); } + + // equality operators required by standard + template + struct rebind { + using other = crt_buffer_allocator; + }; + + bool operator==(const crt_buffer_allocator&) const noexcept { return true; } + bool operator!=(const crt_buffer_allocator&) const noexcept { return false; } +}; + +} // namespace tlx + +#endif diff --git a/3rdparty/yasio/yasio/byte_buffer.hpp b/3rdparty/yasio/yasio/tlx/byte_buffer.hpp similarity index 83% rename from 3rdparty/yasio/yasio/byte_buffer.hpp rename to 3rdparty/yasio/yasio/tlx/byte_buffer.hpp index 75f44050be75..31b3d43edda0 100644 --- a/3rdparty/yasio/yasio/byte_buffer.hpp +++ b/3rdparty/yasio/yasio/tlx/byte_buffer.hpp @@ -27,16 +27,16 @@ SOFTWARE. */ #ifndef YASIO__BYTE_BUFFER_HPP #define YASIO__BYTE_BUFFER_HPP -#include "yasio/pod_vector.hpp" +#include "yasio/tlx/array_buffer.hpp" -namespace yasio +namespace tlx { - -template , enable_if_t::value, int> = 0> -using basic_byte_buffer = array_buffer<_Ty, _Alloc>; +// basic_byte_buffer restricted to byte types +template > +using basic_byte_buffer = typename std::enable_if::value, tlx::array_buffer<_Ty, _Alloc>>::type; using sbyte_buffer = basic_byte_buffer; using byte_buffer = basic_byte_buffer; -} // namespace yasio +} // namespace tlx #endif diff --git a/3rdparty/yasio/yasio/utils.hpp b/3rdparty/yasio/yasio/tlx/chrono.hpp similarity index 85% rename from 3rdparty/yasio/yasio/utils.hpp rename to 3rdparty/yasio/yasio/tlx/chrono.hpp index da2234a3c3db..7290e151d1e2 100644 --- a/3rdparty/yasio/yasio/utils.hpp +++ b/3rdparty/yasio/yasio/tlx/chrono.hpp @@ -33,7 +33,7 @@ SOFTWARE. #include #include "yasio/compiler/feature_test.hpp" -namespace yasio +namespace tlx { // typedefs typedef long long highp_time_t; @@ -68,29 +68,6 @@ inline highp_time_t clock() // https://docs.microsoft.com/en-us/windows/desktop/sysinfo/acquiring-high-resolution-time-stamps inline highp_time_t time_now() { return ::time(nullptr); } -#if YASIO__HAS_CXX17 -using std::clamp; -#else -template -const _Ty& clamp(const _Ty& v, const _Ty& lo, const _Ty& hi) -{ - assert(!(hi < lo)); - return v < lo ? lo : hi < v ? hi : v; -} -#endif - -template -inline void invoke_dtor(_Ty* p) -{ - p->~_Ty(); -} - -inline bool is_regular_file(const char* path) -{ - struct stat st; - return (::stat(path, &st) == 0) && (st.st_mode & S_IFREG); -} - -} // namespace yasio +} // namespace tlx #endif diff --git a/3rdparty/yasio/yasio/file.hpp b/3rdparty/yasio/yasio/tlx/file_io.hpp similarity index 84% rename from 3rdparty/yasio/yasio/file.hpp rename to 3rdparty/yasio/yasio/tlx/file_io.hpp index edaf0cf67455..7abbd5977517 100644 --- a/3rdparty/yasio/yasio/file.hpp +++ b/3rdparty/yasio/yasio/tlx/file_io.hpp @@ -28,13 +28,13 @@ SOFTWARE. #pragma once -#include "yasio/string.hpp" -#include "yasio/string_view.hpp" +#include "yasio/tlx/string.hpp" +#include "yasio/tlx/string_view.hpp" #include -namespace yasio +namespace tlx { -inline yasio::string read_text_file(cxx17::string_view file_path) +inline tlx::string read_text_file(std::string_view file_path) { std::ifstream fin(file_path.data(), std::ios_base::binary); if (fin.is_open()) @@ -43,7 +43,7 @@ inline yasio::string read_text_file(cxx17::string_view file_path) auto n = static_cast(fin.tellg()); if (n > 0) { - yasio::string ret; + tlx::string ret; ret.resize_and_overwrite(n, [&fin](char* out, size_t outlen) { fin.seekg(std::ios_base::beg); fin.read(out, outlen); @@ -52,6 +52,13 @@ inline yasio::string read_text_file(cxx17::string_view file_path) return ret; } } - return yasio::string{}; + return tlx::string{}; } -} // namespace yasio + +inline bool is_regular_file(const char* path) +{ + struct stat st; + return (::stat(path, &st) == 0) && (st.st_mode & S_IFREG); +} + +} // namespace tlx diff --git a/3rdparty/yasio/yasio/tlx/memory.hpp b/3rdparty/yasio/yasio/tlx/memory.hpp new file mode 100644 index 000000000000..e223f6f8ffc6 --- /dev/null +++ b/3rdparty/yasio/yasio/tlx/memory.hpp @@ -0,0 +1,463 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// A multi-platform support c++11 library with focus on asynchronous socket I/O for any +// client application. +////////////////////////////////////////////////////////////////////////////////////////// +/* +The MIT License (MIT) + +Copyright (c) 2012-2025 HALX99 + +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. +*/ +#ifndef YASIO__MEMORY +#define YASIO__MEMORY +#include +#include +#include +#include +#include +#include + +#include "yasio/compiler/feature_test.hpp" + +namespace tlx +{ +template +struct construct_helper { + template + static _Ty* construct_at(_Ty* p, Args&&... args) + { + return ::new (static_cast(p)) _Ty(std::forward(args)...); + } +}; +template +struct construct_helper<_Ty, false> { + template + static _Ty* construct_at(_Ty* p, Args&&... args) + { + return ::new (static_cast(p)) _Ty{std::forward(args)...}; + } +}; + +template +inline _Ty* construct_at(_Ty* p, Args&&... args) +{ + return construct_helper<_Ty, std::is_constructible<_Ty, Args&&...>::value>::construct_at(p, std::forward(args)...); +} + +template +inline void invoke_dtor(_Ty* p) +{ + p->~_Ty(); +} + +struct __zero_then_variadic_args_t { + explicit __zero_then_variadic_args_t() = default; +}; // tag type for value-initializing first, constructing second from remaining args + +struct __one_then_variadic_args_t { + explicit __one_then_variadic_args_t() = default; +}; // tag type for constructing first from one arg, constructing second from remaining args + +template && !std::is_final_v<_Ty1>> +class __compressed_pair final : private _Ty1 { // store a pair of values, deriving from empty first +public: + _Ty2 _Myval2; + + using _Mybase = _Ty1; // for visualization + + template + constexpr explicit __compressed_pair(__zero_then_variadic_args_t, _Other2&&... _Val2) noexcept : _Ty1(), _Myval2(std::forward<_Other2>(_Val2)...) + {} + + template + constexpr __compressed_pair(__one_then_variadic_args_t, _Other1&& _Val1, _Other2&&... _Val2) noexcept + : _Ty1(std::forward<_Other1>(_Val1)), _Myval2(std::forward<_Other2>(_Val2)...) + {} + + constexpr _Ty1& _Get_first() noexcept { return *this; } + + constexpr const _Ty1& _Get_first() const noexcept { return *this; } +}; + +template +class __compressed_pair<_Ty1, _Ty2, false> final { // store a pair of values, not deriving from first +public: + _Ty1 _Myval1; + _Ty2 _Myval2; + + template + constexpr explicit __compressed_pair(__zero_then_variadic_args_t, _Other2&&... _Val2) noexcept : _Myval1(), _Myval2(std::forward<_Other2>(_Val2)...) + {} + + template + constexpr __compressed_pair(__one_then_variadic_args_t, _Other1&& _Val1, _Other2&&... _Val2) noexcept + : _Myval1(std::forward<_Other1>(_Val1)), _Myval2(std::forward<_Other2>(_Val2)...) + {} + + constexpr _Ty1& _Get_first() noexcept { return _Myval1; } + + constexpr const _Ty1& _Get_first() const noexcept { return _Myval1; } +}; + +template +using rebind_alloc_t = typename std::allocator_traits<_Alloc>::template rebind_alloc<_Value_type>; + +template +struct __tidy_guard { // class with destructor that calls _Tidy + _Ty* _Target; + YASIO__CONSTEXPR ~__tidy_guard() + { + if (_Target) + { + _Target->_Tidy(); + } + } +}; + +template +struct _Identity { + using type = _Ty; +}; +template +using identity_t = typename _Identity<_Ty>::type; + +template +class __uninitialized_backout_al { +public: + using allocator_traits = typename std::allocator_traits; + using pointer = typename allocator_traits::pointer; + using value_type = typename allocator_traits::value_type; + + __uninitialized_backout_al(pointer dest, Alloc& al) : _dest(dest), _cur(dest), _alloc(al), _released(false) {} + + ~__uninitialized_backout_al() + { + if (!_released) + { + for (auto p = _dest; p != _cur; ++p) + { + std::allocator_traits::destroy(_alloc, p); + } + } + } + + template + void _Emplace_back(Args&&... args) + { + std::allocator_traits::construct(_alloc, _cur, std::forward(args)...); + ++_cur; + } + + pointer _Release() + { + _released = true; + return _cur; + } + +private: + pointer _dest; + pointer _cur; + Alloc& _alloc; + bool _released; +}; + +struct __value_init_tag { // tag to request value-initialization + explicit __value_init_tag() = default; +}; + +template +using iter_ref_t = typename std::iterator_traits::reference; + +inline void __xlength_error(const char* what) { throw ::std::length_error(what); } + +inline void __xout_of_range(const char* what) { throw ::std::out_of_range(what); } + +static_assert(std::is_same_v::value_type, int>); + +template +inline constexpr bool is_pod_iterator_v = std::is_trivially_copyable_v::value_type>; + +template +inline constexpr bool bitcopy_assignable_v = std::is_trivially_copyable_v::value_type> && + std::is_same_v::value_type, typename std::pointer_traits::element_type>; + +template +typename Alloc::pointer uninitialized_fill_n(typename Alloc::pointer first, size_t count, const typename Alloc::value_type& val, Alloc& alloc) +{ + using T = typename Alloc::value_type; + + if constexpr (std::is_trivially_copyable_v) + { + for (size_t i = 0; i < count; ++i) + { + first[i] = val; + } + return first + count; + } + else + { + for (size_t i = 0; i < count; ++i) + { + std::allocator_traits::construct(alloc, first + i, val); + } + return first + count; + } +} + +template +constexpr OutPtr uninitialized_move(InIt first, InIt last, OutPtr dest, Alloc& alloc) +{ + using T = typename Alloc::value_type; + const auto count = static_cast(last - first); + + if constexpr (std::is_trivially_copyable_v) + { + if (!std::is_constant_evaluated()) + { + ::memmove(std::to_address(dest), std::to_address(first), count * sizeof(T)); + return dest + count; + } + } + + __uninitialized_backout_al backout{dest, alloc}; + for (; first != last; ++first) + { + backout._Emplace_back(std::move(*first)); + } + return backout._Release(); +} + +template +constexpr OutPtr uninitialized_copy_n(InIt first, size_t count, OutPtr dest, Alloc& alloc) +{ + using T = typename Alloc::value_type; + + if constexpr (std::is_trivially_copyable_v) + { + ::memmove(std::to_address(dest), std::to_address(first), count * sizeof(T)); + return dest + count; + } + else + { + __uninitialized_backout_al backout{dest, alloc}; + for (; count != 0; ++first, --count) + { + backout._Emplace_back(*first); + } + return backout._Release(); + } +} + +template +typename Alloc::pointer uninitialized_copy(InIt first, InIt last, typename Alloc::pointer dest, Alloc& alloc) +{ + using T = typename Alloc::value_type; + + const auto count = static_cast(last - first); + + if constexpr (std::is_trivially_copyable_v) + { + ::memmove(dest, &*first, count * sizeof(T)); + return dest + count; + } + else + { + __uninitialized_backout_al backout{dest, alloc}; + for (; first != last; ++first) + { + backout._Emplace_back(*first); + } + return backout._Release(); + } +} + +template +constexpr void destroy_range(Ptr first, Ptr last, Alloc& alloc) noexcept +{ + using T = typename Alloc::value_type; + + if constexpr (!std::is_trivially_destructible_v) + { + for (; first != last; ++first) + { + std::allocator_traits::destroy(alloc, std::to_address(first)); + } + } +} + +template +typename Alloc::pointer uninitialized_value_construct_n(typename Alloc::pointer first, size_t count, Alloc& alloc) +{ + using T = typename Alloc::value_type; + + if constexpr (std::is_trivially_constructible_v && std::is_trivially_destructible_v) + { + ::memset(first, 0, count * sizeof(T)); + return first + count; + } + else + { + __uninitialized_backout_al backout{first, alloc}; + for (; count > 0; --count) + { + backout._Emplace_back(); + } + return backout._Release(); + } +} + +template +OutCtgIt copy_memmove_n(InCtgIt first, size_t count, OutCtgIt dest) +{ + using T = typename std::iterator_traits::value_type; + + const auto byte_count = count * sizeof(T); + + const auto src_ptr = std::to_address(first); + const auto dest_ptr = std::to_address(dest); + + ::memmove(dest_ptr, src_ptr, byte_count); + + if constexpr (std::is_pointer_v) + { + return dest_ptr + count; + } + else + { + return dest + static_cast::difference_type>(count); + } +} + +template +constexpr OutIt move_unchecked(InIt first, InIt last, OutIt dest) +{ + using T = typename std::iterator_traits::value_type; + const auto count = static_cast(last - first); + + if constexpr (std::is_trivially_copyable_v) + { + ::memmove(std::to_address(dest), std::to_address(first), count * sizeof(T)); + return dest + count; + } + else + { + for (; first != last; ++first, ++dest) + { + *dest = std::move(*first); + } + return dest; + } +} + +template +_CtgIt2 copy_backward_memmove(_CtgIt1 _First, _CtgIt1 _Last, _CtgIt2 _Dest) +{ + // implement copy_backward-like function as memmove + const auto _First_ptr = std::to_address(_First); + const auto _Last_ptr = std::to_address(_Last); + const auto _Dest_ptr = std::to_address(_Dest); + + const auto _First_ch = const_cast(reinterpret_cast(_First_ptr)); + const auto _Last_ch = const_cast(reinterpret_cast(_Last_ptr)); + const auto _Dest_ch = const_cast(reinterpret_cast(_Dest_ptr)); + + const auto _Count = static_cast(_Last_ch - _First_ch); + const auto _Result = ::memmove(_Dest_ch - _Count, _First_ch, _Count); + + if constexpr (std::is_pointer_v<_CtgIt2>) + { + return static_cast<_CtgIt2>(_Result); + } + else + { + using diff_t = typename std::iterator_traits<_CtgIt2>::difference_type; + return _Dest - static_cast(_Last_ptr - _First_ptr); + } +} + +template +_BidIt2 copy_backward_memmove(std::move_iterator<_BidIt1> _First, std::move_iterator<_BidIt1> _Last, _BidIt2 _Dest) +{ + return copy_backward_memmove(_First.base(), _Last.base(), _Dest); +} + +template +_BidIt2 move_backward_unchecked(_BidIt1 _First, _BidIt1 _Last, _BidIt2 _Dest) +{ + // move [_First, _Last) backwards to [..., _Dest) + // note: move_backward_unchecked has callers other than the move_backward family + if constexpr (is_pod_iterator_v<_BidIt2>) + { + if (!std::is_constant_evaluated()) + { + return copy_backward_memmove(_First, _Last, _Dest); + } + } + + while (_First != _Last) + { + *--_Dest = std::move(*--_Last); + } + + return _Dest; +} + +template +constexpr OutIt copy_n_unchecked4(InIt first, SizeTy count, OutIt dest) +{ + using T = typename std::iterator_traits::value_type; + + static_assert(std::is_integral_v, "SizeTy must be integer-like"); + if (count < 0) + return dest; + + if constexpr (std::is_trivially_copyable_v) + { + if (!std::is_constant_evaluated()) + { + ::memmove(std::to_address(dest), std::to_address(first), count * sizeof(T)); + return dest + count; + } + } + + for (; count != 0; ++dest, ++first, --count) + { + *dest = *first; + } + return dest; +} + +} // namespace yasio + +#define _TLX_VERIFY_RANGE(cond, mesg) \ + do \ + { \ + if (cond) \ + ; /* contextually convertible to bool paranoia */ \ + else \ + { \ + throw std::out_of_range(mesg); \ + } \ + \ + } while (false) + +#define _TLX_INTERNAL_CHECK(cond) assert(cond) + +#endif diff --git a/3rdparty/yasio/yasio/shared_mutex.hpp b/3rdparty/yasio/yasio/tlx/shared_mutex.hpp similarity index 95% rename from 3rdparty/yasio/yasio/shared_mutex.hpp rename to 3rdparty/yasio/yasio/tlx/shared_mutex.hpp index 25c6f83bbc5a..8061d506e648 100644 --- a/3rdparty/yasio/yasio/shared_mutex.hpp +++ b/3rdparty/yasio/yasio/tlx/shared_mutex.hpp @@ -22,10 +22,16 @@ /// The shared_mutex workaround on c++11 #if YASIO__HAS_CXX17 && !defined(__APPLE__) # include +namespace tlx +{ +using shared_mutex = ::std::shared_mutex; +template +using shared_lock = ::std::shared_lock<_Mutex>; +} // namespace tlx #else # include # include -namespace cxx17 +namespace tlx { // CLASS TEMPLATE shared_mutex class shared_mutex { @@ -60,7 +66,7 @@ class shared_mutex { bool one_or_more_readers() const { return (state_ & n_readers_) > 0; } - shared_mutex(shared_mutex const&) = delete; + shared_mutex(shared_mutex const&) = delete; shared_mutex& operator=(shared_mutex const&) = delete; public: @@ -183,7 +189,7 @@ class shared_lock { return *this; } - shared_lock(const shared_lock&) = delete; + shared_lock(const shared_lock&) = delete; shared_lock& operator=(const shared_lock&) = delete; void lock() @@ -244,7 +250,7 @@ class shared_lock { yasio__throw_error0(std::errc::resource_deadlock_would_occur); } }; -} // namespace cxx17 +} // namespace tlx #endif #endif diff --git a/3rdparty/yasio/yasio/singleton.hpp b/3rdparty/yasio/yasio/tlx/singleton.hpp similarity index 99% rename from 3rdparty/yasio/yasio/singleton.hpp rename to 3rdparty/yasio/yasio/tlx/singleton.hpp index eebfef83f4a3..b868e22a6f36 100644 --- a/3rdparty/yasio/yasio/singleton.hpp +++ b/3rdparty/yasio/yasio/tlx/singleton.hpp @@ -50,7 +50,7 @@ SOFTWARE. #include #include -namespace yasio +namespace tlx { template class singleton_constructor { @@ -154,6 +154,6 @@ std::atomic<_Ty*> singleton<_Ty>::__single__; template std::mutex singleton<_Ty>::__mutex__; -} // namespace yasio +} // namespace tlx #endif diff --git a/3rdparty/yasio/yasio/string.hpp b/3rdparty/yasio/yasio/tlx/string.hpp similarity index 63% rename from 3rdparty/yasio/yasio/string.hpp rename to 3rdparty/yasio/yasio/tlx/string.hpp index bd4044a2841d..e0cedd6e9b11 100644 --- a/3rdparty/yasio/yasio/string.hpp +++ b/3rdparty/yasio/yasio/tlx/string.hpp @@ -1,4 +1,3 @@ - ////////////////////////////////////////////////////////////////////////////////////////// // A multi-platform support c++11 library with focus on asynchronous socket I/O for any // client application. @@ -26,8 +25,8 @@ 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. -The yasio dedicated string (API not 100% compatible with stl) concepts: - a. no SSO, no COW, sizeof(yasio::string) = 24(x64), 12(x86) +The tlx dedicated string (API not 100% compatible with stl) concepts: + a. no SSO, no COW, sizeof(tlx::string) = 24(x64), 12(x86) b. The resize behavior differrent stl, always allocate exactly c. By default resize without fill (uninitialized and for overwrite), use insert/append insetad if you want fill memory inside container @@ -47,13 +46,16 @@ The yasio dedicated string (API not 100% compatible with stl) concepts: #include #include #include -#include "yasio/buffer_alloc.hpp" -#include "yasio/string_view.hpp" +#include "yasio/tlx/buffer_alloc.hpp" // crt_buffer_allocator +#include "yasio/tlx/string_view.hpp" +#include "yasio/tlx/memory.hpp" // compressed_pair -namespace yasio +namespace tlx { -template , enable_if_t::value, int> = 0> +template , _TLX enable_if_t::value, int> = 0> class basic_string { + YASIO__CONSTEXPR _Alloc& _Getal() noexcept { return _Mypair._Get_first(); } + public: using pointer = _Elem*; using const_pointer = const _Elem*; @@ -63,30 +65,41 @@ class basic_string { using iterator = _Elem*; // transparent iterator using const_iterator = const _Elem*; using allocator_type = _Alloc; - using _Alloc_traits = buffer_allocator_traits<_Alloc>; + using _Alloc_traits = std::allocator_traits<_Alloc>; using size_type = typename _Alloc_traits::size_type; using _Traits = std::char_traits<_Elem>; - using view_type = cxx17::basic_string_view<_Elem>; + using view_type = std::basic_string_view<_Elem>; using my_type = basic_string<_Elem, _Alloc>; - static const size_t npos = -1; - basic_string() {} + static const size_t npos = static_cast(-1); + + // compressed storage: allocator + 3 pointers (_Myfirst, _Mylast, _Myend) + struct _Str_storage { + pointer _Myfirst = nullptr; // begin + pointer _Mylast = nullptr; // one past last character + pointer _Myend = nullptr; // one past end of storage + }; + __compressed_pair _Mypair; + + basic_string() : _Mypair(__one_then_variadic_args_t{}, _Alloc{}) {} basic_string(nullptr_t) = delete; - explicit basic_string(size_type count) { resize(static_cast(count)); } - basic_string(size_type count, const_reference val) { resize(static_cast(count), val); } + explicit basic_string(size_type count) : _Mypair(__one_then_variadic_args_t{}, _Alloc{}) { resize(static_cast(count)); } + basic_string(size_type count, const_reference val) : _Mypair(__one_then_variadic_args_t{}, _Alloc{}) { resize(static_cast(count), val); } template ::value, int> = 0> - basic_string(_Iter first, _Iter last) + basic_string(_Iter first, _Iter last) : _Mypair(__one_then_variadic_args_t{}, _Alloc{}) { assign(first, last); } - basic_string(const basic_string& rhs) { assign(rhs); }; - basic_string(basic_string&& rhs) YASIO__NOEXCEPT { assign(std::move(rhs)); } - basic_string(view_type rhs) { assign(rhs); } - basic_string(const_pointer ntcs) { assign(ntcs); } - basic_string(const_pointer ntcs, size_type count) { assign(ntcs, ntcs + count); } + basic_string(const basic_string& rhs) : _Mypair(__one_then_variadic_args_t{}, _Alloc{}) { assign(rhs); } + basic_string(basic_string&& rhs) YASIO__NOEXCEPT : _Mypair(__one_then_variadic_args_t{}, _Alloc{}) { _Assign_rv(std::move(rhs)); } + basic_string(view_type rhs) : _Mypair(__one_then_variadic_args_t{}, _Alloc{}) { assign(rhs); } + basic_string(const_pointer ntcs) : _Mypair(__one_then_variadic_args_t{}, _Alloc{}) { assign(ntcs); } + basic_string(const_pointer ntcs, size_type count) : _Mypair(__one_then_variadic_args_t{}, _Alloc{}) { assign(ntcs, ntcs + count); } /*basic_string(std::initializer_list rhs) { _Assign_range(rhs.begin(), rhs.end()); }*/ ~basic_string() { _Tidy(); } + operator view_type() const YASIO__NOEXCEPT { return this->view(); } view_type view() const YASIO__NOEXCEPT { return view_type(this->c_str(), this->size()); } + basic_string& operator=(const basic_string& rhs) { assign(rhs); @@ -97,6 +110,7 @@ class basic_string { this->swap(rhs); return *this; } + template basic_string& operator+=(const _Cont& rhs) { @@ -107,6 +121,7 @@ class basic_string { this->push_back(rhs); return *this; } + template ::value, int> = 0> void assign(_Iter first, _Iter last) { @@ -117,20 +132,27 @@ class basic_string { void assign(const_pointer ntcs, size_type count) { _Assign_range(ntcs, ntcs + count); } void assign(const basic_string& rhs) { _Assign_range(rhs.begin(), rhs.end()); } void assign(basic_string&& rhs) { _Assign_rv(std::move(rhs)); } + void swap(basic_string& rhs) YASIO__NOEXCEPT { - std::swap(_Myfirst, rhs._Myfirst); - std::swap(_Mysize, rhs._Mysize); - std::swap(_Myres, rhs._Myres); + std::swap(_Getal(), rhs._Getal()); + + auto& a = _Mypair._Myval2; + auto& b = rhs._Mypair._Myval2; + std::swap(a._Myfirst, b._Myfirst); + std::swap(a._Mylast, b._Mylast); + std::swap(a._Myend, b._Myend); } + template ::value, int> = 0> iterator insert(iterator _Where, _Iter first, _Iter last) { - auto _Mylast = _Myfirst + _Mysize; - _YASIO_VERIFY_RANGE(_Where >= _Myfirst && _Where <= _Mylast && first <= last, "basic_string: out of range!"); + auto& st = _Mypair._Myval2; + auto _Mylast = st._Mylast; + _TLX_VERIFY_RANGE(_Where >= st._Myfirst && _Where <= _Mylast && first <= last, "basic_string: out of range!"); if (first != last) { - auto insertion_pos = static_cast(std::distance(_Myfirst, _Where)); + auto insertion_pos = static_cast(std::distance(st._Myfirst, _Where)); if (_Where == _Mylast) append(first, last); else @@ -140,131 +162,173 @@ class basic_string { auto count = static_cast(std::distance(first, last)); if (insertion_pos >= 0) { - auto old_size = _Mylast - _Myfirst; + auto old_size = static_cast(_Mylast - st._Myfirst); expand(count); - _Where = _Myfirst + insertion_pos; - _Mylast = _Myfirst + _Mysize; + _Where = st._Myfirst + insertion_pos; + _Mylast = st._Mylast; auto move_to = _Where + count; - std::copy_n(_Where, _Mylast - move_to, move_to); + std::copy_n(_Where, static_cast(_Mylast - move_to), move_to); std::copy_n((iterator)ifirst, count, _Where); } } - return _Myfirst + insertion_pos; + return st._Myfirst + insertion_pos; } return _Where; } + iterator insert(iterator _Where, size_type count, const_reference val) { - auto _Mylast = _Myfirst + _Mysize; - _YASIO_VERIFY_RANGE(_Where >= _Myfirst && _Where <= _Mylast, "basic_string: out of range!"); + auto& st = _Mypair._Myval2; + auto _Mylast = st._Mylast; + _TLX_VERIFY_RANGE(_Where >= st._Myfirst && _Where <= _Mylast, "basic_string: out of range!"); if (count) { - auto insertion_pos = std::distance(_Myfirst, _Where); + auto insertion_pos = std::distance(st._Myfirst, _Where); if (_Where == _Mylast) append(count, val); else { if (insertion_pos >= 0) { - const auto old_size = _Mysize; + const auto old_size = size(); expand(count); - _Where = _Myfirst + insertion_pos; - _Mylast = _Myfirst + _Mysize; + _Where = st._Myfirst + insertion_pos; + _Mylast = st._Mylast; auto move_to = _Where + count; - std::copy_n(_Where, _Mylast - move_to, move_to); + std::copy_n(_Where, static_cast(_Mylast - move_to), move_to); std::fill_n(_Where, count, val); } } - return _Myfirst + insertion_pos; + return st._Myfirst + insertion_pos; } return _Where; } + basic_string& append(view_type value) { return this->append(value.begin(), value.end()); } template ::value, int> = 0> basic_string& append(_Iter first, const _Iter last) { if (first != last) { + auto& st = _Mypair._Myval2; auto ifirst = std::addressof(*first); static_assert(sizeof(*ifirst) == sizeof(value_type), "basic_string: iterator type incompatible!"); auto count = static_cast(std::distance(first, last)); if (count > 1) { - const auto old_size = _Mysize; + const auto old_size = size(); expand(count); - std::copy_n((iterator)ifirst, count, _Myfirst + old_size); + std::copy_n((iterator)ifirst, count, st._Myfirst + old_size); } else if (count == 1) push_back(static_cast(*(iterator)ifirst)); } return *this; } + basic_string& append(size_type count, const_reference val) { expand(count, val); return *this; } + void push_back(value_type&& v) { push_back(v); } void push_back(const value_type& v) { expand(1); back() = v; } + iterator erase(iterator _Where) { - const auto _Mylast = _Myfirst + _Mysize; - _YASIO_VERIFY_RANGE(_Where >= _Myfirst && _Where < _Mylast, "basic_string: out of range!"); - _Mysize = static_cast(std::move(_Where + 1, _Mylast, _Where) - _Myfirst); + auto& st = _Mypair._Myval2; + const auto _Mylast = st._Mylast; + _TLX_VERIFY_RANGE(_Where >= st._Myfirst && _Where < _Mylast, "basic_string: out of range!"); + st._Mylast = std::move(_Where + 1, _Mylast, _Where); + // keep null terminator + *_Mylast_ptr() = value_type(0); return _Where; } + iterator erase(iterator first, iterator last) { - const auto _Mylast = _Myfirst + _Mysize; - _YASIO_VERIFY_RANGE((first <= last) && first >= _Myfirst && last <= _Mylast, "basic_string: out of range!"); - _Mysize = static_cast(std::move(last, _Mylast, first) - _Myfirst); + auto& st = _Mypair._Myval2; + const auto _Mylast = st._Mylast; + _TLX_VERIFY_RANGE((first <= last) && first >= st._Myfirst && last <= _Mylast, "basic_string: out of range!"); + st._Mylast = std::move(last, _Mylast, first); + // keep null terminator + *_Mylast_ptr() = value_type(0); return first; } + value_type& front() { - _YASIO_VERIFY_RANGE(!empty(), "basic_string: out of range!"); - return *_Myfirst; + _TLX_VERIFY_RANGE(!empty(), "basic_string: out of range!"); + return *_Mypair._Myval2._Myfirst; } + value_type& back() { - _YASIO_VERIFY_RANGE(!empty(), "basic_string: out of range!"); - return _Myfirst[_Mysize - 1]; + _TLX_VERIFY_RANGE(!empty(), "basic_string: out of range!"); + return *(_Mypair._Myval2._Mylast - 1); + } + + static YASIO__CONSTEXPR size_type max_size() YASIO__NOEXCEPT + { + // static form to avoid needing allocator instance + return static_cast(-1) / sizeof(value_type); } - static YASIO__CONSTEXPR size_type max_size() YASIO__NOEXCEPT { return _Alloc_traits::max_size(); } #pragma region Iterators iterator begin() YASIO__NOEXCEPT { return this->data(); } - iterator end() YASIO__NOEXCEPT { return begin() + _Mysize; } + iterator end() YASIO__NOEXCEPT { return _Mypair._Myval2._Mylast; } const_iterator begin() const YASIO__NOEXCEPT { return this->data(); } - const_iterator end() const YASIO__NOEXCEPT { return begin() + _Mysize; } + const_iterator end() const YASIO__NOEXCEPT { return _Mypair._Myval2._Mylast; } #pragma endregion - pointer data() YASIO__NOEXCEPT { return _Myfirst; } - const_pointer data() const YASIO__NOEXCEPT { return _Myfirst; } - const_pointer c_str() const YASIO__NOEXCEPT { return _Myfirst ? _Myfirst : reinterpret_cast(&_Myfirst);; } + pointer data() YASIO__NOEXCEPT { return _Mypair._Myval2._Myfirst; } + const_pointer data() const YASIO__NOEXCEPT { return _Mypair._Myval2._Myfirst; } + + const_pointer c_str() const YASIO__NOEXCEPT + { + auto& st = _Mypair._Myval2; + return st._Myfirst ? st._Myfirst : reinterpret_cast(&st._Myfirst); + } + const_reference operator[](size_type index) const { return this->at(index); } reference operator[](size_type index) { return this->at(index); } const_reference at(size_type index) const { - _YASIO_VERIFY_RANGE(index < this->size(), "basic_string: out of range!"); - return _Myfirst[index]; + _TLX_VERIFY_RANGE(index < this->size(), "basic_string: out of range!"); + return _Mypair._Myval2._Myfirst[index]; } reference at(size_type index) { - _YASIO_VERIFY_RANGE(index < this->size(), "basic_string: out of range!"); - return _Myfirst[index]; + _TLX_VERIFY_RANGE(index < this->size(), "basic_string: out of range!"); + return _Mypair._Myval2._Myfirst[index]; } #pragma region Capacity - size_type capacity() const YASIO__NOEXCEPT { return _Myres; } - size_type size() const YASIO__NOEXCEPT { return _Mysize; } - size_type length() const YASIO__NOEXCEPT { return _Mysize; } - void clear() YASIO__NOEXCEPT { _Mysize = 0; } - bool empty() const YASIO__NOEXCEPT { return _Mysize == 0; } + size_type capacity() const YASIO__NOEXCEPT + { + auto& st = _Mypair._Myval2; + return static_cast(st._Myend - st._Myfirst); + } + size_type size() const YASIO__NOEXCEPT + { + auto& st = _Mypair._Myval2; + return static_cast(st._Mylast - st._Myfirst); + } + size_type length() const YASIO__NOEXCEPT { return size(); } + void clear() YASIO__NOEXCEPT + { + auto& st = _Mypair._Myval2; + st._Mylast = st._Myfirst; + if (st._Myfirst) + *st._Mylast = value_type(0); + } + bool empty() const YASIO__NOEXCEPT { return _Mypair._Myval2._Mylast == _Mypair._Myval2._Myfirst; } + void resize(size_type new_size) { if (this->capacity() < new_size) @@ -272,6 +336,7 @@ class basic_string { else _Eos(new_size); } + void expand(size_type count) { const auto new_size = this->size() + count; @@ -280,28 +345,36 @@ class basic_string { else _Eos(new_size); } + void shrink_to_fit() { // reduce capacity to size, provide strong guarantee - if (_Mysize != _Myres) + auto& st = _Mypair._Myval2; + if (st._Mylast != st._Myend) { // something to do - if (!_Mysize) + if (st._Mylast == st._Myfirst) _Tidy(); else - _Reallocate<_Reallocation_policy::_Exactly>(_Mysize); + _Reallocate<_Reallocation_policy::_Exactly>(size()); } } + void reserve(size_type new_cap) { if (this->capacity() < new_cap) _Reallocate<_Reallocation_policy::_Exactly>(new_cap); } + template void resize_and_overwrite(const size_type _New_size, _Operation _Op) { _Reallocate<_Reallocation_policy::_Exactly>(_New_size); - _Eos(std::move(_Op)(_Myfirst, _New_size)); + auto& st = _Mypair._Myval2; + // _Op writes up to _New_size and returns new size + size_type written = std::move(_Op)(st._Myfirst, _New_size); + _Eos(written); } #pragma endregion + void resize(size_type new_size, const_reference val) { auto old_size = this->size(); @@ -309,9 +382,10 @@ class basic_string { { resize(new_size); if (old_size < new_size) - std::fill_n(_Myfirst + old_size, new_size - old_size, val); + std::fill_n(_Mypair._Myval2._Myfirst + old_size, new_size - old_size, val); } } + void expand(size_type count, const_reference val) { if (count) @@ -319,29 +393,35 @@ class basic_string { auto old_size = this->size(); expand(count); if (count) - std::fill_n(_Myfirst + old_size, count, val); + std::fill_n(_Mypair._Myval2._Myfirst + old_size, count, val); } } + template pointer detach_abi(_Intty& len) YASIO__NOEXCEPT { - len = static_cast<_Intty>(this->size()); - auto ptr = _Myfirst; - _Myfirst = nullptr; - _Mysize = _Myres = 0; + auto& st = _Mypair._Myval2; + len = static_cast<_Intty>(this->size()); + auto ptr = st._Myfirst; + st._Myfirst = st._Mylast = st._Myend = nullptr; return ptr; } + pointer detach_abi() YASIO__NOEXCEPT { size_type ignored_len; return this->detach_abi(ignored_len); } + void attach_abi(pointer ptr, size_type len) { _Tidy(); - _Myfirst = ptr; - _Mysize = _Myres = len; + auto& st = _Mypair._Myval2; + st._Myfirst = ptr; + st._Mylast = ptr + len; + st._Myend = ptr + len; } + pointer release_pointer() YASIO__NOEXCEPT { return detach_abi(); } #pragma region find stubs, String operations @@ -367,41 +447,38 @@ class basic_string { my_type& replace(const size_type _Off, size_type _Nx, view_type value) { return this->replace(_Off, _Nx, value.data(), value.length()); } my_type& replace(const size_type _Off, size_type _Nx, const _Elem* const _Ptr, const size_type _Count) { // replace port from https://github.com/microsoft/stl - _YASIO_VERIFY_RANGE(_Off < _Mysize, "basic_string: out of range!"); - _Nx = (std::min)(_Nx, _Mysize - _Off); + auto& st = _Mypair._Myval2; + _TLX_VERIFY_RANGE(_Off < size(), "basic_string: out of range!"); + _Nx = (std::min)(_Nx, size() - _Off); if (_Nx == _Count) { // size doesn't change, so a single move does the trick - _Traits::move(_Myfirst + _Off, _Ptr, _Count); + _Traits::move(st._Myfirst + _Off, _Ptr, _Count); return *this; } - const size_type _Old_size = _Mysize; + const size_type _Old_size = size(); const size_type _Suffix_size = _Old_size - _Nx - _Off + 1; if (_Count < _Nx) { // suffix shifts backwards; we don't have to move anything out of the way - _Elem* const _Old_ptr = _Myfirst; + _Elem* const _Old_ptr = st._Myfirst; _Elem* const _Insert_at = _Old_ptr + _Off; _Traits::move(_Insert_at, _Ptr, _Count); _Traits::move(_Insert_at + _Count, _Insert_at + _Nx, _Suffix_size); const auto _New_size = _Old_size - (_Nx - _Count); - // _ASAN_STRING_MODIFY(*this, _Old_size, _New_size); - _Mysize = _New_size; + _Eos(_New_size); return *this; } const size_type _Growth = static_cast(_Count - _Nx); - // checking for overlapping ranges is technically UB (considering string literals), so just always reallocate - // and copy to the new buffer if constant evaluated -#if YASIO__HAS_CXX20 if (!std::is_constant_evaluated()) -#endif // _HAS_CXX20 { - if (_Growth <= _Myres - _Old_size) + const size_type _Old_capacity = capacity(); + if (_Growth <= _Old_capacity - _Old_size) { // growth fits - _Mysize = _Old_size + _Growth; - _Elem* const _Old_ptr = _Myfirst; + _Eos(_Old_size + _Growth); + _Elem* const _Old_ptr = st._Myfirst; _Elem* const _Insert_at = _Old_ptr + _Off; _Elem* const _Suffix_at = _Insert_at + _Nx; @@ -420,12 +497,7 @@ class basic_string { } _Traits::move(_Suffix_at + _Growth, _Suffix_at, _Suffix_size); - // next case must be move, in case _Ptr begins before _Insert_at and contains part of the hole; - // this case doesn't occur in insert because the new content must come from outside the removed - // content there (because in insert there is no removed content) _Traits::move(_Insert_at, _Ptr, _Ptr_shifted_after); - // the next case can be copy, because it comes from the chunk moved out of the way in the - // first move, and the hole we're filling can't alias the chunk we moved out of the way _Traits::copy(_Insert_at + _Ptr_shifted_after, _Ptr + _Growth + _Ptr_shifted_after, _Count - _Ptr_shifted_after); return *this; } @@ -439,24 +511,26 @@ class basic_string { }, _Off, _Nx, _Ptr, _Count); } + template my_type& _Reallocate_grow_by(const size_type _Size_increase, _Fty _Fn, _ArgTys... _Args) { - const size_type _Old_size = _Mysize; + const size_type _Old_size = size(); if (max_size() - _Old_size < _Size_increase) throw std::length_error("string too long"); const size_type _New_size = _Old_size + _Size_increase; - const size_type _Old_capacity = _Myres; const size_type _New_capacity = _Calculate_growth(_New_size); - pointer _New_ptr = _Alloc::reallocate(_Myfirst, _Myres, _New_capacity + 1); // throws + auto& st = _Mypair._Myval2; + auto& alloc = _Getal(); + pointer _New_ptr = alloc.reallocate(st._Myfirst, static_cast(st._Myend - st._Myfirst), _New_capacity + 1); // throws - _Mysize = _New_size; - _Myres = _New_capacity; + _Eos(_New_size); + st._Myend = _New_ptr + (_New_capacity + 1); - const pointer _Old_ptr = _Myfirst; + const pointer _Old_ptr = st._Myfirst; _Fn(_New_ptr, _Old_size, _Args...); - _Myfirst = _New_ptr; + st._Myfirst = _New_ptr; return *this; } @@ -497,63 +571,86 @@ class basic_string { private: void _Eos(size_type size) YASIO__NOEXCEPT { - _Mysize = size; - _Myfirst[_Mysize] = static_cast(0); + auto& st = _Mypair._Myval2; + st._Mylast = st._Myfirst + size; + if (st._Myfirst) + *st._Mylast = static_cast(0); + } + + // convenience: get address of current null-terminator within capacity + pointer _Mylast_ptr() YASIO__NOEXCEPT + { + auto& st = _Mypair._Myval2; + return st._Mylast; // points to null terminator slot } + template ::value, int> = 0> void _Assign_range(_Iter first, _Iter last) { + auto& st = _Mypair._Myval2; auto ifirst = std::addressof(*first); static_assert(sizeof(*ifirst) == sizeof(value_type), "basic_string: iterator type incompatible!"); - if (ifirst != _Myfirst) + if (ifirst != st._Myfirst) { - _Mysize = 0; + st._Mylast = st._Myfirst; // size = 0 if (last > first) { const auto count = static_cast(std::distance(first, last)); resize(count); - std::copy_n((iterator)ifirst, count, _Myfirst); + std::copy_n((iterator)ifirst, count, st._Myfirst); } } } + void _Assign_rv(basic_string&& rhs) { - memcpy(this, &rhs, sizeof(rhs)); - memset(&rhs, 0, sizeof(rhs)); + // move allocator and storage + std::swap(_Getal(), rhs._Getal()); + _Mypair._Myval2 = rhs._Mypair._Myval2; + rhs._Mypair._Myval2 = _Str_storage{}; } + enum class _Reallocation_policy { _At_least, _Exactly }; + template <_Reallocation_policy _Policy> void _Resize_reallocate(size_type size) { _Reallocate<_Policy>(size); _Eos(size); } + template <_Reallocation_policy _Policy> void _Reallocate(size_type size) { + auto& st = _Mypair._Myval2; + auto& alloc = _Getal(); size_type new_cap; if YASIO__CONSTEXPR (_Policy == _Reallocation_policy::_Exactly) new_cap = size + 1; else - new_cap = (std::max)(_Calculate_growth(size), size + 1); - auto _Newvec = _Alloc::reallocate(_Myfirst, _Myres, new_cap); + new_cap = (std::max)(_Calculate_growth(size), size) + 1; + + pointer _Newvec = alloc.reallocate(st._Myfirst, static_cast(st._Myend - st._Myfirst), new_cap); if (_Newvec) { - _Myfirst = _Newvec; - _Myres = new_cap; + st._Myend = _Newvec + new_cap; + const auto cur_size = size; // caller will set exact size via _Eos + st._Myfirst = _Newvec; + st._Mylast = _Newvec + cur_size; } else throw std::bad_alloc{}; } + size_type _Calculate_growth(const size_type _Newsize) const { // given _Oldcapacity and _Newsize, calculate geometric growth const size_type _Oldcapacity = capacity(); - YASIO__CONSTEXPR auto _Max = max_size(); + const size_type _Max = max_size(); if (_Oldcapacity > _Max - _Oldcapacity / 2) return _Max; // geometric growth would overflow @@ -565,20 +662,20 @@ class basic_string { return _Geometric; // geometric growth is sufficient } + void _Tidy() YASIO__NOEXCEPT { // free all storage - if (_Myfirst) + auto& st = _Mypair._Myval2; + auto& alloc = _Getal(); + if (st._Myfirst) { - _Alloc::deallocate(_Myfirst, _Myres); - _Myfirst = nullptr; - _Mysize = _Myres = 0; + alloc.deallocate(st._Myfirst, static_cast(st._Myend - st._Myfirst)); + st._Myfirst = st._Mylast = st._Myend = nullptr; } } - - pointer _Myfirst = nullptr; - size_type _Mysize = 0; - size_type _Myres = 0; }; + +// aliases using string = basic_string; #if defined(__cpp_lib_char8_t) using u8string = basic_string; @@ -586,4 +683,4 @@ using u8string = basic_string; using wstring = basic_string; using u16string = basic_string; using u32string = basic_string; -} // namespace yasio +} // namespace tlx diff --git a/3rdparty/yasio/yasio/tlx/string_view.hpp b/3rdparty/yasio/yasio/tlx/string_view.hpp new file mode 100644 index 000000000000..e40d3518ba02 --- /dev/null +++ b/3rdparty/yasio/yasio/tlx/string_view.hpp @@ -0,0 +1,240 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// A multi-platform support c++11 library with focus on asynchronous socket I/O for any +// client application. +////////////////////////////////////////////////////////////////////////////////////////// +/* +The MIT License (MIT) + +Copyright (c) 2012-2025 HALX99 +Copyright (c) 2016 Matthew Rodusek(matthew.rodusek@gmail.com) + +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. +See: https://github.com/bitwizeshift/string_view-standalone +*/ +#ifndef YASIO__STRING_VIEW_HPP +#define YASIO__STRING_VIEW_HPP +#include +#include +#include +#include +#include +#include "yasio/impl/char_traits.hpp" +#include "yasio/compiler/feature_test.hpp" + +/// wcsncasecmp workaround for android API level < 23, copy from msvc ucrt 10.0.18362.0 'wcsnicmp' +#if (defined(__ANDROID_API__) && __ANDROID_API__ < 23) || defined(__MINGW32__) +inline int wcsncasecmp(wchar_t const* const lhs, wchar_t const* const rhs, size_t const count) +{ + if (count == 0) + { + return 0; + } + + wchar_t const* lhs_ptr = reinterpret_cast(lhs); + wchar_t const* rhs_ptr = reinterpret_cast(rhs); + + int result; + int lhs_value; + int rhs_value; + size_t remaining = count; + do + { + lhs_value = ::towlower(*lhs_ptr++); + rhs_value = ::towlower(*rhs_ptr++); + result = lhs_value - rhs_value; + } while (result == 0 && lhs_value != 0 && --remaining != 0); + + return result; +} +#endif + +namespace tlx +{ +template +using decay_t = typename std::decay::type; +template +using remove_const_t = typename std::remove_const::type; +namespace char_ranges +{ // allow get char type from char*, wchar_t*, std::string, std::wstring +template +struct value_type { + using type = typename _Ty::value_type; +}; + +template +struct value_type<_Ty&> { + using type = remove_const_t<_Ty>; +}; + +template +struct value_type<_Ty*> { + using type = remove_const_t<_Ty>; +}; +} // namespace char_ranges + +// starts_with(), since C++20: +template +inline bool starts_with(std::basic_string_view<_CharT> lhs, + std::basic_string_view<_CharT> v) // (1) +{ + return lhs.size() >= v.size() && lhs.compare(0, v.size(), v) == 0; +} + +template +inline bool starts_with(_T1&& lhs, _T2&& v) // (2) +{ + using char_type = typename char_ranges::value_type>::type; + return starts_with(std::basic_string_view{lhs}, std::basic_string_view{v}); +} + +template +inline bool starts_with(std::basic_string_view<_CharT> lhs, int c) // (3) +{ + return !lhs.empty() && lhs.front() == c; +} + +template +inline bool starts_with(_Ty&& lhs, int c) // (4) +{ + using char_type = typename char_ranges::value_type>::type; + return starts_with(std::basic_string_view{lhs}, c); +} + +// ends_with(), since C++20: +template +inline bool ends_with(std::basic_string_view<_CharT> lhs, + std::basic_string_view<_CharT> v) // (1) +{ + auto offset = lhs.size() - v.size(); + return lhs.size() >= v.size() && lhs.compare(offset, v.size(), v) == 0; +} + +template +inline bool ends_with(_T1&& lhs, _T2&& v) // (2) +{ + using char_type = typename char_ranges::value_type>::type; + return ends_with(std::basic_string_view{lhs}, std::basic_string_view{v}); +} + +template +inline bool ends_with(std::basic_string_view<_CharT> lhs, int c) // (3) +{ + return !lhs.empty() && lhs.back() == c; +} + +template +inline bool ends_with(_Ty&& lhs, int c) // (4) +{ + using char_type = typename char_ranges::value_type>::type; + return ends_with(std::basic_string_view{lhs}, c); +} + +/// The case insensitive implementation of starts_with, ends_with +namespace ic +{ +template +inline bool iequals(std::basic_string_view<_CharT> lhs, std::basic_string_view<_CharT> v); +#if defined(_MSC_VER) +template <> +inline bool iequals(std::basic_string_view lhs, std::basic_string_view v) +{ + return lhs.size() == v.size() && ::_strnicmp(lhs.data(), v.data(), v.size()) == 0; +} +template <> +inline bool iequals(std::basic_string_view lhs, std::basic_string_view v) +{ + return lhs.size() == v.size() && ::_wcsnicmp(lhs.data(), v.data(), v.size()) == 0; +} +#else +template <> +inline bool iequals(std::basic_string_view lhs, std::basic_string_view v) +{ + return lhs.size() == v.size() && ::strncasecmp(lhs.data(), v.data(), v.size()) == 0; +} +template <> +inline bool iequals(std::basic_string_view lhs, std::basic_string_view v) +{ + return lhs.size() == v.size() && ::wcsncasecmp(lhs.data(), v.data(), v.size()) == 0; +} +#endif +template +inline bool iequals(_T1&& lhs, _T2&& v) +{ + using char_type = typename char_ranges::value_type>::type; + return iequals(std::basic_string_view{lhs}, std::basic_string_view{v}); +} +// starts_with(), since C++20: +template +inline bool starts_with(std::basic_string_view<_CharT> lhs, + std::basic_string_view<_CharT> v) // (1) +{ + return lhs.size() >= v.size() && iequals(lhs.substr(0, v.size()), v); +} + +template +inline bool starts_with(_T1&& lhs, _T2&& v) // (2) +{ + using char_type = typename char_ranges::value_type>::type; + return starts_with(std::basic_string_view{lhs}, std::basic_string_view{v}); +} + +template +inline bool starts_with(std::basic_string_view<_CharT> lhs, int c) // (3) +{ + return !lhs.empty() && ::tolower(lhs.front()) == ::tolower(c); +} + +template +inline bool starts_with(_Ty&& lhs, int c) // (4) +{ + using char_type = typename char_ranges::value_type>::type; + return starts_with(std::basic_string_view{lhs}, c); +} + +// ends_with(), since C++20: +template +inline bool ends_with(std::basic_string_view<_CharT> lhs, + std::basic_string_view<_CharT> v) // (1) +{ + return lhs.size() >= v.size() && iequals(lhs.substr(lhs.size() - v.size(), lhs.npos), v); +} + +template +inline bool ends_with(_T1&& lhs, _T2&& v) // (2) +{ + using char_type = typename char_ranges::value_type>::type; + return ends_with(std::basic_string_view{lhs}, std::basic_string_view{v}); +} + +template +inline bool ends_with(std::basic_string_view<_CharT> lhs, int c) // (3) +{ + return !lhs.empty() && ::tolower(lhs.back()) == ::tolower(c); +} + +template +inline bool ends_with(_Ty&& lhs, int c) // (4) +{ + using char_type = typename char_ranges::value_type>::type; + return ends_with(std::basic_string_view{lhs}, c); +} +} // namespace ic +} // namespace tlx + +#endif diff --git a/3rdparty/yasio/yasio/type_traits.hpp b/3rdparty/yasio/yasio/tlx/type_traits.hpp similarity index 99% rename from 3rdparty/yasio/yasio/type_traits.hpp rename to 3rdparty/yasio/yasio/tlx/type_traits.hpp index 8f579e95a275..6eabd241125a 100644 --- a/3rdparty/yasio/yasio/type_traits.hpp +++ b/3rdparty/yasio/yasio/tlx/type_traits.hpp @@ -32,7 +32,7 @@ SOFTWARE. #include #include "yasio/sz.hpp" -namespace yasio +namespace tlx { template struct aligned_storage_size { diff --git a/3rdparty/yasio/yasio/tlx/vector.hpp b/3rdparty/yasio/yasio/tlx/vector.hpp new file mode 100644 index 000000000000..4f5ef0df83e5 --- /dev/null +++ b/3rdparty/yasio/yasio/tlx/vector.hpp @@ -0,0 +1,1680 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// A multi-platform support c++11 library with focus on asynchronous socket I/O for any +// client application. +////////////////////////////////////////////////////////////////////////////////////////// +/* +The MIT License (MIT) + +Copyright (c) 2012-2025 HALX99 + +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. + +Version: 5.0.0 +Inspired by Microsoft STL, tailored for dedicated use cases. + +The vector aka array_buffer concepts: + a. resize(void)/extend(void) doesn't fill default constructor (uninitialized for overwrite on POD path) + b. Transparent iterator + c. Extensions APIs: + - operator+= + - extend: extend size + - resize_and_overwrite + - detach_abi: release ownership + - attach_abi: take owership +*/ +#pragma once + +#include +#include +#include +#include +#include +#include "yasio/compiler/feature_test.hpp" +#include "yasio/tlx/type_traits.hpp" +#include "yasio/tlx/memory.hpp" // for compressed_pair and ::construct_at + +namespace tlx +{ + +// Writable iterator for sequential containers +template +class sequence_const_iterator { +public: + using iterator_concept = std::contiguous_iterator_tag; + using iterator_category = std::random_access_iterator_tag; + using value_type = typename _Myvec::value_type; + using difference_type = typename _Myvec::difference_type; + using pointer = typename _Myvec::const_pointer; + using reference = const value_type&; + + using _Tptr = typename _Myvec::pointer; + + constexpr sequence_const_iterator() noexcept : _Ptr() {} + + constexpr sequence_const_iterator(_Tptr _Parg) noexcept : _Ptr(_Parg) {} + + constexpr reference operator*() const noexcept { return *_Ptr; } + + constexpr pointer operator->() const noexcept { return _Ptr; } + + constexpr sequence_const_iterator& operator++() noexcept + { + ++_Ptr; + return *this; + } + + constexpr sequence_const_iterator operator++(int) noexcept + { + sequence_const_iterator _Tmp = *this; + ++*this; + return _Tmp; + } + + constexpr sequence_const_iterator& operator--() noexcept + { + --_Ptr; + return *this; + } + + constexpr sequence_const_iterator operator--(int) noexcept + { + sequence_const_iterator _Tmp = *this; + --*this; + return _Tmp; + } + + constexpr sequence_const_iterator& operator+=(const difference_type _Off) noexcept + { + _Ptr += _Off; + return *this; + } + + constexpr sequence_const_iterator operator+(const difference_type _Off) const noexcept + { + sequence_const_iterator _Tmp = *this; + _Tmp += _Off; + return _Tmp; + } + + friend constexpr sequence_const_iterator operator+(const difference_type _Off, sequence_const_iterator _Next) noexcept + { + _Next += _Off; + return _Next; + } + + constexpr sequence_const_iterator& operator-=(const difference_type _Off) noexcept { return *this += -_Off; } + + constexpr sequence_const_iterator operator-(const difference_type _Off) const noexcept + { + sequence_const_iterator _Tmp = *this; + _Tmp -= _Off; + return _Tmp; + } + + constexpr difference_type operator-(const sequence_const_iterator& _Right) const noexcept { return static_cast(_Ptr - _Right._Ptr); } + + constexpr reference operator[](const difference_type _Off) const noexcept { return *(*this + _Off); } + + constexpr bool operator==(const sequence_const_iterator& _Right) const noexcept { return _Ptr == _Right._Ptr; } + + bool operator!=(const sequence_const_iterator& _Right) const noexcept { return !(*this == _Right); } + + bool operator<(const sequence_const_iterator& _Right) const noexcept { return _Ptr < _Right._Ptr; } + + bool operator>(const sequence_const_iterator& _Right) const noexcept { return _Right < *this; } + + bool operator<=(const sequence_const_iterator& _Right) const noexcept { return !(_Right < *this); } + + bool operator>=(const sequence_const_iterator& _Right) const noexcept { return !(*this < _Right); } + + _Tptr _Ptr; // pointer to element in vector +}; + +template +class sequence_iterator : public sequence_const_iterator<_Myvec> { +public: + using _Mybase = sequence_const_iterator<_Myvec>; + + using iterator_concept = std::contiguous_iterator_tag; + using iterator_category = std::random_access_iterator_tag; + using value_type = typename _Myvec::value_type; + using difference_type = typename _Myvec::difference_type; + using pointer = typename _Myvec::pointer; + using reference = value_type&; + + using _Mybase::_Mybase; + + constexpr reference operator*() const noexcept { return const_cast(_Mybase::operator*()); } + + constexpr pointer operator->() const noexcept { return this->_Ptr; } + + constexpr sequence_iterator& operator++() noexcept + { + _Mybase::operator++(); + return *this; + } + + constexpr sequence_iterator operator++(int) noexcept + { + sequence_iterator _Tmp = *this; + _Mybase::operator++(); + return _Tmp; + } + + constexpr sequence_iterator& operator--() noexcept + { + _Mybase::operator--(); + return *this; + } + + constexpr sequence_iterator operator--(int) noexcept + { + sequence_iterator _Tmp = *this; + _Mybase::operator--(); + return _Tmp; + } + + constexpr sequence_iterator& operator+=(const difference_type _Off) noexcept + { + _Mybase::operator+=(_Off); + return *this; + } + + constexpr sequence_iterator operator+(const difference_type _Off) const noexcept + { + sequence_iterator _Tmp = *this; + _Tmp += _Off; + return _Tmp; + } + + friend constexpr sequence_iterator operator+(const difference_type _Off, sequence_iterator _Next) noexcept + { + _Next += _Off; + return _Next; + } + + constexpr sequence_iterator& operator-=(const difference_type _Off) noexcept + { + _Mybase::operator-=(_Off); + return *this; + } + + using _Mybase::operator-; + + constexpr sequence_iterator operator-(const difference_type _Off) const noexcept + { + sequence_iterator _Tmp = *this; + _Tmp -= _Off; + return _Tmp; + } + + constexpr reference operator[](const difference_type _Off) const noexcept { return const_cast(_Mybase::operator[](_Off)); } +}; + +template +struct _Vec_iter_types { + using value_type = _Value_type; + using size_type = _Size_type; + using difference_type = _Difference_type; + using pointer = _Pointer; + using const_pointer = _Const_pointer; +}; + +template +struct _Vector_val { + using value_type = typename _Val_types::value_type; + using size_type = typename _Val_types::size_type; + using difference_type = typename _Val_types::difference_type; + using pointer = typename _Val_types::pointer; + using const_pointer = typename _Val_types::const_pointer; + using reference = value_type&; + using const_reference = const value_type&; + + constexpr _Vector_val() noexcept : _Myfirst(), _Mylast(), _Myend() {} + constexpr _Vector_val(pointer _First, pointer _Last, pointer _End) noexcept : _Myfirst(_First), _Mylast(_Last), _Myend(_End) {} + + constexpr void _Swap_val(_Vector_val& _Right) noexcept + { + std::swap(_Myfirst, _Right._Myfirst); // intentional ADL + std::swap(_Mylast, _Right._Mylast); // intentional ADL + std::swap(_Myend, _Right._Myend); // intentional ADL + } + + constexpr void _Take_contents(_Vector_val& _Right) noexcept + { + _Myfirst = _Right._Myfirst; + _Mylast = _Right._Mylast; + _Myend = _Right._Myend; + + _Right._Myfirst = nullptr; + _Right._Mylast = nullptr; + _Right._Myend = nullptr; + } + + pointer _Myfirst; + pointer _Mylast; + pointer _Myend; +}; + +template > +class vector { // varying size array of values +private: + template + friend class _Vb_val; + friend __tidy_guard; + + using _Alty = _TLX rebind_alloc_t<_Alloc, _Ty>; + using _Alty_traits = std::allocator_traits<_Alty>; + +public: + // static constexpr bool is_trivial = std::is_trivially_constructible_v<_Ty>::value || is_trivially_destructible_v<_Ty>; + + static_assert(std::is_object_v<_Ty>, "The C++ Standard forbids containers of non-object types " + "because of [container.requirements]."); + + using value_type = _Ty; + using allocator_type = _Alloc; + using pointer = typename _Alty_traits::pointer; + using const_pointer = typename _Alty_traits::const_pointer; + using reference = _Ty&; + using const_reference = const _Ty&; + using size_type = typename _Alty_traits::size_type; + using difference_type = typename _Alty_traits::difference_type; + +private: + // _Vector_val, _Simple_types<_Ty>, _Vec_iter_types<_Ty, size_type, difference_type, pointer, const_pointer>>> + using _Scary_val = _Vector_val<_Vec_iter_types<_Ty, size_type, difference_type, pointer, const_pointer>>; + + struct _Reallocation_guard { + _Alloc& _Al; + pointer _New_begin; + size_type _New_capacity; + pointer _Constructed_first; + pointer _Constructed_last; + + _Reallocation_guard& operator=(const _Reallocation_guard&) = delete; + _Reallocation_guard& operator=(_Reallocation_guard&&) = delete; + + constexpr ~_Reallocation_guard() noexcept + { + if (_New_begin != nullptr) + { + _TLX destroy_range(_Constructed_first, _Constructed_last, _Al); + _Al.deallocate(_New_begin, _New_capacity); + } + } + }; + + struct _Simple_reallocation_guard { + _Alloc& _Al; + pointer _New_begin; + size_type _New_capacity; + + _Simple_reallocation_guard& operator=(const _Simple_reallocation_guard&) = delete; + _Simple_reallocation_guard& operator=(_Simple_reallocation_guard&&) = delete; + + constexpr ~_Simple_reallocation_guard() noexcept + { + if (_New_begin != nullptr) + { + _Al.deallocate(_New_begin, _New_capacity); + } + } + }; + + struct _Vaporization_guard { // vaporize the detached piece + vector* _Target; + pointer _Vaporized_first; + pointer _Vaporized_last; + pointer _Destroyed_first; + + _Vaporization_guard& operator=(const _Vaporization_guard&) = delete; + _Vaporization_guard& operator=(_Vaporization_guard&&) = delete; + + ~_Vaporization_guard() noexcept + { + if (_Target != nullptr) + { + auto& _Al = _Target->_Getal(); + auto& _Mylast = _Target->_Mypair._Myval2._Mylast; + destroy_range(_Destroyed_first, _Mylast, _Al); + _Mylast = _Vaporized_first; + } + } + }; + +public: + using iterator = sequence_iterator<_Scary_val>; + using const_iterator = sequence_const_iterator<_Scary_val>; + + constexpr explicit vector(const _Alloc& _Al = _Alloc{}) noexcept : _Mypair(_TLX __one_then_variadic_args_t{}, _Al) {} + + constexpr explicit vector(const size_type _Count, const _Alloc& _Al = _Alloc()) : _Mypair(_TLX __one_then_variadic_args_t{}, _Al) { _Construct_n(_Count); } + + constexpr vector(const size_type _Count, const _Ty& _Val, const _Alloc& _Al = _Alloc()) : _Mypair(_TLX __one_then_variadic_args_t{}, _Al) + { + _Construct_n(_Count, _Val); + } + + template ::value, int> = 0> + constexpr vector(_Iter _First, _Iter _Last, const _Alloc& _Al = _Alloc()) : _Mypair(_TLX __one_then_variadic_args_t{}, _Al) + { + auto _UFirst = _First; + auto _ULast = _Last; + + // since we only care about pointer-like iterators, we can always compute length + const auto _Length = static_cast(_ULast - _UFirst); + const auto _Count = static_cast(_Length); + + _Construct_n(_Count, _UFirst, _ULast); + } + + constexpr vector(std::initializer_list<_Ty> _Ilist, const _Alloc& _Al = _Alloc()) : _Mypair(_TLX __one_then_variadic_args_t{}, _Al) + { + _Construct_n(static_cast(_Ilist.size()), _Ilist.begin(), _Ilist.end()); + } + + constexpr vector(const vector& _Right) : _Mypair(_TLX __one_then_variadic_args_t{}, _Alty_traits::select_on_container_copy_construction(_Right._Getal())) + { + const auto& _Right_data = _Right._Mypair._Myval2; + const auto _Count = static_cast(_Right_data._Mylast - _Right_data._Myfirst); + _Construct_n(_Count, _Right_data._Myfirst, _Right_data._Mylast); + } + + constexpr vector(const vector& _Right, const _TLX identity_t<_Alloc>& _Al) : _Mypair(_TLX __one_then_variadic_args_t{}, _Al) + { + const auto& _Right_data = _Right._Mypair._Myval2; + const auto _Count = static_cast(_Right_data._Mylast - _Right_data._Myfirst); + _Construct_n(_Count, _Right_data._Myfirst, _Right_data._Mylast); + } + + constexpr vector(vector&& _Right) noexcept + : _Mypair(_TLX __one_then_variadic_args_t{}, std::move(_Right._Getal()), std::exchange(_Right._Mypair._Myval2._Myfirst, nullptr), + std::exchange(_Right._Mypair._Myval2._Mylast, nullptr), std::exchange(_Right._Mypair._Myval2._Myend, nullptr)) + {} + + constexpr vector(vector&& _Right, + const _TLX identity_t<_Alloc>& _Al_) noexcept(std::allocator_traits<_Alloc>::is_always_equal::value && std::is_nothrow_move_constructible_v<_Ty>) + : _Mypair(_TLX __one_then_variadic_args_t{}, _Al_) + { + _Alty& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + auto& _Right_data = _Right._Mypair._Myval2; + + if constexpr (!_Alty_traits::is_always_equal::value) + { + if (_Al != _Right._Getal()) + { + const auto _Count = static_cast(_Right_data._Mylast - _Right_data._Myfirst); + if (_Count != 0) + { + _Buy_raw(_Count); + _My_data._Mylast = uninitialized_move(_Right_data._Myfirst, _Right_data._Mylast, _My_data._Myfirst, _Al); + } + return; + } + } + + _My_data._Take_contents(_Right_data); + } + + constexpr vector& operator=(vector&& _Right) noexcept + { + if (this == std::addressof(_Right)) + { + return *this; + } + + _Tidy(); + _Mypair._Myval2._Take_contents(_Right._Mypair._Myval2); + return *this; + } + + constexpr ~vector() noexcept { _Tidy(); } + +private: + template + constexpr _Ty& _Emplace_one_at_back(_Valty&&... _Val) + { + // insert by perfectly forwarding into element at end, provide strong guarantee + auto& _My_data = _Mypair._Myval2; + pointer& _Mylast = _My_data._Mylast; + + if (_Mylast != _My_data._Myend) + { + return _Emplace_back_with_unused_capacity(std::forward<_Valty>(_Val)...); + } + + return *_Emplace_reallocate(_Mylast, std::forward<_Valty>(_Val)...); + } + + template + constexpr _Ty& _Emplace_back_with_unused_capacity(Valty&&... val) + { + auto& data = _Mypair._Myval2; + pointer& last = data._Mylast; + _TLX_INTERNAL_CHECK(last != data._Myend); + + if constexpr (std::is_nothrow_constructible_v<_Ty, Valty...>) + { + tlx::construct_at(last, std::forward(val)...); + } + else + { + _Alty_traits::construct(_Getal(), std::to_address(last), std::forward(val)...); + } + + _Ty& result = *last; + ++last; + return result; + } + + template + constexpr pointer _Emplace_reallocate(const pointer _Whereptr, _Valty&&... _Val) + { + // reallocate and insert by perfectly forwarding _Val at _Whereptr + _Alty& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + + _TLX_INTERNAL_CHECK(_Mylast == _My_data._Myend); // check that we have no unused capacity + + const auto _Whereoff = static_cast(_Whereptr - _Myfirst); + const auto _Oldsize = static_cast(_Mylast - _Myfirst); + + if (_Oldsize == max_size()) + { + _Xlength(); + } + + const size_type _Newsize = _Oldsize + 1; + size_type _Newcapacity = _Calculate_growth(_Newsize); + + const pointer _Newvec = _Al.allocate(_Newcapacity); + const pointer _Constructed_last = _Newvec + _Whereoff + 1; + + _Reallocation_guard _Guard{_Al, _Newvec, _Newcapacity, _Constructed_last, _Constructed_last}; + auto& _Constructed_first = _Guard._Constructed_first; + + _Alty_traits::construct(_Al, _Newvec + _Whereoff, std::forward<_Valty>(_Val)...); + _Constructed_first = _Newvec + _Whereoff; + + if (_Whereptr == _Mylast) + { // at back, provide strong guarantee + if constexpr (std::is_nothrow_move_constructible_v<_Ty> || !std::is_copy_constructible_v<_Ty>) + { + _TLX uninitialized_move(_Myfirst, _Mylast, _Newvec, _Al); + } + else + { + _TLX uninitialized_copy(_Myfirst, _Mylast, _Newvec, _Al); + } + } + else + { // provide basic guarantee + _TLX uninitialized_move(_Myfirst, _Whereptr, _Newvec, _Al); + _Constructed_first = _Newvec; + _TLX uninitialized_move(_Whereptr, _Mylast, _Newvec + _Whereoff + 1, _Al); + } + + _Guard._New_begin = nullptr; + _Change_array(_Newvec, _Newsize, _Newcapacity); + return _Newvec + _Whereoff; + } + +public: + template + constexpr _Ty& emplace_back(_Valty&&... _Val) + { + // insert by perfectly forwarding into element at end, provide strong guarantee + return _Emplace_one_at_back(std::forward<_Valty>(_Val)...); + } + + constexpr void push_back(const _Ty& _Val) + { // insert element at end, provide strong guarantee + _Emplace_one_at_back(_Val); + } + + constexpr void push_back(_Ty&& _Val) + { + // insert by moving into element at end, provide strong guarantee + _Emplace_one_at_back(std::move(_Val)); + } + +#pragma region extension APIs + + constexpr size_type size_bytes() const { return size() * sizeof(value_type); } + + constexpr vector& operator+=(const value_type& val) + { + push_back(val); + return *this; + } + + template + constexpr vector& operator+=(const _Cont& rhs) + { + return this->extend(std::begin(rhs), std::end(rhs)); + } + + template + constexpr vector& extend(_Iter first, _Iter last) + { + insert(end(), first, last); + return *this; + } + + constexpr vector& extend(size_type count) + { + resize(size() + count); + return *this; + } + + constexpr vector& extend(size_type count, const value_type& val) + { + resize(size() + count, val); + return *this; + } + + template + void resize_and_overwrite(const size_type new_size, _Operation op) + { + _Reallocate<_Reallocation_policy::_Exactly>(new_size); + + auto& _My_data = _Mypair._Myval2; + _My_data._Mylast = _My_data._Myfirst + (std::move(op)(_My_data._Myfirst, new_size)); + } + + pointer detach_abi() noexcept + { + auto& _My_data = _Mypair._Myval2; + pointer p = _My_data._Myfirst; + _My_data._Myfirst = nullptr; + _My_data._Mylast = nullptr; + _My_data._Myend = nullptr; + return p; + } + + void attach_abi(pointer ptr, size_type len, size_type capacity = (size_type)-1) + { + auto& _My_data = _Mypair._Myval2; + _My_data._Myfirst = ptr; + _My_data._Mylast = ptr + len; + _My_data._Myend = ptr + (capacity != (size_type)-1 ? capacity : len); + } + + void shrink_to_empty() + { + clear(); + shrink_to_fit(); + } +#pragma endregion + +public: + template + constexpr iterator emplace(const_iterator _Where, _Valty&&... _Val) + { + auto _Whereptr = _Where._Ptr; + auto& _My_data = _Mypair._Myval2; + auto _Oldlast = _My_data._Mylast; + + if (_Oldlast != _My_data._Myend) + { + if (_Whereptr == _Oldlast) + { // at back, strong guarantee + _Emplace_back_with_unused_capacity(std::forward<_Valty>(_Val)...); + } + else + { + auto& _Al = _Getal(); + // construct a copy of the last element at the new end + _Alty_traits::construct(_Al, std::to_address(_Oldlast), std::move(_Oldlast[-1])); + ++_My_data._Mylast; + + // shift elements one position to the right + _TLX move_backward_unchecked(_Whereptr, _Oldlast - 1, _Oldlast); + + // construct new element at the insertion position + _Alty_traits::construct(_Al, std::to_address(_Whereptr), std::forward<_Valty>(_Val)...); + } + + return iterator(_Whereptr); + } + + // no capacity left, reallocate and emplace + return iterator(_Emplace_reallocate(_Whereptr, std::forward<_Valty>(_Val)...)); + } + + constexpr iterator insert(const_iterator _Where, const _Ty& _Val) + { // insert _Val at _Where + return emplace(_Where, _Val); + } + + constexpr iterator insert(const_iterator _Where, _Ty&& _Val) + { // insert by moving _Val at _Where + return emplace(_Where, std::move(_Val)); + } + + template + constexpr iterator insert(const_iterator _Where, const size_type _Count, const _Ty& _Val) + { + // insert _Count copies of _Val at _Where + const pointer _Whereptr = _Where._Ptr; + + auto& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + pointer& _Mylast = _My_data._Mylast; + + const pointer _Oldfirst = _My_data._Myfirst; + const pointer _Oldlast = _Mylast; + + const auto _Whereoff = static_cast(_Whereptr - _Oldfirst); + const auto _Unused_capacity = static_cast(_My_data._Myend - _Oldlast); + const bool _One_at_back = _Count == 1 && _Whereptr == _Oldlast; + + if (_Count == 0) + { // nothing to do, avoid invalidating iterators + } + else if (_Count > _Unused_capacity) + { // reallocate + const auto _Oldsize = static_cast(_Oldlast - _Oldfirst); + + if (_Count > max_size() - _Oldsize) + { + _Xlength(); + } + + const size_type _Newsize = _Oldsize + _Count; + size_type _Newcapacity = _Calculate_growth(_Newsize); + + const pointer _Newvec = _Al.allocate(_Newcapacity); + const pointer _Constructed_last = _Newvec + _Whereoff + _Count; + + _Reallocation_guard _Guard{_Al, _Newvec, _Newcapacity, _Constructed_last, _Constructed_last}; + auto& _Constructed_first = _Guard._Constructed_first; + + _TLX uninitialized_fill_n(_Newvec + _Whereoff, _Count, _Val, _Al); + _Constructed_first = _Newvec + _Whereoff; + + if (_One_at_back) + { // strong guarantee + if constexpr (std::is_nothrow_move_constructible_v<_Ty> || !std::is_copy_constructible_v<_Ty>) + { + _TLX uninitialized_move(_Oldfirst, _Oldlast, _Newvec, _Al); + } + else + { + _TLX uninitialized_copy(_Oldfirst, _Oldlast, _Newvec, _Al); + } + } + else + { // basic guarantee + _TLX uninitialized_move(_Oldfirst, _Whereptr, _Newvec, _Al); + _Constructed_first = _Newvec; + _TLX uninitialized_move(_Whereptr, _Oldlast, _Newvec + _Whereoff + _Count, _Al); + } + + _Guard._New_begin = nullptr; + _Change_array(_Newvec, _Newsize, _Newcapacity); + } + else if (_One_at_back) + { // strong guarantee + _Emplace_back_with_unused_capacity(_Val); + } + else + { // basic guarantee + const auto _Affected_elements = static_cast(_Oldlast - _Whereptr); + + if (_Count > _Affected_elements) + { // new stuff spills off end + _Mylast = _TLX uninitialized_fill_n(_Oldlast, _Count - _Affected_elements, _Val, _Al); + _Mylast = _TLX uninitialized_move(_Whereptr, _Oldlast, _Mylast, _Al); + std::fill(_Whereptr, _Oldlast, _Val); + } + else + { // new stuff can all be assigned + _Mylast = _TLX uninitialized_move(_Oldlast - _Count, _Oldlast, _Oldlast, _Al); + _TLX move_backward_unchecked(_Whereptr, _Oldlast - _Count, _Oldlast); + std::fill_n(_Whereptr, _Count, _Val); + } + } + + return iterator(_My_data._Myfirst + _Whereoff); + } + +private: + template + constexpr void _Insert_counted_range(const_iterator _Where, _Iter _First, const size_type _Count) + { + // insert counted range _First + [0, _Count) at _Where + auto _Whereptr = _Where._Ptr; + + auto& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + pointer& _Mylast = _My_data._Mylast; + + const pointer _Oldfirst = _My_data._Myfirst; + const pointer _Oldlast = _Mylast; + const auto _Unused_capacity = static_cast(_My_data._Myend - _Oldlast); + + if (_Count == 0) + { // nothing to do, avoid invalidating iterators + } + else if (_Count > _Unused_capacity) + { // reallocate + const auto _Oldsize = static_cast(_Oldlast - _Oldfirst); + + if (_Count > max_size() - _Oldsize) + { + _Xlength(); + } + + const size_type _Newsize = _Oldsize + _Count; + size_type _Newcapacity = _Calculate_growth(_Newsize); + + const pointer _Newvec = _Al.allocate(_Newcapacity); + const auto _Whereoff = static_cast(_Whereptr - _Oldfirst); + const pointer _Constructed_last = _Newvec + _Whereoff + _Count; + + _Reallocation_guard _Guard{_Al, _Newvec, _Newcapacity, _Constructed_last, _Constructed_last}; + auto& _Constructed_first = _Guard._Constructed_first; + + _TLX uninitialized_copy_n(std::move(_First), _Count, _Newvec + _Whereoff, _Al); + _Constructed_first = _Newvec + _Whereoff; + + if (_Count == 1 && _Whereptr == _Oldlast) + { // one at back, provide strong guarantee + if constexpr (std::is_nothrow_move_constructible_v<_Ty> || !std::is_copy_constructible_v<_Ty>) + { + _TLX uninitialized_move(_Oldfirst, _Oldlast, _Newvec, _Al); + } + else + { + _TLX uninitialized_copy(_Oldfirst, _Oldlast, _Newvec, _Al); + } + } + else + { // provide basic guarantee + _TLX uninitialized_move(_Oldfirst, _Whereptr, _Newvec, _Al); + _Constructed_first = _Newvec; + _TLX uninitialized_move(_Whereptr, _Oldlast, _Newvec + _Whereoff + _Count, _Al); + } + + _Guard._New_begin = nullptr; + _Change_array(_Newvec, _Newsize, _Newcapacity); + } + else + { // Attempt to provide the strong guarantee for EmplaceConstructible failure. + // If we encounter copy/move construction/assignment failure, provide the basic guarantee. + // (For one-at-back, this provides the strong guarantee.) + + const auto _Affected_elements = static_cast(_Oldlast - _Whereptr); + + if (_Count < _Affected_elements) + { // some affected elements must be assigned + _Mylast = _TLX uninitialized_move(_Oldlast - _Count, _Oldlast, _Oldlast, _Al); + _TLX move_backward_unchecked(_Whereptr, _Oldlast - _Count, _Oldlast); + _TLX destroy_range(_Whereptr, _Whereptr + _Count, _Al); + + _TLX uninitialized_copy_n(std::move(_First), _Count, _Whereptr, _Al); + // glue the broken pieces back together + + _Vaporization_guard _Guard{this, _Whereptr, _Oldlast, _Whereptr + _Count}; + _TLX uninitialized_move(_Whereptr + _Count, _Whereptr + 2 * _Count, _Whereptr, _Al); + _Guard._Target = nullptr; + + _TLX move_unchecked(_Whereptr + 2 * _Count, _Mylast, _Whereptr + _Count); + _TLX destroy_range(_Oldlast, _Mylast, _Al); + _Mylast = _Oldlast; + } + else + { // affected elements don't overlap before/after + const pointer _Relocated = _Whereptr + _Count; + _Mylast = _TLX uninitialized_move(_Whereptr, _Oldlast, _Relocated, _Al); + _TLX destroy_range(_Whereptr, _Oldlast, _Al); + + _TLX uninitialized_copy_n(std::move(_First), _Count, _Whereptr, _Al); + // glue the broken pieces back together + + _Vaporization_guard _Guard{this, _Whereptr, _Oldlast, _Relocated}; + _TLX uninitialized_move(_Relocated, _Mylast, _Whereptr, _Al); + _Guard._Target = nullptr; + + _TLX destroy_range(_Relocated, _Mylast, _Al); + _Mylast = _Oldlast; + } + } + } + +public: + template , int> = 0> + constexpr iterator insert(const_iterator _Where, _Iter _First, _Iter _Last) + { + auto _Whereptr = _Where._Ptr; + auto& _My_data = _Mypair._Myval2; + const pointer _Oldfirst = _My_data._Myfirst; + + const auto _Whereoff = static_cast(_Whereptr - _Oldfirst); + const auto _Count = static_cast(_Last - _First); + + _Insert_counted_range(_Where, _First, _Count); + + return iterator(_My_data._Myfirst + _Whereoff); + } + + constexpr iterator insert(const_iterator _Where, std::initializer_list<_Ty> _Ilist) + { + const pointer _Whereptr = _Where._Ptr; + auto& _My_data = _Mypair._Myval2; + const pointer _Oldfirst = _My_data._Myfirst; + const auto _Whereoff = static_cast(_Whereptr - _Oldfirst); + + const auto _Count = static_cast(_Ilist.size()); + _Insert_counted_range(_Where, _Ilist.begin(), _Count); + return iterator(_My_data._Myfirst + _Whereoff); + } + + constexpr void assign(const size_type _Newsize, const _Ty& _Val) + { + // assign _Newsize * _Val + auto& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + + constexpr bool _Nothrow_construct = std::is_nothrow_copy_constructible_v<_Ty>; + + const auto _Oldcapacity = static_cast(_My_data._Myend - _Myfirst); + if (_Newsize > _Oldcapacity) + { // reallocate + _Clear_and_reserve_geometric(_Newsize); + if constexpr (_Nothrow_construct) + { + _Mylast = _TLX uninitialized_fill_n(_Myfirst, _Newsize, _Val, _Al); + } + else + { + _Mylast = _TLX uninitialized_fill_n(_Myfirst, _Newsize, _Val, _Al); + } + + return; + } + + const auto _Oldsize = static_cast(_Mylast - _Myfirst); + if (_Newsize > _Oldsize) + { + std::fill(_Myfirst, _Mylast, _Val); + if constexpr (_Nothrow_construct) + { + _Mylast = _TLX uninitialized_fill_n(_Mylast, _Newsize - _Oldsize, _Val, _Al); + } + else + { + _Mylast = _TLX uninitialized_fill_n(_Mylast, _Newsize - _Oldsize, _Val, _Al); + } + } + else + { + const pointer _Newlast = _Myfirst + _Newsize; + std::fill(_Myfirst, _Newlast, _Val); + _TLX destroy_range(_Newlast, _Mylast, _Al); + _Mylast = _Newlast; + } + } + +private: + template + constexpr void _Assign_counted_range(_Iter _First, const size_type _Newsize) + { + // assign elements from counted range _First + [0, _Newsize) + auto& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + pointer& _Myend = _My_data._Myend; + + constexpr bool _Nothrow_construct = std::is_nothrow_constructible_v<_Ty, iter_ref_t<_Iter>>; + + const auto _Oldcapacity = static_cast(_Myend - _Myfirst); + if (_Newsize > _Oldcapacity) + { + _Clear_and_reserve_geometric(_Newsize); + if constexpr (_Nothrow_construct) + { + _Mylast = _TLX uninitialized_copy_n(std::move(_First), _Newsize, _Myfirst, _Al); + } + else + { + _Mylast = _TLX uninitialized_copy_n(std::move(_First), _Newsize, _Myfirst, _Al); + } + return; + } + + const auto _Oldsize = static_cast(_Mylast - _Myfirst); + if (_Newsize > _Oldsize) + { + bool _Copied = false; + if constexpr (_TLX bitcopy_assignable_v<_Iter, pointer>) + { + if (!std::is_constant_evaluated()) + { + copy_memmove_n(_First, static_cast(_Oldsize), _Myfirst); + _First += _Oldsize; + _Copied = true; + } + } + + if (!_Copied) + { + for (auto _Mid = _Myfirst; _Mid != _Mylast; ++_Mid, (void)++_First) + { + *_Mid = *_First; + } + } + + if constexpr (_Nothrow_construct) + { + _Mylast = _TLX uninitialized_copy_n(std::move(_First), _Newsize - _Oldsize, _Mylast, _Al); + } + else + { + _Mylast = _TLX uninitialized_copy_n(std::move(_First), _Newsize - _Oldsize, _Mylast, _Al); + } + } + else + { + const pointer _Newlast = _Myfirst + _Newsize; + _TLX copy_n_unchecked4(std::move(_First), _Newsize, _Myfirst); + _TLX destroy_range(_Newlast, _Mylast, _Al); + _Mylast = _Newlast; + } + } + +public: + template , int> = 0> + constexpr void assign(_Iter _First, _Iter _Last) + { + const auto _Length = static_cast(_Last - _First); // pointer difference + const auto _Count = static_cast(_Length); + + _Assign_counted_range(_First, _Count); + } + + constexpr void assign(const std::initializer_list<_Ty> _Ilist) + { + const auto _Count = static_cast(_Ilist.size()); + _Assign_counted_range(_Ilist.begin(), _Count); + } + + constexpr vector& operator=(const vector& _Right) + { + if (this == std::addressof(_Right)) + { + return *this; // self-assignment, nothing to do + } + + _Tidy(); // clear current contents + + auto& _Right_data = _Right._Mypair._Myval2; + const size_type _Count = static_cast(_Right_data._Mylast - _Right_data._Myfirst); + + _Assign_counted_range(_Right_data._Myfirst, _Count); // copy elements from _Right + + return *this; + } + + constexpr vector& operator=(std::initializer_list<_Ty> _Ilist) + { + const auto _Count = static_cast(_Ilist.size()); + _Assign_counted_range(_Ilist.begin(), _Count); + return *this; + } + +private: + template + constexpr void _Resize_reallocate(const size_type _Newsize, const _Ty2& _Val) + { + if (_Newsize > max_size()) + { + _Xlength(); + } + + auto& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + + const auto _Oldsize = static_cast(_Mylast - _Myfirst); + size_type _Newcapacity = _Calculate_growth(_Newsize); + + const pointer _Newvec = _Al.allocate(_Newcapacity); + const pointer _Appended_first = _Newvec + _Oldsize; + + _Reallocation_guard _Guard{_Al, _Newvec, _Newcapacity, _Appended_first, _Appended_first}; + auto& _Appended_last = _Guard._Constructed_last; + + if constexpr (std::is_same_v<_Ty2, _Ty>) + { + _Appended_last = _TLX uninitialized_fill_n(_Appended_first, _Newsize - _Oldsize, _Val, _Al); + } + else + { + _Appended_last = _TLX uninitialized_value_construct_n(_Appended_first, _Newsize - _Oldsize, _Al); + } + + if constexpr (std::is_nothrow_move_constructible_v<_Ty> || !std::is_copy_constructible_v<_Ty>) + { + _TLX uninitialized_move(_Myfirst, _Mylast, _Newvec, _Al); + } + else + { + _TLX uninitialized_copy(_Myfirst, _Mylast, _Newvec, _Al); + } + + _Guard._New_begin = nullptr; + _Change_array(_Newvec, _Newsize, _Newcapacity); + } + + template + constexpr void _Resize(const size_type _Newsize, const _Ty2& _Val) + { + // trim or append elements, provide strong guarantee + auto& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + const auto _Oldsize = static_cast(_Mylast - _Myfirst); + if (_Newsize < _Oldsize) + { // trim + const pointer _Newlast = _Myfirst + _Newsize; + destroy_range(_Newlast, _Mylast, _Al); + _Mylast = _Newlast; + return; + } + + if (_Newsize > _Oldsize) + { // append + const auto _Oldcapacity = static_cast(_My_data._Myend - _Myfirst); + if (_Newsize > _Oldcapacity) + { // reallocate + _Resize_reallocate(_Newsize, _Val); + return; + } + + const pointer _Oldlast = _Mylast; + if constexpr (std::is_same_v<_Ty2, _Ty>) + { + _Mylast = _TLX uninitialized_fill_n(_Oldlast, _Newsize - _Oldsize, _Val, _Al); + } + else + { + _Mylast = _TLX uninitialized_value_construct_n(_Oldlast, _Newsize - _Oldsize, _Al); + } + } + + // if _Newsize == _Oldsize, do nothing; avoid invalidating iterators + } + +public: + constexpr void resize(const size_type _Newsize) + { + // trim or append value-initialized elements, provide strong guarantee + _Resize(_Newsize, __value_init_tag{}); + } + + constexpr void resize(const size_type _Newsize, const _Ty& _Val) + { + // trim or append copies of _Val, provide strong guarantee + _Resize(_Newsize, _Val); + } + +private: + enum class _Reallocation_policy + { + _At_least, + _Exactly + }; + + template <_Reallocation_policy _Policy> + constexpr void _Reallocate(const size_type& _Newcapacity) + { + // set capacity to _Newcapacity (without geometric growth), provide strong guarantee + auto& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + + const auto _Size = static_cast(_Mylast - _Myfirst); + + pointer _Newvec; + if constexpr (_Policy == _Reallocation_policy::_At_least) + { + _Newvec = _Al.allocate(_Newcapacity); + } + else + { + _Newvec = _Al.allocate(_Newcapacity); + } + + _Simple_reallocation_guard _Guard{_Al, _Newvec, _Newcapacity}; + + if constexpr (std::is_nothrow_move_constructible_v<_Ty> || !std::is_copy_constructible_v<_Ty>) + { + uninitialized_move(_Myfirst, _Mylast, _Newvec, _Al); + } + else + { + uninitialized_copy(_Myfirst, _Mylast, _Newvec, _Al); + } + + _Guard._New_begin = nullptr; + _Change_array(_Newvec, _Size, _Newcapacity); + } + + constexpr void _Clear_and_reserve_geometric(const size_type _Newsize) + { + auto& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + pointer& _Myend = _My_data._Myend; + + if (_Newsize > max_size()) + { + _Xlength(); + } + + const size_type _Newcapacity = _Calculate_growth(_Newsize); + + if (_Myfirst) + { // destroy and deallocate old array + _TLX destroy_range(_Myfirst, _Mylast, _Al); + _Al.deallocate(_Myfirst, static_cast(_Myend - _Myfirst)); + + _Myfirst = nullptr; + _Mylast = nullptr; + _Myend = nullptr; + } + + _Buy_raw(_Newcapacity); + } + +public: + constexpr void reserve(size_type _Newcapacity) + { + // increase capacity to _Newcapacity (without geometric growth), provide strong guarantee + if (_Newcapacity > capacity()) + { // something to do (reserve() never shrinks) + if (_Newcapacity > max_size()) + { + _Xlength(); + } + + _Reallocate<_Reallocation_policy::_At_least>(_Newcapacity); + } + } + + constexpr void shrink_to_fit() + { // reduce capacity to size, provide strong guarantee + auto& _My_data = _Mypair._Myval2; + const pointer _Oldlast = _My_data._Mylast; + if (_Oldlast != _My_data._Myend) + { // something to do + const pointer _Oldfirst = _My_data._Myfirst; + if (_Oldfirst == _Oldlast) + { + _Tidy(); + } + else + { + size_type _Newcapacity = static_cast(_Oldlast - _Oldfirst); + _Reallocate<_Reallocation_policy::_Exactly>(_Newcapacity); + } + } + } + + constexpr void pop_back() noexcept /* strengthened */ + { + auto& _My_data = _Mypair._Myval2; + pointer& _Mylast = _My_data._Mylast; + + _Alty_traits::destroy(_Getal(), std::to_address(_Mylast - 1)); + --_Mylast; + } + + constexpr iterator erase(const_iterator _Where) noexcept /* strengthened */ + { + auto _Whereptr = _Where._Ptr; + auto& _My_data = _Mypair._Myval2; + pointer& _Mylast = _My_data._Mylast; + + move_unchecked(_Whereptr + 1, _Mylast, _Whereptr); + _Alty_traits::destroy(_Getal(), std::to_address(_Mylast - 1)); + --_Mylast; + return iterator(_Whereptr); + } + + constexpr iterator erase(const_iterator _First, const_iterator _Last) noexcept /* strengthened */ + { + auto _Firstptr = _First._Ptr; + auto _Lastptr = _Last._Ptr; + auto& _My_data = _Mypair._Myval2; + pointer& _Mylast = _My_data._Mylast; + + if (_Firstptr != _Lastptr) + { // something to do, invalidate iterators + const pointer _Newlast = move_unchecked(_Lastptr, _Mylast, _Firstptr); + destroy_range(_Newlast, _Mylast, _Getal()); + _Mylast = _Newlast; + } + + return iterator(_Firstptr); + } + + constexpr void clear() noexcept + { // erase all + auto& _My_data = _Mypair._Myval2; + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + + if (_Myfirst == _Mylast) + { // already empty, nothing to do + // This is an optimization for debug mode: we can avoid taking the debug lock to invalidate iterators. + // Note that when clearing an empty vector, this will preserve past-the-end iterators, which is allowed by + // N4950 [sequence.reqmts]/54 "a.clear() [...] may invalidate the past-the-end iterator". + return; + } + + destroy_range(_Myfirst, _Mylast, _Getal()); + _Mylast = _Myfirst; + } + + constexpr void swap(vector& _Right) noexcept /* strengthened */ + { + if (this != std::addressof(_Right)) + { + std::swap(_Getal(), _Right._Getal()); + _Mypair._Myval2._Swap_val(_Right._Mypair._Myval2); + } + } + + constexpr _Ty* data() noexcept { return _Mypair._Myval2._Myfirst; } + + constexpr const _Ty* data() const noexcept { return _Mypair._Myval2._Myfirst; } + + constexpr iterator begin() noexcept + { + auto& _My_data = _Mypair._Myval2; + return iterator(_My_data._Myfirst); + } + + constexpr const_iterator begin() const noexcept + { + auto& _My_data = _Mypair._Myval2; + return const_iterator(_My_data._Myfirst); + } + + constexpr iterator end() noexcept + { + auto& _My_data = _Mypair._Myval2; + return iterator(_My_data._Mylast); + } + + constexpr const_iterator end() const noexcept + { + auto& _My_data = _Mypair._Myval2; + return const_iterator(_My_data._Mylast); + } + + constexpr const_iterator cbegin() const noexcept { return begin(); } + + constexpr const_iterator cend() const noexcept { return end(); } + + constexpr bool empty() const noexcept + { + auto& _My_data = _Mypair._Myval2; + return _My_data._Myfirst == _My_data._Mylast; + } + + constexpr size_type size() const noexcept + { + auto& _My_data = _Mypair._Myval2; + return static_cast(_My_data._Mylast - _My_data._Myfirst); + } + + constexpr size_type max_size() const noexcept + { + return (std::min)(static_cast((std::numeric_limits::max)()), _Alty_traits::max_size(_Getal())); + } + + constexpr size_type capacity() const noexcept + { + auto& _My_data = _Mypair._Myval2; + return static_cast(_My_data._Myend - _My_data._Myfirst); + } + + constexpr _Ty& operator[](const size_type _Pos) noexcept /* strengthened */ + { + auto& _My_data = _Mypair._Myval2; + return _My_data._Myfirst[_Pos]; + } + + constexpr const _Ty& operator[](const size_type _Pos) const noexcept /* strengthened */ + { + auto& _My_data = _Mypair._Myval2; + return _My_data._Myfirst[_Pos]; + } + + constexpr _Ty& at(const size_type _Pos) + { + auto& _My_data = _Mypair._Myval2; + if (static_cast(_My_data._Mylast - _My_data._Myfirst) <= _Pos) + { + _Xrange(); + } + + return _My_data._Myfirst[_Pos]; + } + + constexpr const _Ty& at(const size_type _Pos) const + { + auto& _My_data = _Mypair._Myval2; + if (static_cast(_My_data._Mylast - _My_data._Myfirst) <= _Pos) + { + _Xrange(); + } + + return _My_data._Myfirst[_Pos]; + } + + constexpr _Ty& front() noexcept /* strengthened */ + { + auto& _My_data = _Mypair._Myval2; + return *_My_data._Myfirst; + } + + constexpr const _Ty& front() const noexcept /* strengthened */ + { + auto& _My_data = _Mypair._Myval2; + return *_My_data._Myfirst; + } + + constexpr _Ty& back() noexcept /* strengthened */ + { + auto& _My_data = _Mypair._Myval2; + return _My_data._Mylast[-1]; + } + + constexpr const _Ty& back() const noexcept /* strengthened */ + { + auto& _My_data = _Mypair._Myval2; + return _My_data._Mylast[-1]; + } + + constexpr allocator_type get_allocator() const noexcept { return static_cast(_Getal()); } + +private: + constexpr size_type _Calculate_growth(const size_type _Newsize) const + { + // given _Oldcapacity and _Newsize, calculate geometric growth + const size_type _Oldcapacity = capacity(); + const auto _Max = max_size(); + + if (_Oldcapacity > _Max - _Oldcapacity / 2) + { + return _Max; // geometric growth would overflow + } + + const size_type _Geometric = _Oldcapacity + _Oldcapacity / 2; + + if (_Geometric < _Newsize) + { + return _Newsize; // geometric growth would be insufficient + } + + return _Geometric; // geometric growth is sufficient + } + + constexpr void _Buy_raw(size_type _Newcapacity) + { + // allocate array with _Newcapacity elements + auto& _My_data = _Mypair._Myval2; + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + pointer& _Myend = _My_data._Myend; + + _TLX_INTERNAL_CHECK(!_Myfirst && !_Mylast && !_Myend); // check that *this is tidy + _TLX_INTERNAL_CHECK(0 < _Newcapacity && _Newcapacity <= max_size()); + + const pointer _Newvec = _Getal().allocate(_Newcapacity); + _Myfirst = _Newvec; + _Mylast = _Newvec; + _Myend = _Newvec + _Newcapacity; + } + + constexpr void _Buy_nonzero(const size_type _Newcapacity) + { + // allocate array with _Newcapacity elements +#ifdef _ENABLE_TLX_INTERNAL_CHECK + auto& _My_data = _Mypair._Myval2; + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + pointer& _Myend = _My_data._Myend; + _TLX_INTERNAL_CHECK(!_Myfirst && !_Mylast && !_Myend); // check that *this is tidy + _TLX_INTERNAL_CHECK(0 < _Newcapacity); +#endif // _ENABLE_TLX_INTERNAL_CHECK + + if (_Newcapacity > max_size()) + { + _Xlength(); + } + + _Buy_raw(_Newcapacity); + } + + constexpr void _Change_array(const pointer _Newvec, const size_type _Newsize, const size_type _Newcapacity) noexcept + { + // orphan all iterators, discard old array, acquire new array + auto& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + pointer& _Myend = _My_data._Myend; + + if (_Myfirst) + { // destroy and deallocate old array + _TLX destroy_range(_Myfirst, _Mylast, _Al); + _Al.deallocate(_Myfirst, static_cast(_Myend - _Myfirst)); + } + + _Myfirst = _Newvec; + _Mylast = _Newvec + _Newsize; + _Myend = _Newvec + _Newcapacity; + } + + constexpr void _Tidy() noexcept + { // free all storage + auto& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + pointer& _Myend = _My_data._Myend; + + if (_Myfirst) + { // destroy and deallocate old array + _TLX destroy_range(_Myfirst, _Mylast, _Al); + _Al.deallocate(_Myfirst, static_cast(_Myend - _Myfirst)); + + _Myfirst = nullptr; + _Mylast = nullptr; + _Myend = nullptr; + } + } + + template + constexpr void _Construct_n(const size_type _Count, _Valty&&... _Val) + { + // Dispatch between the three sized constructions: + // 1-arg -> value-construction, e.g. vector(5) + // 2-arg -> fill, e.g. vector(5, "meow") + // 3-arg -> sized range construction, e.g. vector{"Hello", "Fluffy", "World"} + + auto& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + + if (_Count != 0) + { + _Buy_nonzero(_Count); + + if constexpr (sizeof...(_Val) == 0) + { + // value-construction + _My_data._Mylast = uninitialized_value_construct_n(_My_data._Myfirst, _Count, _Al); + } + else if constexpr (sizeof...(_Val) == 1) + { + // fill construction + _My_data._Mylast = uninitialized_fill_n(_My_data._Myfirst, _Count, _Val..., _Al); + } + else if constexpr (sizeof...(_Val) == 2) + { + // range construction + _My_data._Mylast = uninitialized_copy(std::forward<_Valty>(_Val)..., _My_data._Myfirst, _Al); + } + else + { + // unsupported overload + } + } + } + + constexpr void _Move_assign_unequal_alloc(vector& _Right) + { + auto& _Al = _Getal(); + auto& _My_data = _Mypair._Myval2; + auto& _Right_data = _Right._Mypair._Myval2; + + const pointer _First = _Right_data._Myfirst; + const pointer _Last = _Right_data._Mylast; + const auto _Newsize = static_cast(_Last - _First); + + pointer& _Myfirst = _My_data._Myfirst; + pointer& _Mylast = _My_data._Mylast; + + constexpr bool _Nothrow_construct = std::is_nothrow_move_constructible_v<_Ty>; + + const auto _Oldcapacity = static_cast(_My_data._Myend - _Myfirst); + if (_Newsize > _Oldcapacity) + { + _Clear_and_reserve_geometric(_Newsize); + if constexpr (_Nothrow_construct) + { + _Mylast = uninitialized_move(_First, _Last, _Myfirst, _Al); + } + else + { + _Mylast = uninitialized_move(_First, _Last, _Myfirst, _Al); + } + + return; + } + + const auto _Oldsize = static_cast(_Mylast - _Myfirst); + if (_Newsize > _Oldsize) + { + const pointer _Mid = _First + _Oldsize; + move_unchecked(_First, _Mid, _Myfirst); + + if constexpr (_Nothrow_construct) + { + _Mylast = uninitialized_move(_Mid, _Last, _Mylast, _Al); + } + else + { + _Mylast = uninitialized_move(_Mid, _Last, _Mylast, _Al); + } + } + else + { + const pointer _Newlast = _Myfirst + _Newsize; + move_unchecked(_First, _Last, _Myfirst); + _Mylast = _Newlast; + } + } + + static void _Xlength() { _TLX __xlength_error("vector too long"); } + + static void _Xrange() { _TLX __xout_of_range("invalid vector subscript"); } + + constexpr _Alty& _Getal() noexcept { return _Mypair._Get_first(); } + + constexpr const _Alty& _Getal() const noexcept { return _Mypair._Get_first(); } + + __compressed_pair<_Alty, _Scary_val> _Mypair; +}; + +#pragma region c++20 like std::erase +template +void erase(vector<_Ty, _Alloc>& cont, const _Ty& val) +{ + cont.erase(std::remove(cont.begin(), cont.end(), val), cont.end()); +} +template +void erase_if(vector<_Ty, _Alloc>& cont, _Pr pred) +{ + cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); +} +#pragma endregion + +#pragma region ordered insert, for flat container emulating +template +inline typename _Cont::iterator ordered_insert(_Cont& vec, typename _Cont::value_type const& val) +{ + return vec.insert(std::upper_bound(vec.begin(), vec.end(), val), val); +} + +template +inline typename _Cont::iterator ordered_insert(_Cont& vec, typename _Cont::value_type const& val, _Pred pred) +{ + return vec.insert(std::upper_bound(vec.begin(), vec.end(), val, pred), val); +} +#pragma endregion + +} // namespace tlx + +namespace std +{ +template +struct pointer_traits<_TLX sequence_const_iterator<_Myvec>> { + using pointer = _TLX sequence_const_iterator<_Myvec>; + using element_type = const pointer::value_type; + using difference_type = pointer::difference_type; + + static constexpr element_type* to_address(const pointer _Iter) noexcept { return std::to_address(_Iter._Ptr); } +}; +template +struct pointer_traits<_TLX sequence_iterator<_Myvec>> { + using pointer = _TLX sequence_iterator<_Myvec>; + using element_type = pointer::value_type; + using difference_type = pointer::difference_type; + + static constexpr element_type* to_address(const pointer _Iter) noexcept { return std::to_address(_Iter._Ptr); } +}; +} // namespace std diff --git a/3rdparty/yasio/yasio/wtimer_hres.hpp b/3rdparty/yasio/yasio/wtimer_hres.hpp index 0b10a1a7b176..8f44141956b8 100644 --- a/3rdparty/yasio/yasio/wtimer_hres.hpp +++ b/3rdparty/yasio/yasio/wtimer_hres.hpp @@ -29,7 +29,6 @@ SOFTWARE. #ifdef _WIN32 # include "yasio/config.hpp" -# include "yasio/utils.hpp" # if defined(YASIO__USE_TIMEAPI) # include @@ -56,7 +55,7 @@ struct wtimer_hres { TIMECAPS tc; if (TIMERR_NOERROR == timeGetDevCaps(&tc, sizeof(TIMECAPS))) { - timer_res_ = yasio::clamp(static_cast(timer_res / _1ms_den), tc.wPeriodMin, tc.wPeriodMax); + timer_res_ = std::clamp(static_cast(timer_res / _1ms_den), tc.wPeriodMin, tc.wPeriodMax); timeBeginPeriod(timer_res_); } # else diff --git a/3rdparty/yasio/yasio/xxsocket.cpp b/3rdparty/yasio/yasio/xxsocket.cpp index 1fc1043c969e..209c4f4d88c7 100644 --- a/3rdparty/yasio/yasio/xxsocket.cpp +++ b/3rdparty/yasio/yasio/xxsocket.cpp @@ -36,7 +36,7 @@ SOFTWARE. # include "yasio/xxsocket.hpp" #endif -#include "yasio/utils.hpp" +#include "yasio/tlx/chrono.hpp" #if !defined(_WIN32) # include "yasio/impl/ifaddrs.hpp" @@ -718,9 +718,9 @@ int xxsocket::send_n(socket_native_type s, const void* buf, int len, std::chrono if (n == -1 && xxsocket::not_send_error(error)) { // Wait upto for the blocking to subside. - auto start = yasio::highp_clock(); + auto start = tlx::highp_clock(); int const rtn = handle_write_ready(s, wtimeout); - wtimeout -= std::chrono::microseconds(yasio::highp_clock() - start); + wtimeout -= std::chrono::microseconds(tlx::highp_clock() - start); // Did select() succeed? if (rtn != -1 && wtimeout.count() > 0) @@ -768,9 +768,9 @@ int xxsocket::recv_n(socket_native_type s, void* buf, int len, std::chrono::micr if (n == -1 && xxsocket::not_recv_error(error)) { // Wait upto for the blocking to subside. - auto start = yasio::highp_clock(); + auto start = tlx::highp_clock(); int const rtn = handle_read_ready(s, wtimeout); - wtimeout -= std::chrono::microseconds(yasio::highp_clock() - start); + wtimeout -= std::chrono::microseconds(tlx::highp_clock() - start); // Did select() succeed? if (rtn != -1 && wtimeout.count() > 0) @@ -834,9 +834,9 @@ int xxsocket::select(socket_native_type s, fd_set* readfds, fd_set* writefds, fd timeval waitd_tv = {static_cast(wtimeout.count() / std::micro::den), static_cast(wtimeout.count() % std::micro::den)}; - long long start = highp_clock(); + long long start = tlx::highp_clock(); n = ::select(static_cast(s + 1), readfds, writefds, exceptfds, &waitd_tv); - wtimeout -= std::chrono::microseconds(highp_clock() - start); + wtimeout -= std::chrono::microseconds(tlx::highp_clock() - start); if (n < 0 && xxsocket::get_last_errno() == EINTR) { @@ -944,7 +944,7 @@ unsigned int xxsocket::tcp_rtt() const { return xxsocket::tcp_rtt(this->fd); } unsigned int xxsocket::tcp_rtt(socket_native_type s) { #if defined(_WIN32) -# if defined(NTDDI_WIN10_RS2) && NTDDI_VERSION >= NTDDI_WIN10_RS2 +# if YASIO__OS_NT10_RS2 TCP_INFO_v0 info; DWORD tcpi_ver = 0, bytes_transferred = 0; int status = WSAIoctl(s, SIO_TCP_INFO, @@ -1035,6 +1035,21 @@ const char* xxsocket::strerror_r(int error, char* buf, size_t buflen) return buf; } +void xxsocket::update_connect_context(socket_native_type s, std::error_code& ec) +{ +#if defined(_WIN32) + if (!ec) + { + // Need to set the SO_UPDATE_CONNECT_CONTEXT option so that getsockname + // and getpeername will work on the connected socket. + // socket_ops::state_type state = 0; + const int so_update_connect_context = 0x7010; + if (xxsocket::set_optval(s, SOL_SOCKET, so_update_connect_context, nullptr, 0) < 0) + ec = std::error_code(::WSAGetLastError(), std::system_category()); + } +#endif +} + const char* xxsocket::gai_strerror(int error) { #if defined(_WIN32) diff --git a/3rdparty/yasio/yasio/xxsocket.hpp b/3rdparty/yasio/yasio/xxsocket.hpp index b81ad5c0ce87..f44051d9cadb 100644 --- a/3rdparty/yasio/yasio/xxsocket.hpp +++ b/3rdparty/yasio/yasio/xxsocket.hpp @@ -40,7 +40,7 @@ SOFTWARE. #include #include "yasio/impl/socket.hpp" #include "yasio/logging.hpp" -#include "yasio/string_view.hpp" +#include "yasio/tlx/string_view.hpp" namespace yasio { @@ -1066,6 +1066,8 @@ class YASIO_API xxsocket { YASIO__DECL static const char* strerror_r(int error, char* buf, size_t buflen); YASIO__DECL static const char* gai_strerror(int error); + YASIO__DECL static void update_connect_context(socket_native_type s, std::error_code& ec); + /// /// Resolve both ipv4 and ipv6 address as-is /// @@ -1174,7 +1176,7 @@ template <> struct hash { std::size_t operator()(const yasio::ip::endpoint& ep) const YASIO__NOEXCEPT { - return std::hash()(cxx17::string_view{reinterpret_cast(&ep), static_cast(ep.len())}); + return std::hash()(std::string_view{reinterpret_cast(&ep), static_cast(ep.len())}); } }; } // namespace std diff --git a/3rdparty/yasio/yasio/yasio.natvis b/3rdparty/yasio/yasio/yasio.natvis index e49aba7ddefc..ff12db8a306a 100644 --- a/3rdparty/yasio/yasio/yasio.natvis +++ b/3rdparty/yasio/yasio/yasio.natvis @@ -1,82 +1,82 @@ - - - {{ size={_Mysize} capacity={_Myres} }} + + + {{ size={_Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst} capacity={_Mypair._Myval2._Myend - _Mypair._Myval2._Myfirst} }} - _Mysize - _Myres + _Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst + _Mypair._Myval2._Myend - _Mypair._Myval2._Myfirst - _Mysize - _Myfirst + _Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst + _Mypair._Myval2._Myfirst - - {{ size={_Mysize} {_Myfirst,[_Mysize]s8} }} + + {{ size={_Mysize} {_Mypair._Myval2._Myfirst,[_Mysize]s8} }} - _Mysize - _Myres + _Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst + _Mypair._Myval2._Myend - _Mypair._Myval2._Myfirst - _Mysize - _Myfirst + _Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst + _Mypair._Myval2._Myfirst - - - {_Myfirst,s8} - {&_Myfirst,s8} - _Myfirst,s8 - &_Myfirst,s8 + + + {_Mypair._Myval2._Myfirst,s8} + {&_Mypair._Myval2._Myfirst,s8} + _Mypair._Myval2._Myfirst,s8 + &_Mypair._Myval2._Myfirst,s8 - _Mysize - _Myres - - _Mysize - _Myfirst + _Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst + _Mypair._Myval2._Myend - _Mypair._Myval2._Myfirst + + _Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst + _Mypair._Myval2._Myfirst - - _Mysize - &_Myfirst + + _Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst + &_Mypair._Myval2._Myfirst - - - - {_Myfirst,su} - {&_Myfirst,su} - _Myfirst,su - &_Myfirst,su + + + + {_Mypair._Myval2._Myfirst,su} + {&_Mypair._Myval2._Myfirst,su} + _Mypair._Myval2._Myfirst,su + &_Mypair._Myval2._Myfirst,su - _Mysize - _Myres - - _Mysize - _Myfirst + _Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst + _Mypair._Myval2._Myend - _Mypair._Myval2._Myfirst + + _Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst + _Mypair._Myval2._Myfirst - - _Mysize - &_Myfirst + + _Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst + &_Mypair._Myval2._Myfirst - - {_Myfirst,s32} - {&_Myfirst,s32} - _Myfirst,s32 - &_Myfirst,s32 + + {_Mypair._Myval2._Myfirst,s32} + {&_Mypair._Myval2._Myfirst,s32} + _Mypair._Myval2._Myfirst,s32 + &_Mypair._Myval2._Myfirst,s32 - _Mysize - _Myres - - _Mysize - _Myfirst + _Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst + _Mypair._Myval2._Myend - _Mypair._Myval2._Myfirst + + _Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst + _Mypair._Myval2._Myfirst - - _Mysize - &_Myfirst + + _Mypair._Myval2._Mylast - _Mypair._Myval2._Myfirst + &_Mypair._Myval2._Myfirst diff --git a/axmol/2d/ActionCoroutine.h b/axmol/2d/ActionCoroutine.h index 6956b2718401..ac172f080136 100644 --- a/axmol/2d/ActionCoroutine.h +++ b/axmol/2d/ActionCoroutine.h @@ -33,22 +33,22 @@ THE SOFTWARE. #if __has_include() # include -namespace axstd +namespace tlx { using suspend_always = std::suspend_always; template using coroutine_handle = std::coroutine_handle<_Ty>; -} // namespace axstd +} // namespace tlx #elif __has_include() // fallback to experimental, currently only for android, in the future may don't required, // for example: we upgrade ndk in the future releases of axmol # include -namespace axstd +namespace tlx { using suspend_always = std::experimental::suspend_always; template using coroutine_handle = std::experimental::coroutine_handle<_Ty>; -} // namespace axstd +} // namespace tlx #else # error This compiler missing c++20 coroutine #endif @@ -66,7 +66,7 @@ class AX_DLL Coroutine public: class promise_type; - using handle = axstd::coroutine_handle; + using handle = tlx::coroutine_handle; class promise_type { public: @@ -74,18 +74,18 @@ class AX_DLL Coroutine Action* currentAction() const noexcept { return _currentAction; } - auto final_suspend() const noexcept { return axstd::suspend_always{}; } + auto final_suspend() const noexcept { return tlx::suspend_always{}; } auto get_return_object() noexcept { return Coroutine(handle::from_promise(*this)); } - auto initial_suspend() const noexcept { return axstd::suspend_always{}; } + auto initial_suspend() const noexcept { return tlx::suspend_always{}; } auto yield_value(Action* action) { AX_SAFE_RELEASE(_currentAction); _currentAction = action; AX_SAFE_RETAIN(_currentAction); - return axstd::suspend_always{}; + return tlx::suspend_always{}; } void return_void() {} diff --git a/axmol/2d/AutoPolygon.cpp b/axmol/2d/AutoPolygon.cpp index 6db35c336a7e..2ea34720c5d5 100644 --- a/axmol/2d/AutoPolygon.cpp +++ b/axmol/2d/AutoPolygon.cpp @@ -30,7 +30,7 @@ THE SOFTWARE. #include "axmol/2d/AutoPolygon.h" #include "poly2tri/poly2tri.h" #include "axmol/base/Director.h" -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" #include "axmol/renderer/TextureCache.h" #include "clipper2/clipper.h" #include @@ -608,8 +608,8 @@ TrianglesCommand::Triangles AutoPolygon::triangulate(const std::vector& po cdt.Triangulate(); std::vector tris = cdt.GetTriangles(); - axstd::pod_vector indices(tris.size() * 3); - axstd::pod_vector verts; + tlx::pod_vector indices(tris.size() * 3); + tlx::pod_vector verts; verts.reserve(indices.size() / 2); // we won't know the size of verts until we process all of the triangles! unsigned short idx = 0; @@ -649,7 +649,7 @@ TrianglesCommand::Triangles AutoPolygon::triangulate(const std::vector& po // Triangles should really use std::vector and not arrays for verts and indices. // Then the above memcpy would not be necessary - TrianglesCommand::Triangles triangles = {verts.release_pointer(), indices.release_pointer(), (unsigned int)vdx, + TrianglesCommand::Triangles triangles = {verts.detach_abi(), indices.detach_abi(), (unsigned int)vdx, (unsigned int)idx}; return triangles; } diff --git a/axmol/2d/ComponentContainer.cpp b/axmol/2d/ComponentContainer.cpp index 78861ae88f3b..87826aea44aa 100644 --- a/axmol/2d/ComponentContainer.cpp +++ b/axmol/2d/ComponentContainer.cpp @@ -61,7 +61,7 @@ bool ComponentContainer::add(Component* com) AXASSERT(false, "ComponentContainer already have this kind of component"); break; } - axstd::set_item(_componentMap, componentName, com); //_componentMap[componentName] = com; + tlx::set_item(_componentMap, componentName, com); //_componentMap[componentName] = com; com->retain(); com->setOwner(_owner); com->onAdd(); diff --git a/axmol/2d/ComponentContainer.h b/axmol/2d/ComponentContainer.h index a49d11c5645d..a95858e095ec 100644 --- a/axmol/2d/ComponentContainer.h +++ b/axmol/2d/ComponentContainer.h @@ -65,7 +65,7 @@ class AX_DLL ComponentContainer bool isEmpty() const { return _componentMap.empty(); } private: - axstd::string_map _componentMap; + tlx::string_map _componentMap; Node* _owner; friend class Node; diff --git a/axmol/2d/DrawNode.cpp b/axmol/2d/DrawNode.cpp index b9cd06fb367e..d6699d1fc274 100644 --- a/axmol/2d/DrawNode.cpp +++ b/axmol/2d/DrawNode.cpp @@ -72,10 +72,10 @@ static bool isConvex(const Vec2* verts, int count) return true; // is convex } -static V2F_T2F_C4F* expandBufferAndGetPointer(axstd::pod_vector& buffer, size_t count) +static V2F_T2F_C4F* expandBufferAndGetPointer(tlx::pod_vector& buffer, size_t count) { size_t oldSize = buffer.size(); - buffer.expand(count); + buffer.extend(count); return buffer.data() + oldSize; } @@ -226,7 +226,7 @@ void DrawNode::draw(Renderer* renderer, const Mat4& transform, uint32_t flags) } } -static void udpateCommand(CustomCommand& cmd, const axstd::pod_vector& buffer) +static void udpateCommand(CustomCommand& cmd, const tlx::pod_vector& buffer) { if (buffer.empty()) { @@ -413,7 +413,7 @@ void DrawNode::drawQuadBezier(const Vec2& origin, return; } - axstd::pod_vector _vertices{ + tlx::pod_vector _vertices{ static_cast(segments + 1)}; // Vec2* _vertices = _abuf.get(segments + 1); float t = 0.0f; @@ -443,7 +443,7 @@ void DrawNode::drawCubicBezier(const Vec2& origin, return; } - axstd::pod_vector _vertices{static_cast(segments + 1)}; + tlx::pod_vector _vertices{static_cast(segments + 1)}; float t = 0.0f; for (unsigned int i = 0; i < segments; i++) @@ -488,7 +488,7 @@ void DrawNode::drawCardinalSpline(const PointArray* configIn, float lt; float deltaT = 1.0f / config->count(); - axstd::pod_vector _vertices{static_cast(segments)}; + tlx::pod_vector _vertices{static_cast(segments)}; for (unsigned int i = 0; i < segments; i++) { @@ -839,7 +839,7 @@ void DrawNode::_drawPolygon(const Vec2* verts, auto _vertices = _transform(verts, count, closedPolygon); - axstd::pod_vector triangleList; + tlx::pod_vector triangleList; int vertex_count = 0; @@ -984,7 +984,7 @@ void DrawNode::_drawPolygon(const Vec2* verts, Vec2 offset, n; }; - axstd::pod_vector extrude{static_cast(sizeof(struct ExtrudeVerts) * count)}; + tlx::pod_vector extrude{static_cast(sizeof(struct ExtrudeVerts) * count)}; for (unsigned int i = 0; i < count; i++) { @@ -1304,7 +1304,7 @@ void DrawNode::_drawAStar(const Vec2& center, const float coef = 2.0f * (float)M_PI / segments; float halfAngle = coef / 2.0f; - axstd::pod_vector _vertices(segments * 2 + 1); + tlx::pod_vector _vertices(segments * 2 + 1); int i = 0; for (unsigned int a = 0; a < segments; a++) @@ -1465,7 +1465,7 @@ void DrawNode::_drawPie(const Vec2& center, { const float coef = 2.0f * (float)M_PI / DEGREES; - axstd::pod_vector _vertices(DEGREES + 2); + tlx::pod_vector _vertices(DEGREES + 2); int n = 0; float rads = 0.0f; @@ -1517,7 +1517,7 @@ void DrawNode::_drawPie(const Vec2& center, } } -axstd::pod_vector DrawNode::_transform(const Vec2* _vertices, unsigned int& count, bool closedPolygon) +tlx::pod_vector DrawNode::_transform(const Vec2* _vertices, unsigned int& count, bool closedPolygon) { Vec2 vert0 = _vertices[0]; int closedCounter = 0; @@ -1527,7 +1527,7 @@ axstd::pod_vector DrawNode::_transform(const Vec2* _vertices, unsigned int closedCounter = 1; } - axstd::pod_vector vert(count + closedCounter); + tlx::pod_vector vert(count + closedCounter); if (properties.transform == false) { memcpy(vert.data(), _vertices, count * sizeof(Vec2)); diff --git a/axmol/2d/DrawNode.h b/axmol/2d/DrawNode.h index bc6ad6dde506..f8d3fae12149 100644 --- a/axmol/2d/DrawNode.h +++ b/axmol/2d/DrawNode.h @@ -33,7 +33,7 @@ #pragma once #include "axmol/2d/Node.h" -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" #include "axmol/base/Types.h" #include "axmol/renderer/CustomCommand.h" #include "axmol/math/Math.h" @@ -561,9 +561,9 @@ class AX_DLL DrawNode : public Node, public BlendProtocol CustomCommand _customCommandPoint; CustomCommand _customCommandLine; - axstd::pod_vector _triangles; - axstd::pod_vector _points; - axstd::pod_vector _lines; + tlx::pod_vector _triangles; + tlx::pod_vector _points; + tlx::pod_vector _lines; private: // Internal function _drawPoint @@ -661,7 +661,7 @@ class AX_DLL DrawNode : public Node, public BlendProtocol * @param count The number of vertices. * @param closedPolygon The closedPolygon flag. */ - axstd::pod_vector _transform(const Vec2* vertices, unsigned int& count, bool closedPolygon = false); + tlx::pod_vector _transform(const Vec2* vertices, unsigned int& count, bool closedPolygon = false); void applyTransform(const Vec2* from, Vec2* to, unsigned int count); diff --git a/axmol/2d/FontAtlas.cpp b/axmol/2d/FontAtlas.cpp index 807d66f84ba3..8b08f611459e 100644 --- a/axmol/2d/FontAtlas.cpp +++ b/axmol/2d/FontAtlas.cpp @@ -45,7 +45,7 @@ const int FontAtlas::CacheTextureWidth = 512; const int FontAtlas::CacheTextureHeight = 512; const char* FontAtlas::CMD_RESET_FONTATLAS = "__ax_RESET_FONTATLAS"; -void FontAtlas::loadFontAtlas(std::string_view fontatlasFile, axstd::string_map& outAtlasMap) +void FontAtlas::loadFontAtlas(std::string_view fontatlasFile, tlx::string_map& outAtlasMap) { using namespace ::simdjson; @@ -319,7 +319,7 @@ bool FontAtlas::findNewCharacters(const std::u32string& u32Text) if (_letterDefinitions.empty()) { - std::copy(u32Text.begin(), u32Text.end(), std::inserter(_newChars, _newChars.end())); + _newChars.insert(u32Text.begin(), u32Text.end()); } else { diff --git a/axmol/2d/FontAtlas.h b/axmol/2d/FontAtlas.h index 97e81b22c8bb..fc33ef74e3d6 100644 --- a/axmol/2d/FontAtlas.h +++ b/axmol/2d/FontAtlas.h @@ -70,7 +70,7 @@ class AX_DLL FontAtlas : public Object static const int CacheTextureWidth; static const int CacheTextureHeight; static const char* CMD_RESET_FONTATLAS; - static void loadFontAtlas(std::string_view fontatlasFile, axstd::string_map& outAtlasMap); + static void loadFontAtlas(std::string_view fontatlasFile, tlx::string_map& outAtlasMap); /** */ FontAtlas(Font* theFont); @@ -145,7 +145,7 @@ class AX_DLL FontAtlas : public Object void updateTextureContent(rhi::PixelFormat format, int startY); - axstd::flat_set _newChars; + tlx::flat_set _newChars; std::unordered_map _atlasTextures; std::unordered_map _letterDefinitions; diff --git a/axmol/2d/FontAtlasCache.cpp b/axmol/2d/FontAtlasCache.cpp index 4feb76b63fed..6994ced9c834 100644 --- a/axmol/2d/FontAtlasCache.cpp +++ b/axmol/2d/FontAtlasCache.cpp @@ -38,7 +38,7 @@ namespace ax { -axstd::string_map FontAtlasCache::_atlasMap; +tlx::string_map FontAtlasCache::_atlasMap; void FontAtlasCache::purgeCachedData() { diff --git a/axmol/2d/FontAtlasCache.h b/axmol/2d/FontAtlasCache.h index 2c274680ee12..a326d2dc49fa 100644 --- a/axmol/2d/FontAtlasCache.h +++ b/axmol/2d/FontAtlasCache.h @@ -79,7 +79,7 @@ class AX_DLL FontAtlasCache static void unloadFontAtlasTTF(std::string_view fontFileName); private: - static axstd::string_map _atlasMap; + static tlx::string_map _atlasMap; }; } // namespace ax diff --git a/axmol/2d/FontFreeType.cpp b/axmol/2d/FontFreeType.cpp index deadb84f1973..35273ed7da12 100644 --- a/axmol/2d/FontFreeType.cpp +++ b/axmol/2d/FontFreeType.cpp @@ -68,7 +68,7 @@ typedef struct _DataRef unsigned int referenceCount = 0; } DataRef; -static axstd::string_map s_cacheFontData; +static tlx::string_map s_cacheFontData; // ------ freetype2 stream parsing support --- static unsigned long ft_stream_read_callback(FT_Stream stream, diff --git a/axmol/2d/MotionStreak.h b/axmol/2d/MotionStreak.h index 66b8bdf9b56b..8920981c7fbd 100644 --- a/axmol/2d/MotionStreak.h +++ b/axmol/2d/MotionStreak.h @@ -30,7 +30,7 @@ THE SOFTWARE. #include "axmol/base/Protocols.h" #include "axmol/2d/Node.h" #include "axmol/renderer/CustomCommand.h" -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" namespace ax { @@ -189,7 +189,7 @@ class AX_DLL MotionStreak : public Node, public TextureProtocol Vec2* _pointVertexes = nullptr; float* _pointState = nullptr; - axstd::pod_vector _vertices; + tlx::pod_vector _vertices; CustomCommand _customCommand; diff --git a/axmol/2d/ParticleSystem.cpp b/axmol/2d/ParticleSystem.cpp index 3031180df338..ab352253b230 100644 --- a/axmol/2d/ParticleSystem.cpp +++ b/axmol/2d/ParticleSystem.cpp @@ -635,7 +635,7 @@ bool ParticleSystem::initWithDictionary(const ValueMap& dictionary, std::string_ if (dataLen != 0) { // if it fails, try to get it from the base64-gzipped data - yasio::byte_buffer buffer = utils::base64Decode(textureData); + auto buffer = utils::base64Decode(textureData); AXASSERT(!buffer.empty(), "CCParticleSystem: error decoding textureImageData"); AX_BREAK_IF(buffer.empty()); @@ -647,7 +647,7 @@ bool ParticleSystem::initWithDictionary(const ValueMap& dictionary, std::string_ // Director::getInstance()->getTextureCache()->addUIImage() image = new Image(); const auto imageDataLen = deflated.size(); - bool isOK = image->initWithImageData(deflated.release_pointer(), imageDataLen, true); + bool isOK = image->initWithImageData(deflated.detach_abi(), imageDataLen, true); AXASSERT(isOK, "CCParticleSystem: error init image with Data"); AX_BREAK_IF(!isOK); diff --git a/axmol/2d/ProgressTimer.h b/axmol/2d/ProgressTimer.h index 31267cb312e8..d05bc33e25e7 100644 --- a/axmol/2d/ProgressTimer.h +++ b/axmol/2d/ProgressTimer.h @@ -31,7 +31,7 @@ THE SOFTWARE. #include "axmol/2d/Node.h" #include "axmol/renderer/PipelineDesc.h" -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" namespace ax { @@ -187,8 +187,8 @@ class AX_DLL ProgressTimer : public Node Vec2 _barChangeRate; float _percentage = 0.0f; Sprite* _sprite = nullptr; - axstd::pod_vector _vertexData; - axstd::pod_vector _indexData; + tlx::pod_vector _vertexData; + tlx::pod_vector _indexData; bool _reverseDirection = false; CustomCommand _customCommand; diff --git a/axmol/2d/SpriteFrameCache.cpp b/axmol/2d/SpriteFrameCache.cpp index 95d8d1e62974..e04a15abec42 100644 --- a/axmol/2d/SpriteFrameCache.cpp +++ b/axmol/2d/SpriteFrameCache.cpp @@ -327,8 +327,8 @@ void SpriteFrameCache::insertFrame(const std::shared_ptr& spriteShe _spriteFrames.insert(frameId, spriteFrame); // add SpriteFrame if (spriteSheet->pathId == (uint64_t)-1) spriteSheet->pathId = computeHash(spriteSheet->path); - axstd::set_item(_spriteSheets, spriteSheet->pathId, spriteSheet); - axstd::set_item(_spriteFrameToSpriteSheetMap, frameId, spriteSheet); + tlx::set_item(_spriteSheets, spriteSheet->pathId, spriteSheet); + tlx::set_item(_spriteFrameToSpriteSheetMap, frameId, spriteSheet); } bool SpriteFrameCache::eraseFrame(std::string_view frameName) diff --git a/axmol/2d/SpriteFrameCache.h b/axmol/2d/SpriteFrameCache.h index 89145aeacd4f..c1f940870ee5 100644 --- a/axmol/2d/SpriteFrameCache.h +++ b/axmol/2d/SpriteFrameCache.h @@ -297,8 +297,8 @@ class AX_DLL SpriteFrameCache private: ax::Map _spriteFrames; - axstd::hash_map> _spriteSheets; - axstd::hash_map> _spriteFrameToSpriteSheetMap; + tlx::hash_map> _spriteSheets; + tlx::hash_map> _spriteFrameToSpriteSheetMap; std::map> _spriteSheetLoaders; }; diff --git a/axmol/2d/SpriteSheetLoader.h b/axmol/2d/SpriteSheetLoader.h index 827fddba4b4d..269c3326373d 100644 --- a/axmol/2d/SpriteSheetLoader.h +++ b/axmol/2d/SpriteSheetLoader.h @@ -64,7 +64,7 @@ class SpriteSheet std::string path; uint32_t format; uint64_t pathId = (uint64_t)-1; - axstd::hash_set frames; + tlx::hash_set frames; bool full = false; }; diff --git a/axmol/2d/TMXXMLParser.cpp b/axmol/2d/TMXXMLParser.cpp index 61325a57a10b..ddc2361fee30 100644 --- a/axmol/2d/TMXXMLParser.cpp +++ b/axmol/2d/TMXXMLParser.cpp @@ -455,7 +455,7 @@ void TMXMapInfo::startElement(void* /*ctx*/, const char* name, const char** atts Vec2 layerSize = layer->_layerSize; auto tilesAmount = static_cast(layerSize.width * layerSize.height); - layer->_tiles = (uint32_t*)axstd::pod_vector(tilesAmount, 0U).release_pointer(); + layer->_tiles = (uint32_t*)tlx::pod_vector(tilesAmount, 0U).detach_abi(); } else if (encoding == "base64") { @@ -721,11 +721,11 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name) return; } - layer->_tiles = reinterpret_cast(buffer.release_pointer()); + layer->_tiles = reinterpret_cast(buffer.detach_abi()); } else { - layer->_tiles = reinterpret_cast(buffer.release_pointer()); + layer->_tiles = reinterpret_cast(buffer.detach_abi()); } tmxMapInfo->setCurrentString(""); @@ -737,9 +737,9 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name) tmxMapInfo->setStoringCharacters(false); auto currentString = tmxMapInfo->getCurrentString(); - axstd::pod_vector tileGids; - axstd::split_cb(currentString, '\n', [&tileGids](const char* first, const char* last) { - axstd::split_cb(std::string_view{first, static_cast(last - first)}, ',', + tlx::pod_vector tileGids; + tlx::split_cb(currentString, '\n', [&tileGids](const char* first, const char* last) { + tlx::split_cb(std::string_view{first, static_cast(last - first)}, ',', [&tileGids](const char* _first, const char* _last) { unsigned int gid{0}; std::from_chars(_first, _last, gid); @@ -747,7 +747,7 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name) }); }); - layer->_tiles = tileGids.release_pointer(); + layer->_tiles = tileGids.detach_abi(); tmxMapInfo->setCurrentString(""); } diff --git a/axmol/3d/Animation3D.cpp b/axmol/3d/Animation3D.cpp index 26df65a7766f..0166b2806d33 100644 --- a/axmol/3d/Animation3D.cpp +++ b/axmol/3d/Animation3D.cpp @@ -27,7 +27,7 @@ #include "axmol/3d/Animation3D.h" #include "axmol/3d/Bundle3D.h" #include "axmol/platform/FileUtils.h" -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" #include "axmol/tlx/utility.hpp" namespace ax @@ -109,8 +109,8 @@ bool Animation3D::init(const Animation3DData& data) _duration = data._totalTime; { - axstd::pod_vector keys; - axstd::pod_vector values; + tlx::pod_vector keys; + tlx::pod_vector values; for (const auto& iter : data._translationKeys) { Curve* curve = _boneCurves[iter.first]; @@ -123,9 +123,9 @@ bool Animation3D::init(const Animation3DData& data) if (iter.second.empty()) continue; - axstd::resize_and_transform(iter.second.begin(), iter.second.end(), keys, + tlx::resize_and_transform(iter.second.begin(), iter.second.end(), keys, [](const auto& keyIter) { return keyIter._time; }); - axstd::resize_and_transform(iter.second.begin(), iter.second.end(), values, + tlx::resize_and_transform(iter.second.begin(), iter.second.end(), values, [](const auto& keyIter) { return keyIter._key; }); curve->translateCurve = Curve::AnimationCurveVec3::create(&keys[0], &values[0].x, (int)keys.size()); @@ -135,8 +135,8 @@ bool Animation3D::init(const Animation3DData& data) } { - axstd::pod_vector keys; - axstd::pod_vector values; + tlx::pod_vector keys; + tlx::pod_vector values; for (const auto& iter : data._rotationKeys) { Curve* curve = _boneCurves[iter.first]; @@ -149,9 +149,9 @@ bool Animation3D::init(const Animation3DData& data) if (iter.second.empty()) continue; - axstd::resize_and_transform(iter.second.begin(), iter.second.end(), keys, + tlx::resize_and_transform(iter.second.begin(), iter.second.end(), keys, [](const auto& keyIter) { return keyIter._time; }); - axstd::resize_and_transform(iter.second.begin(), iter.second.end(), values, + tlx::resize_and_transform(iter.second.begin(), iter.second.end(), values, [](const auto& keyIter) { return keyIter._key; }); curve->rotCurve = Curve::AnimationCurveQuat::create(&keys[0], &values[0].x, (int)keys.size()); @@ -161,8 +161,8 @@ bool Animation3D::init(const Animation3DData& data) } { - axstd::pod_vector keys; - axstd::pod_vector values; + tlx::pod_vector keys; + tlx::pod_vector values; for (const auto& iter : data._scaleKeys) { Curve* curve = _boneCurves[iter.first]; @@ -175,9 +175,9 @@ bool Animation3D::init(const Animation3DData& data) if (iter.second.empty()) continue; - axstd::resize_and_transform(iter.second.begin(), iter.second.end(), keys, + tlx::resize_and_transform(iter.second.begin(), iter.second.end(), keys, [](const auto& keyIter) { return keyIter._time; }); - axstd::resize_and_transform(iter.second.begin(), iter.second.end(), values, + tlx::resize_and_transform(iter.second.begin(), iter.second.end(), values, [](const auto& keyIter) { return keyIter._key; }); curve->scaleCurve = Curve::AnimationCurveVec3::create(&keys[0], &values[0].x, (int)keys.size()); diff --git a/axmol/3d/Animation3D.h b/axmol/3d/Animation3D.h index 5d236fdbb1fb..5c56822ae810 100644 --- a/axmol/3d/Animation3D.h +++ b/axmol/3d/Animation3D.h @@ -82,7 +82,7 @@ class AX_DLL Animation3D : public Object Curve* getBoneCurveByName(std::string_view name) const; /**get the bone Curves set*/ - const axstd::string_map& getBoneCurves() const { return _boneCurves; } + const tlx::string_map& getBoneCurves() const { return _boneCurves; } Animation3D(); virtual ~Animation3D(); @@ -93,7 +93,7 @@ class AX_DLL Animation3D : public Object bool initWithFile(std::string_view filename, std::string_view animationName); protected: - axstd::string_map _boneCurves; // bone curves map, key bone name, value AnimationCurve + tlx::string_map _boneCurves; // bone curves map, key bone name, value AnimationCurve float _duration; // animation duration }; @@ -125,7 +125,7 @@ class Animation3DCache static Animation3DCache* _cacheInstance; // cache instance - axstd::string_map _animations; // cached animations + tlx::string_map _animations; // cached animations }; // end of 3d group diff --git a/axmol/3d/Bundle3DData.h b/axmol/3d/Bundle3DData.h index 4a00c0d7a615..7f5820975284 100644 --- a/axmol/3d/Bundle3DData.h +++ b/axmol/3d/Bundle3DData.h @@ -36,7 +36,8 @@ #include #include "axmol/3d/shaderinfos.h" -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" +#include "axmol/tlx/byte_buffer.hpp" namespace ax { @@ -115,7 +116,7 @@ class IndexArray assert(_stride == sizeof(_Ty)); auto ifirst = reinterpret_cast(first); auto size_bytes = std::distance(first, last) * sizeof(_Ty); - _buffer.insert((yasio::byte_buffer::iterator)position, ifirst, ifirst + size_bytes); + _buffer.insert(tlx::byte_buffer::iterator(position), ifirst, ifirst + size_bytes); } template , int> = 0> @@ -188,9 +189,9 @@ class IndexArray size_t bsize() const { return _buffer.size(); } /** Resizes the count of indices in the container. */ - void resize(size_t size) { _buffer.resize(static_cast(size * _stride)); } + void resize(size_t size) { _buffer.resize(static_cast(size * _stride)); } /** Resizes the container in bytes. */ - void bresize(size_t size) { _buffer.resize(static_cast(size)); } + void bresize(size_t size) { _buffer.resize(static_cast(size)); } /** Returns true if the container is empty. Otherwise, false. */ bool empty() const { return _buffer.empty(); } @@ -202,14 +203,14 @@ class IndexArray for (auto it = _buffer.begin(); it != _buffer.end(); it += _stride) { uint32_t val = 0; - memcpy(&val, it, _stride); + memcpy(&val, std::to_address(it), _stride); cb(val); } } protected: unsigned char _stride; - yasio::byte_buffer _buffer; + tlx::byte_buffer _buffer; }; /**mesh vertex attribute @@ -307,7 +308,7 @@ struct MeshData std::vector subMeshIds; // subMesh Names (since 3.3) std::vector subMeshAABB; int numIndex; - axstd::pod_vector attribs; + tlx::pod_vector attribs; int attribCount; public: @@ -521,9 +522,9 @@ struct Animation3DData }; public: - axstd::string_map> _translationKeys; - axstd::string_map> _rotationKeys; - axstd::string_map> _scaleKeys; + tlx::string_map> _translationKeys; + tlx::string_map> _rotationKeys; + tlx::string_map> _scaleKeys; float _totalTime; diff --git a/axmol/3d/Mesh.cpp b/axmol/3d/Mesh.cpp index e6d935c9752d..b34788ed1fce 100644 --- a/axmol/3d/Mesh.cpp +++ b/axmol/3d/Mesh.cpp @@ -200,7 +200,7 @@ Mesh* Mesh::create(const std::vector& positions, { int perVertexSizeInFloat = 0; std::vector vertices; - axstd::pod_vector attribs; + tlx::pod_vector attribs; MeshVertexAttrib att; att.type = rhi::VertexFormat::FLOAT3; @@ -259,7 +259,7 @@ Mesh* Mesh::create(const std::vector& positions, Mesh* Mesh::create(const std::vector& vertices, int /*perVertexSizeInFloat*/, const IndexArray& indices, - const axstd::pod_vector& attribs) + const tlx::pod_vector& attribs) { MeshData meshdata; meshdata.attribs = attribs; diff --git a/axmol/3d/Mesh.h b/axmol/3d/Mesh.h index 524db0e14d8d..c18d4721d96b 100644 --- a/axmol/3d/Mesh.h +++ b/axmol/3d/Mesh.h @@ -79,7 +79,7 @@ class AX_DLL Mesh : public Object static Mesh* create(const std::vector& vertices, int perVertexSizeInFloat, const IndexArray& indices, - const axstd::pod_vector& attribs); + const tlx::pod_vector& attribs); /** * create mesh @@ -281,7 +281,7 @@ class AX_DLL Mesh : public Object void resetLightUniformValues(); void setLightUniforms(Pass* pass, Scene* scene, const Vec4& color, unsigned int lightmask); void bindMeshCommand(); - axstd::hash_map _textures; // textures that submesh is using + tlx::hash_map _textures; // textures that submesh is using MeshSkin* _skin; // skin bool _visible; // is the submesh visible @@ -303,7 +303,7 @@ class AX_DLL Mesh : public Object Material* _material; AABB _aabb; std::function _visibleChanged; - axstd::string_map> _meshCommands; + tlx::string_map> _meshCommands; /// light parameters std::vector _dirLightUniformColorValues; diff --git a/axmol/3d/MeshDataCache.h b/axmol/3d/MeshDataCache.h index a91a45075173..3aac64226e47 100644 --- a/axmol/3d/MeshDataCache.h +++ b/axmol/3d/MeshDataCache.h @@ -86,7 +86,7 @@ class AX_DLL MeshDataCache protected: static MeshDataCache* _cacheInstance; - axstd::string_map _meshDatas; // cached mesh data + tlx::string_map _meshDatas; // cached mesh data }; // end of 3d group diff --git a/axmol/3d/MeshMaterial.h b/axmol/3d/MeshMaterial.h index 255be8570216..7db6602b1774 100644 --- a/axmol/3d/MeshMaterial.h +++ b/axmol/3d/MeshMaterial.h @@ -196,7 +196,7 @@ class MeshMaterialCache protected: static MeshMaterialCache* _cacheInstance; // cache instance - axstd::string_map _materials; // cached materials + tlx::string_map _materials; // cached materials }; // end of 3d group diff --git a/axmol/3d/MeshRenderer.cpp b/axmol/3d/MeshRenderer.cpp index ec70910c3702..edc8283cb169 100644 --- a/axmol/3d/MeshRenderer.cpp +++ b/axmol/3d/MeshRenderer.cpp @@ -65,7 +65,7 @@ MeshRenderer* MeshRenderer::create() MeshRenderer* MeshRenderer::create(std::string_view modelPath) { - return create(modelPath, axstd::empty_sv); + return create(modelPath, tlx::empty_sv); } MeshRenderer* MeshRenderer::create(std::string_view modelPath, std::string_view texturePath) diff --git a/axmol/3d/MeshRenderer.h b/axmol/3d/MeshRenderer.h index d308140a3231..f5f03f04545f 100644 --- a/axmol/3d/MeshRenderer.h +++ b/axmol/3d/MeshRenderer.h @@ -312,7 +312,7 @@ class AX_DLL MeshRenderer : public Node, public BlendProtocol Vector _meshVertexDatas; - axstd::string_map _attachments; + tlx::string_map _attachments; BlendFunc _blend; diff --git a/axmol/3d/MeshVertexIndexData.h b/axmol/3d/MeshVertexIndexData.h index eaa8dd9c56d5..cad6e504d8cc 100644 --- a/axmol/3d/MeshVertexIndexData.h +++ b/axmol/3d/MeshVertexIndexData.h @@ -146,7 +146,7 @@ class AX_DLL MeshVertexData : public Object rhi::Buffer* _vertexBuffer = nullptr; // vertex buffer ssize_t _sizePerVertex = -1; Vector _indices; // index data - axstd::pod_vector _attribs; // vertex attributes + tlx::pod_vector _attribs; // vertex attributes int _vertexCount = 0; // vertex count std::vector _vertexData; diff --git a/axmol/3d/ObjLoader.cpp b/axmol/3d/ObjLoader.cpp index 3c5c39b4e066..fd3bed273a73 100644 --- a/axmol/3d/ObjLoader.cpp +++ b/axmol/3d/ObjLoader.cpp @@ -458,7 +458,7 @@ static std::string& replacePathSeperator(std::string& path) return path; } -std::string LoadMtl(axstd::string_map& material_map, std::vector& materials, std::istream& inStream) +std::string LoadMtl(tlx::string_map& material_map, std::vector& materials, std::istream& inStream) { std::stringstream err; @@ -681,7 +681,7 @@ std::string LoadMtl(axstd::string_map& material_map, std::vector& materials, - axstd::string_map& matMap) + tlx::string_map& matMap) { std::string filepath; @@ -749,7 +749,7 @@ std::string LoadObj(std::vector& shapes, std::string name; // material - axstd::string_map material_map; + tlx::string_map material_map; std::map vertexCache; int material = -1; diff --git a/axmol/3d/ObjLoader.h b/axmol/3d/ObjLoader.h index 9e6f5272aa26..1ed1d62e515e 100644 --- a/axmol/3d/ObjLoader.h +++ b/axmol/3d/ObjLoader.h @@ -77,7 +77,7 @@ class MaterialReader virtual std::string operator()(std::string_view matId, std::vector& materials, - axstd::string_map& matMap) = 0; + tlx::string_map& matMap) = 0; }; class MaterialFileReader : public MaterialReader @@ -87,7 +87,7 @@ class MaterialFileReader : public MaterialReader virtual ~MaterialFileReader() {} virtual std::string operator()(std::string_view matId, std::vector& materials, - axstd::string_map& matMap); + tlx::string_map& matMap); private: std::string m_mtlBasePath; @@ -113,5 +113,5 @@ std::string LoadObj(std::vector& shapes, // [output] /// Loads materials into std::map /// Returns an empty string if successful -std::string LoadMtl(axstd::string_map& material_map, std::vector& materials, std::istream& inStream); +std::string LoadMtl(tlx::string_map& material_map, std::vector& materials, std::istream& inStream); } // namespace tinyobj diff --git a/axmol/3d/Terrain.cpp b/axmol/3d/Terrain.cpp index 3d6b92fc6078..0f56790ce3c9 100644 --- a/axmol/3d/Terrain.cpp +++ b/axmol/3d/Terrain.cpp @@ -38,7 +38,7 @@ using namespace ax; #include "axmol/rhi/Buffer.h" #include "axmol/base/Director.h" #include "axmol/base/Types.h" -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" #include "axmol/tlx/utility.hpp" #include "axmol/base/EventType.h" #include "axmol/2d/Camera.h" @@ -1314,8 +1314,8 @@ void Terrain::Chunk::updateIndicesLOD() void Terrain::Chunk::calculateAABB() { - axstd::pod_vector pos; - axstd::resize_and_transform(_originalVertices.begin(), _originalVertices.end(), pos, + tlx::pod_vector pos; + tlx::resize_and_transform(_originalVertices.begin(), _originalVertices.end(), pos, [](const auto& it) { return it._position; }); _aabb.updateMinMax(&pos[0], pos.size()); } diff --git a/axmol/3d/VertexInputBinding.cpp b/axmol/3d/VertexInputBinding.cpp index 9663008708e9..8af472e3c967 100644 --- a/axmol/3d/VertexInputBinding.cpp +++ b/axmol/3d/VertexInputBinding.cpp @@ -38,7 +38,7 @@ namespace ax * render objects */ -static axstd::hash_map* s_vertexInputBindingCache; +static tlx::hash_map* s_vertexInputBindingCache; void VertexInputBinding::purgeCache() { @@ -79,7 +79,7 @@ VertexInputBinding* VertexInputBinding::spawn(MeshIndexData* meshIndexData, auto hash = XXH32(&hashMe, sizeof(hashMe), 0); if (!s_vertexInputBindingCache) - s_vertexInputBindingCache = new axstd::hash_map(); + s_vertexInputBindingCache = new tlx::hash_map(); auto cache = s_vertexInputBindingCache; auto it = cache->find(hash); if (it != cache->end()) diff --git a/axmol/audio/AudioDecoderManager.cpp b/axmol/audio/AudioDecoderManager.cpp index 46c384493a82..7c495e829a40 100644 --- a/axmol/audio/AudioDecoderManager.cpp +++ b/axmol/audio/AudioDecoderManager.cpp @@ -38,7 +38,7 @@ THE SOFTWARE. # include "axmol/audio/AudioDecoderEXT.h" #endif -#include "yasio/string_view.hpp" +#include "yasio/tlx/string_view.hpp" namespace ax { @@ -60,7 +60,7 @@ void AudioDecoderManager::destroy() AudioDecoder* AudioDecoderManager::createDecoder(std::string_view path) { - if (cxx20::ic::ends_with(path, ".ogg") || cxx20::ic::ends_with(path, ".opus")) + if (tlx::ic::ends_with(path, ".ogg") || tlx::ic::ends_with(path, ".opus")) { constexpr char VORBIS_SIGN[] = {0x1, 'v', 'o', 'r', 'b', 'i', 's', '\0'}; constexpr char OPUS_SIGN[] = {'O', 'p', 'u', 's', 'H', 'e', 'a', 'd'}; @@ -96,11 +96,11 @@ AudioDecoder* AudioDecoderManager::createDecoder(std::string_view path) } } #if !defined(__APPLE__) - else if (cxx20::ic::ends_with(path, ".mp3")) + else if (tlx::ic::ends_with(path, ".mp3")) { return new AudioDecoderMp3(); } - else if (cxx20::ic::ends_with(path, ".wav")) + else if (tlx::ic::ends_with(path, ".wav")) { return new AudioDecoderWav(); } diff --git a/axmol/audio/AudioEngine.cpp b/axmol/audio/AudioEngine.cpp index 1d3eb65032a1..4fd1727e5691 100644 --- a/axmol/audio/AudioEngine.cpp +++ b/axmol/audio/AudioEngine.cpp @@ -49,9 +49,9 @@ const int AudioEngine::INVALID_AUDIO_ID = -1; const float AudioEngine::TIME_UNKNOWN = -1.0f; // audio file path,audio IDs -axstd::string_map> AudioEngine::_audioPathIDMap; +tlx::string_map> AudioEngine::_audioPathIDMap; // profileName,ProfileHelper -axstd::string_map AudioEngine::_audioPathProfileHelperMap; +tlx::string_map AudioEngine::_audioPathProfileHelperMap; unsigned int AudioEngine::_maxInstances = MAX_AUDIOINSTANCES; AudioEngine::ProfileHelper* AudioEngine::_defaultProfileHelper = nullptr; std::unordered_map AudioEngine::_audioIDInfoMap; diff --git a/axmol/audio/AudioEngine.h b/axmol/audio/AudioEngine.h index 2fabd8dd7e32..ab0612d84490 100644 --- a/axmol/audio/AudioEngine.h +++ b/axmol/audio/AudioEngine.h @@ -492,10 +492,10 @@ class AX_DLL AudioEngine static std::unordered_map _audioIDInfoMap; // audio file path,audio IDs - static axstd::string_map> _audioPathIDMap; + static tlx::string_map> _audioPathIDMap; // profileName,ProfileHelper - static axstd::string_map _audioPathProfileHelperMap; + static tlx::string_map _audioPathProfileHelperMap; static unsigned int _maxInstances; diff --git a/axmol/audio/AudioEngineImpl.h b/axmol/audio/AudioEngineImpl.h index 744f3da4bcf8..4629ca2e2b8e 100644 --- a/axmol/audio/AudioEngineImpl.h +++ b/axmol/audio/AudioEngineImpl.h @@ -97,7 +97,7 @@ class AX_DLL AudioEngineImpl : public ax::Object std::queue _unusedSourcesPool; // filePath,bufferInfo - axstd::string_map> _audioCaches; + tlx::string_map> _audioCaches; // audioID,AudioInfo std::unordered_map _audioPlayers; diff --git a/axmol/axmol.natvis b/axmol/axmol.natvis index d8326354c156..9513a74417b9 100644 --- a/axmol/axmol.natvis +++ b/axmol/axmol.natvis @@ -1,6 +1,6 @@ - + {{ size={_Mylast - _Myfirst} capacity={_Myend - _Myfirst} }} _Mylast - _Myfirst @@ -12,7 +12,7 @@ - + {{size = {_Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst}}} _Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst @@ -25,7 +25,7 @@ - + {{size = {_Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst}}} _Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst @@ -38,7 +38,7 @@ - + {{size = {_Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst}}} _Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst @@ -51,7 +51,7 @@ - + {{size = {_Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst}}} _Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst diff --git a/axmol/base/Console.cpp b/axmol/base/Console.cpp index 7ccd20aaa992..666feb4e89ca 100644 --- a/axmol/base/Console.cpp +++ b/axmol/base/Console.cpp @@ -740,7 +740,7 @@ void Console::performCommand(socket_native_type fd, std::string_view command) } int index = 0; - axstd::string_map::iterator it; + tlx::string_map::iterator it; std::string cmd_args; for (auto rgn : std::views::split(command, ' ')) { @@ -1135,10 +1135,10 @@ void Console::commandTouchSubCommandTap(socket_native_type fd, std::string_view switch (argi++) { case 1: - axstd::from_chars(argv.data(), argv.data() + argv.length(), x); + tlx::from_chars(argv.data(), argv.data() + argv.length(), x); break; case 2: - axstd::from_chars(argv.data(), argv.data() + argv.length(), x); + tlx::from_chars(argv.data(), argv.data() + argv.length(), x); break; } if (argi == 3) @@ -1406,7 +1406,7 @@ void Console::printFileUtils(socket_native_type fd) Console::Utility::sendPrompt(fd); } -void Console::sendHelp(socket_native_type fd, const axstd::string_map& commands, const char* msg) +void Console::sendHelp(socket_native_type fd, const tlx::string_map& commands, const char* msg) { Console::Utility::sendToConsole(fd, msg, strlen(msg)); for (auto&& it : commands) diff --git a/axmol/base/Console.h b/axmol/base/Console.h index faad6b6d1f9a..346b4ccc5ee1 100644 --- a/axmol/base/Console.h +++ b/axmol/base/Console.h @@ -145,7 +145,7 @@ class AX_DLL Console : public Object std::string _help; Callback _callback; - axstd::string_map _subCommands; + tlx::string_map _subCommands; }; /** Constructor */ @@ -259,7 +259,7 @@ class AX_DLL Console : public Object bool _endThread; bool _isIpv6Server; - axstd::string_map _commands; + tlx::string_map _commands; // strings generated by axmol sent to the remote console bool _sendDebugStrings; @@ -279,7 +279,7 @@ class AX_DLL Console : public Object void printFileUtils(socket_native_type fd); /** send help message to console */ - static void sendHelp(socket_native_type fd, const axstd::string_map& commands, const char* msg); + static void sendHelp(socket_native_type fd, const tlx::string_map& commands, const char* msg); }; } // namespace ax diff --git a/axmol/base/Data.cpp b/axmol/base/Data.cpp index ee0698e9bc8f..674ad314efc6 100644 --- a/axmol/base/Data.cpp +++ b/axmol/base/Data.cpp @@ -108,14 +108,13 @@ void Data::fastSet(uint8_t* bytes, const ssize_t size) { AXASSERT(size >= 0, "fastSet size should be non-negative"); // AXASSERT(bytes, "bytes should not be nullptr"); - (void)_impl.release_pointer(); // forget internal pointer + _impl.shrink_to_empty(); _impl.attach_abi(bytes, size); } void Data::clear() { _impl.clear(); - _impl.shrink_to_fit(); } uint8_t* Data::takeBuffer(ssize_t* size) @@ -123,7 +122,7 @@ uint8_t* Data::takeBuffer(ssize_t* size) auto buffer = getBytes(); if (size) *size = getSize(); - return _impl.release_pointer(); + return _impl.detach_abi(); } } // namespace ax diff --git a/axmol/base/Data.h b/axmol/base/Data.h index b6f53c95bf68..bff2918548e8 100644 --- a/axmol/base/Data.h +++ b/axmol/base/Data.h @@ -49,7 +49,7 @@ class AX_DLL Data const uint8_t* data() const { return _impl.data(); } uint8_t* data() { return _impl.data(); } - operator yasio::byte_buffer&() { return _impl; } + operator tlx::byte_buffer&() { return _impl; } /** * This parameter is defined for convenient reference if a null Data object is needed. @@ -154,7 +154,7 @@ class AX_DLL Data unsigned char* takeBuffer(ssize_t* size); private: - mutable axstd::byte_buffer _impl; + mutable tlx::byte_buffer _impl; }; } // namespace ax diff --git a/axmol/base/Director.cpp b/axmol/base/Director.cpp index 58d3b4587e8e..a929ae2ef278 100644 --- a/axmol/base/Director.cpp +++ b/axmol/base/Director.cpp @@ -1122,8 +1122,7 @@ void Director::reset() MeshMaterial::releaseBuiltInMaterial(); MeshMaterial::releaseCachedMaterial(); #endif - VertexLayoutManager::destroyInstance(); - + rhi::SamplerCache::destroyInstance(); } @@ -1136,6 +1135,7 @@ void Director::cleanupDirector() AX_SAFE_DELETE(_renderer); ProgramManager::destroyInstance(); + VertexLayoutManager::destroyInstance(); rhi::DriverBase::destroyInstance(); // OpenGL view diff --git a/axmol/base/Environment.cpp b/axmol/base/Environment.cpp index 134561ff375b..ed6ad04be4f0 100644 --- a/axmol/base/Environment.cpp +++ b/axmol/base/Environment.cpp @@ -328,7 +328,7 @@ const Value& Environment::getValue(std::string_view key, const Value& defaultVal void Environment::setValue(std::string_view key, const Value& value) { - axstd::set_item(_valueDict, key, value); // _valueDict[key] = value; + tlx::set_item(_valueDict, key, value); // _valueDict[key] = value; } // diff --git a/axmol/base/EventDispatcher.h b/axmol/base/EventDispatcher.h index 1ba8f702114c..2e54c53e6910 100644 --- a/axmol/base/EventDispatcher.h +++ b/axmol/base/EventDispatcher.h @@ -330,10 +330,10 @@ class AX_DLL EventDispatcher : public Object void cleanToRemovedListeners(); /** Listeners map */ - axstd::string_map _listenerMap; + tlx::string_map _listenerMap; /** The map of dirty flag */ - axstd::string_map _priorityDirtyFlagMap; + tlx::string_map _priorityDirtyFlagMap; /** The map of node and event listeners */ std::unordered_map*> _nodeListenersMap; diff --git a/axmol/base/JsonWriter.h b/axmol/base/JsonWriter.h index e316a9fee0e0..7edc2e4215a6 100644 --- a/axmol/base/JsonWriter.h +++ b/axmol/base/JsonWriter.h @@ -30,7 +30,7 @@ Copyright (c) 2019-present Axmol Engine contributors (see AUTHORS.md). #include -#include "yasio/byte_buffer.hpp" +#include "axmol/tlx/byte_buffer.hpp" #include "axmol/tlx/format.hpp" namespace ax @@ -223,10 +223,10 @@ class JsonWriter { if constexpr (_Pretty) if (_level) - _buffer.expand(_level * _options.indentCharCount, _options.indentChar); + _buffer.extend(_level * _options.indentCharCount, _options.indentChar); } - yasio::sbyte_buffer _buffer; + tlx::sbyte_buffer _buffer; uint16_t _level{0}; bool _pendingValue{false}; JsonWriterOptions _options; diff --git a/axmol/base/Logging.cpp b/axmol/base/Logging.cpp index 5a6709a3364a..8754a4f11b7a 100644 --- a/axmol/base/Logging.cpp +++ b/axmol/base/Logging.cpp @@ -25,7 +25,7 @@ #include "axmol/base/Logging.h" -#include "yasio/utils.hpp" +#include "yasio/tlx/chrono.hpp" #include "fmt/color.h" #if defined(_WIN32) @@ -141,7 +141,7 @@ AX_API LogItem&& preprocessLog(LogItem&& item) if (bitmask::any(s_logFmtFlags, LogFmtFlag::TimeStamp)) { struct tm ts = {0}; - auto tv_msec = yasio::clock(); + auto tv_msec = tlx::clock(); auto tv_sec = static_cast(tv_msec / std::milli::den); localtime_r(&tv_sec, &ts); prefix_size += fmt::format_to_n(wptr + prefix_size, buffer_size - prefix_size, diff --git a/axmol/base/Map.h b/axmol/base/Map.h index f44289f57d19..b83d6c459fca 100644 --- a/axmol/base/Map.h +++ b/axmol/base/Map.h @@ -435,7 +435,7 @@ class Map }; template -using StringMap = Map; +using StringMap = Map; } // namespace ax // end group diff --git a/axmol/base/ObjectFactory.h b/axmol/base/ObjectFactory.h index 873b1d5f9434..6fb8dd38b691 100644 --- a/axmol/base/ObjectFactory.h +++ b/axmol/base/ObjectFactory.h @@ -51,7 +51,7 @@ class AX_DLL ObjectFactory Instance _fun; InstanceFunc _func; }; - typedef axstd::string_map FactoryMap; + typedef tlx::string_map FactoryMap; static ObjectFactory* getInstance(); static void destroyInstance(); diff --git a/axmol/base/Properties.cpp b/axmol/base/Properties.cpp index d453b0914db7..f4673e403e72 100644 --- a/axmol/base/Properties.cpp +++ b/axmol/base/Properties.cpp @@ -428,7 +428,7 @@ signed char Properties::readChar() { if (eof()) return EOF; - return static_cast(*_data)[(*_dataIdx)++]; + return static_cast(*_data)[(*_dataIdx)++]; } char* Properties::readLine(char* output, int num) @@ -442,7 +442,7 @@ char* Properties::readLine(char* output, int num) for (i = 0; i < num && dataIdx + i < _data->size(); i++) { - auto c = static_cast(*_data)[dataIdx + i]; + auto c = static_cast(*_data)[dataIdx + i]; if (c == '\n') break; output[i] = c; diff --git a/axmol/base/RefPtr.h b/axmol/base/RefPtr.h index f05798804c2f..b4fad348d5c7 100644 --- a/axmol/base/RefPtr.h +++ b/axmol/base/RefPtr.h @@ -38,7 +38,7 @@ namespace ax { template -using retain_ptr = axstd::retain_ptr>; +using retain_ptr = tlx::retain_ptr>; template using RefPtr = retain_ptr; diff --git a/axmol/base/Scheduler.cpp b/axmol/base/Scheduler.cpp index ab5c3fc26c4b..e1aa499851cc 100644 --- a/axmol/base/Scheduler.cpp +++ b/axmol/base/Scheduler.cpp @@ -343,20 +343,20 @@ void Scheduler::unschedule(std::string_view key, void* target) } } -void Scheduler::priorityIn(axstd::pod_vector& list, +void Scheduler::priorityIn(tlx::pod_vector& list, const ccSchedulerFunc& callback, void* target, int priority, bool paused) { auto sched = new SchedHandle(&list, callback, target, priority, paused); - axstd::insert_sorted(list, sched, + tlx::ordered_insert(list, sched, [](const SchedHandle* lhs, const SchedHandle* rhs) { return lhs->priority < rhs->priority; }); _schedIndexMap.emplace(target, sched); } -void Scheduler::appendIn(axstd::pod_vector& list, +void Scheduler::appendIn(tlx::pod_vector& list, const ccSchedulerFunc& callback, void* target, bool paused) @@ -385,14 +385,14 @@ void Scheduler::activeWaitList() else if (sched->priority > 0) { sched->owner = &_updatesPosList; - axstd::insert_sorted(_updatesPosList, sched, [](const SchedHandle* lhs, const SchedHandle* rhs) { + tlx::ordered_insert(_updatesPosList, sched, [](const SchedHandle* lhs, const SchedHandle* rhs) { return lhs->priority < rhs->priority; }); } else { sched->owner = &_updatesNegList; - axstd::insert_sorted(_updatesNegList, sched, [](const SchedHandle* lhs, const SchedHandle* rhs) { + tlx::ordered_insert(_updatesNegList, sched, [](const SchedHandle* lhs, const SchedHandle* rhs) { return lhs->priority < rhs->priority; }); } @@ -474,7 +474,7 @@ void Scheduler::unscheduleUpdate(void* target) if (!_indexMapLocked) { - axstd::erase(*sched->owner, sched); + tlx::erase(*sched->owner, sched); delete sched; } else @@ -500,7 +500,7 @@ void Scheduler::unscheduleAllWithMinPriority(int minPriority) unscheduleAllForTarget(timerIt); } - axstd::pod_vector targets; + tlx::pod_vector targets; for (auto&& entry : _waitList) { @@ -822,7 +822,7 @@ void Scheduler::update(float dt) // delete all updates that are removed in update for (auto&& sched : _updateDeleteVector) { - axstd::erase(*sched->owner, sched); + tlx::erase(*sched->owner, sched); delete sched; } diff --git a/axmol/base/Scheduler.h b/axmol/base/Scheduler.h index 1a4202e22f1c..6162994e2e98 100644 --- a/axmol/base/Scheduler.h +++ b/axmol/base/Scheduler.h @@ -32,7 +32,7 @@ THE SOFTWARE. #include #include #include -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" #include "axmol/base/Object.h" #include "axmol/base/Vector.h" @@ -156,11 +156,11 @@ class AX_DLL TimerScriptHandler : public Timer struct SchedHandle { - SchedHandle(axstd::pod_vector* o, const ccSchedulerFunc& cb, void* t, int pri, bool psd) noexcept + SchedHandle(tlx::pod_vector* o, const ccSchedulerFunc& cb, void* t, int pri, bool psd) noexcept : owner(o), callback(cb), target(t), priority(pri), paused(psd) {} SchedHandle(const SchedHandle&) = delete; - axstd::pod_vector* owner; // the owner sched list of this sched + tlx::pod_vector* owner; // the owner sched list of this sched ccSchedulerFunc callback; void* target; int priority; @@ -484,12 +484,12 @@ class AX_DLL Scheduler : public Object // update specific - void priorityIn(axstd::pod_vector& list, + void priorityIn(tlx::pod_vector& list, const ccSchedulerFunc& callback, void* target, int priority, bool paused); - void appendIn(axstd::pod_vector& list, const ccSchedulerFunc& callback, void* target, bool paused); + void appendIn(tlx::pod_vector& list, const ccSchedulerFunc& callback, void* target, bool paused); void addToWaitList(const ccSchedulerFunc& callback, void* target, int priority, bool paused); @@ -499,19 +499,19 @@ class AX_DLL Scheduler : public Object float _timeScale; - axstd::pod_vector _waitList; // list wait active + tlx::pod_vector _waitList; // list wait active // // "updates with priority" stuff // - axstd::pod_vector _updatesNegList; // list of priority < 0 - axstd::pod_vector _updates0List; // list priority == 0 - axstd::pod_vector _updatesPosList; // list priority > 0 + tlx::pod_vector _updatesNegList; // list of priority < 0 + tlx::pod_vector _updates0List; // list priority == 0 + tlx::pod_vector _updatesPosList; // list priority > 0 // weak reference SchedHandle map used to fetch quickly the list entries for pause,delete,etc std::unordered_map _schedIndexMap; // the vector holds list entries that needs to be deleted after update - axstd::pod_vector _updateDeleteVector; + tlx::pod_vector _updateDeleteVector; // Used for "selectors with interval" std::unordered_map _timersMap; diff --git a/axmol/base/SimpleTimer.cpp b/axmol/base/SimpleTimer.cpp index 63a886ee2b97..fd601ecbea73 100644 --- a/axmol/base/SimpleTimer.cpp +++ b/axmol/base/SimpleTimer.cpp @@ -24,7 +24,7 @@ THE SOFTWARE. #include "axmol/base/SimpleTimer.h" #include "yasio/object_pool.hpp" -#include "yasio/ref_ptr.hpp" +#include "axmol/tlx/memory.hpp" #include "axmol/base/Director.h" #include "axmol/base/Scheduler.h" @@ -74,7 +74,7 @@ TIMER_ID loop(unsigned int n, float interval, vcallback_t callback, bool bNative { if (n > 0 && interval >= 0) { - yasio::ref_ptr timerObj(new TimerObject(std::move(callback))); + tlx::retain_ptr timerObj(new TimerObject(std::move(callback)), tlx::adopt_object); auto timerId = reinterpret_cast(++TimerObject::s_timerId); @@ -94,7 +94,7 @@ TIMER_ID delay(float delay, vcallback_t callback, bool bNative) { if (delay > 0) { - yasio::ref_ptr timerObj(new TimerObject(std::move(callback))); + tlx::retain_ptr timerObj(new TimerObject(std::move(callback)), tlx::adopt_object); auto timerId = reinterpret_cast(++TimerObject::s_timerId); std::string key = fmt::format("STMR#{}", fmt::ptr(timerId)); diff --git a/axmol/base/UserDefault.cpp b/axmol/base/UserDefault.cpp index 3df2a62f8d46..a7b36ca5a017 100644 --- a/axmol/base/UserDefault.cpp +++ b/axmol/base/UserDefault.cpp @@ -71,7 +71,7 @@ std::string UserDefault::_userDefaultFileName = "UserDefault.bin"; std::string UserDefault::_userDefaultFileName = "UserDefault.xml"; #endif -static void ud_setkey(std::string& lhs, const cxx17::string_view& rhs) +static void ud_setkey(std::string& lhs, const std::string_view& rhs) { static const size_t keyLen = 16; if (!rhs.empty()) @@ -84,7 +84,7 @@ static void ud_setkey(std::string& lhs, const cxx17::string_view& rhs) lhs.assign(keyLen, '\0'); } -static void ud_write_v_s(UserDefault* ud, yasio::obstream& obs, const cxx17::string_view value) +static void ud_write_v_s(UserDefault* ud, yasio::obstream& obs, const std::string_view value) { size_t value_offset = obs.length(); obs.write_v(value); @@ -93,7 +93,7 @@ static void ud_write_v_s(UserDefault* ud, yasio::obstream& obs, const cxx17::str ud->encrypt(obs.data() + value_offset, value.length(), AES_ENCRYPT); } -void UserDefault::setEncryptEnabled(bool enabled, cxx17::string_view key, cxx17::string_view iv) +void UserDefault::setEncryptEnabled(bool enabled, std::string_view key, std::string_view iv) { _encryptEnabled = enabled; if (_encryptEnabled) diff --git a/axmol/base/UserDefault.h b/axmol/base/UserDefault.h index 95f04e164a56..68f05079af5e 100644 --- a/axmol/base/UserDefault.h +++ b/axmol/base/UserDefault.h @@ -28,10 +28,9 @@ THE SOFTWARE. #include "axmol/platform/PlatformMacros.h" #include - +#include #include #include "mio/mio.hpp" -#include "yasio/string_view.hpp" #include "axmol/platform/FileStream.h" /** @@ -225,7 +224,7 @@ class AX_DLL UserDefault ** key: 16bytes key ** iv: 16bytes iv */ - virtual void setEncryptEnabled(bool enabled, cxx17::string_view key, cxx17::string_view iv); + virtual void setEncryptEnabled(bool enabled, std::string_view key, std::string_view iv); /* * Mark encrypt function as virtual, default use AES cfb128 encrypt/decrypt @@ -259,7 +258,7 @@ class AX_DLL UserDefault void updateValueForKey(std::string_view key, std::string_view value); protected: - axstd::string_map _values; + tlx::string_map _values; static UserDefault* _userDefault; static std::string _userDefaultFileName; diff --git a/axmol/base/Utils.cpp b/axmol/base/Utils.cpp index fd70d9a879b9..277477dc4974 100644 --- a/axmol/base/Utils.cpp +++ b/axmol/base/Utils.cpp @@ -57,7 +57,7 @@ THE SOFTWARE. #include "axmol/tlx/byte_buffer.hpp" #include "axmol/tlx/charconv.hpp" #include "axmol/tlx/utility.hpp" -#include "yasio/string_view.hpp" +#include "yasio/tlx/string_view.hpp" using namespace std::string_view_literals; @@ -230,7 +230,7 @@ double atof(std::string_view str) return 0.0; double ret{0.0}; - axstd::from_chars(str.data(), str.data() + str.size(), ret); + tlx::from_chars(str.data(), str.data() + str.size(), ret); return ret; } @@ -818,12 +818,12 @@ AX_DLL std::string&& filePathToUrl(std::string&& path) { if (path[0] == '/') path.insert(0, LOCAL_FILE_URL_PREFIX.data(), LOCAL_FILE_URL_PREFIX.length() - 1); - else if (!cxx20::ic::starts_with(path, LOCAL_FILE_URL_PREFIX)) + else if (!tlx::ic::starts_with(path, LOCAL_FILE_URL_PREFIX)) { #if !defined(__ANDROID__) path.insert(0, LOCAL_FILE_URL_PREFIX.data(), LOCAL_FILE_URL_PREFIX.length()); #else - if (!cxx20::starts_with(path, "assets/"sv)) // not android asset + if (!tlx::starts_with(path, "assets/"sv)) // not android asset path.insert(0, LOCAL_FILE_URL_PREFIX.data(), LOCAL_FILE_URL_PREFIX.length()); else path.replace(0, "assets/"sv.length(), "file:///android_asset/"); @@ -848,7 +848,7 @@ AX_DLL std::string base64Encode(const void* in, size_t inlen) * */ - axstd::resize_and_overrite(ret, n, + tlx::resize_and_overrite(ret, n, [in, inlen](char* out, size_t) { return ax::base64::encode(out, in, inlen); }); return ret; @@ -856,16 +856,16 @@ AX_DLL std::string base64Encode(const void* in, size_t inlen) return std::string{}; } -AX_DLL yasio::byte_buffer base64Decode(std::string_view s) +AX_DLL tlx::byte_buffer base64Decode(std::string_view s) { size_t n = ax::base64::decoded_size(s.length()); if (n > 0) { - axstd::byte_buffer ret; + tlx::byte_buffer ret; ret.resize_and_overwrite(n, [&s](uint8_t* out, size_t) { return ax::base64::decode(out, s.data(), s.size()); }); return ret; } - return yasio::byte_buffer{}; + return tlx::byte_buffer{}; } int base64Encode(const unsigned char* in, unsigned int inLength, char** out) @@ -932,7 +932,7 @@ inline bool expect(const char*& p, const char* end, char c) inline bool parse_float(const char*& p, const char* end, float& out) { skip_ws(p, end); - auto fc = axstd::from_chars(p, end, out); + auto fc = tlx::from_chars(p, end, out); if (fc.ec != std::errc{}) [[unlikely]] return false; p = fc.ptr; diff --git a/axmol/base/Utils.h b/axmol/base/Utils.h index e277113128a8..6304f1765e11 100644 --- a/axmol/base/Utils.h +++ b/axmol/base/Utils.h @@ -288,7 +288,7 @@ AX_DLL void killCurrentProcess(); template static RefPtr makeInstance(F&& memf, Ts&&... args) { - RefPtr pRet(new T(), axstd::adopt_object); + RefPtr pRet(new T(), tlx::adopt_object); if (pRet && std::mem_fn(memf)(pRet.get(), std::forward(args)...)) return pRet; @@ -451,7 +451,7 @@ inline std::string base64Encode(std::span<_Ty, _Extent> in) * @since axmol-1.0.0 */ -AX_DLL yasio::byte_buffer base64Decode(std::string_view s); +AX_DLL tlx::byte_buffer base64Decode(std::string_view s); /** * Encodes bytes into a 64base encoded memory with terminating '\0' character. diff --git a/axmol/base/Value.h b/axmol/base/Value.h index 78209b7404ac..d01ae4ace4c4 100644 --- a/axmol/base/Value.h +++ b/axmol/base/Value.h @@ -43,7 +43,7 @@ namespace ax class Value; typedef std::vector ValueVector; -typedef axstd::string_map ValueMap; +typedef tlx::string_map ValueMap; typedef std::unordered_map ValueMapIntKey; AX_DLL extern const ValueVector ValueVectorNull; diff --git a/axmol/base/Vector.h b/axmol/base/Vector.h index af6e8cc30193..28eae9c5f93f 100644 --- a/axmol/base/Vector.h +++ b/axmol/base/Vector.h @@ -111,7 +111,7 @@ class Vector const_reverse_iterator crend() const { return _data.crend(); } /** Constructor. */ - Vector() : _data() { static_assert(axstd::is_ref_counted_v, "Invalid Type for ax::Vector!"); } + Vector() : _data() { static_assert(tlx::is_ref_counted_v, "Invalid Type for ax::Vector!"); } /** * Constructor with a capacity. @@ -119,7 +119,7 @@ class Vector */ explicit Vector(ssize_t capacity) : _data() { - static_assert(axstd::is_ref_counted_v, "Invalid Type for ax::Vector!"); + static_assert(tlx::is_ref_counted_v, "Invalid Type for ax::Vector!"); AXLOGV("In the default constructor with capacity of Vector."); reserve(capacity); } @@ -143,7 +143,7 @@ class Vector /** Copy constructor. */ Vector(const Vector& other) { - static_assert(axstd::is_ref_counted_v, "Invalid Type for ax::Vector!"); + static_assert(tlx::is_ref_counted_v, "Invalid Type for ax::Vector!"); AXLOGV("In the copy constructor!"); _data = other._data; addRefForAllObjects(); @@ -152,7 +152,7 @@ class Vector /** Constructor with std::move semantic. */ Vector(Vector&& other) { - static_assert(axstd::is_ref_counted_v, "Invalid Type for ax::Vector!"); + static_assert(tlx::is_ref_counted_v, "Invalid Type for ax::Vector!"); AXLOGV("In the move constructor of Vector!"); _data = std::move(other._data); } diff --git a/axmol/base/ZipUtils.cpp b/axmol/base/ZipUtils.cpp index 86342abe1bec..52ec0bc01b4d 100644 --- a/axmol/base/ZipUtils.cpp +++ b/axmol/base/ZipUtils.cpp @@ -48,8 +48,6 @@ #include #include -#include "yasio/string_view.hpp" - // minizip 1.2.0 is same with other platforms #define unzGoToFirstFile64(A, B, C, D) unzGoToFirstFile2(A, B, C, D, NULL, 0, NULL, 0) #define unzGoToNextFile64(A, B, C, D) unzGoToNextFile2(A, B, C, D, NULL, 0, NULL, 0) @@ -63,7 +61,7 @@ bool ZipUtils::s_bEncryptionKeyIsValid = false; // --------------------- ZipUtils --------------------- -yasio::byte_buffer ZipUtils::compressGZ(const void* in, size_t inlen, int level) +tlx::byte_buffer ZipUtils::compressGZ(const void* in, size_t inlen, int level) { int err; Bytef buffer[512]; @@ -77,7 +75,7 @@ yasio::byte_buffer ZipUtils::compressGZ(const void* in, size_t inlen, int level) d_stream.avail_in = static_cast(inlen); d_stream.next_out = buffer; d_stream.avail_out = sizeof(buffer); - yasio::byte_buffer output; + tlx::byte_buffer output; err = deflateInit2(&d_stream, level, Z_DEFLATED, MAX_WBITS + 16 /*well: normaly, gzip is: 16*/, MAX_MEM_LEVEL - 1, Z_DEFAULT_STRATEGY); if (err != Z_OK) // @@ -112,7 +110,7 @@ yasio::byte_buffer ZipUtils::compressGZ(const void* in, size_t inlen, int level) return output; } -yasio::byte_buffer ZipUtils::decompressGZ(const void* in, size_t inlen, int expected_size) +tlx::byte_buffer ZipUtils::decompressGZ(const void* in, size_t inlen, int expected_size) { // inflate int err; Bytef buffer[512]; @@ -126,7 +124,7 @@ yasio::byte_buffer ZipUtils::decompressGZ(const void* in, size_t inlen, int expe d_stream.avail_in = static_cast(inlen); d_stream.next_out = buffer; d_stream.avail_out = sizeof(buffer); - yasio::byte_buffer output; + tlx::byte_buffer output; err = inflateInit2(&d_stream, MAX_WBITS + 32 /*well: normaly, gzip is: 16*/); if (err != Z_OK) // return output; @@ -286,7 +284,7 @@ ssize_t ZipUtils::inflateMemoryWithHint(unsigned char* in, ssize_t inLength, uns auto outBuffer = decompressGZ(std::span{in, in + inLength}, static_cast(outLengthHint)); auto outLen = outBuffer.size(); if (out) - *out = outBuffer.release_pointer(); + *out = outBuffer.detach_abi(); return outLen; } @@ -312,7 +310,7 @@ int ZipUtils::inflateGZipFile(const char* path, unsigned char** out) } /* 512k initial decompress buffer */ - yasio::byte_buffer buffer; + tlx::byte_buffer buffer; buffer.reserve(512); uint8_t readBuffer[512]; @@ -330,7 +328,7 @@ int ZipUtils::inflateGZipFile(const char* path, unsigned char** out) break; } - buffer.append(readBuffer, readBuffer + 512); + buffer.extend(readBuffer, readBuffer + 512); } if (gzclose(inFile) != Z_OK) @@ -340,7 +338,7 @@ int ZipUtils::inflateGZipFile(const char* path, unsigned char** out) auto totalSize = buffer.size(); if (out) - *out = buffer.release_pointer(); + *out = buffer.detach_abi(); return static_cast(totalSize); } @@ -467,7 +465,7 @@ int ZipUtils::inflateCCZBuffer(const unsigned char* buffer, ssize_t bufferLen, u return -1; } - axstd::byte_buffer outBuffer(len); + tlx::byte_buffer outBuffer(len); unsigned long destlen = len; size_t source = (size_t)buffer + sizeof(*header); @@ -478,7 +476,7 @@ int ZipUtils::inflateCCZBuffer(const unsigned char* buffer, ssize_t bufferLen, u AXLOGW("CCZ: Failed to uncompress data"); return -1; } - *out = outBuffer.release_pointer(); + *out = outBuffer.detach_abi(); return len; } @@ -660,7 +658,7 @@ struct ZipFilePrivate std::unique_ptr memfs; // std::unordered_map is faster if available on the platform - typedef axstd::string_map FileListContainer; + typedef tlx::string_map FileListContainer; FileListContainer fileList; zlib_filefunc64_def functionOverrides{}; @@ -786,7 +784,7 @@ std::vector ZipFile::listFiles(std::string_view pathname) const for (auto&& item : _data->fileList) { std::string_view filename = item.first; - if (cxx20::starts_with(filename, cxx17::string_view{dirname})) + if (tlx::starts_with(filename, std::string_view{dirname})) { std::string_view suffix{filename.substr(dirname.length())}; auto pos = suffix.find('/'); diff --git a/axmol/base/ZipUtils.h b/axmol/base/ZipUtils.h index 27e295e01529..d034de3f9a87 100644 --- a/axmol/base/ZipUtils.h +++ b/axmol/base/ZipUtils.h @@ -78,18 +78,18 @@ class AX_DLL ZipUtils { public: template - inline static yasio::byte_buffer compressGZ(std::span<_Ty, _Extent> in, int level = -1) + inline static tlx::byte_buffer compressGZ(std::span<_Ty, _Extent> in, int level = -1) { return compressGZ(in.data(), in.size_bytes(), level); } template - inline static yasio::byte_buffer decompressGZ(std::span<_Ty, _Extent> in, int expected_size = -1) + inline static tlx::byte_buffer decompressGZ(std::span<_Ty, _Extent> in, int expected_size = -1) { return decompressGZ(in.data(), in.size_bytes(), expected_size); } - static yasio::byte_buffer compressGZ(const void* in, size_t inlen, int level = -1); - static yasio::byte_buffer decompressGZ(const void* in, size_t inlen, int expected_size = -1); + static tlx::byte_buffer compressGZ(const void* in, size_t inlen, int level = -1); + static tlx::byte_buffer decompressGZ(const void* in, size_t inlen, int expected_size = -1); /** * Inflates either zlib or gzip deflated memory. The inflated memory is expected to be freed by the caller. diff --git a/axmol/base/astc.cpp b/axmol/base/astc.cpp index badc08fe2905..72cd67dc73ad 100644 --- a/axmol/base/astc.cpp +++ b/axmol/base/astc.cpp @@ -20,7 +20,7 @@ #include #include "astcenc/astcenc.h" #include "astcenc/astcenc_internal_entry.h" -#include "yasio/utils.hpp" +#include "yasio/tlx/chrono.hpp" #include "axmol/base/Director.h" @@ -215,13 +215,13 @@ template struct benchmark_printer { benchmark_printer(_FMT&& fmt, int w, int h, float den) - : _fmt(fmt), _w(w), _h(h), _den(den), _start(yasio::highp_clock()) + : _fmt(fmt), _w(w), _h(h), _den(den), _start(tlx::highp_clock()) {} - ~benchmark_printer() { AXLOGI("{}", fmt::format(_fmt, _w, _h, (yasio::highp_clock() - _start) / _den)); } + ~benchmark_printer() { AXLOGI("{}", fmt::format(_fmt, _w, _h, (tlx::highp_clock() - _start) / _den)); } _FMT _fmt; int _w, _h; float _den; - yasio::highp_time_t _start; + tlx::highp_time_t _start; }; int astc_decompress_image(const uint8_t* in, uint32_t inlen, diff --git a/axmol/media/AndroidMediaEngine.h b/axmol/media/AndroidMediaEngine.h index 2a98b06d1f30..90294cad4d49 100644 --- a/axmol/media/AndroidMediaEngine.h +++ b/axmol/media/AndroidMediaEngine.h @@ -77,8 +77,8 @@ class AndroidMediaEngine : public MediaEngine int _videoRotation{0}; int _videoPF{-1}; - yasio::byte_buffer _frameBuffer1; // for write - yasio::byte_buffer _frameBuffer2; // for read + tlx::byte_buffer _frameBuffer1; // for write + tlx::byte_buffer _frameBuffer2; // for read mutable std::mutex _frameBuffer1Mtx; double _currentTime{}; diff --git a/axmol/media/AvfMediaEngine.mm b/axmol/media/AvfMediaEngine.mm index fef2c9dbd6b2..76c8c7dc1323 100644 --- a/axmol/media/AvfMediaEngine.mm +++ b/axmol/media/AvfMediaEngine.mm @@ -193,7 +193,7 @@ - (void)observeValueForKeyPath:(NSString*)keyPath NSURL* nsMediaUrl = nil; std::string_view Path; - if (cxx20::starts_with(sourceUri, "file://"sv)) + if (tlx::starts_with(sourceUri, "file://"sv)) { // Media Framework doesn't percent encode the URL, so the path portion is just a native file path. // Extract it and then use it create a proper URL. diff --git a/axmol/media/MediaEngine.cpp b/axmol/media/MediaEngine.cpp index f8c2a7c5508e..416c9554edb8 100644 --- a/axmol/media/MediaEngine.cpp +++ b/axmol/media/MediaEngine.cpp @@ -40,7 +40,7 @@ # include "axmol/media/VlcMediaEngine.h" #endif -namespace axstd +namespace tlx { // static_pointer_cast overload for std::shared_ptr using std::static_pointer_cast; @@ -56,7 +56,7 @@ std::unique_ptr static_pointer_cast(std::unique_ptr&& r) return std::unique_ptr(static_cast(r.release())); } -} // namespace axstd +} // namespace tlx namespace ax { @@ -66,19 +66,19 @@ std::unique_ptr MediaEngineFactory::create() #if defined(WINAPI_FAMILY) # if WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP && !defined(AXME_USE_IMFME) # if defined(AX_ENABLE_MFMEDIA) - return axstd::static_pointer_cast(std::make_unique()); + return tlx::static_pointer_cast(std::make_unique()); # elif defined(AX_ENABLE_VLC_MEDIA) - return axstd::static_pointer_cast(std::make_unique()); + return tlx::static_pointer_cast(std::make_unique()); # endif # else - return axstd::static_pointer_cast(std::make_unique()); + return tlx::static_pointer_cast(std::make_unique()); # endif #elif defined(__APPLE__) - return axstd::static_pointer_cast(std::make_unique()); + return tlx::static_pointer_cast(std::make_unique()); #elif defined(__ANDROID__) - return axstd::static_pointer_cast(std::make_unique()); + return tlx::static_pointer_cast(std::make_unique()); #elif defined(__linux__) && defined(AX_ENABLE_VLC_MEDIA) - return axstd::static_pointer_cast(std::make_unique()); + return tlx::static_pointer_cast(std::make_unique()); #else return nullptr; #endif diff --git a/axmol/media/MediaEngine.h b/axmol/media/MediaEngine.h index 487dcaede3a0..08b715cbb5d9 100644 --- a/axmol/media/MediaEngine.h +++ b/axmol/media/MediaEngine.h @@ -45,8 +45,8 @@ #include #include -#include "yasio/string_view.hpp" -#include "yasio/byte_buffer.hpp" +#include "yasio/tlx/string_view.hpp" +#include "axmol/tlx/byte_buffer.hpp" using namespace std::string_view_literals; diff --git a/axmol/media/VlcMediaEngine.h b/axmol/media/VlcMediaEngine.h index bcef0fcf2986..fbe2384eabf9 100644 --- a/axmol/media/VlcMediaEngine.h +++ b/axmol/media/VlcMediaEngine.h @@ -92,8 +92,8 @@ class VlcMediaEngine : public MediaEngine std::string _videoCodecMimeType; - yasio::byte_buffer _frameBuffer1; // for write - yasio::byte_buffer _frameBuffer2; // for read + tlx::byte_buffer _frameBuffer1; // for write + tlx::byte_buffer _frameBuffer2; // for read mutable std::mutex _frameBuffer1Mtx; }; diff --git a/axmol/media/WmfMediaEngine.h b/axmol/media/WmfMediaEngine.h index 849b72346290..d9c0ea4318d8 100644 --- a/axmol/media/WmfMediaEngine.h +++ b/axmol/media/WmfMediaEngine.h @@ -55,7 +55,7 @@ # include # include -# include "yasio/byte_buffer.hpp" +# include "axmol/tlx/byte_buffer.hpp" namespace ax { @@ -283,8 +283,8 @@ class WmfMediaEngine : public IMFAsyncCallback, public MediaEngine MEVideoPixelFormat m_videoPF = MEVideoPixelFormat::INVALID; mutable std::mutex m_frameBuffer1Mtx; - yasio::byte_buffer m_frameBuffer1; // for write - yasio::byte_buffer m_frameBuffer2; // for read + tlx::byte_buffer m_frameBuffer1; // for write + tlx::byte_buffer m_frameBuffer2; // for read }; struct WmfMediaEngineFactory : public MediaEngineFactory diff --git a/axmol/network/HttpClient-wasm.cpp b/axmol/network/HttpClient-wasm.cpp index ebf14452cd8f..3a3e3557e023 100644 --- a/axmol/network/HttpClient-wasm.cpp +++ b/axmol/network/HttpClient-wasm.cpp @@ -210,7 +210,7 @@ void HttpClient::processResponse(HttpResponse* response, bool isAlone) size_t pos = header.find(":"); if (pos != std::string::npos) { - if (cxx20::ic::starts_with(header, "user-agent")) + if (tlx::ic::starts_with(header, "user-agent")) { AXLOGW("Ignore user-agent for wasm to avoid cause error: Refused to set unsafe header \"User-Agent\""); continue; @@ -250,7 +250,7 @@ void HttpClient::processResponse(HttpResponse* response, bool isAlone) void HttpClient::onRequestComplete(emscripten_fetch_t* fetch) { fetchUserData* userData = reinterpret_cast(fetch->userData); - axstd::retain_ptr response{userData->response, axstd::adopt_object}; + tlx::retain_ptr response{userData->response, tlx::adopt_object}; HttpRequest* request = response->getHttpRequest(); // get response diff --git a/axmol/network/HttpClient.cpp b/axmol/network/HttpClient.cpp index cf158604d9d3..16b58448d05b 100644 --- a/axmol/network/HttpClient.cpp +++ b/axmol/network/HttpClient.cpp @@ -327,17 +327,16 @@ void HttpClient::handleNetworkEvent(yasio::io_event* event) auto& headers = request->getHeaders(); if (!headers.empty()) { - using namespace cxx17; // for string_view literal for (auto&& header : headers) { obs.write_bytes(header); obs.write_bytes("\r\n"); - if (cxx20::ic::starts_with(cxx17::string_view{header}, "User-Agent:"_sv)) + if (tlx::ic::starts_with(std::string_view{header}, "User-Agent:"sv)) headerFlags |= HeaderFlag::UESR_AGENT; - else if (cxx20::ic::starts_with(cxx17::string_view{header}, "Content-Type:"_sv)) + else if (tlx::ic::starts_with(std::string_view{header}, "Content-Type:"sv)) headerFlags |= HeaderFlag::CONTENT_TYPE; - else if (cxx20::ic::starts_with(cxx17::string_view{header}, "Accept:"_sv)) + else if (tlx::ic::starts_with(std::string_view{header}, "Accept:"sv)) headerFlags |= HeaderFlag::ACCEPT; } } @@ -371,7 +370,7 @@ void HttpClient::handleNetworkEvent(yasio::io_event* event) obs.write_bytes(strConentLen); if (requestData && requestDataSize > 0) - obs.write_bytes(cxx17::string_view{requestData, static_cast(requestDataSize)}); + obs.write_bytes(std::string_view{requestData, static_cast(requestDataSize)}); } else { diff --git a/axmol/network/HttpCookie.cpp b/axmol/network/HttpCookie.cpp index c936c1dc0d92..dda48cf0b30a 100644 --- a/axmol/network/HttpCookie.cpp +++ b/axmol/network/HttpCookie.cpp @@ -27,8 +27,7 @@ #include "axmol/network/HttpCookie.h" #include "axmol/network/Uri.h" #include "axmol/platform/FileUtils.h" -#include "yasio/utils.hpp" -#include "yasio/string_view.hpp" +#include "yasio/tlx/chrono.hpp" #include #include @@ -62,13 +61,12 @@ void HttpCookie::readFile() std::string inString = FileUtils::getInstance()->getStringFromFile(_cookieFileName); if (!inString.empty()) { - axstd::split_cb(&inString.front(), inString.length(), '\n', [this](char* s, char* e) { + tlx::split_cb(&inString.front(), inString.length(), '\n', [this](char* s, char* e) { if (*s == '#') // skip comment return; int count = 0; CookieInfo cookieInfo; - using namespace cxx17; - axstd::split_cb(s, e - s, '\t', [&, this](char* ss, char* ee) { + tlx::split_cb(s, e - s, '\t', [&, this](char* ss, char* ee) { auto ch = *ee; // store *ee = '\0'; switch (count) @@ -80,7 +78,7 @@ void HttpCookie::readFile() cookieInfo.path.assign(ss, ee - ss); break; case SECURE_INDEX: - cookieInfo.secure = cxx17::string_view{ss, (size_t)(ee - ss)} == "TRUE"_sv; + cookieInfo.secure = std::string_view{ss, (size_t)(ee - ss)} == "TRUE"sv; break; case EXPIRES_INDEX: cookieInfo.expires = static_cast(strtoll(ss, nullptr, 10)); @@ -110,7 +108,7 @@ const CookieInfo* HttpCookie::getMatchCookie(const Uri& uri) const { for (auto&& cookie : _cookies) { - if (cxx20::ends_with(uri.getHost(), cookie.domain) && cxx20::starts_with(uri.getPath(), cookie.path)) + if (tlx::ends_with(uri.getHost(), cookie.domain) && tlx::starts_with(uri.getPath(), cookie.path)) return &cookie; } @@ -136,9 +134,9 @@ std::string HttpCookie::checkAndGetFormatedMatchCookies(const Uri& uri) for (auto iter = _cookies.begin(); iter != _cookies.end();) { auto& cookie = *iter; - if (cxx20::ends_with(uri.getHost(), cookie.domain) && cxx20::starts_with(uri.getPath(), cookie.path)) + if (tlx::ends_with(uri.getHost(), cookie.domain) && tlx::starts_with(uri.getPath(), cookie.path)) { - if (yasio::time_now() >= cookie.expires) + if (tlx::time_now() >= cookie.expires) { iter = _cookies.erase(iter); continue; @@ -162,41 +160,40 @@ bool HttpCookie::updateOrAddCookie(std::string_view cookie, const Uri& uri) unsigned int count = 0; CookieInfo info; - axstd::split_cb(cookie.data(), cookie.length(), ';', [&](const char* start, const char* end) { + tlx::split_cb(cookie.data(), cookie.length(), ';', [&](const char* start, const char* end) { unsigned int count_ = 0; while (*start == ' ') ++start; // skip ws if (++count > 1) { - cxx17::string_view key; - cxx17::string_view value; - axstd::split_cb(start, end - start, '=', [&](const char* s, const char* e) { + std::string_view key; + std::string_view value; + tlx::split_cb(start, end - start, '=', [&](const char* s, const char* e) { switch (++count_) { case 1: - key = cxx17::string_view(s, e - s); + key = std::string_view(s, e - s); break; case 2: - value = cxx17::string_view(s, e - s); + value = std::string_view(s, e - s); break; } }); - using namespace cxx17; - if (cxx20::ic::iequals(key, "domain"_sv)) + if (tlx::ic::iequals(key, "domain"sv)) { if (!value.empty()) info.domain.assign(value.data(), value.length()); } - else if (cxx20::ic::iequals(key, "path"_sv)) + else if (tlx::ic::iequals(key, "path"sv)) { if (!value.empty()) info.path.assign(value.data(), value.length()); } - else if (cxx20::ic::iequals(key, "expires"_sv)) + else if (tlx::ic::iequals(key, "expires"sv)) { std::string expires_ctime(!value.empty() ? value.data() : "", value.length()); - if (cxx20::ends_with(expires_ctime, " GMT"_sv)) + if (tlx::ends_with(expires_ctime, " GMT"sv)) expires_ctime.resize(expires_ctime.length() - sizeof(" GMT") + 1); if (expires_ctime.empty()) return; @@ -224,14 +221,14 @@ bool HttpCookie::updateOrAddCookie(std::string_view cookie, const Uri& uri) info.expires = mktime(&dt); } } - else if (cxx20::ic::iequals(key, "secure"_sv)) + else if (tlx::ic::iequals(key, "secure"sv)) { info.secure = true; } } else { // first is cookie name - axstd::split_cb(start, end - start, '=', [&](const char* s, const char* e) { + tlx::split_cb(start, end - start, '=', [&](const char* s, const char* e) { switch (++count_) { case 1: diff --git a/axmol/network/HttpRequest.h b/axmol/network/HttpRequest.h index 2e90d73f94e1..c8f4a59d7208 100644 --- a/axmol/network/HttpRequest.h +++ b/axmol/network/HttpRequest.h @@ -35,7 +35,7 @@ #include "axmol/base/Object.h" #include "axmol/base/Macros.h" -#include "yasio/byte_buffer.hpp" +#include "axmol/tlx/byte_buffer.hpp" #include "axmol/network/ConcurrentRefCountedBase.h" @@ -301,7 +301,7 @@ class AX_DLL HttpRequest : public ConcurrentRefCountedBase // properties Type _requestType; /// kHttpRequestGet, kHttpRequestPost or other enums std::string _url; /// target url that this request is sent to - yasio::sbyte_buffer _requestData; /// used for POST + tlx::sbyte_buffer _requestData; /// used for POST std::string _tag; /// user defined tag, to identify different requests in response callback ccHttpRequestCallback _pCallback; /// C++11 style callbacks HttpDataCallback _pDataCallback; diff --git a/axmol/network/HttpResponse.h b/axmol/network/HttpResponse.h index 115298c6cb34..b1ed5011a1a9 100644 --- a/axmol/network/HttpResponse.h +++ b/axmol/network/HttpResponse.h @@ -106,9 +106,9 @@ class AX_DLL HttpResponse : public ConcurrentRefCountedBase /** * Get the http response data. - * @return yasio::sbyte_buffer* the pointer that point to the _responseData. + * @return tlx::sbyte_buffer* the pointer that point to the _responseData. */ - yasio::sbyte_buffer* getResponseData() { return &_responseData; } + tlx::sbyte_buffer* getResponseData() { return &_responseData; } bool isSucceed() const { return _responseCode == 200; } @@ -304,7 +304,7 @@ class AX_DLL HttpResponse : public ConcurrentRefCountedBase Uri _requestUri; bool _finished = false; /// to indicate if the http request is successful simply uint64_t _contentLength{0}; - yasio::sbyte_buffer _responseData; /// the returned raw data. You can also dump it as a string + tlx::sbyte_buffer _responseData; /// the returned raw data. You can also dump it as a string std::string _currentHeader; std::string _currentHeaderValue; ResponseHeaderMap _responseHeaders; /// the returned raw header data. You can also dump it as a string diff --git a/axmol/network/WebSocket-wasm.h b/axmol/network/WebSocket-wasm.h index f6b8a4186b57..9a8d6c6674dd 100644 --- a/axmol/network/WebSocket-wasm.h +++ b/axmol/network/WebSocket-wasm.h @@ -27,7 +27,7 @@ #include "axmol/platform/PlatformMacros.h" #include #include "axmol/base/Object.h" -#include "yasio/byte_buffer.hpp" +#include "axmol/tlx/byte_buffer.hpp" #include diff --git a/axmol/network/WebSocket.cpp b/axmol/network/WebSocket.cpp index 9e8d1f8e42a1..41e283beee67 100644 --- a/axmol/network/WebSocket.cpp +++ b/axmol/network/WebSocket.cpp @@ -184,7 +184,7 @@ struct WebSocketProtocol if (fin) flags |= WS_FIN; auto frame_size = websocket_calc_frame_size((websocket_flags)flags, len); - yasio::sbyte_buffer sb; + tlx::sbyte_buffer sb; sb.resize(frame_size); websocket_build_frame(sb.data(), (websocket_flags)flags, mask, buf, len); return ws._service->write(ws._transport, std::move(sb)); // write(sendbuf_.base, frame_size); @@ -364,7 +364,7 @@ int WebSocket::on_frame_body(websocket_parser* parser, const char* at, size_t le websocket_parser_decode(const_cast(at), at, length, parser); std::unique_lock lck(ws->_receivedDataMtx); - ws->_receivedData.append(at, at + length); + ws->_receivedData.extend(at, at + length); return 0; } diff --git a/axmol/network/WebSocket.h b/axmol/network/WebSocket.h index ee7c6b848a97..b276e4ed9049 100644 --- a/axmol/network/WebSocket.h +++ b/axmol/network/WebSocket.h @@ -50,7 +50,7 @@ # include "axmol/base/Scheduler.h" # include "axmol/base/ConcurrentDeque.h" # include "yasio/yasio_fwd.hpp" -# include "yasio/byte_buffer.hpp" +# include "axmol/tlx/byte_buffer.hpp" # include "axmol/network/Uri.h" # include "llhttp.h" # include "websocket_parser.h" @@ -152,17 +152,17 @@ class AX_DLL WebSocket class MessageEvent : public Event { public: - MessageEvent(yasio::sbyte_buffer&& message, bool isBinary) : _message(std::move(message)), _isBinary(isBinary) + MessageEvent(tlx::sbyte_buffer&& message, bool isBinary) : _message(std::move(message)), _isBinary(isBinary) { this->_type = Type::ON_MESSAGE; } - yasio::sbyte_buffer& getMessage() { return _message; } - const yasio::sbyte_buffer& getMessage() const { return _message; } + tlx::sbyte_buffer& getMessage() { return _message; } + const tlx::sbyte_buffer& getMessage() const { return _message; } bool isBinary() const { return _isBinary; } private: - yasio::sbyte_buffer _message; + tlx::sbyte_buffer _message; bool _isBinary; /* TODO: issued; @@ -429,7 +429,7 @@ class AX_DLL WebSocket std::string _closeReason; // for receiveData - yasio::sbyte_buffer _receivedData; + tlx::sbyte_buffer _receivedData; std::recursive_mutex _receivedDataMtx; EventListenerCustom* _resetDirectorListener; diff --git a/axmol/physics/PhysicsCollider.h b/axmol/physics/PhysicsCollider.h index 06cc317b661b..bf665e055929 100644 --- a/axmol/physics/PhysicsCollider.h +++ b/axmol/physics/PhysicsCollider.h @@ -33,7 +33,7 @@ # include "axmol/math/Math.h" # include "box2d/box2d.h" -# include "axmol/tlx/pod_vector.hpp" +# include "axmol/tlx/vector.hpp" namespace ax { @@ -337,7 +337,7 @@ class AX_DLL PhysicsCollider : public Object protected: PhysicsBody* _body; - axstd::pod_vector _b2Shapes; + tlx::pod_vector _b2Shapes; Type _type; float _area; diff --git a/axmol/physics3d/PhysicsMeshRenderer.cpp b/axmol/physics3d/PhysicsMeshRenderer.cpp index c10d56f3c474..a1ef35acae07 100644 --- a/axmol/physics3d/PhysicsMeshRenderer.cpp +++ b/axmol/physics3d/PhysicsMeshRenderer.cpp @@ -39,7 +39,7 @@ PhysicsMeshRenderer* PhysicsMeshRenderer::create(std::string_view modelPath, auto ret = new PhysicsMeshRenderer(); if (ret->initWithFile(modelPath)) { - ret->setModelTexture(modelPath, axstd::empty_sv); + ret->setModelTexture(modelPath, tlx::empty_sv); auto obj = Physics3DRigidBody::create(rigidDes); ret->_physicsComponent = Physics3DComponent::create(obj, translateInPhysics, rotInPhsyics); ret->addComponent(ret->_physicsComponent); @@ -59,7 +59,7 @@ PhysicsMeshRenderer* PhysicsMeshRenderer::createWithCollider(std::string_view mo auto ret = new PhysicsMeshRenderer(); if (ret->initWithFile(modelPath)) { - ret->setModelTexture(modelPath, axstd::empty_sv); + ret->setModelTexture(modelPath, tlx::empty_sv); auto obj = Physics3DCollider::create(colliderDes); ret->_physicsComponent = Physics3DComponent::create(obj, translateInPhysics, rotInPhsyics); ret->addComponent(ret->_physicsComponent); diff --git a/axmol/platform/FileUtils.cpp b/axmol/platform/FileUtils.cpp index 38c80c09713a..4bf09e912952 100644 --- a/axmol/platform/FileUtils.cpp +++ b/axmol/platform/FileUtils.cpp @@ -46,7 +46,6 @@ THE SOFTWARE. #if defined(_WIN32) # include "ntcvt/ntcvt.hpp" -# include "yasio/string_view.hpp" #endif #include "pugixml/pugixml.hpp" @@ -176,7 +175,7 @@ class DictMaker : public SAXDelegator // add a new dictionary into the pre dictionary AXASSERT(!_dictStack.empty(), "The state is wrong!"); ValueMap* preDict = _dictStack.top(); - auto& curVal = axstd::set_item(*preDict, _curKey, Value(ValueMap()))->second; + auto& curVal = tlx::set_item(*preDict, _curKey, Value(ValueMap()))->second; _curDict = &curVal.asValueMap(); } @@ -572,7 +571,7 @@ FileUtils::Status FileUtils::getContents(std::string_view filename, ResizableBuf std::string FileUtils::getPathForFilename(std::string_view filename, std::string_view searchPath) const { auto file = filename; - std::string_view file_path = axstd::empty_sv; + std::string_view file_path = tlx::empty_sv; size_t pos = filename.find_last_of('/'); if (pos != std::string::npos) { @@ -857,8 +856,8 @@ bool FileUtils::isAbsolutePathInternal(std::string_view path) // see also: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN return ((path.length() > 2 && ((raw[0] >= 'a' && raw[0] <= 'z') || (raw[0] >= 'A' && raw[0] <= 'Z')) && raw[1] == ':') // Normal absolute path - || cxx20::starts_with(path, R"(\\?\)") // Win32 File Namespaces for Long Path - || cxx20::starts_with(path, R"(\\.\)") // Win32 Device Namespaces for device + || tlx::starts_with(path, R"(\\?\)") // Win32 File Namespaces for Long Path + || tlx::starts_with(path, R"(\\.\)") // Win32 Device Namespaces for device || (raw[0] == '/' || raw[0] == '\\') // Current disk drive ); #else @@ -1031,7 +1030,7 @@ bool FileUtils::createDirectories(std::string_view path) const bool fail{false}; std::string mpath{path}; - axstd::splitpath_cb(&mpath.front(), [](char* ptr) { return *ptr != '\0'; }, [&fail](const char* subpath) { + tlx::splitpath_cb(&mpath.front(), [](char* ptr) { return *ptr != '\0'; }, [&fail](const char* subpath) { struct stat st; if (stat(subpath, &st) != 0) { diff --git a/axmol/platform/FileUtils.h b/axmol/platform/FileUtils.h index 8de36d5ad224..84825f3ba62f 100644 --- a/axmol/platform/FileUtils.h +++ b/axmol/platform/FileUtils.h @@ -76,9 +76,9 @@ class ResizableBufferAdapter : public ResizableBuffer void resize_and_overwrite(size_t num_of_bytes, std::function op) override { if constexpr (element_size == 1) - axstd::resize_and_overrite(*_cont, num_of_bytes, std::move(op)); + tlx::resize_and_overrite(*_cont, num_of_bytes, std::move(op)); else - axstd::resize_and_overrite(*_cont, count_element(num_of_bytes), + tlx::resize_and_overrite(*_cont, count_element(num_of_bytes), [op_ = std::move(op)](void* out, size_t count) { const auto num_of_bytes = op_(out, count * element_size); return count_element(num_of_bytes); @@ -207,7 +207,7 @@ class AX_DLL FileUtils * - Status::TooLarge when there file to be read is too large (> 2^32-1), the buffer will not changed. * - Status::ObtainSizeFailed when failed to obtain the file size, the buffer will not changed. */ - template >> + template >> Status getContents(std::string_view filename, T* buffer) const { ResizableBufferAdapter buf(buffer); @@ -562,10 +562,10 @@ class AX_DLL FileUtils virtual void listFilesRecursively(std::string_view dirPath, std::vector* files) const; /** Returns the full path cache. */ - const axstd::string_map getFullPathCache() const { return _fullPathCache; } + const tlx::string_map getFullPathCache() const { return _fullPathCache; } /** Returns the full path cache. */ - const axstd::string_map getFullPathCacheDir() const { return _fullPathCacheDir; } + const tlx::string_map getFullPathCacheDir() const { return _fullPathCacheDir; } /** * Checks whether a file exists without considering search paths and resolution orders. @@ -655,13 +655,13 @@ class AX_DLL FileUtils * The full path cache for normal files. When a file is found, it will be added into this cache. * This variable is used for improving the performance of file search. */ - mutable axstd::string_map _fullPathCache; + mutable tlx::string_map _fullPathCache; /** * The full path cache for directories. When a diretory is found, it will be added into this cache. * This variable is used for improving the performance of file search. */ - mutable axstd::string_map _fullPathCacheDir; + mutable tlx::string_map _fullPathCacheDir; /** * Writable path. diff --git a/axmol/platform/Image.cpp b/axmol/platform/Image.cpp index 0853f0edf7fe..b7a2495e9b2d 100644 --- a/axmol/platform/Image.cpp +++ b/axmol/platform/Image.cpp @@ -2356,7 +2356,7 @@ bool Image::initWithS3TCData(uint8_t* data, ssize_t dataLen, bool ownData) int bytePerPixel = 4; unsigned int stride = width * bytePerPixel; - auto decodeImageData = axstd::make_unique_for_overwrite(stride * height); + auto decodeImageData = tlx::make_unique_for_overwrite(stride * height); if (FOURCC_DXT1 == header->ddsd.DUMMYUNIONNAMEN4.ddpfPixelFormat.fourCC) { s3tc_decode(pixelData + encodeOffset, &decodeImageData[0], width, height, S3TCDecodeFlag::DXT1); diff --git a/axmol/platform/android/Device-android.cpp b/axmol/platform/android/Device-android.cpp index 5788a535a574..876b0d32fc69 100644 --- a/axmol/platform/android/Device-android.cpp +++ b/axmol/platform/android/Device-android.cpp @@ -101,8 +101,7 @@ class BitmapDC // If the path name returned includes the 'assets' dir then that needs to be removed, because the // android.content.Context requires this portion of the path to be omitted for assets inside the app // package. - using namespace cxx17; - if (cxx20::starts_with(cxx17::string_view{fullPathOrFontName}, "assets/"_sv)) + if (tlx::starts_with(std::string_view{fullPathOrFontName}, "assets/"sv)) { fullPathOrFontName = fullPathOrFontName.substr(sizeof("assets/") - 1); // Chop out the 'assets/' portion of the path. diff --git a/axmol/platform/android/FileUtils-android.cpp b/axmol/platform/android/FileUtils-android.cpp index 597e5e2c587c..ccef3080be30 100644 --- a/axmol/platform/android/FileUtils-android.cpp +++ b/axmol/platform/android/FileUtils-android.cpp @@ -229,7 +229,7 @@ int64_t FileUtilsAndroid::getFileSize(std::string_view filepath) const { std::string_view path; std::string relativePath; - if (cxx20::starts_with(filepath, _defaultResRootPath)) + if (tlx::starts_with(filepath, _defaultResRootPath)) { path = relativePath = filepath.substr(_defaultResRootPath.size()); } diff --git a/axmol/platform/android/RenderViewImpl-android.cpp b/axmol/platform/android/RenderViewImpl-android.cpp index 7bf312de8963..bf726047667b 100644 --- a/axmol/platform/android/RenderViewImpl-android.cpp +++ b/axmol/platform/android/RenderViewImpl-android.cpp @@ -201,7 +201,7 @@ Rect RenderViewImpl::getSafeAreaRect() const float insetLeft = 0.0f; float insetRight = 0.0f; - static axstd::pod_vector cornerRadii = + static tlx::pod_vector cornerRadii = JniHelper::callStaticIntArrayMethod("dev/axmol/lib/AxmolEngine", "getDeviceCornerRadii"); if (isScreenRound) @@ -291,7 +291,7 @@ Rect RenderViewImpl::getSafeAreaRect() const if (isCutoutEnabled) { // screen with enabled cutout area (ex. Google Pixel 3 XL, Huawei P20, Asus ZenFone 5, etc) - static axstd::pod_vector safeInsets = + static tlx::pod_vector safeInsets = JniHelper::callStaticIntArrayMethod("dev/axmol/lib/AxmolEngine", "getSafeInsets"); if (safeInsets.size() >= 4) diff --git a/axmol/platform/android/jni/JniHelper.h b/axmol/platform/android/jni/JniHelper.h index 88dc5126b51d..96ca487d732f 100644 --- a/axmol/platform/android/jni/JniHelper.h +++ b/axmol/platform/android/jni/JniHelper.h @@ -35,7 +35,7 @@ THE SOFTWARE. #include "axmol/platform/PlatformMacros.h" #include "axmol/math/Vec3.h" #include "jni/jni.hpp" -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" namespace jni { @@ -267,10 +267,10 @@ class AX_DLL JniHelper /** @brief Call of Java static float* method - @return axstd::pod_vector + @return tlx::pod_vector */ template - static axstd::pod_vector callStaticFloatArrayMethod(const char* className, + static tlx::pod_vector callStaticFloatArrayMethod(const char* className, const char* methodName, Ts&&... xs) { @@ -290,7 +290,7 @@ class AX_DLL JniHelper } jsize len = t.env->GetArrayLength(array); - axstd::pod_vector result(len); + tlx::pod_vector result(len); jfloat* elems = t.env->GetFloatArrayElements(array, 0); if (elems) { @@ -310,10 +310,10 @@ class AX_DLL JniHelper /** @brief Call of Java static int* method - @return axstd::pod_vector + @return tlx::pod_vector */ template - static axstd::pod_vector callStaticIntArrayMethod(const char* className, + static tlx::pod_vector callStaticIntArrayMethod(const char* className, const char* methodName, Ts&&... xs) { @@ -333,7 +333,7 @@ class AX_DLL JniHelper } jsize len = t.env->GetArrayLength(array); - axstd::pod_vector result(len); + tlx::pod_vector result(len); jint* elems = t.env->GetIntArrayElements(array, 0); if (elems) { diff --git a/axmol/platform/desktop/RenderViewImpl.h b/axmol/platform/desktop/RenderViewImpl.h index 31a264b36099..baa1289236a0 100644 --- a/axmol/platform/desktop/RenderViewImpl.h +++ b/axmol/platform/desktop/RenderViewImpl.h @@ -36,7 +36,7 @@ THE SOFTWARE. #endif #include "GLFW/glfw3.h" #if defined(__EMSCRIPTEN__) -# include "axmol/tlx/pod_vector.hpp" +# include "axmol/tlx/vector.hpp" struct EmscriptenMouseEvent; struct EmscriptenTouchEvent; struct EmscriptenFullscreenChangeEvent; @@ -200,9 +200,9 @@ class AX_DLL RenderViewImpl : public RenderView std::string _glfwError; #if defined(__EMSCRIPTEN__) - axstd::pod_vector _touchesId; - axstd::pod_vector _touchesX; - axstd::pod_vector _touchesY; + tlx::pod_vector _touchesId; + tlx::pod_vector _touchesX; + tlx::pod_vector _touchesY; #endif float _mouseX{0.0f}; diff --git a/axmol/platform/wasm/FileUtils-wasm.cpp b/axmol/platform/wasm/FileUtils-wasm.cpp index d9cd0fbae86f..b70ec2b42669 100644 --- a/axmol/platform/wasm/FileUtils-wasm.cpp +++ b/axmol/platform/wasm/FileUtils-wasm.cpp @@ -92,7 +92,7 @@ bool FileUtilsEmscripten::isFileExistInternal(std::string_view path) const std::string strPath(path); if (strPath[0] != '/') { // Not absolute path, add the default root path at the beginning. - if (!cxx20::starts_with(strPath, _defaultResRootPath)) + if (!tlx::starts_with(strPath, _defaultResRootPath)) { // Didn't find "assets/" at the beginning of the path, adding it. strPath.insert(0, _defaultResRootPath); } diff --git a/axmol/platform/win32/Application-win32.cpp b/axmol/platform/win32/Application-win32.cpp index 261bad64783c..ae45df985285 100644 --- a/axmol/platform/win32/Application-win32.cpp +++ b/axmol/platform/win32/Application-win32.cpp @@ -32,7 +32,6 @@ THE SOFTWARE. #include #include -#include "yasio/string_view.hpp" #include "yasio/wtimer_hres.hpp" #include "ntcvt/ntcvt.hpp" @@ -320,10 +319,8 @@ static void PVRFrameEnableControlWindow(bool bEnable) return; } - using namespace cxx17; - const WCHAR* wszValue = L"hide_gui"; - const auto svNewData = (bEnable) ? L"NO"_sv : L"YES"_sv; + const auto svNewData = (bEnable) ? L"NO"sv : L"YES"sv; WCHAR wszOldData[256] = {0}; DWORD dwSize = static_cast(sizeof(wszOldData)); LSTATUS status = RegQueryValueExW(hKey, wszValue, 0, nullptr, (LPBYTE)wszOldData, &dwSize); diff --git a/axmol/platform/win32/FileUtils-win32.cpp b/axmol/platform/win32/FileUtils-win32.cpp index 2888b3422da3..ae49cf32f552 100644 --- a/axmol/platform/win32/FileUtils-win32.cpp +++ b/axmol/platform/win32/FileUtils-win32.cpp @@ -273,7 +273,7 @@ bool FileUtilsWin32::createDirectories(std::string_view dirPath) const bool fail = false; if ((GetFileAttributesW(path.c_str())) == INVALID_FILE_ATTRIBUTES) { - axstd::splitpath_cb(&path.front(), [](wchar_t* ptr) { return *ptr != '\0'; }, + tlx::splitpath_cb(&path.front(), [](wchar_t* ptr) { return *ptr != '\0'; }, [&dirPath, &fail](const wchar_t* subpath) { auto attribs = GetFileAttributesW(subpath); if (attribs == INVALID_FILE_ATTRIBUTES) diff --git a/axmol/platform/winrt/FileUtilsWinRT.cpp b/axmol/platform/winrt/FileUtilsWinRT.cpp index 4e3abcbd3303..5933c49126c5 100644 --- a/axmol/platform/winrt/FileUtilsWinRT.cpp +++ b/axmol/platform/winrt/FileUtilsWinRT.cpp @@ -164,7 +164,7 @@ bool FileUtilsWinRT::createDirectories(std::string_view dirPath) const bool fail = false; if ((GetFileAttributesW(path.c_str())) == INVALID_FILE_ATTRIBUTES) { - axstd::splitpath_cb(&path.front(), [](wchar_t* ptr) { return *ptr != '\0'; }, + tlx::splitpath_cb(&path.front(), [](wchar_t* ptr) { return *ptr != '\0'; }, [&dirPath, &fail](const wchar_t* subpath) { auto attribs = GetFileAttributesW(subpath); if (attribs == INVALID_FILE_ATTRIBUTES) diff --git a/axmol/renderer/Material.h b/axmol/renderer/Material.h index cce9f429681c..e2e588f19b77 100644 --- a/axmol/renderer/Material.h +++ b/axmol/renderer/Material.h @@ -208,7 +208,7 @@ class AX_DLL Material : public Object // weak reference Node* _target = nullptr; - axstd::string_map _textureSlots; + tlx::string_map _textureSlots; int _textureSlotIndex = 0; bool _isTransparent = false; // is this mesh transparent. diff --git a/axmol/renderer/TextureCache.h b/axmol/renderer/TextureCache.h index e0710c5a726f..2b5340230215 100644 --- a/axmol/renderer/TextureCache.h +++ b/axmol/renderer/TextureCache.h @@ -256,7 +256,7 @@ class AX_DLL TextureCache : public Object int _outstandingTaskCount; - axstd::string_map _textures; + tlx::string_map _textures; static std::string s_etc1AlphaFileSuffix; }; diff --git a/axmol/renderer/VertexLayoutManager.cpp b/axmol/renderer/VertexLayoutManager.cpp index 23572f397a62..0a822f0452e4 100644 --- a/axmol/renderer/VertexLayoutManager.cpp +++ b/axmol/renderer/VertexLayoutManager.cpp @@ -23,7 +23,7 @@ ****************************************************************************/ #include "axmol/renderer/VertexLayoutManager.h" #include "axmol/rhi/DriverBase.h" -#include "yasio/singleton.hpp" +#include "axmol/tlx/singleton.hpp" namespace ax { @@ -199,12 +199,12 @@ static constexpr size_t MAX_DESC_POOL_SIZE = 64; VertexLayoutManager* VertexLayoutManager::getInstance() { - return yasio::singleton::instance(); + return tlx::singleton::instance(); } void VertexLayoutManager::destroyInstance() { - yasio::singleton::destroy(); + tlx::singleton::destroy(); } VertexLayoutManager::VertexLayoutManager() diff --git a/axmol/renderer/VertexLayoutManager.h b/axmol/renderer/VertexLayoutManager.h index a64f0f6c91ce..e5aa109e2b11 100644 --- a/axmol/renderer/VertexLayoutManager.h +++ b/axmol/renderer/VertexLayoutManager.h @@ -23,7 +23,7 @@ ****************************************************************************/ #pragma once -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" #include "axmol/tlx/hlookup.hpp" #include "axmol/rhi/RHITypes.h" #include "axmol/rhi/VertexLayout.h" @@ -74,8 +74,8 @@ class AX_DLL VertexLayoutManager private: VertexLayout* getBuiltinVertexLayout(VertexLayoutKind kind, rhi::Program* prog); - axstd::pod_vector _builtinVertexLayouts; - axstd::hash_map _customVertexLayouts; + tlx::pod_vector _builtinVertexLayouts; + tlx::hash_map _customVertexLayouts; std::vector _vertexLayoutDescPool; }; diff --git a/axmol/rhi/Program.h b/axmol/rhi/Program.h index 3174675a7237..9b67f0f6d38b 100644 --- a/axmol/rhi/Program.h +++ b/axmol/rhi/Program.h @@ -103,7 +103,7 @@ class AX_DLL Program : public Object * Get active vertex attributes. * @return Active vertex attributes. key is active attribute name, Value is corresponding attribute info. */ - virtual const axstd::string_map& getActiveVertexInputs() const = 0; + virtual const tlx::string_map& getActiveVertexInputs() const = 0; /** * Get vertex shader. @@ -140,7 +140,7 @@ class AX_DLL Program : public Object * Get all uniformInfos. * @return The uniformInfos. */ - virtual const axstd::string_map& getActiveUniformInfos(ShaderStage stage) const = 0; + virtual const tlx::string_map& getActiveUniformInfos(ShaderStage stage) const = 0; VertexLayout* getVertexLayout() const { return _vertexLayout; } diff --git a/axmol/rhi/ProgramState.cpp b/axmol/rhi/ProgramState.cpp index 9a4790e4b744..fd5b66fc3188 100644 --- a/axmol/rhi/ProgramState.cpp +++ b/axmol/rhi/ProgramState.cpp @@ -72,6 +72,8 @@ void TextureBindingSet::assign(const TextureBindingSet& other) #if AX_ENABLE_CONTEXT_LOSS_RECOVERY setTextureArray(other.loc, other.slots, other.texs); #else + + std::vector fuck; setTextureArray(-1, other.slots, other.texs); #endif } @@ -128,7 +130,7 @@ void TextureBindingSet::setTextureArray(int location, std::span slots, std::span texs) +void TextureBindingSet::setTextureArray(int location, std::span slots, std::span texs) { bool retain = !slots.empty() && (slots.size() == texs.size()); diff --git a/axmol/rhi/ProgramState.h b/axmol/rhi/ProgramState.h index 3104f8bb19d2..03d141934352 100644 --- a/axmol/rhi/ProgramState.h +++ b/axmol/rhi/ProgramState.h @@ -37,7 +37,7 @@ #include "axmol/rhi/RHITypes.h" #include "axmol/rhi/Program.h" #include "axmol/renderer/VertexLayoutManager.h" -#include "yasio/byte_buffer.hpp" +#include "axmol/tlx/byte_buffer.hpp" namespace ax::rhi { @@ -82,12 +82,12 @@ struct AX_DLL TextureBindingSet void setTexture(int location, int slot, rhi::Texture* tex); void setTextureArray(int location, std::span units); - void setTextureArray(int location, std::span slots, std::span texs); + void setTextureArray(int location, std::span slots, std::span texs); void releaseTextures(); - axstd::pod_vector slots; - mutable axstd::pod_vector texs; + tlx::pod_vector slots; + mutable tlx::pod_vector texs; #if AX_ENABLE_CONTEXT_LOSS_RECOVERY int loc = -1; #endif @@ -171,7 +171,7 @@ class AX_DLL ProgramState : public Object return _program->getVertexInputDesc(name); } - const axstd::string_map& getActiveVertexInputs() const + const tlx::string_map& getActiveVertexInputs() const { return _program->getActiveVertexInputs(); } @@ -234,7 +234,8 @@ class AX_DLL ProgramState : public Object */ std::span getVertexUniformBuffer() const { - return std::span{_uniformBuffer.begin() + _vertexUniformBufferStart, _uniformBuffer.end()}; + return std::span{_uniformBuffer.data() + _vertexUniformBufferStart, + _uniformBuffer.size() - _vertexUniformBufferStart}; } /** @@ -243,7 +244,7 @@ class AX_DLL ProgramState : public Object */ std::span getFragmentUniformBuffer() const { - return std::span{_uniformBuffer.begin(), _uniformBuffer.begin() + _vertexUniformBufferStart}; + return std::span{_uniformBuffer.data(), _vertexUniformBufferStart}; } #endif @@ -357,7 +358,7 @@ class AX_DLL ProgramState : public Object rhi::Program* _program = nullptr; std::unordered_map _callbackUniforms; - yasio::sbyte_buffer _uniformBuffer; + tlx::sbyte_buffer _uniformBuffer; #if AX_RENDER_API != AX_RENDER_API_GL std::size_t _vertexUniformBufferStart = 0; #endif diff --git a/axmol/rhi/SamplerCache.cpp b/axmol/rhi/SamplerCache.cpp index 8aa3fcfe0db0..eb818f2513c3 100644 --- a/axmol/rhi/SamplerCache.cpp +++ b/axmol/rhi/SamplerCache.cpp @@ -23,17 +23,17 @@ ****************************************************************************/ #include "axmol/rhi/SamplerCache.h" #include "axmol/rhi/DriverBase.h" -#include "yasio/singleton.hpp" +#include "axmol/tlx/singleton.hpp" namespace ax::rhi { SamplerCache* SamplerCache::getInstance() { - return yasio::singleton::instance(); + return tlx::singleton::instance(); } void SamplerCache::destroyInstance() { - yasio::singleton::destroy(); + tlx::singleton::destroy(); } SamplerCache::SamplerCache() diff --git a/axmol/rhi/SamplerCache.h b/axmol/rhi/SamplerCache.h index 45775cd83f0d..2a72986d6e54 100644 --- a/axmol/rhi/SamplerCache.h +++ b/axmol/rhi/SamplerCache.h @@ -25,7 +25,7 @@ #pragma once #include "axmol/tlx/hlookup.hpp" -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" #include "RHITypes.h" namespace ax::rhi @@ -60,10 +60,10 @@ class SamplerCache void createBuiltinSamplers(); void createBuiltinSampler(uint32_t samplerIndex, const SamplerDesc& desc); - axstd::pod_vector _builtinSamplers; - axstd::hash_map _customSamplers; + tlx::pod_vector _builtinSamplers; + tlx::hash_map _customSamplers; - axstd::hash_map _samplersRegsitry; // sampler desc => sampler index registry + tlx::hash_map _samplersRegsitry; // sampler desc => sampler index registry DriverBase* _driver{nullptr}; diff --git a/axmol/rhi/Texture.cpp b/axmol/rhi/Texture.cpp index 05601c67d842..0c1b8684e73f 100644 --- a/axmol/rhi/Texture.cpp +++ b/axmol/rhi/Texture.cpp @@ -53,7 +53,7 @@ void Texture::zeroTexData() auto size = w * h * _bitsPerPixel / 8; assert(size > 0); - axstd::byte_buffer blackPixels; + tlx::byte_buffer blackPixels; blackPixels.resize(size, 0); updateData(blackPixels.data(), w, h, 0, 0); diff --git a/axmol/rhi/d3d11/Buffer11.h b/axmol/rhi/d3d11/Buffer11.h index e11368bd7f66..b674d9d67174 100644 --- a/axmol/rhi/d3d11/Buffer11.h +++ b/axmol/rhi/d3d11/Buffer11.h @@ -71,7 +71,7 @@ class BufferImpl final : public Buffer private: void createNativeBuffer(const void* initial); - axstd::byte_buffer _defaultData; + tlx::byte_buffer _defaultData; bool _needDefaultStoredData = false; ID3D11Device* _device; // weak ref diff --git a/axmol/rhi/d3d11/DepthStencilState11.h b/axmol/rhi/d3d11/DepthStencilState11.h index 020824017a84..0a4cc602d0d4 100644 --- a/axmol/rhi/d3d11/DepthStencilState11.h +++ b/axmol/rhi/d3d11/DepthStencilState11.h @@ -50,7 +50,7 @@ class DepthStencilStateImpl : public DepthStencilState private: ID3D11Device* _device = nullptr; // weak ref - axstd::hash_map> _stateCache; + tlx::hash_map> _stateCache; ComPtr _activeState; ComPtr _disableState; diff --git a/axmol/rhi/d3d11/Program11.cpp b/axmol/rhi/d3d11/Program11.cpp index d4326c60a27c..c0f0fbbb1349 100644 --- a/axmol/rhi/d3d11/Program11.cpp +++ b/axmol/rhi/d3d11/Program11.cpp @@ -53,7 +53,7 @@ const VertexInputDesc* ProgramImpl::getVertexInputDesc(std::string_view name) co return _vertexShader->getVertexInputDesc(name); } -const axstd::string_map& ProgramImpl::getActiveVertexInputs() const +const tlx::string_map& ProgramImpl::getActiveVertexInputs() const { return _vertexShader->getActiveVertexInputs(); } @@ -105,7 +105,7 @@ std::size_t ProgramImpl::getUniformBufferSize(ShaderStage stage) const return 0; } -const axstd::string_map& ProgramImpl::getActiveUniformInfos(ShaderStage stage) const +const tlx::string_map& ProgramImpl::getActiveUniformInfos(ShaderStage stage) const { return stage == ShaderStage::VERTEX ? _vertexShader->getActiveUniformInfos() : _fragmentShader->getActiveUniformInfos(); diff --git a/axmol/rhi/d3d11/Program11.h b/axmol/rhi/d3d11/Program11.h index 7d4671d7cd91..0f76aaca9b58 100644 --- a/axmol/rhi/d3d11/Program11.h +++ b/axmol/rhi/d3d11/Program11.h @@ -83,7 +83,7 @@ class ProgramImpl : public Program * Get active vertex attributes. * @return Active vertex attributes. key is active attribute name, Value is corresponding attribute info. */ - const axstd::string_map& getActiveVertexInputs() const override; + const tlx::string_map& getActiveVertexInputs() const override; /** * Get vertex shader module. @@ -120,7 +120,7 @@ class ProgramImpl : public Program * Get all uniformInfos. * @return The uniformInfos. */ - const axstd::string_map& getActiveUniformInfos(ShaderStage stage) const override; + const tlx::string_map& getActiveUniformInfos(ShaderStage stage) const override; ID3DBlob* getVSBlob() const; diff --git a/axmol/rhi/d3d11/RenderContext11.h b/axmol/rhi/d3d11/RenderContext11.h index 520e8aa04d21..53cc8674443a 100644 --- a/axmol/rhi/d3d11/RenderContext11.h +++ b/axmol/rhi/d3d11/RenderContext11.h @@ -253,7 +253,7 @@ class RenderContextImpl : public RenderContext UINT _screenHeight{0}; RenderPassDesc _renderPassDesc{}; - axstd::pod_vector _nullSRVs; + tlx::pod_vector _nullSRVs; UINT _textureBounds{0}; UINT _swapChainFlags{0}; diff --git a/axmol/rhi/d3d11/RenderPipeline11.h b/axmol/rhi/d3d11/RenderPipeline11.h index ece85d4efb23..d28e7c550566 100644 --- a/axmol/rhi/d3d11/RenderPipeline11.h +++ b/axmol/rhi/d3d11/RenderPipeline11.h @@ -49,7 +49,7 @@ class RenderPipelineImpl : public RenderPipeline ID3D11Device* _device = nullptr; ID3D11DeviceContext* _context = nullptr; - axstd::hash_map> _blendCache; + tlx::hash_map> _blendCache; }; /** @} */ diff --git a/axmol/rhi/d3d11/ShaderModule11.h b/axmol/rhi/d3d11/ShaderModule11.h index 6c273ec9d25c..1d537258dbb5 100644 --- a/axmol/rhi/d3d11/ShaderModule11.h +++ b/axmol/rhi/d3d11/ShaderModule11.h @@ -80,13 +80,13 @@ class ShaderModuleImpl : public ShaderModule * Get active attribute informations. * @return Active attribute informations. key is attribute name and Value is corresponding attribute info. */ - inline const axstd::string_map& getActiveVertexInputs() const { return _activeVertexInputs; } + inline const tlx::string_map& getActiveVertexInputs() const { return _activeVertexInputs; } /** * Get all uniformInfos. * @return The uniformInfos. */ - inline const axstd::string_map& getActiveUniformInfos() const { return _activeUniformInfos; } + inline const tlx::string_map& getActiveUniformInfos() const { return _activeUniformInfos; } /** * Get maximum uniform location. @@ -113,8 +113,8 @@ class ShaderModuleImpl : public ShaderModule IUnknown* _shader = nullptr; ID3DBlob* _blob = nullptr; - axstd::string_map _activeVertexInputs; - axstd::string_map _activeUniformInfos; + tlx::string_map _activeVertexInputs; + tlx::string_map _activeUniformInfos; const VertexInputDesc* _builtinVertexInputs[VIK_COUNT]; diff --git a/axmol/rhi/d3d11/VertexLayout11.cpp b/axmol/rhi/d3d11/VertexLayout11.cpp index a567b82322fb..132e969d05b9 100644 --- a/axmol/rhi/d3d11/VertexLayout11.cpp +++ b/axmol/rhi/d3d11/VertexLayout11.cpp @@ -81,7 +81,7 @@ void VertexLayoutImpl::apply(ID3D11DeviceContext* context, Program* program) con auto progImpl = static_cast(program); auto device = static_cast(DriverBase::getInstance())->getDevice(); - axstd::pod_vector inputElements; + tlx::pod_vector inputElements; auto& bindings = getBindings(); inputElements.reserve(bindings.size()); diff --git a/axmol/rhi/d3d12/Buffer12.h b/axmol/rhi/d3d12/Buffer12.h index 047e008dddf4..8f582f0b7363 100644 --- a/axmol/rhi/d3d12/Buffer12.h +++ b/axmol/rhi/d3d12/Buffer12.h @@ -73,7 +73,7 @@ class BufferImpl final : public Buffer static std::size_t alignTo(std::size_t value, std::size_t alignment); private: - axstd::byte_buffer _defaultData; + tlx::byte_buffer _defaultData; bool _needDefaultStoredData = false; DriverImpl* _driver{nullptr}; diff --git a/axmol/rhi/d3d12/DepthStencilState12.cpp b/axmol/rhi/d3d12/DepthStencilState12.cpp index 1929fddd5519..3700177c55ac 100644 --- a/axmol/rhi/d3d12/DepthStencilState12.cpp +++ b/axmol/rhi/d3d12/DepthStencilState12.cpp @@ -92,7 +92,7 @@ static D3D12_DEPTH_STENCILOP_DESC make_op_desc(const StencilDesc& s) DepthStencilStateImpl::DepthStencilStateImpl() { - _hash = axstd::hash_bytes(&_dsDesc, sizeof(_dsDesc)); + _hash = tlx::hash_bytes(&_dsDesc, sizeof(_dsDesc)); // Disabled state (depth test/write off, stencil off) _disableDesc.DepthEnable = FALSE; @@ -112,7 +112,7 @@ void DepthStencilStateImpl::update(const DepthStencilDesc& desc) { DepthStencilState::update(desc); - _hash = axstd::hash_bytes(&_dsDesc, sizeof(_dsDesc)); + _hash = tlx::hash_bytes(&_dsDesc, sizeof(_dsDesc)); if (!isEnabled()) { diff --git a/axmol/rhi/d3d12/Driver12.cpp b/axmol/rhi/d3d12/Driver12.cpp index e0673ac1039e..320b88421094 100644 --- a/axmol/rhi/d3d12/Driver12.cpp +++ b/axmol/rhi/d3d12/Driver12.cpp @@ -947,8 +947,8 @@ bool DriverImpl::generateMipmaps(ID3D12GraphicsCommandList* cmd, ID3D12Resource* ensureMipmapPipeline(isArray); // lazy init PSO + root signature // Build SRV/UAV descriptors for each mip (CPU-only descriptors in your existing pools) - axstd::pod_vector mipSrvs(mipCount); - axstd::pod_vector mipUavs(mipCount); + tlx::pod_vector mipSrvs(mipCount); + tlx::pod_vector mipUavs(mipCount); for (UINT m = 0; m < mipCount; ++m) { @@ -999,7 +999,7 @@ bool DriverImpl::generateMipmaps(ID3D12GraphicsCommandList* cmd, ID3D12Resource* D3D12_GPU_DESCRIPTOR_HANDLE srv; D3D12_GPU_DESCRIPTOR_HANDLE uav; }; - axstd::pod_vector passViews(passCount); + tlx::pod_vector passViews(passCount); const auto cpuStart = _mipmapSrvHeap->GetCPUDescriptorHandleForHeapStart(); const auto gpuStart = _mipmapSrvHeap->GetGPUDescriptorHandleForHeapStart(); diff --git a/axmol/rhi/d3d12/Program12.cpp b/axmol/rhi/d3d12/Program12.cpp index 8f39bf0ee97b..ba935586e73f 100644 --- a/axmol/rhi/d3d12/Program12.cpp +++ b/axmol/rhi/d3d12/Program12.cpp @@ -53,7 +53,7 @@ const VertexInputDesc* ProgramImpl::getVertexInputDesc(std::string_view name) co return _vertexShader->getVertexInputDesc(name); } -const axstd::string_map& ProgramImpl::getActiveVertexInputs() const +const tlx::string_map& ProgramImpl::getActiveVertexInputs() const { return _vertexShader->getActiveVertexInputs(); } @@ -107,7 +107,7 @@ std::size_t ProgramImpl::getUniformBufferSize(ShaderStage stage) const return 0; } -const axstd::string_map& ProgramImpl::getActiveUniformInfos(ShaderStage stage) const +const tlx::string_map& ProgramImpl::getActiveUniformInfos(ShaderStage stage) const { return stage == ShaderStage::VERTEX ? _vertexShader->getActiveUniformInfos() : _fragmentShader->getActiveUniformInfos(); diff --git a/axmol/rhi/d3d12/Program12.h b/axmol/rhi/d3d12/Program12.h index 0a1066b9d72c..80a59789f1da 100644 --- a/axmol/rhi/d3d12/Program12.h +++ b/axmol/rhi/d3d12/Program12.h @@ -45,7 +45,7 @@ class ProgramImpl : public Program const VertexInputDesc* getVertexInputDesc(std::string_view name) const override; const VertexInputDesc* getVertexInputDesc(VertexInputKind name) const override; - const axstd::string_map& getActiveVertexInputs() const override; + const tlx::string_map& getActiveVertexInputs() const override; ShaderModuleImpl* getVertexShader() const { return _vertexShader; } ShaderModuleImpl* getFragmentShader() const { return _fragmentShader; } @@ -54,7 +54,7 @@ class ProgramImpl : public Program int getMaxFragmentLocation() const override; std::size_t getUniformBufferSize(ShaderStage stage) const override; - const axstd::string_map& getActiveUniformInfos(ShaderStage stage) const override; + const tlx::string_map& getActiveUniformInfos(ShaderStage stage) const override; const D3D12BlobHandle& getVSBlob() const { return _vertexShader->internalHandle(); } const D3D12BlobHandle& getPSBlob() const { return _fragmentShader->internalHandle(); } diff --git a/axmol/rhi/d3d12/RenderPipeline12.cpp b/axmol/rhi/d3d12/RenderPipeline12.cpp index d7c0d01a1247..e52e020e1e1c 100644 --- a/axmol/rhi/d3d12/RenderPipeline12.cpp +++ b/axmol/rhi/d3d12/RenderPipeline12.cpp @@ -103,7 +103,7 @@ static inline uintptr_t makePSOKey(const rhi::BlendDesc& blendDesc, ((uint32_t)primitiveGroup << 16) | (rs.CullMode << 8) | (rs.FrontCounterClockwise ? 1 : 0); const auto seed = (uint64_t)vlHash << 32 | (uint64_t)rasterComp; - return axstd::hash_bytes(&hashMe, sizeof(hashMe), seed); + return tlx::hash_bytes(&hashMe, sizeof(hashMe), seed); } else { @@ -118,7 +118,7 @@ static inline uintptr_t makePSOKey(const rhi::BlendDesc& blendDesc, const auto rasterComp = ((uint32_t)primitiveGroup << 16) | (rs.CullMode << 8) | (rs.FrontCounterClockwise ? 1 : 0); - return axstd::hash_bytes(&hashMe, sizeof(hashMe), rasterComp); + return tlx::hash_bytes(&hashMe, sizeof(hashMe), rasterComp); } } @@ -206,14 +206,14 @@ void RenderPipelineImpl::updateRootSignature(ProgramImpl* program) UINT rootIndex = 0; - axstd::pod_vector rootParams; + tlx::pod_vector rootParams; rootParams.reserve(4); // VS UBO, FS UBO, FS SRV table, FS Sampler table auto vs = program->getVertexShader(); auto fs = program->getFragmentShader(); // --- FS SRVs (textures) -> descriptor table, space = SET_INDEX_SRV --- - axstd::pod_vector srvRanges; + tlx::pod_vector srvRanges; // --- Sampler descriptor table (global heap) --- D3D12_DESCRIPTOR_RANGE samplerRange{}; diff --git a/axmol/rhi/d3d12/RenderPipeline12.h b/axmol/rhi/d3d12/RenderPipeline12.h index 103f3ce17a99..1d7c3e6009b2 100644 --- a/axmol/rhi/d3d12/RenderPipeline12.h +++ b/axmol/rhi/d3d12/RenderPipeline12.h @@ -104,8 +104,8 @@ class RenderPipelineImpl : public RenderPipeline RootSignatureEntry* _activeRootSignature{nullptr}; ComPtr _activePSO; - axstd::hash_map> _psoCache; - axstd::hash_map _rootSigCache; + tlx::hash_map> _psoCache; + tlx::hash_map _rootSigCache; }; } // namespace ax::rhi::d3d12 diff --git a/axmol/rhi/d3d12/ShaderModule12.h b/axmol/rhi/d3d12/ShaderModule12.h index 3962a46e3d1f..72f148f96b75 100644 --- a/axmol/rhi/d3d12/ShaderModule12.h +++ b/axmol/rhi/d3d12/ShaderModule12.h @@ -96,13 +96,13 @@ class ShaderModuleImpl : public ShaderModule * Get active attribute informations. * @return Active attribute informations. key is attribute name and Value is corresponding attribute info. */ - inline const axstd::string_map& getActiveVertexInputs() const { return _activeVertexInputs; } + inline const tlx::string_map& getActiveVertexInputs() const { return _activeVertexInputs; } /** * Get all uniformInfos. * @return The uniformInfos. */ - inline const axstd::string_map& getActiveUniformInfos() const { return _activeUniformInfos; } + inline const tlx::string_map& getActiveUniformInfos() const { return _activeUniformInfos; } inline const std::vector& getActiveUniformBlockInfos() const { return _activeUniformBlockInfos; } inline const std::vector& getActiveSamplerInfos() const { return _activeSamplerInfos; } @@ -131,8 +131,8 @@ class ShaderModuleImpl : public ShaderModule D3D12BlobHandle _nativeHandle; - axstd::string_map _activeVertexInputs; - axstd::string_map _activeUniformInfos; + tlx::string_map _activeVertexInputs; + tlx::string_map _activeUniformInfos; std::vector _activeUniformBlockInfos; std::vector _activeSamplerInfos; diff --git a/axmol/rhi/d3d12/Texture12.h b/axmol/rhi/d3d12/Texture12.h index 4a03fa4a5be8..3ceeb4f5a71a 100644 --- a/axmol/rhi/d3d12/Texture12.h +++ b/axmol/rhi/d3d12/Texture12.h @@ -28,7 +28,7 @@ #include "axmol/rhi/DXUtils.h" #include #include -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" namespace ax::rhi::d3d12 { @@ -76,7 +76,7 @@ class ResourceStateTracker } private: - std::vector> _states; + std::vector> _states; }; /** diff --git a/axmol/rhi/metal/ProgramMTL.h b/axmol/rhi/metal/ProgramMTL.h index 19ee9ebbf800..fb6c1903b1ef 100644 --- a/axmol/rhi/metal/ProgramMTL.h +++ b/axmol/rhi/metal/ProgramMTL.h @@ -83,7 +83,7 @@ class ProgramImpl : public Program * Get active vertex attributes. * @return Active vertex attributes. key is active attribute name, Value is corresponding attribute info. */ - const axstd::string_map& getActiveVertexInputs() const override; + const tlx::string_map& getActiveVertexInputs() const override; /** * Get vertex shader module. @@ -120,7 +120,7 @@ class ProgramImpl : public Program * Get all uniformInfos. * @return The uniformInfos. */ - const axstd::string_map& getActiveUniformInfos(ShaderStage stage) const override; + const tlx::string_map& getActiveUniformInfos(ShaderStage stage) const override; private: ShaderModuleImpl* _vertexShader = nullptr; diff --git a/axmol/rhi/metal/ProgramMTL.mm b/axmol/rhi/metal/ProgramMTL.mm index ff28df3073fd..5449a00ba18d 100644 --- a/axmol/rhi/metal/ProgramMTL.mm +++ b/axmol/rhi/metal/ProgramMTL.mm @@ -91,7 +91,7 @@ of this software and associated documentation files (the "Software"), to deal return _fragmentShader->getMaxLocation(); } -const axstd::string_map& ProgramImpl::getActiveVertexInputs() const +const tlx::string_map& ProgramImpl::getActiveVertexInputs() const { return _vertexShader->getActiveVertexInputs(); } @@ -111,7 +111,7 @@ of this software and associated documentation files (the "Software"), to deal return 0; } -const axstd::string_map& ProgramImpl::getActiveUniformInfos(ShaderStage stage) const +const tlx::string_map& ProgramImpl::getActiveUniformInfos(ShaderStage stage) const { switch (stage) { diff --git a/axmol/rhi/metal/RenderPipelineMTL.h b/axmol/rhi/metal/RenderPipelineMTL.h index b560ce37f7aa..729241b0817d 100644 --- a/axmol/rhi/metal/RenderPipelineMTL.h +++ b/axmol/rhi/metal/RenderPipelineMTL.h @@ -75,7 +75,7 @@ class RenderPipelineImpl : public RenderPipeline PixelFormat _colorAttachmentsFormat[MAX_COLOR_ATTCHMENT] = {PixelFormat::NONE}; PixelFormat _depthStencilPF = PixelFormat::NONE; - axstd::hash_map> _mtlStateCache; + tlx::hash_map> _mtlStateCache; }; // end of _metal group diff --git a/axmol/rhi/metal/ShaderModuleMTL.h b/axmol/rhi/metal/ShaderModuleMTL.h index 6976d1f6a6bf..16d0a9668168 100644 --- a/axmol/rhi/metal/ShaderModuleMTL.h +++ b/axmol/rhi/metal/ShaderModuleMTL.h @@ -94,13 +94,13 @@ class ShaderModuleImpl : public ShaderModule * Get active attribute informations. * @return Active attribute informations. key is attribute name and Value is corresponding attribute info. */ - inline const axstd::string_map& getActiveVertexInputs() const { return _activeVertexInputs; } + inline const tlx::string_map& getActiveVertexInputs() const { return _activeVertexInputs; } /** * Get all uniformInfos. * @return The uniformInfos. */ - inline const axstd::string_map& getActiveUniformInfos() const { return _activeUniformInfos; } + inline const tlx::string_map& getActiveUniformInfos() const { return _activeUniformInfos; } /** * Get maximum uniform location. @@ -123,8 +123,8 @@ class ShaderModuleImpl : public ShaderModule id _mtlFunction = nil; - axstd::string_map _activeVertexInputs; - axstd::string_map _activeUniformInfos; + tlx::string_map _activeVertexInputs; + tlx::string_map _activeUniformInfos; const VertexInputDesc* _builtinVertexInputs[VIK_COUNT]; diff --git a/axmol/rhi/opengl/DriverGL.cpp b/axmol/rhi/opengl/DriverGL.cpp index 467f5022e090..6ee23067f73f 100644 --- a/axmol/rhi/opengl/DriverGL.cpp +++ b/axmol/rhi/opengl/DriverGL.cpp @@ -35,7 +35,7 @@ #include "axmol/rhi/opengl/MacrosGL.h" #include "axmol/rhi/opengl/VertexLayoutGL.h" -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" #include "axmol/tlx/utility.hpp" #include "axmol/tlx/format.hpp" #include "xxhash/xxhash.h" @@ -143,7 +143,7 @@ DriverImpl::DriverImpl() }); // texture compressions - axstd::pod_vector formats; + tlx::pod_vector formats; GLint numFormats{0}; glGetIntegerv(GL_NUM_COMPRESSED_TEXTURE_FORMATS, &numFormats); if (numFormats > 0) @@ -407,7 +407,7 @@ static GLuint compileShader(GLenum shaderType, const GLchar* source) if (logLength > 1) { - auto errorLog = axstd::make_unique_for_overwrite(static_cast(logLength)); + auto errorLog = tlx::make_unique_for_overwrite(static_cast(logLength)); glGetShaderInfoLog(shader, logLength, nullptr, static_cast(errorLog.get())); AXLOGE("axmol:ERROR: Failed to compile shader, detail: {}\n{}", errorLog.get(), source); } diff --git a/axmol/rhi/opengl/ProgramGL.cpp b/axmol/rhi/opengl/ProgramGL.cpp index 570512a947b5..006823df0b43 100644 --- a/axmol/rhi/opengl/ProgramGL.cpp +++ b/axmol/rhi/opengl/ProgramGL.cpp @@ -30,8 +30,8 @@ #include "axmol/base/EventDispatcher.h" #include "axmol/base/EventType.h" #include "axmol/tlx/utility.hpp" -#include "axmol/tlx/pod_vector.hpp" -#include "yasio/byte_buffer.hpp" +#include "axmol/tlx/vector.hpp" +#include "axmol/tlx/byte_buffer.hpp" #include "axmol/rhi/opengl/UtilsGL.h" #include "axmol/rhi/opengl/OpenGLState.h" @@ -128,7 +128,7 @@ void ProgramImpl::compileProgram() glGetProgramiv(_program, GL_INFO_LOG_LENGTH, &errorInfoLen); if (errorInfoLen > 1) { - auto errorInfo = axstd::make_unique_for_overwrite(static_cast(errorInfoLen)); + auto errorInfo = tlx::make_unique_for_overwrite(static_cast(errorInfoLen)); glGetProgramInfoLog(_program, errorInfoLen, NULL, errorInfo.get()); AXLOGE("axmol:ERROR: {}: failed to link program: {} ", __FUNCTION__, errorInfo.get()); } @@ -198,7 +198,7 @@ void ProgramImpl::reflectVertexInputs() _activeVertexInputs.reserve(numOfActiveInputs); constexpr int MAX_VERTEX_INPUT_NAME_LENGTH = 255; - auto attrName = axstd::make_unique_for_overwrite(MAX_VERTEX_INPUT_NAME_LENGTH + 1); + auto attrName = tlx::make_unique_for_overwrite(MAX_VERTEX_INPUT_NAME_LENGTH + 1); GLint attrNameLen = 0; GLenum attrType; @@ -240,7 +240,7 @@ void ProgramImpl::reflectUniformInfos() GLint numblocks{0}; glGetProgramiv(_program, GL_ACTIVE_UNIFORM_BLOCKS, &numblocks); - axstd::pod_vector uniformBlcokOffsets(numblocks); + tlx::pod_vector uniformBlcokOffsets(numblocks); for (int blockIndex = 0; blockIndex < numblocks; ++blockIndex) { GLint blockSize{0}; @@ -404,12 +404,12 @@ int ProgramImpl::getOriginalLocation(int location) const } #endif -const axstd::string_map& ProgramImpl::getActiveVertexInputs() const +const tlx::string_map& ProgramImpl::getActiveVertexInputs() const { return _activeVertexInputs; } -const axstd::string_map& ProgramImpl::getActiveUniformInfos(ShaderStage /*stage*/) const +const tlx::string_map& ProgramImpl::getActiveUniformInfos(ShaderStage /*stage*/) const { return _activeUniformInfos; } diff --git a/axmol/rhi/opengl/ProgramGL.h b/axmol/rhi/opengl/ProgramGL.h index e97ca5d16f02..372bd90ce09a 100644 --- a/axmol/rhi/opengl/ProgramGL.h +++ b/axmol/rhi/opengl/ProgramGL.h @@ -37,7 +37,7 @@ #include #include -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" namespace ax::rhi::gl { @@ -146,7 +146,7 @@ class ProgramImpl : public Program * Get active vertex attributes. * @return Active vertex attributes. key is active attribute name, Value is corresponding attribute info. */ - const axstd::string_map& getActiveVertexInputs() const override; + const tlx::string_map& getActiveVertexInputs() const override; /** * Get uniform buffer size in bytes that can hold all the uniforms. @@ -159,7 +159,7 @@ class ProgramImpl : public Program * Get all uniformInfos. * @return The uniformInfos. */ - const axstd::string_map& getActiveUniformInfos(ShaderStage stage) const override; + const tlx::string_map& getActiveUniformInfos(ShaderStage stage) const override; void bindUniformBuffers(const char* buffer, size_t bufferSize); @@ -187,12 +187,12 @@ class ProgramImpl : public Program ShaderModuleImpl* _vertexShaderModule = nullptr; ShaderModuleImpl* _fragmentShaderModule = nullptr; - axstd::pod_vector _uniformBuffers; + tlx::pod_vector _uniformBuffers; std::vector _attributeInfos; - axstd::string_map _activeVertexInputs; - axstd::string_map _activeUniformInfos; + tlx::string_map _activeVertexInputs; + tlx::string_map _activeUniformInfos; #if AX_ENABLE_CONTEXT_LOSS_RECOVERY std::unordered_map diff --git a/axmol/rhi/opengl/RenderContextGL.cpp b/axmol/rhi/opengl/RenderContextGL.cpp index bfb940e52b56..fb5a96fd2da6 100644 --- a/axmol/rhi/opengl/RenderContextGL.cpp +++ b/axmol/rhi/opengl/RenderContextGL.cpp @@ -449,7 +449,7 @@ void RenderContextImpl::readPixels(RenderTarget* rt, glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, nullptr); auto buffer_ptr = (uint8_t*)glMapBufferRange(GL_PIXEL_PACK_BUFFER, 0, bufferSize, GL_MAP_READ_BIT); #else - axstd::byte_buffer buffer(static_cast(bufferSize), 0); + tlx::byte_buffer buffer(static_cast(bufferSize), 0); auto buffer_ptr = buffer.data(); glReadPixels(x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer_ptr); #endif @@ -482,7 +482,7 @@ void RenderContextImpl::readPixels(RenderTarget* rt, #if AX_HAVE_MAP_BUFFER_RANGE pbd._data.copy(buffer_ptr, static_cast(bufferSize)); #else - static_cast(pbd._data).swap(buffer); + static_cast(pbd._data).swap(buffer); #endif } } diff --git a/axmol/rhi/opengl/ShaderModuleGL.cpp b/axmol/rhi/opengl/ShaderModuleGL.cpp index 53692888efa6..e6ba41fc2c6b 100644 --- a/axmol/rhi/opengl/ShaderModuleGL.cpp +++ b/axmol/rhi/opengl/ShaderModuleGL.cpp @@ -62,7 +62,7 @@ void ShaderModuleImpl::compileShader(ShaderStage stage, std::string_view source) if (logLength > 1) { - auto errorLog = axstd::make_unique_for_overwrite(static_cast(logLength)); + auto errorLog = tlx::make_unique_for_overwrite(static_cast(logLength)); glGetShaderInfoLog(_shader, logLength, nullptr, (GLchar*)errorLog.get()); AXLOGE("axmol:ERROR: Failed to compile shader, detail: {}\n{}", errorLog.get(), source.data()); } diff --git a/axmol/rhi/vulkan/BufferVK.h b/axmol/rhi/vulkan/BufferVK.h index 606167683486..59ec9146f6d9 100644 --- a/axmol/rhi/vulkan/BufferVK.h +++ b/axmol/rhi/vulkan/BufferVK.h @@ -72,7 +72,7 @@ class BufferImpl final : public Buffer private: void createNativeBuffer(const void* initial); - axstd::byte_buffer _defaultData; + tlx::byte_buffer _defaultData; bool _needDefaultStoredData = false; DriverImpl* _driver{nullptr}; diff --git a/axmol/rhi/vulkan/DepthStencilStateVK.cpp b/axmol/rhi/vulkan/DepthStencilStateVK.cpp index 07d652adeb40..332e595e9071 100644 --- a/axmol/rhi/vulkan/DepthStencilStateVK.cpp +++ b/axmol/rhi/vulkan/DepthStencilStateVK.cpp @@ -93,7 +93,7 @@ static VkStencilOpState make_op_state(const StencilDesc& s) DepthStencilStateImpl::DepthStencilStateImpl() { - _hash = axstd::hash_bytes(&_dsDesc, sizeof(_dsDesc)); + _hash = tlx::hash_bytes(&_dsDesc, sizeof(_dsDesc)); // Disabled state _disableInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO; @@ -109,7 +109,7 @@ void DepthStencilStateImpl::update(const DepthStencilDesc& desc) { DepthStencilState::update(desc); - _hash = axstd::hash_bytes(&_dsDesc, sizeof(_dsDesc)); + _hash = tlx::hash_bytes(&_dsDesc, sizeof(_dsDesc)); if (!isEnabled()) { diff --git a/axmol/rhi/vulkan/DriverVK.cpp b/axmol/rhi/vulkan/DriverVK.cpp index 788d596fad70..a93bbe1a8fc4 100644 --- a/axmol/rhi/vulkan/DriverVK.cpp +++ b/axmol/rhi/vulkan/DriverVK.cpp @@ -104,7 +104,7 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL vkDebugCallback(VkDebugUtilsMessageSeverit return VK_FALSE; } -static std::pair resolveAdapter(const axstd::pod_vector& devices, +static std::pair resolveAdapter(const tlx::pod_vector& devices, VkInstance instance, PowerPreference pref) { @@ -274,7 +274,7 @@ void DriverImpl::initializeFactory() appInfo.apiVersion = VK_API_VERSION_1_3; // axmol requires vulkan-1.3 // Collect required extensions - axstd::pod_vector extensions; + tlx::pod_vector extensions; extensions.push_back(VK_KHR_SURFACE_EXTENSION_NAME); #if AX_TARGET_PLATFORM == AX_PLATFORM_WIN32 @@ -342,7 +342,7 @@ void DriverImpl::initializeDevice() vkEnumeratePhysicalDevices(_factory, &count, nullptr); AXASSERT(count > 0, "No Vulkan physical devices found"); - axstd::pod_vector devices(count); + tlx::pod_vector devices(count); vkEnumeratePhysicalDevices(_factory, &count, devices.data()); auto [physical, graphicsQueueFamily] = resolveAdapter(devices, _factory, contextAttrs.powerPreference); @@ -365,7 +365,7 @@ void DriverImpl::initializeDevice() /* * https://vulkan.lunarg.com/doc/view/1.4.328.1/windows/antora/spec/latest/chapters/drawing.html#VUID-vkCmdDraw-dynamicPrimitiveTopologyUnrestricted-07500 */ - axstd::pod_vector deviceExtensions; + tlx::pod_vector deviceExtensions; deviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); deviceExtensions.push_back(VK_EXT_EXTENDED_DYNAMIC_STATE_EXTENSION_NAME); @@ -867,8 +867,8 @@ void DriverImpl::cleanPendingResources() // Rebuild swapchain attachments from a swapchain image handle. // Note: swapchainImage must be a VkImage (provided as void* to keep signature parity). -void DriverImpl::rebuildSwapchainAttachments(const axstd::pod_vector& images, - const axstd::pod_vector& imageViews, +void DriverImpl::rebuildSwapchainAttachments(const tlx::pod_vector& images, + const tlx::pod_vector& imageViews, const VkExtent2D& extent, PixelFormat imagePF) { diff --git a/axmol/rhi/vulkan/DriverVK.h b/axmol/rhi/vulkan/DriverVK.h index d4f4564ba2b3..c2c069d14f32 100644 --- a/axmol/rhi/vulkan/DriverVK.h +++ b/axmol/rhi/vulkan/DriverVK.h @@ -160,8 +160,8 @@ class DriverImpl : public DriverBase void processDisposalQueue(uint64_t completedFenceValue); - void rebuildSwapchainAttachments(const axstd::pod_vector& images, - const axstd::pod_vector&, + void rebuildSwapchainAttachments(const tlx::pod_vector& images, + const tlx::pod_vector&, const VkExtent2D&, PixelFormat imagePF); @@ -205,7 +205,7 @@ class DriverImpl : public DriverBase VkCommandPool _commandPool{VK_NULL_HANDLE}; std::mutex _commandPoolMutex; - axstd::pod_vector _disposalQueue; + tlx::pod_vector _disposalQueue; uint32_t _graphicsQueueFamily{0}; uint32_t _presentQueueFamily{0}; @@ -216,7 +216,7 @@ class DriverImpl : public DriverBase std::string _shaderVersion; // store and provide swapchain render target attachments - axstd::pod_vector _swapchainColorAttachments; + tlx::pod_vector _swapchainColorAttachments; uint32_t _currentSwapchainImageIndex = 0; TextureImpl* _swapchainDepthStencilAttachment = nullptr; }; diff --git a/axmol/rhi/vulkan/ProgramVK.cpp b/axmol/rhi/vulkan/ProgramVK.cpp index 1808c63ae5ba..130d0541af69 100644 --- a/axmol/rhi/vulkan/ProgramVK.cpp +++ b/axmol/rhi/vulkan/ProgramVK.cpp @@ -53,7 +53,7 @@ const VertexInputDesc* ProgramImpl::getVertexInputDesc(std::string_view name) co return _vertexShader->getVertexInputDesc(name); } -const axstd::string_map& ProgramImpl::getActiveVertexInputs() const +const tlx::string_map& ProgramImpl::getActiveVertexInputs() const { return _vertexShader->getActiveVertexInputs(); } @@ -107,7 +107,7 @@ std::size_t ProgramImpl::getUniformBufferSize(ShaderStage stage) const return 0; } -const axstd::string_map& ProgramImpl::getActiveUniformInfos(ShaderStage stage) const +const tlx::string_map& ProgramImpl::getActiveUniformInfos(ShaderStage stage) const { return stage == ShaderStage::VERTEX ? _vertexShader->getActiveUniformInfos() : _fragmentShader->getActiveUniformInfos(); diff --git a/axmol/rhi/vulkan/ProgramVK.h b/axmol/rhi/vulkan/ProgramVK.h index f620fc9e49d3..cd8d334eff88 100644 --- a/axmol/rhi/vulkan/ProgramVK.h +++ b/axmol/rhi/vulkan/ProgramVK.h @@ -45,7 +45,7 @@ class ProgramImpl : public Program const VertexInputDesc* getVertexInputDesc(std::string_view name) const override; const VertexInputDesc* getVertexInputDesc(VertexInputKind name) const override; - const axstd::string_map& getActiveVertexInputs() const override; + const tlx::string_map& getActiveVertexInputs() const override; ShaderModuleImpl* getVertexShader() const { return _vertexShader; } ShaderModuleImpl* getFragmentShader() const { return _fragmentShader; } @@ -54,7 +54,7 @@ class ProgramImpl : public Program int getMaxFragmentLocation() const override; std::size_t getUniformBufferSize(ShaderStage stage) const override; - const axstd::string_map& getActiveUniformInfos(ShaderStage stage) const override; + const tlx::string_map& getActiveUniformInfos(ShaderStage stage) const override; // Vulkan specific: return VkShaderModule handles VkShaderModule getVSModule() const { return _vertexShader->internalHandle(); } diff --git a/axmol/rhi/vulkan/RenderContextVK.cpp b/axmol/rhi/vulkan/RenderContextVK.cpp index ad56c16e00fd..e8a3e3735c1f 100644 --- a/axmol/rhi/vulkan/RenderContextVK.cpp +++ b/axmol/rhi/vulkan/RenderContextVK.cpp @@ -112,7 +112,7 @@ inline bool operator==(const VkRect2D& a, const VkRect2D& b) a.extent.height == b.extent.height; } -static void destroySemphores(axstd::pod_vector& semaphores, VkDevice device) +static void destroySemphores(tlx::pod_vector& semaphores, VkDevice device) { for (auto semaphore : semaphores) vkDestroySemaphore(device, semaphore, nullptr); diff --git a/axmol/rhi/vulkan/RenderContextVK.h b/axmol/rhi/vulkan/RenderContextVK.h index 04622c9d94d8..8c51124cdfe3 100644 --- a/axmol/rhi/vulkan/RenderContextVK.h +++ b/axmol/rhi/vulkan/RenderContextVK.h @@ -181,8 +181,8 @@ class RenderContextImpl : public RenderContext VkCommandPool _commandPool{VK_NULL_HANDLE}; - axstd::pod_vector _swapchainImages; - axstd::pod_vector _swapchainImageViews; + tlx::pod_vector _swapchainImages; + tlx::pod_vector _swapchainImageViews; uint32_t _semaphoreIndex{0}; @@ -197,13 +197,13 @@ class RenderContextImpl : public RenderContext #if !_AX_USE_DESCRIPTOR_CACHE std::array _descriptorPools{}; #endif - std::array, MAX_FRAMES_IN_FLIGHT> _inFlightDescriptorStates; + std::array, MAX_FRAMES_IN_FLIGHT> _inFlightDescriptorStates; - axstd::pod_vector _acquireCompleteSemaphores; - axstd::pod_vector _renderFinishedSemaphores; + tlx::pod_vector _acquireCompleteSemaphores; + tlx::pod_vector _renderFinishedSemaphores; - axstd::pod_vector _descriptorWritesPerFrame; - axstd::pod_vector _descriptorImageInfosPerFrame; + tlx::pod_vector _descriptorWritesPerFrame; + tlx::pod_vector _descriptorImageInfosPerFrame; VkCommandBuffer _currentCmdBuffer{VK_NULL_HANDLE}; // weak pointer diff --git a/axmol/rhi/vulkan/RenderPipelineVK.cpp b/axmol/rhi/vulkan/RenderPipelineVK.cpp index e21ae3228702..fcd67799498e 100644 --- a/axmol/rhi/vulkan/RenderPipelineVK.cpp +++ b/axmol/rhi/vulkan/RenderPipelineVK.cpp @@ -137,7 +137,7 @@ static inline uintptr_t makePipelineKey(const rhi::BlendDesc& blendDesc, HashMe hashMe{ .blend = blendDesc, .dsHash = dsState->getHash(), .prog = program, .pass = renderPass, .vlHash = vlHash}; - return axstd::hash_bytes(&hashMe, sizeof(hashMe), 0); + return tlx::hash_bytes(&hashMe, sizeof(hashMe), 0); } // Build the VkPipelineColorBlendAttachmentState from BlendDesc @@ -281,8 +281,8 @@ void RenderPipelineImpl::updateDescriptorSetLayouts(ProgramImpl* program) return; } - axstd::pod_vector ubBindings; - axstd::pod_vector samplerBindings; + tlx::pod_vector ubBindings; + tlx::pod_vector samplerBindings; DescriptorSetLayoutState dslState{}; @@ -393,7 +393,7 @@ void RenderPipelineImpl::updateGraphicsPipeline(const PipelineDesc& desc, VkRend } // Shader stages - axstd::pod_vector stages; + tlx::pod_vector stages; if (auto vs = program->getVSModule()) { VkPipelineShaderStageCreateInfo& s = stages.emplace_back(); @@ -499,7 +499,7 @@ void RenderPipelineImpl::recycleDescriptorState(DescriptorState& state) { AXLOGD("DescriptorSetCache miss: no pool found for pipelineLayout={}, creating new pool", fmt::ptr(state.ownerLayout)); - it = _descriptorCache.emplace(state.ownerLayout, DescriptorPool{}).first; + it = _descriptorCache.emplace(state.ownerLayout, DescriptorPool()).first; } // Push the allocation back into the free list for the given frame index diff --git a/axmol/rhi/vulkan/RenderPipelineVK.h b/axmol/rhi/vulkan/RenderPipelineVK.h index 7c0b14678ba0..7c2f961750e8 100644 --- a/axmol/rhi/vulkan/RenderPipelineVK.h +++ b/axmol/rhi/vulkan/RenderPipelineVK.h @@ -73,7 +73,7 @@ class RenderPipelineImpl : public RenderPipeline int frameIndex; // Frame index (for multi-frame in flight) }; - using DescriptorPool = std::array, MAX_FRAMES_IN_FLIGHT>; + using DescriptorPool = std::array, MAX_FRAMES_IN_FLIGHT>; explicit RenderPipelineImpl(VkDevice device); ~RenderPipelineImpl(); @@ -137,12 +137,12 @@ class RenderPipelineImpl : public RenderPipeline VkPipeline _activePipeline{VK_NULL_HANDLE}; - axstd::pod_vector _descriptorPools; + tlx::pod_vector _descriptorPools; - axstd::hash_map _descriptorLayoutCache; - axstd::hash_map _pipelineLayoutCache; - axstd::hash_map _pipelineCache; // PSO cache - axstd::hash_map _descriptorCache; + tlx::hash_map _descriptorLayoutCache; + tlx::hash_map _pipelineLayoutCache; + tlx::hash_map _pipelineCache; // PSO cache + tlx::hash_map _descriptorCache; // TODO: std::multimap _programToPipelineMap; diff --git a/axmol/rhi/vulkan/RenderTargetVK.cpp b/axmol/rhi/vulkan/RenderTargetVK.cpp index 857ed8b462e0..943829a38184 100644 --- a/axmol/rhi/vulkan/RenderTargetVK.cpp +++ b/axmol/rhi/vulkan/RenderTargetVK.cpp @@ -39,7 +39,7 @@ namespace ax::rhi::vk // - Attachment count // - Framebuffer width/height static uintptr_t makeFramebufferKeyHash(VkRenderPass rp, - const axstd::pod_vector& views, + const tlx::pod_vector& views, uint32_t width, uint32_t height) { @@ -53,9 +53,9 @@ static uintptr_t makeFramebufferKeyHash(VkRenderPass rp, } hdr{reinterpret_cast(rp), static_cast(views.size()), width, height}; // Hash header first, then hash the views array in order. - uintptr_t h = axstd::hash_bytes(&hdr, sizeof(hdr), 0); + uintptr_t h = tlx::hash_bytes(&hdr, sizeof(hdr), 0); if (!views.empty()) - h = axstd::hash_bytes(views.data(), views.size_bytes(), h); + h = tlx::hash_bytes(views.data(), views.size_bytes(), h); return h; } @@ -270,7 +270,7 @@ void RenderTargetImpl::updateFramebuffer(VkCommandBuffer /*cmd*/) hashMe.attachmentsHash = _attachmentViewsHash; hashMe.renderPassh = _renderPass; - auto key = axstd::hash_bytes(&hashMe, sizeof(hashMe)); + auto key = tlx::hash_bytes(&hashMe, sizeof(hashMe)); if (auto it = _framebufferCache.find(key); it != _framebufferCache.end()) { _framebuffer = it->second; @@ -278,7 +278,7 @@ void RenderTargetImpl::updateFramebuffer(VkCommandBuffer /*cmd*/) else { // Build ordered views vector (contiguous colors + optional depth) - axstd::pod_vector views; + tlx::pod_vector views; views.reserve(MAX_COLOR_ATTCHMENT + 1); for (size_t i = 0; i < MAX_COLOR_ATTCHMENT; ++i) { @@ -322,7 +322,7 @@ void RenderTargetImpl::updateFramebuffer(VkCommandBuffer /*cmd*/) void RenderTargetImpl::updateRenderPass(const RenderPassDesc& desc) { - const auto key = axstd::hash_bytes(&desc, sizeof(desc), _attachmentViewsHash); + const auto key = tlx::hash_bytes(&desc, sizeof(desc), _attachmentViewsHash); if (auto it = _renderPassCache.find(key); it != _renderPassCache.end()) { @@ -331,8 +331,8 @@ void RenderTargetImpl::updateRenderPass(const RenderPassDesc& desc) else { // Build attachment descriptions deterministically (contiguous colors + optional depth) - axstd::pod_vector attachments; - axstd::pod_vector colorRefs; + tlx::pod_vector attachments; + tlx::pod_vector colorRefs; VkAttachmentReference depthRef{}; attachments.reserve(MAX_COLOR_ATTCHMENT + 1); colorRefs.reserve(MAX_COLOR_ATTCHMENT); diff --git a/axmol/rhi/vulkan/RenderTargetVK.h b/axmol/rhi/vulkan/RenderTargetVK.h index 368818fa1e6b..e3241949296c 100644 --- a/axmol/rhi/vulkan/RenderTargetVK.h +++ b/axmol/rhi/vulkan/RenderTargetVK.h @@ -72,14 +72,14 @@ class RenderTargetImpl : public RenderTarget std::array _attachmentTexPtrs; uint64_t _attachmentViewsHash{0}; - axstd::pod_vector _clearValues; + tlx::pod_vector _clearValues; VkRenderPass _renderPass{VK_NULL_HANDLE}; // active render pass VkFramebuffer _framebuffer{VK_NULL_HANDLE}; // active framebuffer // Caches keyed by (desc hash, attachment views hash) - axstd::hash_map _renderPassCache; - axstd::hash_map _framebufferCache; + tlx::hash_map _renderPassCache; + tlx::hash_map _framebufferCache; bool _attachmentsDirty{true}; }; diff --git a/axmol/rhi/vulkan/SemaphorePoolVK.h b/axmol/rhi/vulkan/SemaphorePoolVK.h index 27db14ac336d..a5e8c24634b2 100644 --- a/axmol/rhi/vulkan/SemaphorePoolVK.h +++ b/axmol/rhi/vulkan/SemaphorePoolVK.h @@ -24,7 +24,7 @@ #pragma once #include "glad/vulkan.h" -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" namespace ax::rhi::vk { @@ -40,6 +40,6 @@ class SemaphorePool protected: VkDevice _device{VK_NULL_HANDLE}; - axstd::pod_vector _pool; + tlx::pod_vector _pool; }; } // namespace ax::rhi::vk diff --git a/axmol/rhi/vulkan/ShaderModuleVK.h b/axmol/rhi/vulkan/ShaderModuleVK.h index 66862f615b9f..def7cb3e1d64 100644 --- a/axmol/rhi/vulkan/ShaderModuleVK.h +++ b/axmol/rhi/vulkan/ShaderModuleVK.h @@ -87,13 +87,13 @@ class ShaderModuleImpl : public ShaderModule * Get active attribute informations. * @return Active attribute informations. key is attribute name and Value is corresponding attribute info. */ - inline const axstd::string_map& getActiveVertexInputs() const { return _activeVertexInputs; } + inline const tlx::string_map& getActiveVertexInputs() const { return _activeVertexInputs; } /** * Get all uniformInfos. * @return The uniformInfos. */ - inline const axstd::string_map& getActiveUniformInfos() const { return _activeUniformInfos; } + inline const tlx::string_map& getActiveUniformInfos() const { return _activeUniformInfos; } inline const std::vector& getActiveUniformBlockInfos() const { return _activeUniformBlockInfos; } inline const std::vector& getActiveSamplerInfos() const { return _activeSamplerInfos; } @@ -122,8 +122,8 @@ class ShaderModuleImpl : public ShaderModule VkShaderModule _shader = VK_NULL_HANDLE; - axstd::string_map _activeVertexInputs; - axstd::string_map _activeUniformInfos; + tlx::string_map _activeVertexInputs; + tlx::string_map _activeUniformInfos; std::vector _activeUniformBlockInfos; std::vector _activeSamplerInfos; diff --git a/axmol/rhi/vulkan/TextureVK.h b/axmol/rhi/vulkan/TextureVK.h index 8d2e7092be92..f069c9d8f8cf 100644 --- a/axmol/rhi/vulkan/TextureVK.h +++ b/axmol/rhi/vulkan/TextureVK.h @@ -28,7 +28,7 @@ #include #include -#include "axmol/tlx/pod_vector.hpp" +#include "axmol/tlx/vector.hpp" namespace ax::rhi::vk { @@ -99,7 +99,7 @@ class ImageLayoutTracker } private: - std::vector> _layouts; + std::vector> _layouts; }; /** diff --git a/axmol/tlx/byte_buffer.hpp b/axmol/tlx/byte_buffer.hpp index a5d2b531850c..7ef4aa594af2 100644 --- a/axmol/tlx/byte_buffer.hpp +++ b/axmol/tlx/byte_buffer.hpp @@ -23,10 +23,4 @@ ****************************************************************************/ #pragma once -#include "yasio/byte_buffer.hpp" - -namespace axstd -{ -using byte_buffer = yasio::byte_buffer; -using sbyte_buffer = yasio::sbyte_buffer; -} // namespace axstd +#include "yasio/tlx/byte_buffer.hpp" diff --git a/axmol/tlx/charconv.hpp b/axmol/tlx/charconv.hpp index 392e3c6902db..8dd5ef29a005 100644 --- a/axmol/tlx/charconv.hpp +++ b/axmol/tlx/charconv.hpp @@ -27,17 +27,17 @@ // use fast_float instead: https://github.com/fastfloat/fast_float #if !defined(_WIN32) && defined(__clang__) # include "fast_float/fast_float.h" -namespace axstd +namespace tlx { using fast_float::from_chars; using from_chars_result = fast_float::from_chars_result; -} // namespace axstd +} // namespace tlx #else # include -namespace axstd +namespace tlx { using std::from_chars; using std::from_chars_result; -} // namespace axstd +} // namespace tlx #endif diff --git a/axmol/tlx/filesystem.hpp b/axmol/tlx/filesystem.hpp index a5a99cd366cb..dc03e4dcd98e 100644 --- a/axmol/tlx/filesystem.hpp +++ b/axmol/tlx/filesystem.hpp @@ -28,8 +28,16 @@ #if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000) || \ (defined(__NDK_MAJOR__) && __NDK_MAJOR__ < 22) # include "ghc/filesystem.hpp" -namespace stdfs = ghc::filesystem; +namespace tlx +{ +namespace filesystem = ghc::filesystem; +} #else # include -namespace stdfs = std::filesystem; +namespace tlx +{ +namespace filesystem = std::filesystem; +} #endif + +namespace stdfs = tlx::filesystem; diff --git a/axmol/tlx/flat_map.hpp b/axmol/tlx/flat_map.hpp index 9d5c9f99d770..3f3ec326d33b 100644 --- a/axmol/tlx/flat_map.hpp +++ b/axmol/tlx/flat_map.hpp @@ -20,29 +20,39 @@ THE SOFTWARE. ****************************************************************************/ #pragma once -#include "axmol/tlx/sorted_vector.hpp" +#include "axmol/tlx/flat_map_base.hpp" +#include -namespace axstd +namespace tlx { + // flat_map traits -template , class Alloc = std::allocator>> +template , + class KeyAlloc = std::allocator, + class MappedAlloc = std::allocator> struct flat_map_traits { - using key_type = Key; - using value_type = std::pair; - using key_compare = Compare; - using value_compare = Compare; - using allocator_type = Alloc; - using key_extractor = detail::select1st; + using key_type = Key; + using mapped_type = T; + using key_compare = Compare; + using allocator_type = KeyAlloc; + using key_container = std::vector; + using mapped_container = std::vector; static constexpr bool allow_duplicates = false; }; -/// flat_map -template , class Alloc = std::allocator>> -class flat_map : public detail::sorted_vector> +template , + class KeyAlloc = std::allocator, + class MappedAlloc = std::allocator> +class flat_map : public detail::flat_map_base> { - using impl_type = detail::sorted_vector>; + using traits = flat_map_traits; + using impl_type = detail::flat_map_base; public: using impl_type::impl_type; @@ -50,12 +60,18 @@ class flat_map : public detail::sorted_vectorlower_bound(key); - if (it == this->end() || Compare{}(key, it->first)) + auto& pred = this->_Mykeys._Get_first(); + auto it = this->lower_bound(key); + if (it == this->end() || pred(key, (*it).first)) { - it = this->_Mypair.second().insert(it, {key, T{}}); + auto pos = it._k_it; + auto idx = pos - this->_Mykeys._Myval2.begin(); + this->_Mykeys._Myval2.insert(pos, key); + this->_Myvals.emplace(this->_Myvals.begin() + idx); + it = typename impl_type::iterator(this->_Mykeys._Myval2.begin() + idx, this->_Myvals.begin() + idx); } - return it->second; + return (*it).second; } }; -} // namespace axstd + +} // namespace tlx diff --git a/axmol/tlx/flat_map_base.hpp b/axmol/tlx/flat_map_base.hpp new file mode 100644 index 000000000000..57c05595625a --- /dev/null +++ b/axmol/tlx/flat_map_base.hpp @@ -0,0 +1,284 @@ +/**************************************************************************** + Copyright (c) 2019-present Axmol Engine contributors (see AUTHORS.md). + + https://axmol.dev/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ +#pragma once +#include +#include +#include +#include +#include "yasio/tlx/memory.hpp" + +namespace tlx +{ +namespace detail +{ + +template +class flat_map_base +{ +public: + using key_type = typename _Traits::key_type; + using mapped_type = typename _Traits::mapped_type; + using allocator_type = typename _Traits::allocator_type; + using key_container = typename _Traits::key_container; + using mapped_container = typename _Traits::mapped_container; + +protected: + using key_alloc = typename std::allocator_traits::template rebind_alloc; + using mapped_alloc = typename std::allocator_traits::template rebind_alloc; + +public: + using key_compare = typename _Traits::key_compare; + + using size_type = typename std::allocator_traits::size_type; + using difference_type = typename std::allocator_traits::difference_type; + +#pragma region value and iterator proxy + struct value_proxy + { + const key_type& first; + mapped_type& second; + + value_proxy* operator->() { return this; } + const value_proxy* operator->() const { return this; } + }; + + class iterator + { + public: + using key_iter = typename key_container::iterator; + using mapped_iter = typename mapped_container::iterator; + key_iter _k_it; + mapped_iter _v_it; + + using difference_type = typename key_container::difference_type; + using value_type = value_proxy; + using reference = value_proxy; + using pointer = value_proxy*; + using iterator_category = std::random_access_iterator_tag; + + iterator(key_iter k_it, mapped_iter v_it) : _k_it(k_it), _v_it(v_it) {} + reference operator*() const { return value_proxy{*_k_it, *_v_it}; } + value_proxy operator->() const { return {*_k_it, *_v_it}; } + + iterator& operator++() + { + ++_k_it; + ++_v_it; + return *this; + } + iterator operator++(int) + { + auto tmp = *this; + ++*this; + return tmp; + } + + bool operator==(const iterator& other) const { return _k_it == other._k_it; } + bool operator!=(const iterator& other) const { return !(*this == other); } + }; + + class const_iterator + { + public: + using key_iter = typename key_container::const_iterator; + using mapped_iter = typename mapped_container::const_iterator; + key_iter _k_it; + mapped_iter _v_it; + + using difference_type = typename key_container::difference_type; + using value_type = value_proxy; + using reference = value_proxy; + using pointer = const value_proxy*; + using iterator_category = std::random_access_iterator_tag; + + const_iterator(key_iter k_it, mapped_iter v_it) : _k_it(k_it), _v_it(v_it) {} + reference operator*() const { return value_proxy{*_k_it, const_cast(*_v_it)}; } + value_proxy operator->() const { return {*_k_it, const_cast(*_v_it)}; } + + const_iterator& operator++() + { + ++_k_it; + ++_v_it; + return *this; + } + const_iterator operator++(int) + { + auto tmp = *this; + ++*this; + return tmp; + } + + bool operator==(const const_iterator& other) const { return _k_it == other._k_it; } + bool operator!=(const const_iterator& other) const { return !(*this == other); } + }; +#pragma endregion + + explicit flat_map_base(const key_compare& pred = key_compare(), const allocator_type& alloc = allocator_type()) + : _Mykeys(_TLX __one_then_variadic_args_t{}, pred, key_container(alloc)), _Myvals(alloc) + {} + + void reserve(size_t capacity) + { + _Mykeys._Myval2.reserve(capacity); + _Myvals.reserve(capacity); + } + void clear() + { + _Mykeys._Myval2.clear(); + _Myvals.clear(); + } + + bool empty() const noexcept { return _Mykeys._Myval2.empty(); } + size_t size() const noexcept { return _Mykeys._Myval2.size(); } + + iterator begin() noexcept { return iterator(_Mykeys._Myval2.begin(), _Myvals.begin()); } + iterator end() noexcept { return iterator(_Mykeys._Myval2.end(), _Myvals.end()); } + const_iterator begin() const noexcept { return const_iterator(_Mykeys._Myval2.begin(), _Myvals.begin()); } + const_iterator end() const noexcept { return const_iterator(_Mykeys._Myval2.end(), _Myvals.end()); } + + iterator find(const key_type& key) + { + const auto& pred = _Mykeys._Get_first(); + auto it = lower_bound(key); + if (it != end() && !pred(key, (*it).first) && !pred((*it).first, key)) + return it; + return end(); + } + + const_iterator find(const key_type& key) const + { + const auto& pred = _Mykeys._Get_first(); + auto it = lower_bound(key); + if (it != end() && !pred(key, (*it).first) && !pred((*it).first, key)) + return it; + return end(); + } + + iterator lower_bound(const key_type& key) + { + const auto& pred = _Mykeys._Get_first(); + auto k_it = std::lower_bound(_Mykeys._Myval2.begin(), _Mykeys._Myval2.end(), key, pred); + auto v_it = _Myvals.begin() + (k_it - _Mykeys._Myval2.begin()); + return iterator(k_it, v_it); + } + + const_iterator lower_bound(const key_type& key) const + { + const auto& pred = _Mykeys._Get_first(); + auto k_it = std::lower_bound(_Mykeys._Myval2.begin(), _Mykeys._Myval2.end(), key, pred); + auto v_it = _Myvals.begin() + (k_it - _Mykeys._Myval2.begin()); + return const_iterator(k_it, v_it); + } + + template + void insert(InputIt first, InputIt last) + { + for (; first != last; ++first) + { + insert(first->first, first->second); + } + } + + std::pair insert(const key_type& k, const mapped_type& v) + { + return emplace(std::forward(k), std::forward(v)); + } + + template + std::pair emplace(_KeyArg&& key, _MArgs&&... mapped_args) + { + const auto& pred = _Mykeys._Get_first(); + auto key_it = std::lower_bound(_Mykeys._Myval2.begin(), _Mykeys._Myval2.end(), key, pred); + auto mapped_it = _Myvals.begin() + (key_it - _Mykeys._Myval2.begin()); + + if constexpr (_Traits::allow_duplicates) + { + // multimap: always insert at upper_bound + key_it = _Mykeys._Myval2.insert(key_it, std::forward<_KeyArg>(key)); + mapped_it = _Myvals.insert(mapped_it, mapped_type(std::forward<_MArgs>(mapped_args)...)); + return {iterator(key_it, mapped_it), true}; + } + else + { + // map: only insert if key not found + if (key_it == _Mykeys._Myval2.end() || pred(key, *key_it)) + { + key_it = _Mykeys._Myval2.insert(key_it, std::forward<_KeyArg>(key)); + mapped_it = _Myvals.insert(mapped_it, mapped_type(std::forward<_MArgs>(mapped_args)...)); + return {iterator(key_it, mapped_it), true}; + } + else + { + return {iterator(key_it, mapped_it), false}; + } + } + } + + // erase by iterator + iterator erase(iterator pos) + { + auto k_it = pos._k_it; + auto v_it = pos._v_it; + _Mykeys._Myval2.erase(k_it); + _Myvals.erase(v_it); + return iterator(k_it, v_it); + } + + // erase by key + size_type erase(const key_type& key) + { + const auto& pred = _Mykeys._Get_first(); + auto k_it = std::lower_bound(_Mykeys._Myval2.begin(), _Mykeys._Myval2.end(), key, pred); + auto v_it = _Myvals.begin() + (k_it - _Mykeys._Myval2.begin()); + + if (k_it == _Mykeys._Myval2.end() || pred(key, *k_it) || pred(*k_it, key)) + return 0; // not found + + if constexpr (_Traits::allow_duplicates) + { + // multimap: erase all equal keys + auto k_end = std::upper_bound(k_it, _Mykeys._Myval2.end(), key, pred); + auto v_end = _Myvals.begin() + (k_end - _Mykeys._Myval2.begin()); + + size_type count = static_cast(k_end - k_it); + _Mykeys._Myval2.erase(k_it, k_end); + _Myvals.erase(v_it, v_end); + return count; + } + else + { + // map: erase single element + _Mykeys._Myval2.erase(k_it); + _Myvals.erase(v_it); + return 1; + } + } + + const auto& keys() const { return _Mykeys; } + +protected: + _TLX __compressed_pair _Mykeys; + mapped_container _Myvals; +}; + +} // namespace detail +} // namespace tlx diff --git a/axmol/tlx/flat_multimap.hpp b/axmol/tlx/flat_multimap.hpp index 1691879a0904..c38bab82788d 100644 --- a/axmol/tlx/flat_multimap.hpp +++ b/axmol/tlx/flat_multimap.hpp @@ -20,31 +20,42 @@ THE SOFTWARE. ****************************************************************************/ #pragma once -#include "axmol/tlx/sorted_vector.hpp" +#include "axmol/tlx/flat_map_base.hpp" +#include -namespace axstd +namespace tlx { -// flat_multimap traits -template , class Alloc = std::allocator>> + +// flat_map traits +template , + class KeyAlloc = std::allocator, + class MappedAlloc = std::allocator> struct flat_multimap_traits { - using key_type = Key; - using value_type = std::pair; - using key_compare = Compare; - using value_compare = Compare; - using allocator_type = Alloc; - using key_extractor = detail::select1st; + using key_type = Key; + using mapped_type = T; + using key_compare = Compare; + using allocator_type = KeyAlloc; + using key_container = std::vector; + using mapped_container = std::vector; static constexpr bool allow_duplicates = true; }; -/// flat_multimap -template , class Alloc = std::allocator>> -class flat_multimap : public detail::sorted_vector> +template , + class KeyAlloc = std::allocator, + class MappedAlloc = std::allocator> +class flat_multimap : public detail::flat_map_base> { - using impl_type = detail::sorted_vector>; + using traits = flat_multimap_traits; + using impl_type = detail::flat_map_base; public: using impl_type::impl_type; }; -} // namespace axstd + +} // namespace tlx diff --git a/axmol/tlx/flat_multiset.hpp b/axmol/tlx/flat_multiset.hpp index bfcd1a8d34e9..59d817dfc08f 100644 --- a/axmol/tlx/flat_multiset.hpp +++ b/axmol/tlx/flat_multiset.hpp @@ -20,31 +20,22 @@ THE SOFTWARE. ****************************************************************************/ #pragma once -#include "axmol/tlx/sorted_vector.hpp" +#include "axmol/tlx/flat_set_base.hpp" +#include -namespace axstd +namespace tlx { -// flat_multiset traits template , class Alloc = std::allocator> struct flat_multiset_traits { - using key_type = Key; - using value_type = Key; - using key_compare = Compare; - using value_compare = Compare; - using allocator_type = Alloc; - using key_extractor = detail::identity; - + using key_type = Key; + using value_type = Key; + using key_compare = Compare; + using allocator_type = Alloc; + using container_type = std::vector; static constexpr bool allow_duplicates = true; }; -/// flat_multiset template , class Alloc = std::allocator> -class flat_multiset : public detail::sorted_vector> -{ - using impl_type = detail::sorted_vector>; - -public: - using impl_type::impl_type; -}; -} // namespace axstd +using flat_multiset = tlx::detail::flat_set_base>; +} // namespace tlx diff --git a/axmol/tlx/flat_set.hpp b/axmol/tlx/flat_set.hpp index 98174b678bc4..67a5fbdefe1d 100644 --- a/axmol/tlx/flat_set.hpp +++ b/axmol/tlx/flat_set.hpp @@ -20,31 +20,22 @@ THE SOFTWARE. ****************************************************************************/ #pragma once -#include "axmol/tlx/sorted_vector.hpp" +#include "axmol/tlx/flat_set_base.hpp" +#include -namespace axstd +namespace tlx { -// flat_set traits template , class Alloc = std::allocator> struct flat_set_traits { - using key_type = Key; - using value_type = Key; - using key_compare = Compare; - using value_compare = Compare; - using allocator_type = Alloc; - using key_extractor = detail::identity; - + using key_type = Key; + using value_type = Key; + using key_compare = Compare; + using allocator_type = Alloc; + using container_type = std::vector; static constexpr bool allow_duplicates = false; }; -/// flat_set template , class Alloc = std::allocator> -class flat_set : public detail::sorted_vector> -{ - using impl_type = detail::sorted_vector>; - -public: - using impl_type::impl_type; -}; -} // namespace axstd +using flat_set = tlx::detail::flat_set_base>; +} // namespace tlx diff --git a/axmol/tlx/flat_set_base.hpp b/axmol/tlx/flat_set_base.hpp new file mode 100644 index 000000000000..b2136a5c2e03 --- /dev/null +++ b/axmol/tlx/flat_set_base.hpp @@ -0,0 +1,217 @@ +/**************************************************************************** + Copyright (c) 2019-present Axmol Engine contributors (see AUTHORS.md). + + https://axmol.dev/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ +#pragma once +#include +#include +#include +#include +#include "yasio/tlx/memory.hpp" + +namespace tlx +{ +namespace detail +{ + +template +class flat_set_base +{ +public: + using key_type = typename _Traits::key_type; + using value_type = typename _Traits::key_type; + using allocator_type = typename _Traits::allocator_type; + using container_type = typename _Traits::container_type; + +protected: + using _Alty = _TLX rebind_alloc_t; + using _Alty_traits = std::allocator_traits<_Alty>; + +public: + using key_compare = typename _Traits::key_compare; + + using size_type = typename _Alty_traits::size_type; + using difference_type = typename _Alty_traits::difference_type; + using pointer = typename _Alty_traits::pointer; + using const_pointer = typename _Alty_traits::const_pointer; + using reference = key_type&; + using const_reference = const key_type&; + using iterator = typename container_type::iterator; + using const_iterator = typename container_type::const_iterator; + + explicit flat_set_base(const key_compare& pred = key_compare(), const allocator_type& alloc = allocator_type()) + : _Mypair(_TLX __one_then_variadic_args_t{}, pred, container_type(alloc)) + {} + + void reserve(size_t capacity) { _Mypair._Myval2.reserve(capacity); } + void clear() { _Mypair._Myval2.clear(); } + + bool empty() const noexcept { return _Mypair._Myval2.empty(); } + size_t size() const noexcept { return _Mypair._Myval2.size(); } + + iterator begin() noexcept { return _Mypair._Myval2.begin(); } + iterator end() noexcept { return _Mypair._Myval2.end(); } + const_iterator begin() const noexcept { return _Mypair._Myval2.begin(); } + const_iterator end() const noexcept { return _Mypair._Myval2.end(); } + + iterator find(const key_type& key) + { + auto& cont = _Mypair._Myval2; + auto& pred = _Mypair._Get_first(); + auto it = lower_bound(key); + if (it != cont.end() && !pred(key, *it) && !pred(*it, key)) + return it; + return cont.end(); + } + + const_iterator find(const key_type& key) const + { + const auto& cont = _Mypair._Myval2; + const auto& pred = _Mypair._Get_first(); + auto it = lower_bound(key); + if (it != cont.end() && !pred(key, *it) && !pred(*it, key)) + return it; + return cont.end(); + } + + iterator lower_bound(const key_type& key) + { + auto& cont = _Mypair._Myval2; + auto& pred = _Mypair._Get_first(); + return std::lower_bound(cont.begin(), cont.end(), key, pred); + } + + const_iterator lower_bound(const key_type& key) const + { + const auto& cont = _Mypair._Myval2; + const auto& pred = _Mypair._Get_first(); + return std::lower_bound(cont.begin(), cont.end(), key, pred); + } + + iterator upper_bound(const key_type& key) + { + auto& cont = _Mypair._Myval2; + auto& pred = _Mypair._Get_first(); + return std::upper_bound(cont.begin(), cont.end(), key, pred); + } + + const_iterator upper_bound(const key_type& key) const + { + const auto& cont = _Mypair._Myval2; + const auto& pred = _Mypair._Get_first(); + return std::upper_bound(cont.begin(), cont.end(), key, pred); + } + + std::pair equal_range(const key_type& key) { return {lower_bound(key), upper_bound(key)}; } + + std::pair equal_range(const key_type& key) const + { + return {lower_bound(key), upper_bound(key)}; + } + + template + void insert(InputIt first, InputIt last) + { + auto& cont = _Mypair._Myval2; + auto& pred = _Mypair._Get_first(); + + cont.insert(cont.end(), first, last); + + std::sort(cont.begin(), cont.end(), pred); + + if constexpr (!_Traits::allow_duplicates) + { + cont.erase(std::unique(cont.begin(), cont.end(), + [&](const key_type& a, const key_type& b) { return !pred(a, b) && !pred(b, a); }), + cont.end()); + } + } + + std::pair insert(const key_type& k) { return emplace(k); } + + iterator insert(const_iterator hint, const key_type& k) { return emplace_hint(hint, k); } + + template + std::pair emplace(Args&&... args) + { + key_type k(std::forward(args)...); + auto& cont = _Mypair._Myval2; + auto& comp = _Mypair._Get_first(); + + if constexpr (_Traits::allow_duplicates) + { + auto it = upper_bound(k); + it = cont.insert(it, std::move(k)); + return {it, true}; + } + else + { + auto it = lower_bound(k); + if (it == cont.end() || comp(k, *it)) + { + it = cont.insert(it, std::move(k)); + return {it, true}; + } + return {it, false}; + } + } + + template + iterator emplace_hint(const_iterator hint, Args&&... args) + { + key_type k(std::forward(args)...); + auto& cont = _Mypair._Myval2; + auto& comp = _Mypair._Get_first(); + + if constexpr (_Traits::allow_duplicates) + { + return cont.insert(hint, std::move(k)); + } + else + { + if (hint == cont.end() || comp(k, *hint)) + { + return cont.insert(hint, std::move(k)); + } + else + { + return emplace(std::move(k)).first; + } + } + } + + size_type erase(const key_type& key) + { + auto range = equal_range(key); + size_type count = std::distance(range.first, range.second); + _Mypair._Myval2.erase(range.first, range.second); + return count; + } + + iterator erase(const_iterator it) { return _Mypair._Myval2.erase(it); } + + const auto& keys() const { return _Mypair._Myval2; } + +protected: + _TLX __compressed_pair _Mypair; +}; + +} // namespace detail +} // namespace tlx diff --git a/axmol/tlx/hash.hpp b/axmol/tlx/hash.hpp index 2880639b1a3f..94cf57f17e40 100644 --- a/axmol/tlx/hash.hpp +++ b/axmol/tlx/hash.hpp @@ -3,7 +3,7 @@ #include "xxhash/xxhash.h" #include -namespace axstd +namespace tlx { inline uintptr_t hash_bytes(const void* data, size_t length, uintptr_t seed = 0) { @@ -12,4 +12,4 @@ inline uintptr_t hash_bytes(const void* data, size_t length, uintptr_t seed = 0) else return XXH32(data, length, static_cast(seed)); } -} // namespace axstd +} // namespace tlx diff --git a/axmol/tlx/hlookup.hpp b/axmol/tlx/hlookup.hpp index 699685d5d01a..69c50dd6b324 100644 --- a/axmol/tlx/hlookup.hpp +++ b/axmol/tlx/hlookup.hpp @@ -27,6 +27,7 @@ #pragma once #include #include +#include #include #include #include @@ -38,7 +39,7 @@ using namespace std::string_literals; using namespace std::string_view_literals; -namespace axstd +namespace tlx { struct string_hash { @@ -63,11 +64,11 @@ struct equal_to using is_transparent = void; }; -template -using hash_map = tsl::robin_map<_Kty, _Valty, std::hash<_Kty>, equal_to>; +template >> +using hash_map = tsl::robin_map<_Kty, _Valty, std::hash<_Kty>, equal_to, _Alloc>; -template -using hash_set = tsl::robin_set<_Kty, std::hash<_Kty>, equal_to>; +template > +using hash_set = tsl::robin_set<_Kty, std::hash<_Kty>, equal_to, _Alloc>; template using string_map = tsl::robin_map; @@ -90,4 +91,4 @@ inline auto set_item(_Cont& cont, _Kty&& k, _Valty&& v) inline constexpr auto empty_sv = ""sv; -} // namespace axstd +} // namespace tlx diff --git a/axmol/tlx/memory.hpp b/axmol/tlx/memory.hpp index 4c536ac0db49..e2d0ab9e65de 100644 --- a/axmol/tlx/memory.hpp +++ b/axmol/tlx/memory.hpp @@ -29,7 +29,7 @@ #include #include "axmol/tlx/type_traits.hpp" -namespace axstd +namespace tlx { /** @@ -279,129 +279,7 @@ inline retain_ptr dynamic_pointer_cast(retain_ptr&& p) noexcept return r; } - -/** compressed_pair - * stores two objects, but applies Empty Base Optimization(EBO) when one of them is an empty type. - * This reduces memory overhead. - */ -template && !std::is_final_v<_Ty1>, - bool = std::is_empty_v<_Ty2> && !std::is_final_v<_Ty2>> -class compressed_pair; - -// Case 1: neither empty -template -class compressed_pair<_Ty1, _Ty2, false, false> -{ - _Ty1 _Myval1; - _Ty2 _Myval2; - -public: - // constructors - constexpr compressed_pair() = default; - - constexpr compressed_pair(const _Ty1& v1, const _Ty2& v2) noexcept(std::is_nothrow_copy_constructible_v<_Ty1> && - std::is_nothrow_copy_constructible_v<_Ty2>) - : _Myval1(v1), _Myval2(v2) - {} - - constexpr compressed_pair(_Ty1&& v1, _Ty2&& v2) noexcept(std::is_nothrow_move_constructible_v<_Ty1> && - std::is_nothrow_move_constructible_v<_Ty2>) - : _Myval1(std::move(v1)), _Myval2(std::move(v2)) - {} - - template - constexpr compressed_pair(U1&& v1, U2&& v2) noexcept(std::is_nothrow_constructible_v<_Ty1, U1&&> && - std::is_nothrow_constructible_v<_Ty2, U2&&>) - : _Myval1(std::forward(v1)), _Myval2(std::forward(v2)) - {} - - // accessors - constexpr _Ty1& first() noexcept { return _Myval1; } - constexpr const _Ty1& first() const noexcept { return _Myval1; } - constexpr _Ty2& second() noexcept { return _Myval2; } - constexpr const _Ty2& second() const noexcept { return _Myval2; } -}; - -// Case 2: First empty -template -class compressed_pair<_Ty1, _Ty2, true, false> : private _Ty1 -{ - _Ty2 _Myval2; - -public: - constexpr compressed_pair() = default; - - constexpr compressed_pair(const _Ty1& v1, const _Ty2& v2) noexcept(std::is_nothrow_copy_constructible_v<_Ty2>) - : _Ty1(v1), _Myval2(v2) - {} - - constexpr compressed_pair(_Ty1&& v1, _Ty2&& v2) noexcept(std::is_nothrow_move_constructible_v<_Ty2>) - : _Ty1(std::move(v1)), _Myval2(std::move(v2)) - {} - - template - constexpr compressed_pair(U1&& v1, U2&& v2) noexcept(std::is_nothrow_constructible_v<_Ty2, U2&&>) - : _Ty1(std::forward(v1)), _Myval2(std::forward(v2)) - {} - - constexpr _Ty1& first() noexcept { return *this; } - constexpr const _Ty1& first() const noexcept { return *this; } - constexpr _Ty2& second() noexcept { return _Myval2; } - constexpr const _Ty2& second() const noexcept { return _Myval2; } -}; - -// Case 3: Second empty -template -class compressed_pair<_Ty1, _Ty2, false, true> : private _Ty2 -{ - _Ty1 _Myval1; - -public: - constexpr compressed_pair() = default; - - constexpr compressed_pair(const _Ty1& v1, const _Ty2& v2) noexcept(std::is_nothrow_copy_constructible_v<_Ty1>) - : _Myval1(v1), _Ty2(v2) - {} - - constexpr compressed_pair(_Ty1&& v1, _Ty2&& v2) noexcept(std::is_nothrow_move_constructible_v<_Ty1>) - : _Myval1(std::move(v1)), _Ty2(std::move(v2)) - {} - - template - constexpr compressed_pair(U1&& v1, U2&& v2) noexcept(std::is_nothrow_constructible_v<_Ty1, U1&&>) - : _Myval1(std::forward(v1)), _Ty2(std::forward(v2)) - {} - - constexpr _Ty1& first() noexcept { return _Myval1; } - constexpr const _Ty1& first() const noexcept { return _Myval1; } - constexpr _Ty2& second() noexcept { return *this; } - constexpr const _Ty2& second() const noexcept { return *this; } -}; - -// Case 4: both empty -template -class compressed_pair<_Ty1, _Ty2, true, true> : private _Ty1, private _Ty2 -{ -public: - constexpr compressed_pair() = default; - - constexpr compressed_pair(const _Ty1& v1, const _Ty2& v2) : _Ty1(v1), _Ty2(v2) {} - - constexpr compressed_pair(_Ty1&& v1, _Ty2&& v2) : _Ty1(std::move(v1)), _Ty2(std::move(v2)) {} - - template - constexpr compressed_pair(U1&& v1, U2&& v2) : _Ty1(std::forward(v1)), _Ty2(std::forward(v2)) - {} - - constexpr _Ty1& first() noexcept { return *this; } - constexpr const _Ty1& first() const noexcept { return *this; } - constexpr _Ty2& second() noexcept { return *this; } - constexpr const _Ty2& second() const noexcept { return *this; } -}; - -} // namespace axstd +} // namespace tlx // std::hash @@ -409,9 +287,9 @@ namespace std { template -struct hash<::axstd::retain_ptr> +struct hash<::tlx::retain_ptr> { - std::size_t operator()(::axstd::retain_ptr const& p) const noexcept { return std::hash()(p.get()); } + std::size_t operator()(::tlx::retain_ptr const& p) const noexcept { return std::hash()(p.get()); } }; } // namespace std diff --git a/axmol/tlx/singleton.hpp b/axmol/tlx/singleton.hpp new file mode 100644 index 000000000000..043ed455bef5 --- /dev/null +++ b/axmol/tlx/singleton.hpp @@ -0,0 +1,25 @@ +/**************************************************************************** + Copyright (c) 2019-present Axmol Engine contributors (see AUTHORS.md). + + https://axmol.dev/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ +#pragma once +#include "yasio/tlx/singleton.hpp" diff --git a/axmol/tlx/sorted_vector.hpp b/axmol/tlx/sorted_vector.hpp deleted file mode 100644 index 990fbf690304..000000000000 --- a/axmol/tlx/sorted_vector.hpp +++ /dev/null @@ -1,235 +0,0 @@ -/**************************************************************************** - Copyright (c) 2019-present Axmol Engine contributors (see AUTHORS.md). - - https://axmol.dev/ - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - ****************************************************************************/ -#pragma once -#include -#include -#include -#include -#include -#include -#include "axmol/tlx/memory.hpp" - -namespace axstd -{ -namespace detail -{ -template -using _Rebind_alloc_t = typename std::allocator_traits<_Alloc>::template rebind_alloc<_Value_type>; - -/**************************************************************************** - * sorted_vector: generic flat sorted container implementation base on std::vector - * - * This class template provides the core implementation for all flat - * associative containers (flat_map, flat_multimap, flat_set, flat_multiset). - * - * Design: - * - Storage is backed by a contiguous sequence (std::vector). - * - Elements are kept sorted according to the key comparator (_Traits::key_compare). - * - Lookup operations (find, lower_bound, upper_bound, equal_range) use - * binary search on the vector, simulating the semantics of a balanced tree. - * - * Traits: - * - _Traits defines key_type, value_type, allocator_type, key_extractor, - * key_compare, and a constexpr bool allow_duplicates. - * - allow_duplicates = false → map/set semantics (unique keys). - * - allow_duplicates = true → multimap/multiset semantics (duplicate keys allowed). - * - * Complexity: - * - Lookup: O(log N) (binary search). - * - Insert/Erase: O(N) (vector reallocation/shifting). - * - Iteration: O(N), cache-friendly due to contiguous storage. - * - * Purpose: - * - Serves as the common base for flat_map/flat_set variants. - * - Provides STL-compatible interface (begin/end, find, lower_bound, upper_bound, equal_range). - * - Mimics tree-based associative containers but with flat storage for better - * cache locality and reduced memory overhead. - ****************************************************************************/ -template -class sorted_vector -{ -public: - using key_type = typename _Traits::key_type; - using value_type = typename _Traits::value_type; - using allocator_type = typename _Traits::allocator_type; - -protected: - using _Alty = _Rebind_alloc_t; - using _Alty_traits = std::allocator_traits<_Alty>; - -public: - using value_compare = typename _Traits::value_compare; - using key_compare = typename _Traits::key_compare; - using key_extractor = typename _Traits::key_extractor; - - using size_type = typename _Alty_traits::size_type; - using difference_type = typename _Alty_traits::difference_type; - using pointer = typename _Alty_traits::pointer; - using const_pointer = typename _Alty_traits::const_pointer; - using reference = value_type&; - using const_reference = const value_type&; - using container_type = std::vector; - using iterator = typename container_type::iterator; - using const_iterator = typename container_type::const_iterator; - - explicit sorted_vector(const key_compare& pred = key_compare(), const allocator_type& alloc = allocator_type()) - : _Mypair(pred, container_type(alloc)) - {} - - void reserve(size_t capacity) { _Mypair.second().reserve(capacity); } - void clear() { _Mypair.second().clear(); } - - bool empty() const noexcept { return _Mypair.second().empty(); } - size_t size() const noexcept { return _Mypair.second().size(); } - - iterator begin() noexcept { return _Mypair.second().begin(); } - iterator end() noexcept { return _Mypair.second().end(); } - const_iterator begin() const noexcept { return _Mypair.second().begin(); } - const_iterator end() const noexcept { return _Mypair.second().end(); } - - iterator find(const key_type& key) - { - auto& cont = _Mypair.second(); - auto& pred = _Mypair.first(); - auto it = lower_bound(key); - if (it != cont.end() && !pred(key, key_extractor{}(*it)) && !pred(key_extractor{}(*it), key)) - return it; - return cont.end(); - } - - const_iterator find(const key_type& key) const - { - const auto& cont = _Mypair.second(); - const auto& pred = _Mypair.first(); - auto it = lower_bound(key); - if (it != cont.end() && !pred(key, key_extractor{}(*it)) && !pred(key_extractor{}(*it), key)) - return it; - return cont.end(); - } - - iterator lower_bound(const key_type& key) - { - auto& cont = _Mypair.second(); - auto& pred = _Mypair.first(); - return std::lower_bound(cont.begin(), cont.end(), key, - [&](const value_type& v, const key_type& k) { return pred(key_extractor{}(v), k); }); - } - - const_iterator lower_bound(const key_type& key) const - { - const auto& cont = _Mypair.second(); - const auto& pred = _Mypair.first(); - return std::lower_bound(cont.begin(), cont.end(), key, - [&](const value_type& v, const key_type& k) { return pred(key_extractor{}(v), k); }); - } - - iterator upper_bound(const key_type& key) - { - auto& cont = _Mypair.second(); - auto& pred = _Mypair.first(); - return std::upper_bound(cont.begin(), cont.end(), key, - [&](const key_type& k, const value_type& v) { return pred(k, key_extractor{}(v)); }); - } - - const_iterator upper_bound(const key_type& key) const - { - const auto& cont = _Mypair.second(); - const auto& pred = _Mypair.first(); - return std::upper_bound(cont.begin(), cont.end(), key, - [&](const key_type& k, const value_type& v) { return pred(k, key_extractor{}(v)); }); - } - - std::pair equal_range(const key_type& key) { return {lower_bound(key), upper_bound(key)}; } - - std::pair equal_range(const key_type& key) const - { - return {lower_bound(key), upper_bound(key)}; - } - - iterator insert(iterator /*hint*/, const value_type& v) - { - // ignore hint, do sorted insertion - return insert(v).first; - } - - std::pair insert(const value_type& v) - { - auto& cont = _Mypair.second(); - auto& comp = _Mypair.first(); - const key_type& k = key_extractor{}(v); - - if constexpr (_Traits::allow_duplicates) - { - auto it = upper_bound(k); - it = cont.insert(it, v); - return {it, true}; - } - else - { - auto it = lower_bound(k); - if (it == cont.end() || comp(k, key_extractor{}(*it))) - { - it = cont.insert(it, v); - return {it, true}; - } - return {it, false}; - } - } - - template - std::pair emplace(Args&&... args) - { - value_type v(std::forward(args)...); - return insert(v); - } - - size_type erase(const key_type& key) - { - auto range = equal_range(key); - size_type count = std::distance(range.first, range.second); - _Mypair.second().erase(range.first, range.second); - return count; - } - - iterator erase(const_iterator it) { return _Mypair.second().erase(it); } - -protected: - ::axstd::compressed_pair _Mypair; -}; - -/// identity extractor: for flat_set -template -struct identity -{ - const Key& operator()(const Key& k) const noexcept { return k; } -}; - -/// select1st extractor: for flat_map -template -struct select1st -{ - using Key = typename _Pair::first_type; - const Key& operator()(const _Pair& p) const noexcept { return p.first; } -}; - -} // namespace detail -} // namespace axstd diff --git a/axmol/tlx/type_traits.hpp b/axmol/tlx/type_traits.hpp index 7ac1941bf380..ac340f396e00 100644 --- a/axmol/tlx/type_traits.hpp +++ b/axmol/tlx/type_traits.hpp @@ -25,7 +25,7 @@ #pragma once #include -namespace axstd +namespace tlx { // enable_if_convertible_t template @@ -75,4 +75,4 @@ struct is_resizable_container inline constexpr bool is_resizable_container_v = is_resizable_container<_T>::value; #pragma endregion -} // namespace axstd +} // namespace tlx diff --git a/axmol/tlx/utility.hpp b/axmol/tlx/utility.hpp index 0e3021295cf3..89326b8ffb64 100644 --- a/axmol/tlx/utility.hpp +++ b/axmol/tlx/utility.hpp @@ -29,7 +29,7 @@ #include "axmol/tlx/feature_test.hpp" -namespace axstd +namespace tlx { template @@ -177,4 +177,4 @@ inline void splitpath_cb(_Elem* s, _Pred&& pred, _Fn&& func) // will convert '\ } } -} // namespace axstd +} // namespace tlx diff --git a/axmol/tlx/pod_vector.hpp b/axmol/tlx/vector.hpp similarity index 82% rename from axmol/tlx/pod_vector.hpp rename to axmol/tlx/vector.hpp index 288d255b7904..dc93fb46c861 100644 --- a/axmol/tlx/pod_vector.hpp +++ b/axmol/tlx/vector.hpp @@ -23,13 +23,10 @@ ****************************************************************************/ #pragma once -#include "yasio/byte_buffer.hpp" +#include "yasio/tlx/array_buffer.hpp" -namespace axstd +namespace tlx { -template > -using pod_vector = yasio::pod_vector<_Elem, _Alloc>; -using yasio::erase; -using yasio::erase_if; -using yasio::insert_sorted; -} // namespace axstd +template > +using pod_vector = _TLX array_buffer<_Ty, _Alloc>; +} // namespace tlx diff --git a/axmol/ui/UIEditBox/UIEditBoxImpl-android.cpp b/axmol/ui/UIEditBox/UIEditBoxImpl-android.cpp index 4584f3429156..8c2d124ed784 100644 --- a/axmol/ui/UIEditBox/UIEditBoxImpl-android.cpp +++ b/axmol/ui/UIEditBox/UIEditBoxImpl-android.cpp @@ -100,8 +100,7 @@ void EditBoxImplAndroid::setNativeFont(const char* pFontName, int fontSize) if (isFontFileExists) { realFontPath = ax::FileUtils::getInstance()->fullPathForFilename(pFontName); - using namespace cxx17; // for cxx17::string_view literal - if (cxx20::starts_with(cxx17::string_view{realFontPath}, "assets/"_sv)) + if (tlx::starts_with(std::string_view{realFontPath}, "assets/"sv)) { realFontPath = realFontPath.substr(sizeof("assets/") - 1); // Chop out the 'assets/' portion of the path. } diff --git a/axmol/ui/UIMediaPlayer.cpp b/axmol/ui/UIMediaPlayer.cpp index e9811dbd3869..f3f8027c7522 100644 --- a/axmol/ui/UIMediaPlayer.cpp +++ b/axmol/ui/UIMediaPlayer.cpp @@ -38,7 +38,7 @@ # include "axmol/media/MediaEngine.h" # include "axmol/ui/UIButton.h" # include "axmol/ui/UILayout.h" -# include "yasio/byte_buffer.hpp" +# include "axmol/tlx/byte_buffer.hpp" //----------------------------------------------------------------------------------------------------------- using namespace ax; diff --git a/axmol/ui/UIRichText.cpp b/axmol/ui/UIRichText.cpp index 7cb1472f9559..044c20d9595b 100644 --- a/axmol/ui/UIRichText.cpp +++ b/axmol/ui/UIRichText.cpp @@ -377,7 +377,7 @@ class MyXMLVisitor : public SAXDelegator RichText::VisitEnterHandler handleVisitEnter; RichText::VisitExitHandler handleVisitExit; }; - typedef axstd::string_map TagTables; + typedef tlx::string_map TagTables; static TagTables _tagTables; @@ -1181,7 +1181,7 @@ void MyXMLVisitor::setTagDescription(std::string_view tag, RichText::VisitExitHandler&& handleVisitExit) { // MyXMLVisitor::_tagTables[tag] = {isFontElement, std::move(handleVisitEnter), std::move(handleVisitExit)}; - axstd::set_item(MyXMLVisitor::_tagTables, tag, + tlx::set_item(MyXMLVisitor::_tagTables, tag, TagBehavior{isFontElement, std::move(handleVisitEnter), std::move(handleVisitExit)}); } @@ -1666,7 +1666,7 @@ ValueMap RichText::getDefaults() const static inline bool parseHexDigit(uint8_t& out, const char* p, int n) { - auto ret = axstd::from_chars(p, p + n, out, 16); + auto ret = tlx::from_chars(p, p + n, out, 16); return ret.ec == std::errc{}; } diff --git a/axmol/ui/UIWebView/UIWebViewImpl-android.cpp b/axmol/ui/UIWebView/UIWebViewImpl-android.cpp index deb5560f592e..6131fabbec87 100644 --- a/axmol/ui/UIWebView/UIWebViewImpl-android.cpp +++ b/axmol/ui/UIWebView/UIWebViewImpl-android.cpp @@ -57,8 +57,7 @@ static std::string getFixedBaseUrl(std::string_view baseUrl) } else if (baseUrl[0] != '/') { - using namespace cxx17; // for cxx17::string_view literal - if (cxx20::starts_with(baseUrl, "assets/"_sv)) + if (tlx::starts_with(baseUrl, "assets/"sv)) { fixedBaseUrl.assign(s_assetsBaseUrl).push_back(baseUrl[7]); } @@ -165,7 +164,7 @@ std::string getUrlStringByFileName(std::string_view fileName) if (urlString[0] == '/') urlString.insert(urlString.begin(), s_sdRootBaseUrl.begin(), s_sdRootBaseUrl.end()); - else if (cxx20::starts_with(cxx17::string_view{urlString}, "assets/"sv)) + else if (tlx::starts_with(std::string_view{urlString}, "assets/"sv)) urlString.replace(0, sizeof("assets/") - 1, s_assetsBaseUrl); else urlString.insert(urlString.begin(), s_assetsBaseUrl.begin(), s_assetsBaseUrl.end()); diff --git a/extensions/DragonBones/src/DragonBones/animation/Animation.cpp b/extensions/DragonBones/src/DragonBones/animation/Animation.cpp index b6fed9d5ec68..eb2dd7ee1101 100644 --- a/extensions/DragonBones/src/DragonBones/animation/Animation.cpp +++ b/extensions/DragonBones/src/DragonBones/animation/Animation.cpp @@ -581,7 +581,7 @@ std::string_view Animation::getLastAnimationName() const return DEFAULT_NAME; } -void Animation::setAnimations(const axstd::string_map& value) +void Animation::setAnimations(const tlx::string_map& value) { if (_animations == value) { diff --git a/extensions/DragonBones/src/DragonBones/animation/Animation.h b/extensions/DragonBones/src/DragonBones/animation/Animation.h index cba0c0f0ed75..509f494e8a10 100644 --- a/extensions/DragonBones/src/DragonBones/animation/Animation.h +++ b/extensions/DragonBones/src/DragonBones/animation/Animation.h @@ -64,7 +64,7 @@ class Animation final : public BaseObject float _inheritTimeScale; std::vector _animationNames; std::vector _animationStates; - axstd::string_map _animations; + tlx::string_map _animations; Armature* _armature; AnimationConfig* _animationConfig; AnimationState* _lastAnimationState; @@ -441,8 +441,8 @@ class Animation final : public BaseObject * @version DragonBones 4.5 * @language zh_CN */ - inline const axstd::string_map& getAnimations() const { return _animations; } - void setAnimations(const axstd::string_map& value); + inline const tlx::string_map& getAnimations() const { return _animations; } + void setAnimations(const tlx::string_map& value); /** * - An AnimationConfig instance that can be used quickly. * @see dragonBones.AnimationConfig diff --git a/extensions/DragonBones/src/DragonBones/animation/AnimationState.cpp b/extensions/DragonBones/src/DragonBones/animation/AnimationState.cpp index e988200cbef8..f89e4972bb73 100644 --- a/extensions/DragonBones/src/DragonBones/animation/AnimationState.cpp +++ b/extensions/DragonBones/src/DragonBones/animation/AnimationState.cpp @@ -83,7 +83,7 @@ void AnimationState::_onClear() void AnimationState::_updateTimelines() { { // Update constraint timelines. - axstd::string_map> constraintTimelines; + tlx::string_map> constraintTimelines; for (const auto timeline : _constraintTimelines) // Create constraint timelines map. { constraintTimelines[timeline->constraint->getName()].push_back(timeline); @@ -137,7 +137,7 @@ void AnimationState::_updateTimelines() void AnimationState::_updateBoneAndSlotTimelines() { { // Update bone timelines. - axstd::string_map> boneTimelines; + tlx::string_map> boneTimelines; for (const auto timeline : _boneTimelines) // Create bone timelines map. { boneTimelines[timeline->bone->getName()].push_back(timeline); @@ -238,7 +238,7 @@ void AnimationState::_updateBoneAndSlotTimelines() } { // Update slot timelines. - axstd::string_map> slotTimelines; + tlx::string_map> slotTimelines; std::vector ffdFlags; for (const auto timeline : _slotTimelines) // Create slot timelines map. { diff --git a/extensions/DragonBones/src/DragonBones/animation/AnimationState.h b/extensions/DragonBones/src/DragonBones/animation/AnimationState.h index 5d928e043ce1..75cfe4e3b1d0 100644 --- a/extensions/DragonBones/src/DragonBones/animation/AnimationState.h +++ b/extensions/DragonBones/src/DragonBones/animation/AnimationState.h @@ -251,7 +251,7 @@ class AnimationState : public BaseObject std::vector _slotTimelines; std::vector _constraintTimelines; std::vector> _poseTimelines; - axstd::string_map _bonePoses; + tlx::string_map _bonePoses; Armature* _armature; ZOrderTimelineState* _zOrderTimeline; diff --git a/extensions/DragonBones/src/DragonBones/factory/BaseFactory.cpp b/extensions/DragonBones/src/DragonBones/factory/BaseFactory.cpp index 3c03ae2b3d01..3834532ab4d4 100644 --- a/extensions/DragonBones/src/DragonBones/factory/BaseFactory.cpp +++ b/extensions/DragonBones/src/DragonBones/factory/BaseFactory.cpp @@ -141,7 +141,7 @@ void BaseFactory::_buildSlots(const BuildArmaturePackage& dataPackage, Armature* return; } - axstd::string_map*> skinSlots; + tlx::string_map*> skinSlots; for (auto& pair : defaultSkin->displays) { auto& displays = pair.second; diff --git a/extensions/DragonBones/src/DragonBones/factory/BaseFactory.h b/extensions/DragonBones/src/DragonBones/factory/BaseFactory.h index f63f30c38b55..82cfd6e5a314 100644 --- a/extensions/DragonBones/src/DragonBones/factory/BaseFactory.h +++ b/extensions/DragonBones/src/DragonBones/factory/BaseFactory.h @@ -68,8 +68,8 @@ class BaseFactory bool autoSearch; protected: - axstd::string_map _dragonBonesDataMap; - axstd::string_map> _textureAtlasDataMap; + tlx::string_map _dragonBonesDataMap; + tlx::string_map> _textureAtlasDataMap; DragonBones* _dragonBones; DataParser* _dataParser; @@ -548,14 +548,14 @@ class BaseFactory /** * @private */ - inline const axstd::string_map>& getAllTextureAtlasData() const + inline const tlx::string_map>& getAllTextureAtlasData() const { return _textureAtlasDataMap; } /** * @private */ - inline const axstd::string_map& getAllDragonBonesData() const { return _dragonBonesDataMap; } + inline const tlx::string_map& getAllDragonBonesData() const { return _dragonBonesDataMap; } /** * - An Worldclock instance updated by engine. * @version DragonBones 5.7 diff --git a/extensions/DragonBones/src/DragonBones/model/AnimationData.h b/extensions/DragonBones/src/DragonBones/model/AnimationData.h index 4591a66bd81c..1e8e1c74f348 100644 --- a/extensions/DragonBones/src/DragonBones/model/AnimationData.h +++ b/extensions/DragonBones/src/DragonBones/model/AnimationData.h @@ -126,23 +126,23 @@ class AnimationData : public BaseObject /** * @private */ - axstd::string_map> boneTimelines; + tlx::string_map> boneTimelines; /** * @private */ - axstd::string_map> slotTimelines; + tlx::string_map> slotTimelines; /** * @private */ - axstd::string_map> constraintTimelines; + tlx::string_map> constraintTimelines; /** * @private */ - axstd::string_map> boneCachedFrameIndices; + tlx::string_map> boneCachedFrameIndices; /** * @private */ - axstd::string_map> slotCachedFrameIndices; + tlx::string_map> slotCachedFrameIndices; /** * @private */ diff --git a/extensions/DragonBones/src/DragonBones/model/ArmatureData.h b/extensions/DragonBones/src/DragonBones/model/ArmatureData.h index 0be05949cbad..a9cc7896f99b 100644 --- a/extensions/DragonBones/src/DragonBones/model/ArmatureData.h +++ b/extensions/DragonBones/src/DragonBones/model/ArmatureData.h @@ -113,23 +113,23 @@ class ArmatureData : public BaseObject /** * @private */ - axstd::string_map bones; + tlx::string_map bones; /** * @private */ - axstd::string_map slots; + tlx::string_map slots; /** * @private */ - axstd::string_map constraints; + tlx::string_map constraints; /** * @private */ - axstd::string_map skins; + tlx::string_map skins; /** * @private */ - axstd::string_map animations; + tlx::string_map animations; /** * - The default skin data. * @version DragonBones 4.5 diff --git a/extensions/DragonBones/src/DragonBones/model/DragonBonesData.h b/extensions/DragonBones/src/DragonBones/model/DragonBonesData.h index 4add32bf174f..16cd0eee16ad 100644 --- a/extensions/DragonBones/src/DragonBones/model/DragonBonesData.h +++ b/extensions/DragonBones/src/DragonBones/model/DragonBonesData.h @@ -107,7 +107,7 @@ class DragonBonesData : public BaseObject /** * @private */ - axstd::string_map armatures; + tlx::string_map armatures; /** * @internal */ diff --git a/extensions/DragonBones/src/DragonBones/model/SkinData.h b/extensions/DragonBones/src/DragonBones/model/SkinData.h index 8a9583c8c479..7105aacd4b27 100644 --- a/extensions/DragonBones/src/DragonBones/model/SkinData.h +++ b/extensions/DragonBones/src/DragonBones/model/SkinData.h @@ -56,7 +56,7 @@ class SkinData : public BaseObject /** * @private */ - axstd::string_map> displays; + tlx::string_map> displays; /** * @private */ @@ -80,7 +80,7 @@ class SkinData : public BaseObject std::vector* getDisplays(std::string_view slotName) { return mapFindB(displays, slotName); } public: // For WebAssembly. TODO parent - const axstd::string_map>& getSlotDisplays() const { return displays; } + const tlx::string_map>& getSlotDisplays() const { return displays; } }; DRAGONBONES_NAMESPACE_END diff --git a/extensions/DragonBones/src/DragonBones/model/TextureAtlasData.h b/extensions/DragonBones/src/DragonBones/model/TextureAtlasData.h index 030115e2be77..b164b13a1a56 100644 --- a/extensions/DragonBones/src/DragonBones/model/TextureAtlasData.h +++ b/extensions/DragonBones/src/DragonBones/model/TextureAtlasData.h @@ -84,7 +84,7 @@ class TextureAtlasData : public BaseObject /** * @private */ - axstd::string_map textures; + tlx::string_map textures; /** * @private */ @@ -106,7 +106,7 @@ class TextureAtlasData : public BaseObject virtual void _onClear() override; public: // For WebAssembly. - const axstd::string_map& getTextures() const { return textures; } + const tlx::string_map& getTextures() const { return textures; } }; /** * @internal diff --git a/extensions/DragonBones/src/DragonBones/parser/JSONDataParser.h b/extensions/DragonBones/src/DragonBones/parser/JSONDataParser.h index 75434648cc68..4ee94b53d4cf 100644 --- a/extensions/DragonBones/src/DragonBones/parser/JSONDataParser.h +++ b/extensions/DragonBones/src/DragonBones/parser/JSONDataParser.h @@ -160,10 +160,10 @@ class JSONDataParser : public DataParser std::vector _cacheRawMeshes; std::vector _cacheMeshes; std::vector _actionFrames; - axstd::string_map _weightSlotPose; - axstd::string_map _weightBonePoses; - axstd::string_map> _cacheBones; - axstd::string_map> _slotChildActions; + tlx::string_map _weightSlotPose; + tlx::string_map _weightBonePoses; + tlx::string_map> _cacheBones; + tlx::string_map> _slotChildActions; public: JSONDataParser() diff --git a/extensions/ImGui/src/ImGui/ImGuiPresenter.h b/extensions/ImGui/src/ImGui/ImGuiPresenter.h index 11c542022305..d85066567ff9 100644 --- a/extensions/ImGui/src/ImGui/ImGuiPresenter.h +++ b/extensions/ImGui/src/ImGui/ImGuiPresenter.h @@ -180,7 +180,7 @@ class ImGuiPresenter int64_t _beginFrames = 0; - axstd::string_map _fontsInfoMap; + tlx::string_map _fontsInfoMap; bool _purgeNextLoop = false; }; diff --git a/extensions/JSONDefault/src/JSONDefault/JSONDefault.h b/extensions/JSONDefault/src/JSONDefault/JSONDefault.h index e85f23885950..1dc2e9b42bbe 100644 --- a/extensions/JSONDefault/src/JSONDefault/JSONDefault.h +++ b/extensions/JSONDefault/src/JSONDefault/JSONDefault.h @@ -29,9 +29,7 @@ THE SOFTWARE. #include "axmol/platform/PlatformMacros.h" #include "extensions/ExtensionMacros.h" #include - -#include "yasio/string_view.hpp" - +#include // rapidjson #include "rapidjson/document.h" diff --git a/extensions/Particle3D/src/Particle3D/PU/PUMaterialManager.cpp b/extensions/Particle3D/src/Particle3D/PU/PUMaterialManager.cpp index 2b53a48cfe41..02bd1b746753 100644 --- a/extensions/Particle3D/src/Particle3D/PU/PUMaterialManager.cpp +++ b/extensions/Particle3D/src/Particle3D/PU/PUMaterialManager.cpp @@ -45,8 +45,6 @@ # include "axmol/tlx/filesystem.hpp" #endif -#include "yasio/string_view.hpp" - namespace ax { diff --git a/extensions/Particle3D/src/Particle3D/PU/PUParticleSystem3D.h b/extensions/Particle3D/src/Particle3D/PU/PUParticleSystem3D.h index 7b5979024f95..da9c4da60480 100644 --- a/extensions/Particle3D/src/Particle3D/PU/PUParticleSystem3D.h +++ b/extensions/Particle3D/src/Particle3D/PU/PUParticleSystem3D.h @@ -207,7 +207,7 @@ struct AX_EX_DLL PUParticle3D : public Particle3D class AX_EX_DLL PUParticleSystem3D : public ParticleSystem3D { public: - typedef axstd::string_map ParticlePoolMap; + typedef tlx::string_map ParticlePoolMap; static const float DEFAULT_WIDTH; static const float DEFAULT_HEIGHT; diff --git a/extensions/Particle3D/src/Particle3D/PU/PUScriptCompiler.cpp b/extensions/Particle3D/src/Particle3D/PU/PUScriptCompiler.cpp index c1b3a3d666fc..86673ca1f15b 100644 --- a/extensions/Particle3D/src/Particle3D/PU/PUScriptCompiler.cpp +++ b/extensions/Particle3D/src/Particle3D/PU/PUScriptCompiler.cpp @@ -76,7 +76,7 @@ void PUObjectAbstractNode::addVariable(std::string_view inName) void PUObjectAbstractNode::setVariable(std::string_view inName, std::string_view value) { // _env[inName] = value; - axstd::set_item(_env, inName, value); + tlx::set_item(_env, inName, value); } std::pair PUObjectAbstractNode::getVariable(std::string_view inName) const @@ -96,7 +96,7 @@ std::pair PUObjectAbstractNode::getVariable(std::string_view return std::make_pair(false, ""); } -const axstd::string_map& PUObjectAbstractNode::getVariables() const +const tlx::string_map& PUObjectAbstractNode::getVariables() const { return _env; } @@ -189,7 +189,7 @@ PUScriptCompiler::~PUScriptCompiler() _compiledScripts.clear(); } -axstd::string_map::iterator PUScriptCompiler::compile(const PUConcreteNodeList& nodes, +tlx::string_map::iterator PUScriptCompiler::compile(const PUConcreteNodeList& nodes, std::string_view file) { if (nodes.empty()) @@ -198,7 +198,7 @@ axstd::string_map::iterator PUScriptCompiler::compile(const PUAbstractNodeList aNodes; convertToAST(nodes, aNodes); - return axstd::set_item(_compiledScripts, file, aNodes); // _compiledScripts[file] = aNodes; + return tlx::set_item(_compiledScripts, file, aNodes); // _compiledScripts[file] = aNodes; // for(PUAbstractNodeList::iterator i = aNodes.begin(); i != aNodes.end(); ++i) //{ // PUScriptTranslator *translator = PUTranslateManager::Instance()->getTranslator(*i); diff --git a/extensions/Particle3D/src/Particle3D/PU/PUScriptCompiler.h b/extensions/Particle3D/src/Particle3D/PU/PUScriptCompiler.h index 75355406b26a..20795db4f8c9 100644 --- a/extensions/Particle3D/src/Particle3D/PU/PUScriptCompiler.h +++ b/extensions/Particle3D/src/Particle3D/PU/PUScriptCompiler.h @@ -73,7 +73,7 @@ class AX_EX_DLL PUAbstractNode class AX_EX_DLL PUObjectAbstractNode : public PUAbstractNode { private: - axstd::string_map _env; + tlx::string_map _env; public: std::string name, cls; @@ -92,7 +92,7 @@ class AX_EX_DLL PUObjectAbstractNode : public PUAbstractNode void addVariable(std::string_view name); void setVariable(std::string_view name, std::string_view value); std::pair getVariable(std::string_view name) const; - const axstd::string_map& getVariables() const; + const tlx::string_map& getVariables() const; }; /** This abstract node represents a script property */ @@ -131,7 +131,7 @@ class AX_EX_DLL PUScriptCompiler { private: - axstd::string_map::iterator compile(const PUConcreteNodeList& nodes, std::string_view file); + tlx::string_map::iterator compile(const PUConcreteNodeList& nodes, std::string_view file); // is it excluded?// bool isNameExcluded(std::string_view cls, PUAbstractNode* parent); @@ -156,7 +156,7 @@ class AX_EX_DLL PUScriptCompiler void visit(PUConcreteNode* node); private: - axstd::string_map _compiledScripts; + tlx::string_map _compiledScripts; PUAbstractNode* _current; PUAbstractNodeList* _nodes; PUParticleSystem3D* _PUParticleSystem3D; diff --git a/extensions/SDFGen/src/SDFGen/SDFGen.cpp b/extensions/SDFGen/src/SDFGen/SDFGen.cpp index 504cb90bc7b3..6f941a2c85ba 100644 --- a/extensions/SDFGen/src/SDFGen/SDFGen.cpp +++ b/extensions/SDFGen/src/SDFGen/SDFGen.cpp @@ -1,7 +1,7 @@ #include "SDFGen.h" -#include -#include +#include +#include #include "axmol/tlx/format.hpp" #include "axmol/base/ZipUtils.h" @@ -10,7 +10,7 @@ #include "misc/cpp/imgui_stdlib.h" #include #include "axmol/base/JsonWriter.h" -#include "yasio/utils.hpp" +#include "yasio/tlx/chrono.hpp" NS_AX_EXT_BEGIN @@ -94,7 +94,7 @@ class FontAtlas : public ax::FontAtlas storePath += path; } - auto start = yasio::highp_clock(); + auto start = tlx::highp_clock(); JsonWriter<> xasset; @@ -147,7 +147,7 @@ class FontAtlas : public ax::FontAtlas fu->writeStringToFile(str, storePath); - _params->cost = (yasio::highp_clock() - start) / 1000.0; + _params->cost = (tlx::highp_clock() - start) / 1000.0; _params->error.clear(); return true; @@ -190,7 +190,7 @@ class FontAtlas : public ax::FontAtlas FontAtlasGenParams* _params{nullptr}; // weak ref std::string _atlasName; // match with runtime - std::vector _pageDatas; + std::vector _pageDatas; }; }; // namespace xasset diff --git a/extensions/assets-manager/src/assets-manager/AssetsManagerEx.cpp b/extensions/assets-manager/src/assets-manager/AssetsManagerEx.cpp index 6ec4f98eea5e..0827ad4c9c4a 100644 --- a/extensions/assets-manager/src/assets-manager/AssetsManagerEx.cpp +++ b/extensions/assets-manager/src/assets-manager/AssetsManagerEx.cpp @@ -784,7 +784,7 @@ void AssetsManagerEx::startUpdate() _tempManifest = _remoteManifest; // Check difference between local manifest and remote manifest - axstd::string_map diff_map = _localManifest->genDiff(_remoteManifest); + tlx::string_map diff_map = _localManifest->genDiff(_remoteManifest); if (diff_map.empty()) { updateSucceed(); diff --git a/extensions/assets-manager/src/assets-manager/AssetsManagerEx.h b/extensions/assets-manager/src/assets-manager/AssetsManagerEx.h index a733f87d64b7..5986ed2e8b24 100644 --- a/extensions/assets-manager/src/assets-manager/AssetsManagerEx.h +++ b/extensions/assets-manager/src/assets-manager/AssetsManagerEx.h @@ -244,7 +244,7 @@ class AX_EX_DLL AssetsManagerEx : public Object std::shared_ptr _downloader; //! The reference to the local assets - const axstd::string_map* _assets = nullptr; + const tlx::string_map* _assets = nullptr; //! The path to store successfully downloaded version. std::string _storagePath; @@ -314,7 +314,7 @@ class AX_EX_DLL AssetsManagerEx : public Object double _totalSize; //! Downloaded size for each file - axstd::string_map _downloadedSize; + tlx::string_map _downloadedSize; //! Total number of assets to download int _totalToDownload = 0; diff --git a/extensions/assets-manager/src/assets-manager/Manifest.cpp b/extensions/assets-manager/src/assets-manager/Manifest.cpp index 0da60bbb0317..7713c0be7cba 100644 --- a/extensions/assets-manager/src/assets-manager/Manifest.cpp +++ b/extensions/assets-manager/src/assets-manager/Manifest.cpp @@ -200,16 +200,16 @@ bool Manifest::versionGreater( return greater; } -axstd::string_map Manifest::genDiff(const Manifest* b) const +tlx::string_map Manifest::genDiff(const Manifest* b) const { - axstd::string_map diff_map; + tlx::string_map diff_map; auto& bAssets = b->getAssets(); std::string key; Asset valueA; Asset valueB; - axstd::string_map::const_iterator valueIt, it; + tlx::string_map::const_iterator valueIt, it; for (it = _assets.begin(); it != _assets.end(); ++it) { key = it->first; @@ -342,7 +342,7 @@ const std::vector& Manifest::getGroups() const return _groups; } -const axstd::string_map& Manifest::getGroupVerions() const +const tlx::string_map& Manifest::getGroupVerions() const { return _groupVer; } @@ -352,7 +352,7 @@ std::string_view Manifest::getGroupVersion(std::string_view group) const return _groupVer.at(group); } -const axstd::string_map& Manifest::getAssets() const +const tlx::string_map& Manifest::getAssets() const { return _assets; } diff --git a/extensions/assets-manager/src/assets-manager/Manifest.h b/extensions/assets-manager/src/assets-manager/Manifest.h index 4dbe78226cbe..31e0f6519cf6 100644 --- a/extensions/assets-manager/src/assets-manager/Manifest.h +++ b/extensions/assets-manager/src/assets-manager/Manifest.h @@ -56,7 +56,7 @@ struct ManifestAsset int downloadState; }; -typedef axstd::string_map DownloadUnits; +typedef tlx::string_map DownloadUnits; class AX_EX_DLL Manifest : public Object { @@ -155,7 +155,7 @@ class AX_EX_DLL Manifest : public Object /** @brief Generate difference between this Manifest and another. * @param b The other manifest */ - axstd::string_map genDiff(const Manifest* b) const; + tlx::string_map genDiff(const Manifest* b) const; /** @brief Generate resuming download assets list * @param units The download units reference to be modified by the generation result @@ -182,7 +182,7 @@ class AX_EX_DLL Manifest : public Object /** @brief Gets all groups version. */ - const axstd::string_map& getGroupVerions() const; + const tlx::string_map& getGroupVerions() const; /** @brief Gets version for the given group. * @param group Key of the requested group @@ -193,7 +193,7 @@ class AX_EX_DLL Manifest : public Object * @brief Gets assets. * @lua NA */ - const axstd::string_map& getAssets() const; + const tlx::string_map& getAssets() const; /** @brief Set the download state for an asset * @param key Key of the asset to set @@ -232,13 +232,13 @@ class AX_EX_DLL Manifest : public Object std::vector _groups; //! The versions of all local group [Optional] - axstd::string_map _groupVer; + tlx::string_map _groupVer; //! The version of local engine std::string _engineVer; //! Full assets list - axstd::string_map _assets; + tlx::string_map _assets; //! All search paths std::vector _searchPaths; diff --git a/extensions/cocostudio/src/cocostudio/ActionTimeline/ActionTimeline.h b/extensions/cocostudio/src/cocostudio/ActionTimeline/ActionTimeline.h index 0369940a81ee..bbd05c1a5c8b 100644 --- a/extensions/cocostudio/src/cocostudio/ActionTimeline/ActionTimeline.h +++ b/extensions/cocostudio/src/cocostudio/ActionTimeline/ActionTimeline.h @@ -223,8 +223,8 @@ class CCS_DLL ActionTimeline : public ax::Action, public ax::PlayableProtocol std::function _frameEventListener; std::function _lastFrameListener; - std::map>> _frameEndCallFuncs; - axstd::string_map _animationInfos; + std::map>> _frameEndCallFuncs; + tlx::string_map _animationInfos; }; NS_TIMELINE_END diff --git a/extensions/cocostudio/src/cocostudio/ActionTimeline/ActionTimelineCache.h b/extensions/cocostudio/src/cocostudio/ActionTimeline/ActionTimelineCache.h index ccd8f2b5c8f9..088567b17894 100644 --- a/extensions/cocostudio/src/cocostudio/ActionTimeline/ActionTimelineCache.h +++ b/extensions/cocostudio/src/cocostudio/ActionTimeline/ActionTimelineCache.h @@ -125,7 +125,7 @@ class CCS_DLL ActionTimelineCache typedef std::function FrameCreateFunc; typedef std::pair Pair; - axstd::string_map _funcs; + tlx::string_map _funcs; ax::StringMap _animationActions; }; diff --git a/extensions/cocostudio/src/cocostudio/ActionTimeline/CSLoader.cpp b/extensions/cocostudio/src/cocostudio/ActionTimeline/CSLoader.cpp index 24cde4ac939d..70aeaf2accf5 100644 --- a/extensions/cocostudio/src/cocostudio/ActionTimeline/CSLoader.cpp +++ b/extensions/cocostudio/src/cocostudio/ActionTimeline/CSLoader.cpp @@ -1417,7 +1417,7 @@ std::string_view CSLoader::getWidgetReaderClassName(Widget* widget) readerName = "WidgetReader"; } else - readerName = axstd::empty_sv; + readerName = tlx::empty_sv; return readerName; } diff --git a/extensions/cocostudio/src/cocostudio/ActionTimeline/SkeletonNode.cpp b/extensions/cocostudio/src/cocostudio/ActionTimeline/SkeletonNode.cpp index 9d4f424f67eb..48eb635c98b8 100644 --- a/extensions/cocostudio/src/cocostudio/ActionTimeline/SkeletonNode.cpp +++ b/extensions/cocostudio/src/cocostudio/ActionTimeline/SkeletonNode.cpp @@ -280,7 +280,7 @@ void SkeletonNode::batchDrawAllSubBones() #endif // AX_STUDIO_ENABLED_VIEW } -void SkeletonNode::changeSkins(const axstd::string_map& boneSkinNameMap) +void SkeletonNode::changeSkins(const tlx::string_map& boneSkinNameMap) { for (auto&& boneskin : boneSkinNameMap) { @@ -314,7 +314,7 @@ const ax::StringMap& SkeletonNode::getAllSubBonesMap() const return _subBonesMap; } -void SkeletonNode::addSkinGroup(std::string_view groupName, axstd::string_map boneSkinNameMap) +void SkeletonNode::addSkinGroup(std::string_view groupName, tlx::string_map boneSkinNameMap) { _skinGroupMap.emplace(groupName, std::move(boneSkinNameMap)); } diff --git a/extensions/cocostudio/src/cocostudio/ActionTimeline/SkeletonNode.h b/extensions/cocostudio/src/cocostudio/ActionTimeline/SkeletonNode.h index 9dfe43767a71..85f7cf537480 100644 --- a/extensions/cocostudio/src/cocostudio/ActionTimeline/SkeletonNode.h +++ b/extensions/cocostudio/src/cocostudio/ActionTimeline/SkeletonNode.h @@ -54,7 +54,7 @@ class CCS_DLL SkeletonNode : public BoneNode *@brief: change displays *@param: boneSkinNameMap, map */ - void changeSkins(const axstd::string_map& boneSkinNameMap); + void changeSkins(const tlx::string_map& boneSkinNameMap); /** *@brief: change displays @@ -67,7 +67,7 @@ class CCS_DLL SkeletonNode : public BoneNode *@param: groupName, key *@param: boneSkinNameMap, map */ - void addSkinGroup(std::string_view groupName, axstd::string_map boneSkinNameMap); + void addSkinGroup(std::string_view groupName, tlx::string_map boneSkinNameMap); ax::Rect getBoundingBox() const override; @@ -95,7 +95,7 @@ class CCS_DLL SkeletonNode : public BoneNode ax::Vec2 _squareVertices[8]; VertexData _vertexData[8]; - axstd::string_map> _skinGroupMap; // map< suit name, map< bone name, skin name> > + tlx::string_map> _skinGroupMap; // map< suit name, map< bone name, skin name> > AX_DISALLOW_COPY_AND_ASSIGN(SkeletonNode); void checkSubBonesDirty(); diff --git a/extensions/cocostudio/src/cocostudio/ArmatureDataManager.h b/extensions/cocostudio/src/cocostudio/ArmatureDataManager.h index 0e9f0a573223..ca36cc0b6f70 100644 --- a/extensions/cocostudio/src/cocostudio/ArmatureDataManager.h +++ b/extensions/cocostudio/src/cocostudio/ArmatureDataManager.h @@ -195,7 +195,7 @@ class CCS_DLL ArmatureDataManager : public ax::Object bool _autoLoadSpriteFile; - axstd::string_map _relativeDatas; + tlx::string_map _relativeDatas; }; } // namespace cocostudio diff --git a/extensions/cocostudio/src/cocostudio/Bone.cpp b/extensions/cocostudio/src/cocostudio/Bone.cpp index 4666f04d2d77..0e58f1183409 100644 --- a/extensions/cocostudio/src/cocostudio/Bone.cpp +++ b/extensions/cocostudio/src/cocostudio/Bone.cpp @@ -92,7 +92,7 @@ Bone::~Bone(void) bool Bone::init() { - return Bone::init(axstd::empty_sv); + return Bone::init(tlx::empty_sv); } bool Bone::init(std::string_view name) diff --git a/extensions/cocostudio/src/cocostudio/SGUIReader.cpp b/extensions/cocostudio/src/cocostudio/SGUIReader.cpp index 52b52087d224..5ae1ee83014d 100644 --- a/extensions/cocostudio/src/cocostudio/SGUIReader.cpp +++ b/extensions/cocostudio/src/cocostudio/SGUIReader.cpp @@ -1644,10 +1644,10 @@ void WidgetPropertiesReader0300::setPropsForAllCustomWidgetFromJsonDictionary(st { GUIReader* guiReader = GUIReader::getInstance(); - axstd::string_map* object_map = guiReader->getParseObjectMap(); + tlx::string_map* object_map = guiReader->getParseObjectMap(); Object* object = (*object_map)[classType]; - axstd::string_map* selector_map = guiReader->getParseCallBackMap(); + tlx::string_map* selector_map = guiReader->getParseCallBackMap(); SEL_ParseEvent selector = (*selector_map)[classType]; if (object && selector) diff --git a/extensions/cocostudio/src/cocostudio/SGUIReader.h b/extensions/cocostudio/src/cocostudio/SGUIReader.h index d80dcbc3402f..e945dfd0adf1 100644 --- a/extensions/cocostudio/src/cocostudio/SGUIReader.h +++ b/extensions/cocostudio/src/cocostudio/SGUIReader.h @@ -90,9 +90,9 @@ class CCS_DLL GUIReader : public ax::Object std::string m_strFilePath; ax::ValueMap _fileDesignSizes; - typedef axstd::string_map ParseCallBackMap; + typedef tlx::string_map ParseCallBackMap; ParseCallBackMap _mapParseSelector; - typedef axstd::string_map ParseObjectMap; + typedef tlx::string_map ParseObjectMap; ParseObjectMap _mapObject; public: diff --git a/extensions/cocostudio/src/cocostudio/SpineSkeletonDataCache.h b/extensions/cocostudio/src/cocostudio/SpineSkeletonDataCache.h index efd00fbcddac..d94b8692eb8f 100644 --- a/extensions/cocostudio/src/cocostudio/SpineSkeletonDataCache.h +++ b/extensions/cocostudio/src/cocostudio/SpineSkeletonDataCache.h @@ -38,7 +38,7 @@ class CCS_DLL SpineSkeletonDataCache void removeAllUnusedData(void); public: - axstd::string_map _cacheTable; + tlx::string_map _cacheTable; }; # else @@ -72,7 +72,7 @@ class SpineSkeletonDataCache void removeAllUnusedData(void); public: - axstd::string_map _cacheTable; + tlx::string_map _cacheTable; }; # endif diff --git a/extensions/cocostudio/src/cocostudio/SpriteFrameCacheHelper.h b/extensions/cocostudio/src/cocostudio/SpriteFrameCacheHelper.h index 8a53eacbff0c..be35145f36a6 100644 --- a/extensions/cocostudio/src/cocostudio/SpriteFrameCacheHelper.h +++ b/extensions/cocostudio/src/cocostudio/SpriteFrameCacheHelper.h @@ -62,7 +62,7 @@ class CCS_DLL SpriteFrameCacheHelper SpriteFrameCacheHelper(); ~SpriteFrameCacheHelper(); - axstd::string_map> _usingSpriteFrames; + tlx::string_map> _usingSpriteFrames; static SpriteFrameCacheHelper* _spriteFrameCacheHelper; }; diff --git a/extensions/fairygui/src/fairygui/TranslationHelper.cpp b/extensions/fairygui/src/fairygui/TranslationHelper.cpp index 4de2ac121d75..54f9911a544b 100644 --- a/extensions/fairygui/src/fairygui/TranslationHelper.cpp +++ b/extensions/fairygui/src/fairygui/TranslationHelper.cpp @@ -15,7 +15,7 @@ NS_FGUI_BEGIN using namespace std; -axstd::string_map > TranslationHelper::strings; +tlx::string_map > TranslationHelper::strings; void TranslationHelper::loadFromXML(const char* xmlString, size_t nBytes) { diff --git a/extensions/fairygui/src/fairygui/TranslationHelper.h b/extensions/fairygui/src/fairygui/TranslationHelper.h index 3ab5bac1c53a..3d484fafcc5b 100644 --- a/extensions/fairygui/src/fairygui/TranslationHelper.h +++ b/extensions/fairygui/src/fairygui/TranslationHelper.h @@ -11,7 +11,7 @@ class PackageItem; class TranslationHelper { public: - static axstd::string_map> strings; + static tlx::string_map> strings; static void loadFromXML(const char *xmlString, size_t nBytes); static void translateComponent(PackageItem* item); diff --git a/extensions/physics-nodes/src/physics-nodes/PhysicsDebugNode.cpp b/extensions/physics-nodes/src/physics-nodes/PhysicsDebugNode.cpp index f478f182ab90..cfd023036866 100644 --- a/extensions/physics-nodes/src/physics-nodes/PhysicsDebugNode.cpp +++ b/extensions/physics-nodes/src/physics-nodes/PhysicsDebugNode.cpp @@ -52,7 +52,7 @@ static void b2DrawSolidPolygon(b2Transform t, b2HexColor color, PhysicsDebugNode* dn) { - axstd::pod_vector vec(vertexCount); + tlx::pod_vector vec(vertexCount); for (size_t i = 0; i < vertexCount; i++) { auto pt = b2TransformPoint(t, verts[i]); diff --git a/extensions/scripting/lua-bindings/auto/axlua_studio_auto.cpp b/extensions/scripting/lua-bindings/auto/axlua_studio_auto.cpp index cf7d340e82f6..98b9490cad0f 100644 --- a/extensions/scripting/lua-bindings/auto/axlua_studio_auto.cpp +++ b/extensions/scripting/lua-bindings/auto/axlua_studio_auto.cpp @@ -24701,7 +24701,7 @@ int lua_ax_studio_SkeletonNode_changeSkins(lua_State* tolua_S) ok = true; do { if (argc == 1) { - tsl::robin_map arg0; + tsl::robin_map arg0; ok &= luaval_to_std_map_string_string(tolua_S, 2, &arg0, "ccs.SkeletonNode:changeSkins"); if (!ok) { break; } @@ -24750,7 +24750,7 @@ int lua_ax_studio_SkeletonNode_addSkinGroup(lua_State* tolua_S) if (argc == 2) { std::string_view arg0; - tsl::robin_map arg1; + tsl::robin_map arg1; ok &= luaval_to_std_string_view(tolua_S, 2,&arg0, "ccs.SkeletonNode:addSkinGroup"); diff --git a/extensions/scripting/lua-bindings/manual/AxluaLoader.cpp b/extensions/scripting/lua-bindings/manual/AxluaLoader.cpp index cfa25a617e19..3d8ddbde7df3 100644 --- a/extensions/scripting/lua-bindings/manual/AxluaLoader.cpp +++ b/extensions/scripting/lua-bindings/manual/AxluaLoader.cpp @@ -31,7 +31,6 @@ THE SOFTWARE. #include "lua-bindings/manual/LuaStack.h" #include "lua-bindings/manual/LuaEngine.h" #include "axmol/platform/FileUtils.h" -#include "yasio/string_view.hpp" using namespace ax; diff --git a/extensions/scripting/lua-bindings/manual/LuaBasicConversions.cpp b/extensions/scripting/lua-bindings/manual/LuaBasicConversions.cpp index b711f407811c..9c5c413477d6 100644 --- a/extensions/scripting/lua-bindings/manual/LuaBasicConversions.cpp +++ b/extensions/scripting/lua-bindings/manual/LuaBasicConversions.cpp @@ -30,7 +30,7 @@ #include std::unordered_map g_luaType; -std::unordered_map g_typeCast; +std::unordered_map g_typeCast; #if _AX_DEBUG >= 1 void luaval_to_native_err(lua_State* L, const char* msg, tolua_Error* err, const char* funcName) @@ -229,7 +229,7 @@ bool luaval_to_std_string(lua_State* L, int lo, std::string* outValue, const cha return ok; } -bool luaval_to_std_string_view(lua_State* L, int lo, cxx17::string_view* outValue, const char* funcName) +bool luaval_to_std_string_view(lua_State* L, int lo, std::string_view* outValue, const char* funcName) { if (NULL == L || NULL == outValue) return false; @@ -249,7 +249,7 @@ bool luaval_to_std_string_view(lua_State* L, int lo, cxx17::string_view* outValu { size_t size; auto rawString = lua_tolstring(L, lo, &size); - *outValue = cxx17::string_view(rawString, size); + *outValue = std::string_view(rawString, size); } return ok; @@ -2837,7 +2837,7 @@ void std_map_string_string_to_luaval(lua_State* L, const std::map* ret, const char* funcName) +bool luaval_to_std_map_string_string(lua_State* L, int lo, tlx::string_map* ret, const char* funcName) { if (nullptr == L || nullptr == ret || lua_gettop(L) < lo) return false; @@ -3030,7 +3030,7 @@ void uniformLocation_to_luaval(lua_State* L, const ax::rhi::UniformLocation& loc lua_rawset(L, -3); } -void program_activeattrs_to_luaval(lua_State* L, const axstd::string_map& attrs) +void program_activeattrs_to_luaval(lua_State* L, const tlx::string_map& attrs) { if (L == nullptr) return; diff --git a/extensions/scripting/lua-bindings/manual/LuaBasicConversions.h b/extensions/scripting/lua-bindings/manual/LuaBasicConversions.h index 5a1b00d4bbaa..6311b24d6610 100644 --- a/extensions/scripting/lua-bindings/manual/LuaBasicConversions.h +++ b/extensions/scripting/lua-bindings/manual/LuaBasicConversions.h @@ -46,13 +46,12 @@ #include "axmol/rhi/VertexLayout.h" #include "axmol/ui/GUIDefine.h" -#include "yasio/string_view.hpp" #include using namespace ax; extern std::unordered_map g_luaType; -extern std::unordered_map g_typeCast; +extern std::unordered_map g_typeCast; #if _AX_DEBUG >= 1 void luaval_to_native_err(lua_State* L, const char* msg, tolua_Error* err, const char* funcName = ""); @@ -187,7 +186,7 @@ extern bool luaval_to_long_long(lua_State* L, int lo, long long* outValue, const * string, otherwise return false. */ extern bool luaval_to_std_string(lua_State* L, int lo, std::string* outValue, const char* funcName = ""); -extern bool luaval_to_std_string_view(lua_State* L, int lo, cxx17::string_view* outValue, const char* funcName = ""); +extern bool luaval_to_std_string_view(lua_State* L, int lo, std::string_view* outValue, const char* funcName = ""); /** * Get a ssize_t value from the given acceptable index of stack. @@ -809,7 +808,7 @@ extern bool luaval_to_std_vector_vec3(lua_State* L, int lo, std::vector* ret, + tlx::string_map* ret, const char* funcName); /**@}**/ @@ -1012,7 +1011,7 @@ const char* getLuaTypeName(T* ret, const char* defaultTypeName) } else { // unlike logic, for windows dll only - cxx17::string_view strkey(typeName); + std::string_view strkey(typeName); auto iter2 = g_typeCast.find(strkey); if (iter2 != g_typeCast.end()) { @@ -1284,7 +1283,7 @@ AX_LUA_DLL bool luaval_to_uniformLocation(lua_State* L, int pos, ax::rhi::Unifor */ AX_LUA_DLL void uniformLocation_to_luaval(lua_State* L, const ax::rhi::UniformLocation& desc); -AX_LUA_DLL void program_activeattrs_to_luaval(lua_State* L, const axstd::string_map& map); +AX_LUA_DLL void program_activeattrs_to_luaval(lua_State* L, const tlx::string_map& map); /** * convert ax::ResourceData to lua object diff --git a/extensions/scripting/lua-bindings/manual/LuaStack.cpp b/extensions/scripting/lua-bindings/manual/LuaStack.cpp index 558262d71bff..968405f446de 100644 --- a/extensions/scripting/lua-bindings/manual/LuaStack.cpp +++ b/extensions/scripting/lua-bindings/manual/LuaStack.cpp @@ -670,9 +670,8 @@ int LuaStack::luaLoadChunksFromZIP(lua_State* L) return 0; } - using namespace cxx17; - const auto BYTECODE_FILE_EXT = ".luac"_sv; - const auto NOT_BYTECODE_FILE_EXT = ".lua"_sv; + const auto BYTECODE_FILE_EXT = ".luac"sv; + const auto NOT_BYTECODE_FILE_EXT = ".lua"sv; const char* zipFilename = lua_tostring(L, -1); lua_settop(L, 0); @@ -703,8 +702,8 @@ int LuaStack::luaLoadChunksFromZIP(lua_State* L) if (pos != std::string::npos) { std::string suffix = filename.substr(pos, filename.length()); - if (cxx17::string_view{suffix} == NOT_BYTECODE_FILE_EXT || - cxx17::string_view{suffix} == BYTECODE_FILE_EXT) + if (std::string_view{suffix} == NOT_BYTECODE_FILE_EXT || + std::string_view{suffix} == BYTECODE_FILE_EXT) { filename.erase(pos); } diff --git a/extensions/scripting/lua-bindings/manual/network/lua_xml_http_request.cpp b/extensions/scripting/lua-bindings/manual/network/lua_xml_http_request.cpp index e417ea522fe1..e462d13d05fa 100644 --- a/extensions/scripting/lua-bindings/manual/network/lua_xml_http_request.cpp +++ b/extensions/scripting/lua-bindings/manual/network/lua_xml_http_request.cpp @@ -36,7 +36,7 @@ #include #include -#include "yasio/byte_buffer.hpp" +#include "axmol/tlx/byte_buffer.hpp" using namespace ax; using namespace ax::network; @@ -112,7 +112,7 @@ class LuaMinXmlHttpRequest : public ax::Object std::string _url; std::string _meth; std::string _type; - yasio::sbyte_buffer _data; + tlx::sbyte_buffer _data; int _readyState; int _status; std::string _statusText; diff --git a/tests/cpp-tests/Source/Box2DTestBed/Box2DTestDebugDrawNode.h b/tests/cpp-tests/Source/Box2DTestBed/Box2DTestDebugDrawNode.h index a634aace93a4..a8919e5617d0 100644 --- a/tests/cpp-tests/Source/Box2DTestBed/Box2DTestDebugDrawNode.h +++ b/tests/cpp-tests/Source/Box2DTestBed/Box2DTestDebugDrawNode.h @@ -81,9 +81,9 @@ class Box2DTestDebugDrawNode : public ax::extension::PhysicsDebugNode CustomCommand _customCommandCircle; CustomCommand _customCommandSolidCircle; CustomCommand _customCommandCapsule; - axstd::pod_vector _circles; - axstd::pod_vector _solidCircles; - axstd::pod_vector _capsules; + tlx::pod_vector _circles; + tlx::pod_vector _solidCircles; + tlx::pod_vector _capsules; bool _circlesDirty{true}; bool _solidCirclesDirty{true}; bool _capsulesDirty{true}; diff --git a/tests/cpp-tests/Source/MeshRendererTest/DrawNode3D.h b/tests/cpp-tests/Source/MeshRendererTest/DrawNode3D.h index deb435b18290..02a988e26c8b 100644 --- a/tests/cpp-tests/Source/MeshRendererTest/DrawNode3D.h +++ b/tests/cpp-tests/Source/MeshRendererTest/DrawNode3D.h @@ -97,7 +97,7 @@ class DrawNode3D : public ax::Node ax::CustomCommand _customCommand; rhi::DepthStencilDesc* _depthstencilDescriptor = nullptr; rhi::UniformLocation _locMVPMatrix; - axstd::pod_vector _bufferLines; + tlx::pod_vector _bufferLines; private: AX_DISALLOW_COPY_AND_ASSIGN(DrawNode3D); diff --git a/tests/cpp-tests/Source/RendererTest/RendererTest.cpp b/tests/cpp-tests/Source/RendererTest/RendererTest.cpp index b36771725ecf..5dec415cd642 100644 --- a/tests/cpp-tests/Source/RendererTest/RendererTest.cpp +++ b/tests/cpp-tests/Source/RendererTest/RendererTest.cpp @@ -66,7 +66,7 @@ class DurationRecorder void reset() { _durations.clear(); } private: - axstd::string_map _durations; + tlx::string_map _durations; }; NewRendererTests::NewRendererTests() diff --git a/tests/cpp-tests/proj.linux/main.cpp b/tests/cpp-tests/proj.linux/main.cpp index 7510124924bd..4cfbf1347734 100644 --- a/tests/cpp-tests/proj.linux/main.cpp +++ b/tests/cpp-tests/proj.linux/main.cpp @@ -23,7 +23,6 @@ ****************************************************************************/ #include "AppDelegate.h" -#include "axmol/cocos2d.h" #include #include diff --git a/tests/unit-tests/CMakeLists.txt b/tests/unit-tests/CMakeLists.txt index 42e17ce846a1..8abe2798b8ef 100644 --- a/tests/unit-tests/CMakeLists.txt +++ b/tests/unit-tests/CMakeLists.txt @@ -50,6 +50,7 @@ set(GAME_SOURCE Source/axmol/platform/FileUtilsTests.cpp Source/axmol/ui/UIHelperTests.cpp + Source/axmol/tlx/ContainerTests.cpp ) diff --git a/tests/unit-tests/Source/axmol/base/UTF8Tests.cpp b/tests/unit-tests/Source/axmol/base/UTF8Tests.cpp index 1a44bbac1780..23424fb5d57c 100644 --- a/tests/unit-tests/Source/axmol/base/UTF8Tests.cpp +++ b/tests/unit-tests/Source/axmol/base/UTF8Tests.cpp @@ -55,8 +55,8 @@ TEST_SUITE("base/UTF8") auto encoded = utils::base64Encode(__utf8Code, sizeof(__utf8Code)); - yasio::byte_buffer bb; - axstd::resize_and_overrite(bb, 10, [](uint8_t* out, size_t sz) { + tlx::byte_buffer bb; + tlx::resize_and_overrite(bb, 10, [](uint8_t* out, size_t sz) { memset(out, '1', sz); return sz; }); diff --git a/tests/unit-tests/Source/axmol/platform/FileUtilsTests.cpp b/tests/unit-tests/Source/axmol/platform/FileUtilsTests.cpp index bcfcba8f57db..557bf563a2f6 100644 --- a/tests/unit-tests/Source/axmol/platform/FileUtilsTests.cpp +++ b/tests/unit-tests/Source/axmol/platform/FileUtilsTests.cpp @@ -217,7 +217,7 @@ TEST_SUITE("platform/FileUtils") TEST_CASE("ResizableBufferAdapter") { - yasio::byte_buffer buffer; + tlx::byte_buffer buffer; fu->getContents("text/123.txt", &buffer); REQUIRE(buffer.size() == 3); diff --git a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp new file mode 100644 index 000000000000..f22e7db061f2 --- /dev/null +++ b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp @@ -0,0 +1,181 @@ +#include +#include "TestUtils.h" +#include + +// #include +// #include + +#include +#include + +#include "axmol/tlx/hlookup.hpp" +#include "axmol/tlx/flat_set.hpp" +#include "axmol/tlx/flat_map.hpp" + +namespace tlx +{ +// flat_set traits +template , class Alloc = std::allocator> +struct flat_set_traits1 +{ + using key_type = Key; + using value_type = Key; + using key_compare = Compare; + using value_compare = Compare; + using allocator_type = Alloc; + using container_type = tlx::vector; + + static constexpr bool allow_duplicates = false; +}; + +/// flat_set +template , class Alloc = std::allocator> +class flat_set1 : public detail::flat_set_base> +{ + using impl_type = detail::flat_set_base>; + +public: + using impl_type::impl_type; +}; +} // namespace tlx + +template +static constexpr bool vector_equals(const _Cont1& c1, const _Cont2& c2) +{ + return c1.size() == c2.size() && 0 == memcmp(c1.data(), c2.data(), c1.size() * sizeof(typename _Cont1::value_type)); +} + +template +static auto benchmark_set(const std::string& name, const std::vector& keys) +{ + Set s; + + auto start = std::chrono::high_resolution_clock::now(); + + for (auto k : keys) + { + s.emplace(k); + } + + auto mid1 = std::chrono::high_resolution_clock::now(); + + volatile int sum = 0; + for (auto k : keys) + { + auto it = s.find(k); + if (it != s.end()) + sum += *it; + } + + auto mid2 = std::chrono::high_resolution_clock::now(); + + for (const auto& v : s) + { + sum += v; + } + + auto end = std::chrono::high_resolution_clock::now(); + + auto insert_time = std::chrono::duration(mid1 - start).count(); + auto find_time = std::chrono::duration(mid2 - mid1).count(); + auto iter_time = std::chrono::duration(end - mid2).count(); + + std::cout << name << " results:\n"; + std::cout << " Insert: " << insert_time << " ms\n"; + std::cout << " Find: " << find_time << " ms\n"; + std::cout << " Iterate:" << iter_time << " ms\n"; + std::cout << " Sum: " << sum << "\n\n"; + + return s; +} + +template +static auto benchmark_map(const std::string& name, const std::vector& keys) +{ + Map m; + + auto start = std::chrono::high_resolution_clock::now(); + + for (auto k : keys) + { + m.emplace(k, k * 2); + } + + auto mid1 = std::chrono::high_resolution_clock::now(); + + volatile int sum = 0; + for (auto k : keys) + { + auto it = m.find(k); + if (it != m.end()) + sum += it->second; + } + + auto mid2 = std::chrono::high_resolution_clock::now(); + + for (const auto& kv : m) + { + sum += kv.second; + } + + auto end = std::chrono::high_resolution_clock::now(); + + auto insert_time = std::chrono::duration(mid1 - start).count(); + auto find_time = std::chrono::duration(mid2 - mid1).count(); + auto iter_time = std::chrono::duration(end - mid2).count(); + + std::cout << name << " results:\n"; + std::cout << " Insert: " << insert_time << " ms\n"; + std::cout << " Find: " << find_time << " ms\n"; + std::cout << " Iterate:" << iter_time << " ms\n"; + std::cout << " Sum: " << sum << "\n\n"; + + return m; +} + +static void run_benchmark() +{ + constexpr size_t N = 100000; + std::vector keys(N); + + std::mt19937 rng(12345); + std::uniform_int_distribution dist(1, N * 10); + + for (size_t i = 0; i < N; ++i) + { + keys[i] = dist(rng); + } + + auto s1 = benchmark_set>("std::set", keys); + auto s2 = benchmark_set>("std::unordered_set", keys); + auto s3 = benchmark_set>("tlx::hash_set", keys); + //auto s4 = benchmark_set>("std::flat_set", keys); + auto s5 = benchmark_set>("tlx::flat_set", keys); + auto s6 = benchmark_set>("tlx::flat_set1", keys); + + auto m1 = benchmark_map>("std::map", keys); + auto m2 = benchmark_map>("std::unordered_map", keys); + auto m3 = benchmark_map>("tlx::hash_map", keys); + //auto m4 = benchmark_map>("std::flat_map", keys); + auto m5 = benchmark_map>("tlx::flat_map", keys); + + std::sort(keys.begin(), keys.end()); + keys.erase(std::unique(keys.begin(), keys.end()), keys.end()); + + CHECK(vector_equals(keys, s5.keys())); + CHECK(vector_equals(keys, s6.keys())); + // CHECK(keys == m5.keys()); +} + +TEST_SUITE("tlx/Containers") +{ + // !!!Don't invoke FileUtils::getInstacne at here, it's dangerous due to + // The test suite function will invoke before entrypoint `main`, it will cause + // crash on Linux(maybe others), crt not initalized properly yet. +#define fu FileUtils::getInstance() + + TEST_CASE("BenchmarkTest") + { + run_benchmark(); + } +} From e0dda4ba5c9f0680a8e922f1dfc409b7aa182b8a Mon Sep 17 00:00:00 2001 From: halx99 Date: Sun, 30 Nov 2025 22:23:12 +0800 Subject: [PATCH 02/17] Fixup --- 3rdparty/yasio/yasio/io_service.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/3rdparty/yasio/yasio/io_service.cpp b/3rdparty/yasio/yasio/io_service.cpp index 3c1675a3c1b6..25aa99416c59 100644 --- a/3rdparty/yasio/yasio/io_service.cpp +++ b/3rdparty/yasio/yasio/io_service.cpp @@ -867,7 +867,7 @@ void io_service::initialize(const io_hostent* channel_eps, int channel_count) create_channels(channel_eps, channel_count); #if !defined(YASIO_USE_CARES) - life_mutex_ = std::make_shared(); + life_mutex_ = std::make_shared(); life_token_ = std::make_shared(); #endif this->state_ = io_service::state::IDLE; @@ -877,7 +877,7 @@ void io_service::finalize() if (this->state_ == io_service::state::IDLE) { #if !defined(YASIO_USE_CARES) - std::unique_lock lck(*life_mutex_); + std::unique_lock lck(*life_mutex_); life_token_.reset(); #endif destroy_channels(); @@ -2064,7 +2064,7 @@ void io_service::start_query(io_channel* ctx) // init async name query thread state auto resolving_host = ctx->remote_host_; auto resolving_port = ctx->remote_port_; - std::weak_ptr weak_mutex = life_mutex_; + std::weak_ptr weak_mutex = life_mutex_; std::weak_ptr life_token = life_token_; std::thread async_resolv_thread([this, life_token, weak_mutex, resolving_host, resolving_port, ctx] { // check life token @@ -2079,7 +2079,7 @@ void io_service::start_query(io_channel* ctx) auto pmtx = weak_mutex.lock(); if (!pmtx) return; - std::shared_lock lck(*pmtx); + tlx::shared_lock lck(*pmtx); // check life token again, when io_service cleanup done, life_token's use_count will be 0, // otherwise, we can safe to do follow assignments. From d9738761ac02fb1709dde901441118e99e5eb4d7 Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 1 Dec 2025 00:06:15 +0800 Subject: [PATCH 03/17] Fixup --- axmol/axmol.natvis | 168 +++++++--- axmol/tlx/flat_map.hpp | 317 ++++++++++++++++-- axmol/tlx/flat_map_base.hpp | 284 ---------------- axmol/tlx/flat_multimap.hpp | 61 ---- axmol/tlx/flat_multiset.hpp | 41 --- axmol/tlx/flat_set.hpp | 188 ++++++++++- axmol/tlx/flat_set_base.hpp | 217 ------------ extensions/SDFGen/src/SDFGen/SDFGen.cpp | 8 +- .../Source/axmol/tlx/ContainerTests.cpp | 82 +++-- 9 files changed, 648 insertions(+), 718 deletions(-) delete mode 100644 axmol/tlx/flat_map_base.hpp delete mode 100644 axmol/tlx/flat_multimap.hpp delete mode 100644 axmol/tlx/flat_multiset.hpp delete mode 100644 axmol/tlx/flat_set_base.hpp diff --git a/axmol/axmol.natvis b/axmol/axmol.natvis index 9513a74417b9..98d888dabf05 100644 --- a/axmol/axmol.natvis +++ b/axmol/axmol.natvis @@ -1,18 +1,7 @@ - - {{ size={_Mylast - _Myfirst} capacity={_Myend - _Myfirst} }} - - _Mylast - _Myfirst - _Myend - _Myfirst - - _Mylast - _Myfirst - _Myfirst - - - - - + + {{size = {_Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst}}} _Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst @@ -24,42 +13,141 @@ - - - {{size = {_Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst}}} + + + + + + + + + + + + + {{ size={size()} }} + - _Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst - _Mypair._Myval2._Mypair._Myval2._Myend - _Mypair._Myval2._Mypair._Myval2._Myfirst - - _Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst - _Mypair._Myval2._Mypair._Myval2._Myfirst - + _Key_compare + size() + + + size() + + *value_at(i) + ++i + + - - - {{size = {_Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst}}} + + + + + + + + + + + {{ size={size()} }} + - _Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst - _Mypair._Myval2._Mypair._Myval2._Myend - _Mypair._Myval2._Mypair._Myval2._Myfirst - - _Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst - _Mypair._Myval2._Mypair._Myval2._Myfirst - + _Key_compare + size() + + + size() + + *value_at(i) + ++i + + - - - {{size = {_Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst}}} + + + + + + + + + + + {{ size={size()} }} + - _Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst - _Mypair._Myval2._Mypair._Myval2._Myend - _Mypair._Myval2._Mypair._Myval2._Myfirst - - _Mypair._Myval2._Mypair._Myval2._Mylast - _Mypair._Myval2._Mypair._Myval2._Myfirst - _Mypair._Myval2._Mypair._Myval2._Myfirst - + _Key_compare + size() + + + size() + + *value_at(i) + ++i + + + + + + + + + + + + + + + + {{ size={size()} }} + + + _Key_compare + size() + + + size() + + *value_at(i) + ++i + + + + + + + + {_Data} + + _Key_compare + _Mykeys + _Myvals + + + + + + ({_Key_it}, {_Mapped_it}) + + _Key_it + _Mapped_it + + + + + + ({_Key_it}, {_Mapped_it}) + + _Key_it + _Mapped_it diff --git a/axmol/tlx/flat_map.hpp b/axmol/tlx/flat_map.hpp index 3f3ec326d33b..60f8ca5f826f 100644 --- a/axmol/tlx/flat_map.hpp +++ b/axmol/tlx/flat_map.hpp @@ -20,58 +20,311 @@ THE SOFTWARE. ****************************************************************************/ #pragma once -#include "axmol/tlx/flat_map_base.hpp" +#include +#include +#include +#include +#include #include +#include "yasio/tlx/memory.hpp" namespace tlx { -// flat_map traits -template , - class KeyAlloc = std::allocator, - class MappedAlloc = std::allocator> -struct flat_map_traits +/// CLASS template flat_map_base +template +class flat_map_base { - using key_type = Key; - using mapped_type = T; - using key_compare = Compare; - using allocator_type = KeyAlloc; - using key_container = std::vector; - using mapped_container = std::vector; - - static constexpr bool allow_duplicates = false; +public: + using key_type = _Key; + using mapped_type = _Mapped; + using key_container = _KeyContainer; + using mapped_container = _MappedContainer; + using key_compare = _Compare; + + using size_type = size_t; + using difference_type = ptrdiff_t; + +#pragma region value and iterator proxy + struct value_proxy + { + const key_type& first; + mapped_type& second; + + value_proxy* operator->() { return this; } + const value_proxy* operator->() const { return this; } + }; + + class iterator + { + public: + using key_iter = typename key_container::iterator; + using mapped_iter = typename mapped_container::iterator; + key_iter _Key_it; + mapped_iter _Mapped_it; + + using difference_type = typename key_container::difference_type; + using value_type = value_proxy; + using reference = value_proxy; + using pointer = value_proxy*; + using iterator_category = std::random_access_iterator_tag; + + iterator(key_iter k_it, mapped_iter v_it) : _Key_it(k_it), _Mapped_it(v_it) {} + reference operator*() const { return value_proxy{*_Key_it, *_Mapped_it}; } + value_proxy operator->() const { return {*_Key_it, *_Mapped_it}; } + + iterator& operator++() + { + ++_Key_it; + ++_Mapped_it; + return *this; + } + iterator operator++(int) + { + auto tmp = *this; + ++*this; + return tmp; + } + + bool operator==(const iterator& other) const { return _Key_it == other._Key_it; } + bool operator!=(const iterator& other) const { return !(*this == other); } + }; + + class const_iterator + { + public: + using key_iter = typename key_container::const_iterator; + using mapped_iter = typename mapped_container::const_iterator; + key_iter _Key_it; + mapped_iter _Mapped_it; + + using difference_type = typename key_container::difference_type; + using value_type = value_proxy; + using reference = value_proxy; + using pointer = const value_proxy*; + using iterator_category = std::random_access_iterator_tag; + + const_iterator(key_iter k_it, mapped_iter v_it) : _Key_it(k_it), _Mapped_it(v_it) {} + reference operator*() const { return value_proxy{*_Key_it, const_cast(*_Mapped_it)}; } + value_proxy operator->() const { return {*_Key_it, const_cast(*_Mapped_it)}; } + + const_iterator& operator++() + { + ++_Key_it; + ++_Mapped_it; + return *this; + } + const_iterator operator++(int) + { + auto tmp = *this; + ++*this; + return tmp; + } + + bool operator==(const const_iterator& other) const { return _Key_it == other._Key_it; } + bool operator!=(const const_iterator& other) const { return !(*this == other); } + }; +#pragma endregion + + flat_map_base() : flat_map_base(key_compare()) {} + explicit flat_map_base(const key_compare& pred) : _Mykeys(), _Myvals(), _Mycomp(pred) {} + + void reserve(size_t capacity) + { + _Mykeys.reserve(capacity); + _Myvals.reserve(capacity); + } + void clear() + { + _Mykeys.clear(); + _Myvals.clear(); + } + + bool empty() const noexcept { return _Mykeys.empty(); } + size_t size() const noexcept { return _Mykeys.size(); } + + iterator begin() noexcept { return iterator(_Mykeys.begin(), _Myvals.begin()); } + iterator end() noexcept { return iterator(_Mykeys.end(), _Myvals.end()); } + const_iterator begin() const noexcept { return const_iterator(_Mykeys.begin(), _Myvals.begin()); } + const_iterator end() const noexcept { return const_iterator(_Mykeys.end(), _Myvals.end()); } + const_iterator cbegin() const noexcept { return const_iterator{std::cbegin(_Mykeys), std::cbegin(_Myvals)}; } + const_iterator cend() const noexcept { return const_iterator{std::cend(_Mykeys), std::cend(_Myvals)}; } + + iterator find(const key_type& key) + { + auto it = this->lower_bound(key); + if (it != end() && !_Mycomp(key, (*it).first) && !_Mycomp((*it).first, key)) + return it; + return end(); + } + + const_iterator find(const key_type& key) const + { + auto it = lower_bound(key); + if (it != end() && !_Mycomp(key, (*it).first) && !_Mycomp((*it).first, key)) + return it; + return end(); + } + + iterator lower_bound(const key_type& key) + { + auto k_it = std::lower_bound(_Mykeys.begin(), _Mykeys.end(), key, _Mycomp); + auto v_it = _Myvals.begin() + (k_it - _Mykeys.begin()); + return iterator(k_it, v_it); + } + + const_iterator lower_bound(const key_type& key) const + { + auto k_it = std::lower_bound(_Mykeys.begin(), _Mykeys.end(), key, _Mycomp); + auto v_it = _Myvals.begin() + (k_it - _Mykeys.begin()); + return const_iterator(k_it, v_it); + } + + template + void insert(InputIt first, InputIt last) + { + for (; first != last; ++first) + { + insert(first->first, first->second); + } + } + + std::pair insert(const key_type& k, const mapped_type& v) + { + return emplace(std::forward(k), std::forward(v)); + } + + template + std::pair emplace(_KeyArg&& key, _MArgs&&... mapped_args) + { + auto key_it = std::lower_bound(_Mykeys.begin(), _Mykeys.end(), key, _Mycomp); + auto mapped_it = _Myvals.begin() + (key_it - _Mykeys.begin()); + + if constexpr (_IsUnique) + { + // map: only insert if key not found + if (key_it == _Mykeys.end() || _Mycomp(key, *key_it)) + { + key_it = _Mykeys.insert(key_it, std::forward<_KeyArg>(key)); + mapped_it = _Myvals.insert(mapped_it, mapped_type(std::forward<_MArgs>(mapped_args)...)); + return {iterator(key_it, mapped_it), true}; + } + else + { + return {iterator(key_it, mapped_it), false}; + } + } + else + { + // multimap: always insert at upper_bound + key_it = _Mykeys.insert(key_it, std::forward<_KeyArg>(key)); + mapped_it = _Myvals.insert(mapped_it, mapped_type(std::forward<_MArgs>(mapped_args)...)); + return {iterator(key_it, mapped_it), true}; + } + } + + // erase by iterator + iterator erase(iterator pos) + { + auto key_it = _Mykeys.erase(pos._Key_it); + auto mapped_it = _Myvals.erase(pos._Mapped_it); + return iterator(key_it, mapped_it); + } + + // erase by key + size_type erase(const key_type& key) + { + auto k_it = std::lower_bound(_Mykeys.begin(), _Mykeys.end(), key, _Mycomp); + auto v_it = _Myvals.begin() + (k_it - _Mykeys.begin()); + + if (k_it == _Mykeys.end() || _Mycomp(key, *k_it) || _Mycomp(*k_it, key)) + return 0; // not found + + if constexpr (_IsUnique) + { + // map: erase single element + _Mykeys.erase(k_it); + _Myvals.erase(v_it); + return 1; + } + else + { + // multimap: erase all equal keys + auto k_end = std::upper_bound(k_it, _Mykeys.end(), key, _Mycomp); + auto v_end = _Myvals.begin() + (k_end - _Mykeys.begin()); + + size_type count = static_cast(k_end - k_it); + _Mykeys.erase(k_it, k_end); + _Myvals.erase(v_it, v_end); + return count; + } + } + + const auto& keys() const { return _Mykeys; } + +protected: + key_container _Mykeys; + mapped_container _Myvals; + [[no_unique_address]] key_compare _Mycomp; }; -template , - class KeyAlloc = std::allocator, - class MappedAlloc = std::allocator> -class flat_map : public detail::flat_map_base> +/// CLASS template flat_map +template , + typename _KeyContainer = std::vector<_Key>, + typename _MappedContainer = std::vector<_Mapped>> +class flat_map : public _TLX flat_map_base { - using traits = flat_map_traits; - using impl_type = detail::flat_map_base; + using impl_type = _TLX flat_map_base; public: using impl_type::impl_type; // operator[] for map semantics - T& operator[](const Key& key) + _Mapped& operator[](const _Key& key) { - auto& pred = this->_Mykeys._Get_first(); - auto it = this->lower_bound(key); - if (it == this->end() || pred(key, (*it).first)) + auto it = this->lower_bound(key); + if (it == this->end() || this->_Mycomp(key, (*it).first)) { - auto pos = it._k_it; - auto idx = pos - this->_Mykeys._Myval2.begin(); - this->_Mykeys._Myval2.insert(pos, key); + auto pos = it._Key_it; + auto idx = pos - this->_Mykeys.begin(); + this->_Mykeys.insert(pos, key); this->_Myvals.emplace(this->_Myvals.begin() + idx); - it = typename impl_type::iterator(this->_Mykeys._Myval2.begin() + idx, this->_Myvals.begin() + idx); + it = typename impl_type::iterator(this->_Mykeys.begin() + idx, this->_Myvals.begin() + idx); } return (*it).second; } + + // at() for map semantics + _Mapped& at(const _Key& key) + { + auto it = this->lower_bound(key); + if (it == this->end() || this->_Mycomp(key, (*it).first)) + throw std::out_of_range("tlx::flat_map::at: key not found"); + return (*it).second; + } + + const _Mapped& at(const _Key& key) const + { + auto it = this->lower_bound(key); + if (it == this->end() || this->_Mycomp(key, (*it).first)) + throw std::out_of_range("tlx::flat_map::at: key not found"); + return (*it).second; + } }; +/// CLASS template flat_multimap +template , + typename _KeyContainer = std::vector<_Key>, + typename _MappedContainer = std::vector<_Mapped>> +using flat_multimap = _TLX flat_map_base; + } // namespace tlx diff --git a/axmol/tlx/flat_map_base.hpp b/axmol/tlx/flat_map_base.hpp deleted file mode 100644 index 57c05595625a..000000000000 --- a/axmol/tlx/flat_map_base.hpp +++ /dev/null @@ -1,284 +0,0 @@ -/**************************************************************************** - Copyright (c) 2019-present Axmol Engine contributors (see AUTHORS.md). - - https://axmol.dev/ - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - ****************************************************************************/ -#pragma once -#include -#include -#include -#include -#include "yasio/tlx/memory.hpp" - -namespace tlx -{ -namespace detail -{ - -template -class flat_map_base -{ -public: - using key_type = typename _Traits::key_type; - using mapped_type = typename _Traits::mapped_type; - using allocator_type = typename _Traits::allocator_type; - using key_container = typename _Traits::key_container; - using mapped_container = typename _Traits::mapped_container; - -protected: - using key_alloc = typename std::allocator_traits::template rebind_alloc; - using mapped_alloc = typename std::allocator_traits::template rebind_alloc; - -public: - using key_compare = typename _Traits::key_compare; - - using size_type = typename std::allocator_traits::size_type; - using difference_type = typename std::allocator_traits::difference_type; - -#pragma region value and iterator proxy - struct value_proxy - { - const key_type& first; - mapped_type& second; - - value_proxy* operator->() { return this; } - const value_proxy* operator->() const { return this; } - }; - - class iterator - { - public: - using key_iter = typename key_container::iterator; - using mapped_iter = typename mapped_container::iterator; - key_iter _k_it; - mapped_iter _v_it; - - using difference_type = typename key_container::difference_type; - using value_type = value_proxy; - using reference = value_proxy; - using pointer = value_proxy*; - using iterator_category = std::random_access_iterator_tag; - - iterator(key_iter k_it, mapped_iter v_it) : _k_it(k_it), _v_it(v_it) {} - reference operator*() const { return value_proxy{*_k_it, *_v_it}; } - value_proxy operator->() const { return {*_k_it, *_v_it}; } - - iterator& operator++() - { - ++_k_it; - ++_v_it; - return *this; - } - iterator operator++(int) - { - auto tmp = *this; - ++*this; - return tmp; - } - - bool operator==(const iterator& other) const { return _k_it == other._k_it; } - bool operator!=(const iterator& other) const { return !(*this == other); } - }; - - class const_iterator - { - public: - using key_iter = typename key_container::const_iterator; - using mapped_iter = typename mapped_container::const_iterator; - key_iter _k_it; - mapped_iter _v_it; - - using difference_type = typename key_container::difference_type; - using value_type = value_proxy; - using reference = value_proxy; - using pointer = const value_proxy*; - using iterator_category = std::random_access_iterator_tag; - - const_iterator(key_iter k_it, mapped_iter v_it) : _k_it(k_it), _v_it(v_it) {} - reference operator*() const { return value_proxy{*_k_it, const_cast(*_v_it)}; } - value_proxy operator->() const { return {*_k_it, const_cast(*_v_it)}; } - - const_iterator& operator++() - { - ++_k_it; - ++_v_it; - return *this; - } - const_iterator operator++(int) - { - auto tmp = *this; - ++*this; - return tmp; - } - - bool operator==(const const_iterator& other) const { return _k_it == other._k_it; } - bool operator!=(const const_iterator& other) const { return !(*this == other); } - }; -#pragma endregion - - explicit flat_map_base(const key_compare& pred = key_compare(), const allocator_type& alloc = allocator_type()) - : _Mykeys(_TLX __one_then_variadic_args_t{}, pred, key_container(alloc)), _Myvals(alloc) - {} - - void reserve(size_t capacity) - { - _Mykeys._Myval2.reserve(capacity); - _Myvals.reserve(capacity); - } - void clear() - { - _Mykeys._Myval2.clear(); - _Myvals.clear(); - } - - bool empty() const noexcept { return _Mykeys._Myval2.empty(); } - size_t size() const noexcept { return _Mykeys._Myval2.size(); } - - iterator begin() noexcept { return iterator(_Mykeys._Myval2.begin(), _Myvals.begin()); } - iterator end() noexcept { return iterator(_Mykeys._Myval2.end(), _Myvals.end()); } - const_iterator begin() const noexcept { return const_iterator(_Mykeys._Myval2.begin(), _Myvals.begin()); } - const_iterator end() const noexcept { return const_iterator(_Mykeys._Myval2.end(), _Myvals.end()); } - - iterator find(const key_type& key) - { - const auto& pred = _Mykeys._Get_first(); - auto it = lower_bound(key); - if (it != end() && !pred(key, (*it).first) && !pred((*it).first, key)) - return it; - return end(); - } - - const_iterator find(const key_type& key) const - { - const auto& pred = _Mykeys._Get_first(); - auto it = lower_bound(key); - if (it != end() && !pred(key, (*it).first) && !pred((*it).first, key)) - return it; - return end(); - } - - iterator lower_bound(const key_type& key) - { - const auto& pred = _Mykeys._Get_first(); - auto k_it = std::lower_bound(_Mykeys._Myval2.begin(), _Mykeys._Myval2.end(), key, pred); - auto v_it = _Myvals.begin() + (k_it - _Mykeys._Myval2.begin()); - return iterator(k_it, v_it); - } - - const_iterator lower_bound(const key_type& key) const - { - const auto& pred = _Mykeys._Get_first(); - auto k_it = std::lower_bound(_Mykeys._Myval2.begin(), _Mykeys._Myval2.end(), key, pred); - auto v_it = _Myvals.begin() + (k_it - _Mykeys._Myval2.begin()); - return const_iterator(k_it, v_it); - } - - template - void insert(InputIt first, InputIt last) - { - for (; first != last; ++first) - { - insert(first->first, first->second); - } - } - - std::pair insert(const key_type& k, const mapped_type& v) - { - return emplace(std::forward(k), std::forward(v)); - } - - template - std::pair emplace(_KeyArg&& key, _MArgs&&... mapped_args) - { - const auto& pred = _Mykeys._Get_first(); - auto key_it = std::lower_bound(_Mykeys._Myval2.begin(), _Mykeys._Myval2.end(), key, pred); - auto mapped_it = _Myvals.begin() + (key_it - _Mykeys._Myval2.begin()); - - if constexpr (_Traits::allow_duplicates) - { - // multimap: always insert at upper_bound - key_it = _Mykeys._Myval2.insert(key_it, std::forward<_KeyArg>(key)); - mapped_it = _Myvals.insert(mapped_it, mapped_type(std::forward<_MArgs>(mapped_args)...)); - return {iterator(key_it, mapped_it), true}; - } - else - { - // map: only insert if key not found - if (key_it == _Mykeys._Myval2.end() || pred(key, *key_it)) - { - key_it = _Mykeys._Myval2.insert(key_it, std::forward<_KeyArg>(key)); - mapped_it = _Myvals.insert(mapped_it, mapped_type(std::forward<_MArgs>(mapped_args)...)); - return {iterator(key_it, mapped_it), true}; - } - else - { - return {iterator(key_it, mapped_it), false}; - } - } - } - - // erase by iterator - iterator erase(iterator pos) - { - auto k_it = pos._k_it; - auto v_it = pos._v_it; - _Mykeys._Myval2.erase(k_it); - _Myvals.erase(v_it); - return iterator(k_it, v_it); - } - - // erase by key - size_type erase(const key_type& key) - { - const auto& pred = _Mykeys._Get_first(); - auto k_it = std::lower_bound(_Mykeys._Myval2.begin(), _Mykeys._Myval2.end(), key, pred); - auto v_it = _Myvals.begin() + (k_it - _Mykeys._Myval2.begin()); - - if (k_it == _Mykeys._Myval2.end() || pred(key, *k_it) || pred(*k_it, key)) - return 0; // not found - - if constexpr (_Traits::allow_duplicates) - { - // multimap: erase all equal keys - auto k_end = std::upper_bound(k_it, _Mykeys._Myval2.end(), key, pred); - auto v_end = _Myvals.begin() + (k_end - _Mykeys._Myval2.begin()); - - size_type count = static_cast(k_end - k_it); - _Mykeys._Myval2.erase(k_it, k_end); - _Myvals.erase(v_it, v_end); - return count; - } - else - { - // map: erase single element - _Mykeys._Myval2.erase(k_it); - _Myvals.erase(v_it); - return 1; - } - } - - const auto& keys() const { return _Mykeys; } - -protected: - _TLX __compressed_pair _Mykeys; - mapped_container _Myvals; -}; - -} // namespace detail -} // namespace tlx diff --git a/axmol/tlx/flat_multimap.hpp b/axmol/tlx/flat_multimap.hpp deleted file mode 100644 index c38bab82788d..000000000000 --- a/axmol/tlx/flat_multimap.hpp +++ /dev/null @@ -1,61 +0,0 @@ -/**************************************************************************** - Copyright (c) 2019-present Axmol Engine contributors (see AUTHORS.md). - - https://axmol.dev/ - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - ****************************************************************************/ -#pragma once -#include "axmol/tlx/flat_map_base.hpp" -#include - -namespace tlx -{ - -// flat_map traits -template , - class KeyAlloc = std::allocator, - class MappedAlloc = std::allocator> -struct flat_multimap_traits -{ - using key_type = Key; - using mapped_type = T; - using key_compare = Compare; - using allocator_type = KeyAlloc; - using key_container = std::vector; - using mapped_container = std::vector; - - static constexpr bool allow_duplicates = true; -}; - -template , - class KeyAlloc = std::allocator, - class MappedAlloc = std::allocator> -class flat_multimap : public detail::flat_map_base> -{ - using traits = flat_multimap_traits; - using impl_type = detail::flat_map_base; - -public: - using impl_type::impl_type; -}; - -} // namespace tlx diff --git a/axmol/tlx/flat_multiset.hpp b/axmol/tlx/flat_multiset.hpp deleted file mode 100644 index 59d817dfc08f..000000000000 --- a/axmol/tlx/flat_multiset.hpp +++ /dev/null @@ -1,41 +0,0 @@ -/**************************************************************************** - Copyright (c) 2019-present Axmol Engine contributors (see AUTHORS.md). - - https://axmol.dev/ - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - ****************************************************************************/ -#pragma once -#include "axmol/tlx/flat_set_base.hpp" -#include - -namespace tlx -{ -template , class Alloc = std::allocator> -struct flat_multiset_traits -{ - using key_type = Key; - using value_type = Key; - using key_compare = Compare; - using allocator_type = Alloc; - using container_type = std::vector; - static constexpr bool allow_duplicates = true; -}; - -template , class Alloc = std::allocator> -using flat_multiset = tlx::detail::flat_set_base>; -} // namespace tlx diff --git a/axmol/tlx/flat_set.hpp b/axmol/tlx/flat_set.hpp index 67a5fbdefe1d..e0199e82800e 100644 --- a/axmol/tlx/flat_set.hpp +++ b/axmol/tlx/flat_set.hpp @@ -20,22 +20,186 @@ THE SOFTWARE. ****************************************************************************/ #pragma once -#include "axmol/tlx/flat_set_base.hpp" -#include +#include +#include +#include +#include +#include "yasio/tlx/memory.hpp" namespace tlx { -template , class Alloc = std::allocator> -struct flat_set_traits +template +class flat_set_base { - using key_type = Key; - using value_type = Key; - using key_compare = Compare; - using allocator_type = Alloc; - using container_type = std::vector; - static constexpr bool allow_duplicates = false; +public: + using key_type = _Kty; + using value_type = _Kty; + using key_compare = _Pred; + using container_type = _Container; + + using size_type = typename container_type::size_type; + using difference_type = typename container_type::difference_type; + using pointer = typename container_type::pointer; + using const_pointer = typename container_type::const_pointer; + using reference = key_type&; + using const_reference = const key_type&; + using iterator = typename container_type::iterator; + using const_iterator = typename container_type::const_iterator; + + flat_set_base() : _Mycont(), _Mycomp() {} + explicit flat_set_base(container_type cont, const key_compare& pred = key_compare()) + : _Mycont(std::move(cont)), _Mycomp(pred) + {} + + void reserve(size_t capacity) { _Mycont.reserve(capacity); } + void clear() { _Mycont.clear(); } + + bool empty() const noexcept { return _Mycont.empty(); } + size_t size() const noexcept { return _Mycont.size(); } + + iterator begin() noexcept { return _Mycont.begin(); } + iterator end() noexcept { return _Mycont.end(); } + const_iterator begin() const noexcept { return _Mycont.begin(); } + const_iterator end() const noexcept { return _Mycont.end(); } + + const_iterator cbegin() const noexcept { return _Mycont.begin(); } + const_iterator cend() const noexcept { return _Mycont.end(); } + + iterator find(const key_type& key) + { + auto it = this->lower_bound(key); + if (it != _Mycont.end() && !_Mycomp(key, *it) && !_Mycomp(*it, key)) + return it; + return _Mycont.end(); + } + + const_iterator find(const key_type& key) const + { + auto it = this->lower_bound(key); + if (it != _Mycont.end() && !_Mycomp(key, *it) && !_Mycomp(*it, key)) + return it; + return _Mycont.end(); + } + + iterator lower_bound(const key_type& key) { return std::lower_bound(_Mycont.begin(), _Mycont.end(), key, _Mycomp); } + + const_iterator lower_bound(const key_type& key) const + { + return std::lower_bound(_Mycont.begin(), _Mycont.end(), key, _Mycomp); + } + + iterator upper_bound(const key_type& key) { return std::upper_bound(_Mycont.begin(), _Mycont.end(), key, _Mycomp); } + + const_iterator upper_bound(const key_type& key) const + { + return std::upper_bound(_Mycont.begin(), _Mycont.end(), key, _Mycomp); + } + + std::pair equal_range(const key_type& key) { return {lower_bound(key), upper_bound(key)}; } + + std::pair equal_range(const key_type& key) const + { + return {this->lower_bound(key), this->upper_bound(key)}; + } + + template + void insert(InputIt first, InputIt last) + { + _Mycont.insert(_Mycont.end(), first, last); + + std::sort(_Mycont.begin(), _Mycont.end(), _Mycomp); + + if constexpr (_IsUnique) + { + _Mycont.erase( + std::unique(_Mycont.begin(), _Mycont.end(), + [&](const key_type& a, const key_type& b) { return !_Mycomp(a, b) && !_Mycomp(b, a); }), + _Mycont.end()); + } + } + + std::pair insert(const key_type& k) { return emplace(k); } + + iterator insert(const_iterator hint, const key_type& k) { return emplace_hint(hint, k); } + + template + std::pair emplace(Args&&... args) + { + key_type k(std::forward(args)...); + if constexpr (_IsUnique) + { + auto it = this->lower_bound(k); + if (it == _Mycont.end() || _Mycomp(k, *it)) + { + it = _Mycont.insert(it, std::move(k)); + return {it, true}; + } + return {it, false}; + } + else + { + auto it = this->upper_bound(k); + it = _Mycont.insert(it, std::move(k)); + return {it, true}; + } + } + + template + iterator emplace_hint(const_iterator hint, Args&&... args) + { + key_type k(std::forward(args)...); + if constexpr (_IsUnique) + { + if (hint == _Mycont.end() || _Mycomp(k, *hint)) + { + return _Mycont.insert(hint, std::move(k)); + } + else + { + return emplace(std::move(k)).first; + } + } + else + { + return _Mycont.insert(hint, std::move(k)); + } + } + + size_type erase(const key_type& key) + { + if constexpr (_IsUnique) + { + const const_iterator _Where = lower_bound(key); + if (_Where != cend() && !_Mycomp(key, *_Where)) + { + _Mycont.erase(_Where); + return 1; + } + return 0; + } + else + { + const auto [_First, _Last] = equal_range(key); + + const auto _Removed = static_cast(_Last - _First); + _Mycont.erase(_First, _Last); + return _Removed; + } + } + + iterator erase(const_iterator it) { return _Mycont.erase(it); } + + const auto& keys() const { return _Mycont; } + +protected: + container_type _Mycont; + [[no_unique_address]] key_compare _Mycomp; }; -template , class Alloc = std::allocator> -using flat_set = tlx::detail::flat_set_base>; +template , class _Container = std::vector<_Kty>> +using flat_set = _TLX flat_set_base; + +template , class _Container = std::vector<_Kty>> +using flat_multiset = _TLX flat_set_base; + } // namespace tlx diff --git a/axmol/tlx/flat_set_base.hpp b/axmol/tlx/flat_set_base.hpp deleted file mode 100644 index b2136a5c2e03..000000000000 --- a/axmol/tlx/flat_set_base.hpp +++ /dev/null @@ -1,217 +0,0 @@ -/**************************************************************************** - Copyright (c) 2019-present Axmol Engine contributors (see AUTHORS.md). - - https://axmol.dev/ - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - THE SOFTWARE. - ****************************************************************************/ -#pragma once -#include -#include -#include -#include -#include "yasio/tlx/memory.hpp" - -namespace tlx -{ -namespace detail -{ - -template -class flat_set_base -{ -public: - using key_type = typename _Traits::key_type; - using value_type = typename _Traits::key_type; - using allocator_type = typename _Traits::allocator_type; - using container_type = typename _Traits::container_type; - -protected: - using _Alty = _TLX rebind_alloc_t; - using _Alty_traits = std::allocator_traits<_Alty>; - -public: - using key_compare = typename _Traits::key_compare; - - using size_type = typename _Alty_traits::size_type; - using difference_type = typename _Alty_traits::difference_type; - using pointer = typename _Alty_traits::pointer; - using const_pointer = typename _Alty_traits::const_pointer; - using reference = key_type&; - using const_reference = const key_type&; - using iterator = typename container_type::iterator; - using const_iterator = typename container_type::const_iterator; - - explicit flat_set_base(const key_compare& pred = key_compare(), const allocator_type& alloc = allocator_type()) - : _Mypair(_TLX __one_then_variadic_args_t{}, pred, container_type(alloc)) - {} - - void reserve(size_t capacity) { _Mypair._Myval2.reserve(capacity); } - void clear() { _Mypair._Myval2.clear(); } - - bool empty() const noexcept { return _Mypair._Myval2.empty(); } - size_t size() const noexcept { return _Mypair._Myval2.size(); } - - iterator begin() noexcept { return _Mypair._Myval2.begin(); } - iterator end() noexcept { return _Mypair._Myval2.end(); } - const_iterator begin() const noexcept { return _Mypair._Myval2.begin(); } - const_iterator end() const noexcept { return _Mypair._Myval2.end(); } - - iterator find(const key_type& key) - { - auto& cont = _Mypair._Myval2; - auto& pred = _Mypair._Get_first(); - auto it = lower_bound(key); - if (it != cont.end() && !pred(key, *it) && !pred(*it, key)) - return it; - return cont.end(); - } - - const_iterator find(const key_type& key) const - { - const auto& cont = _Mypair._Myval2; - const auto& pred = _Mypair._Get_first(); - auto it = lower_bound(key); - if (it != cont.end() && !pred(key, *it) && !pred(*it, key)) - return it; - return cont.end(); - } - - iterator lower_bound(const key_type& key) - { - auto& cont = _Mypair._Myval2; - auto& pred = _Mypair._Get_first(); - return std::lower_bound(cont.begin(), cont.end(), key, pred); - } - - const_iterator lower_bound(const key_type& key) const - { - const auto& cont = _Mypair._Myval2; - const auto& pred = _Mypair._Get_first(); - return std::lower_bound(cont.begin(), cont.end(), key, pred); - } - - iterator upper_bound(const key_type& key) - { - auto& cont = _Mypair._Myval2; - auto& pred = _Mypair._Get_first(); - return std::upper_bound(cont.begin(), cont.end(), key, pred); - } - - const_iterator upper_bound(const key_type& key) const - { - const auto& cont = _Mypair._Myval2; - const auto& pred = _Mypair._Get_first(); - return std::upper_bound(cont.begin(), cont.end(), key, pred); - } - - std::pair equal_range(const key_type& key) { return {lower_bound(key), upper_bound(key)}; } - - std::pair equal_range(const key_type& key) const - { - return {lower_bound(key), upper_bound(key)}; - } - - template - void insert(InputIt first, InputIt last) - { - auto& cont = _Mypair._Myval2; - auto& pred = _Mypair._Get_first(); - - cont.insert(cont.end(), first, last); - - std::sort(cont.begin(), cont.end(), pred); - - if constexpr (!_Traits::allow_duplicates) - { - cont.erase(std::unique(cont.begin(), cont.end(), - [&](const key_type& a, const key_type& b) { return !pred(a, b) && !pred(b, a); }), - cont.end()); - } - } - - std::pair insert(const key_type& k) { return emplace(k); } - - iterator insert(const_iterator hint, const key_type& k) { return emplace_hint(hint, k); } - - template - std::pair emplace(Args&&... args) - { - key_type k(std::forward(args)...); - auto& cont = _Mypair._Myval2; - auto& comp = _Mypair._Get_first(); - - if constexpr (_Traits::allow_duplicates) - { - auto it = upper_bound(k); - it = cont.insert(it, std::move(k)); - return {it, true}; - } - else - { - auto it = lower_bound(k); - if (it == cont.end() || comp(k, *it)) - { - it = cont.insert(it, std::move(k)); - return {it, true}; - } - return {it, false}; - } - } - - template - iterator emplace_hint(const_iterator hint, Args&&... args) - { - key_type k(std::forward(args)...); - auto& cont = _Mypair._Myval2; - auto& comp = _Mypair._Get_first(); - - if constexpr (_Traits::allow_duplicates) - { - return cont.insert(hint, std::move(k)); - } - else - { - if (hint == cont.end() || comp(k, *hint)) - { - return cont.insert(hint, std::move(k)); - } - else - { - return emplace(std::move(k)).first; - } - } - } - - size_type erase(const key_type& key) - { - auto range = equal_range(key); - size_type count = std::distance(range.first, range.second); - _Mypair._Myval2.erase(range.first, range.second); - return count; - } - - iterator erase(const_iterator it) { return _Mypair._Myval2.erase(it); } - - const auto& keys() const { return _Mypair._Myval2; } - -protected: - _TLX __compressed_pair _Mypair; -}; - -} // namespace detail -} // namespace tlx diff --git a/extensions/SDFGen/src/SDFGen/SDFGen.cpp b/extensions/SDFGen/src/SDFGen/SDFGen.cpp index 6f941a2c85ba..ca78b1a52b22 100644 --- a/extensions/SDFGen/src/SDFGen/SDFGen.cpp +++ b/extensions/SDFGen/src/SDFGen/SDFGen.cpp @@ -1,7 +1,7 @@ #include "SDFGen.h" -#include -#include +#include "axmol/tlx/singleton.hpp" +#include "axmol/tlx/byte_buffer.hpp" #include "axmol/tlx/format.hpp" #include "axmol/base/ZipUtils.h" @@ -196,11 +196,11 @@ class FontAtlas : public ax::FontAtlas SDFGen* SDFGen::getInstance() { - return yasio::singleton::instance(); + return tlx::singleton::instance(); } void SDFGen::destroyInstance() { - yasio::singleton::destroy(); + tlx::singleton::destroy(); } void SDFGen::open(ax::Scene* scene) diff --git a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp index f22e7db061f2..87db68c44268 100644 --- a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp +++ b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp @@ -12,32 +12,8 @@ #include "axmol/tlx/flat_set.hpp" #include "axmol/tlx/flat_map.hpp" -namespace tlx -{ -// flat_set traits -template , class Alloc = std::allocator> -struct flat_set_traits1 -{ - using key_type = Key; - using value_type = Key; - using key_compare = Compare; - using value_compare = Compare; - using allocator_type = Alloc; - using container_type = tlx::vector; - - static constexpr bool allow_duplicates = false; -}; - -/// flat_set -template , class Alloc = std::allocator> -class flat_set1 : public detail::flat_set_base> -{ - using impl_type = detail::flat_set_base>; - -public: - using impl_type::impl_type; -}; -} // namespace tlx +template +using my_flat_set = _TLX flat_set<_Tp, std::less<_Tp>, tlx::vector<_Tp>>; template static constexpr bool vector_equals(const _Cont1& c1, const _Cont2& c2) @@ -151,7 +127,7 @@ static void run_benchmark() auto s3 = benchmark_set>("tlx::hash_set", keys); //auto s4 = benchmark_set>("std::flat_set", keys); auto s5 = benchmark_set>("tlx::flat_set", keys); - auto s6 = benchmark_set>("tlx::flat_set1", keys); + auto s6 = benchmark_set>("my_flat_set", keys); auto m1 = benchmark_map>("std::map", keys); auto m2 = benchmark_map>("std::unordered_map", keys); @@ -174,6 +150,58 @@ TEST_SUITE("tlx/Containers") // crash on Linux(maybe others), crt not initalized properly yet. #define fu FileUtils::getInstance() + TEST_CASE("FlatSetTest") + { + tlx::flat_set set1; + set1.emplace(25); + set1.emplace(10); + set1.emplace(34); + set1.emplace(65); + set1.emplace(35); + set1.emplace(10); + + CHECK(set1.size() == 5); + set1.erase(10); + CHECK(set1.size() == 4); + + tlx::flat_multiset set2; + set2.emplace(25); + set2.emplace(10); + set2.emplace(34); + set2.emplace(65); + set2.emplace(35); + set2.emplace(10); + CHECK(set2.size() == 6); + set2.erase(10); + CHECK(set2.size() == 4); + } + + TEST_CASE("FlatMapTest") + { + tlx::flat_map map1; + map1.emplace(25, 66); + map1.emplace(10, 75); + map1.emplace(34, 32); + map1.emplace(65, 31); + map1.emplace(35, 39); + map1.emplace(10, 34); + + CHECK(map1.size() == 5); + map1.erase(10); + CHECK(map1.size() == 4); + + tlx::flat_multimap map2; + map2.emplace(25, 66); + map2.emplace(10, 75); + map2.emplace(34, 32); + map2.emplace(65, 31); + map2.emplace(35, 39); + map2.emplace(10, 34); + CHECK(map2.size() == 6); + map2.erase(10); + CHECK(map2.size() == 4); + } + TEST_CASE("BenchmarkTest") { run_benchmark(); From 85d46757c537ef937e4c05e75a824a7438a494a4 Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 1 Dec 2025 00:24:18 +0800 Subject: [PATCH 04/17] Fixup --- 3rdparty/yasio/yasio/wtimer_hres.hpp | 2 +- .../Source/axmol/tlx/ContainerTests.cpp | 19 +++++++++++++------ 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/3rdparty/yasio/yasio/wtimer_hres.hpp b/3rdparty/yasio/yasio/wtimer_hres.hpp index 8f44141956b8..f7c6961d2404 100644 --- a/3rdparty/yasio/yasio/wtimer_hres.hpp +++ b/3rdparty/yasio/yasio/wtimer_hres.hpp @@ -77,7 +77,7 @@ struct wtimer_hres { ULONG MinimumResolution, MaximumResolution, CurrentResolution; if (NtQueryTimerResolution(&MinimumResolution, &MaximumResolution, &CurrentResolution) != 0) break; - ZwSetTimerResolution(yasio::clamp(timer_res, MaximumResolution, MinimumResolution), TRUE, &timer_res); + ZwSetTimerResolution(std::clamp(timer_res, MaximumResolution, MinimumResolution), TRUE, &timer_res); } while (false); # endif } diff --git a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp index 87db68c44268..d34e78bf4483 100644 --- a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp +++ b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp @@ -2,8 +2,13 @@ #include "TestUtils.h" #include -// #include -// #include +#if __has_include() +# include +# include +# define _AX_STL_HAS_FLAT_CONTAINER 1 +#else +# define _AX_STL_HAS_FLAT_CONTAINER 0 +#endif #include #include @@ -12,7 +17,7 @@ #include "axmol/tlx/flat_set.hpp" #include "axmol/tlx/flat_map.hpp" -template +template using my_flat_set = _TLX flat_set<_Tp, std::less<_Tp>, tlx::vector<_Tp>>; template @@ -122,17 +127,20 @@ static void run_benchmark() keys[i] = dist(rng); } +#if _AX_STL_HAS_FLAT_CONTAINER + auto s4 = benchmark_set>("std::flat_set", keys); + auto m4 = benchmark_map>("std::flat_map", keys); +#endif auto s1 = benchmark_set>("std::set", keys); auto s2 = benchmark_set>("std::unordered_set", keys); auto s3 = benchmark_set>("tlx::hash_set", keys); - //auto s4 = benchmark_set>("std::flat_set", keys); + auto s5 = benchmark_set>("tlx::flat_set", keys); auto s6 = benchmark_set>("my_flat_set", keys); auto m1 = benchmark_map>("std::map", keys); auto m2 = benchmark_map>("std::unordered_map", keys); auto m3 = benchmark_map>("tlx::hash_map", keys); - //auto m4 = benchmark_map>("std::flat_map", keys); auto m5 = benchmark_map>("tlx::flat_map", keys); std::sort(keys.begin(), keys.end()); @@ -140,7 +148,6 @@ static void run_benchmark() CHECK(vector_equals(keys, s5.keys())); CHECK(vector_equals(keys, s6.keys())); - // CHECK(keys == m5.keys()); } TEST_SUITE("tlx/Containers") From adb94b00ab5667a5a562fe1f6389fe753a7b601e Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 1 Dec 2025 00:40:18 +0800 Subject: [PATCH 05/17] Fixup --- 3rdparty/yasio/yasio/io_service.cpp | 2 ++ 3rdparty/yasio/yasio/tlx/string.hpp | 12 ++++++------ 3rdparty/yasio/yasio/tlx/type_traits.hpp | 3 +++ 3rdparty/yasio/yasio/tlx/vector.hpp | 10 ++++++---- axmol/media/AvfMediaEngine.mm | 2 +- axmol/media/MfMediaEngine.cpp | 2 +- axmol/network/HttpClient-wasm.cpp | 2 +- axmol/platform/android/Device-android.cpp | 2 +- axmol/platform/android/FileUtils-android.cpp | 2 +- axmol/platform/wasm/FileUtils-wasm.cpp | 2 +- axmol/rhi/opengl/ProgramGL.cpp | 2 +- axmol/ui/UIEditBox/UIEditBoxImpl-android.cpp | 2 +- axmol/ui/UIWebView/UIWebViewImpl-android.cpp | 2 +- tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp | 8 ++++++++ 14 files changed, 34 insertions(+), 19 deletions(-) diff --git a/3rdparty/yasio/yasio/io_service.cpp b/3rdparty/yasio/yasio/io_service.cpp index 25aa99416c59..2feaa20b91d5 100644 --- a/3rdparty/yasio/yasio/io_service.cpp +++ b/3rdparty/yasio/yasio/io_service.cpp @@ -46,6 +46,8 @@ SOFTWARE. #include "yasio/wtimer_hres.hpp" +#include "yasio/tlx/string.hpp" + #if defined(YASIO_ENABLE_KCP) struct yasio_kcp_options { int kcp_conv_ = 0; diff --git a/3rdparty/yasio/yasio/tlx/string.hpp b/3rdparty/yasio/yasio/tlx/string.hpp index e0cedd6e9b11..2e596dead8e7 100644 --- a/3rdparty/yasio/yasio/tlx/string.hpp +++ b/3rdparty/yasio/yasio/tlx/string.hpp @@ -80,11 +80,11 @@ class basic_string { }; __compressed_pair _Mypair; - basic_string() : _Mypair(__one_then_variadic_args_t{}, _Alloc{}) {} + basic_string() : _Mypair(__zero_then_variadic_args_t{}) {} basic_string(nullptr_t) = delete; explicit basic_string(size_type count) : _Mypair(__one_then_variadic_args_t{}, _Alloc{}) { resize(static_cast(count)); } basic_string(size_type count, const_reference val) : _Mypair(__one_then_variadic_args_t{}, _Alloc{}) { resize(static_cast(count), val); } - template ::value, int> = 0> + template ::value, int> = 0> basic_string(_Iter first, _Iter last) : _Mypair(__one_then_variadic_args_t{}, _Alloc{}) { assign(first, last); @@ -122,7 +122,7 @@ class basic_string { return *this; } - template ::value, int> = 0> + template ::value, int> = 0> void assign(_Iter first, _Iter last) { _Assign_range(first, last); @@ -144,7 +144,7 @@ class basic_string { std::swap(a._Myend, b._Myend); } - template ::value, int> = 0> + template ::value, int> = 0> iterator insert(iterator _Where, _Iter first, _Iter last) { auto& st = _Mypair._Myval2; @@ -205,7 +205,7 @@ class basic_string { } basic_string& append(view_type value) { return this->append(value.begin(), value.end()); } - template ::value, int> = 0> + template ::value, int> = 0> basic_string& append(_Iter first, const _Iter last) { if (first != last) @@ -584,7 +584,7 @@ class basic_string { return st._Mylast; // points to null terminator slot } - template ::value, int> = 0> + template ::value, int> = 0> void _Assign_range(_Iter first, _Iter last) { auto& st = _Mypair._Myval2; diff --git a/3rdparty/yasio/yasio/tlx/type_traits.hpp b/3rdparty/yasio/yasio/tlx/type_traits.hpp index 6eabd241125a..3c87bba0107b 100644 --- a/3rdparty/yasio/yasio/tlx/type_traits.hpp +++ b/3rdparty/yasio/yasio/tlx/type_traits.hpp @@ -45,6 +45,9 @@ struct is_aligned_storage { template struct is_iterator : public std::integral_constant::value> {}; +template +inline constexpr bool is_iterator_v = is_iterator<_Iter>::value; + template using enable_if_t = typename ::std::enable_if<_Test, _Ty>::type; diff --git a/3rdparty/yasio/yasio/tlx/vector.hpp b/3rdparty/yasio/yasio/tlx/vector.hpp index 4f5ef0df83e5..55fa0b4bcebe 100644 --- a/3rdparty/yasio/yasio/tlx/vector.hpp +++ b/3rdparty/yasio/yasio/tlx/vector.hpp @@ -363,7 +363,9 @@ class vector { // varying size array of values using iterator = sequence_iterator<_Scary_val>; using const_iterator = sequence_const_iterator<_Scary_val>; - constexpr explicit vector(const _Alloc& _Al = _Alloc{}) noexcept : _Mypair(_TLX __one_then_variadic_args_t{}, _Al) {} + constexpr vector() noexcept : _Mypair(_TLX __zero_then_variadic_args_t{}) {} + + constexpr explicit vector(const _Alloc& _Al) noexcept : _Mypair(_TLX __one_then_variadic_args_t{}, _Al) {} constexpr explicit vector(const size_type _Count, const _Alloc& _Al = _Alloc()) : _Mypair(_TLX __one_then_variadic_args_t{}, _Al) { _Construct_n(_Count); } @@ -409,8 +411,8 @@ class vector { // varying size array of values std::exchange(_Right._Mypair._Myval2._Mylast, nullptr), std::exchange(_Right._Mypair._Myval2._Myend, nullptr)) {} - constexpr vector(vector&& _Right, - const _TLX identity_t<_Alloc>& _Al_) noexcept(std::allocator_traits<_Alloc>::is_always_equal::value && std::is_nothrow_move_constructible_v<_Ty>) + constexpr vector(vector&& _Right, const _TLX identity_t<_Alloc>& _Al_) noexcept(std::allocator_traits<_Alloc>::is_always_equal::value && + std::is_nothrow_move_constructible_v<_Ty>) : _Mypair(_TLX __one_then_variadic_args_t{}, _Al_) { _Alty& _Al = _Getal(); @@ -864,7 +866,7 @@ class vector { // varying size array of values } public: - template , int> = 0> + template , int> = 0> constexpr iterator insert(const_iterator _Where, _Iter _First, _Iter _Last) { auto _Whereptr = _Where._Ptr; diff --git a/axmol/media/AvfMediaEngine.mm b/axmol/media/AvfMediaEngine.mm index 76c8c7dc1323..c18c17b32102 100644 --- a/axmol/media/AvfMediaEngine.mm +++ b/axmol/media/AvfMediaEngine.mm @@ -29,7 +29,7 @@ of this software and associated documentation files (the "Software"), to deal # include # include -# include "yasio/string_view.hpp" +# include "yasio/tlx/string_view.hpp" # include "yasio/endian_portable.hpp" # if TARGET_OS_IPHONE diff --git a/axmol/media/MfMediaEngine.cpp b/axmol/media/MfMediaEngine.cpp index 18374a26b6c4..2c71075da3f1 100644 --- a/axmol/media/MfMediaEngine.cpp +++ b/axmol/media/MfMediaEngine.cpp @@ -14,7 +14,7 @@ # include "ntcvt/ntcvt.hpp" # include "axmol/media/MFUtils.h" -# include "yasio/string_view.hpp" +# include "yasio/tlx/string_view.hpp" # include "axmol/tlx/format.hpp" diff --git a/axmol/network/HttpClient-wasm.cpp b/axmol/network/HttpClient-wasm.cpp index 3a3e3557e023..f9878a4c4210 100644 --- a/axmol/network/HttpClient-wasm.cpp +++ b/axmol/network/HttpClient-wasm.cpp @@ -30,7 +30,7 @@ #include #include "axmol/base/Director.h" #include "axmol/platform/FileUtils.h" -#include "yasio/string_view.hpp" +#include "yasio/tlx/string_view.hpp" #if EMSCRIPTEN # include diff --git a/axmol/platform/android/Device-android.cpp b/axmol/platform/android/Device-android.cpp index 876b0d32fc69..b2c9a9415416 100644 --- a/axmol/platform/android/Device-android.cpp +++ b/axmol/platform/android/Device-android.cpp @@ -31,7 +31,7 @@ THE SOFTWARE. #include "axmol/base/Types.h" #include "axmol/platform/android/jni/JniHelper.h" #include "axmol/platform/FileUtils.h" -#include "yasio/string_view.hpp" +#include "yasio/tlx/string_view.hpp" static const char* deviceHelperClassName = "dev.axmol.lib.AxmolEngine"; diff --git a/axmol/platform/android/FileUtils-android.cpp b/axmol/platform/android/FileUtils-android.cpp index ccef3080be30..b3b02fb32250 100644 --- a/axmol/platform/android/FileUtils-android.cpp +++ b/axmol/platform/android/FileUtils-android.cpp @@ -34,7 +34,7 @@ THE SOFTWARE. #include #include -#include "yasio/string_view.hpp" +#include "yasio/tlx/string_view.hpp" #define LOG_TAG "FileUtils-android.cpp" #define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__) diff --git a/axmol/platform/wasm/FileUtils-wasm.cpp b/axmol/platform/wasm/FileUtils-wasm.cpp index b70ec2b42669..cd1da29f0b7d 100644 --- a/axmol/platform/wasm/FileUtils-wasm.cpp +++ b/axmol/platform/wasm/FileUtils-wasm.cpp @@ -35,7 +35,7 @@ THE SOFTWARE. # include "axmol/base/text_utils.h" # include -# include "yasio/string_view.hpp" +# include "yasio/tlx/string_view.hpp" using namespace std; diff --git a/axmol/rhi/opengl/ProgramGL.cpp b/axmol/rhi/opengl/ProgramGL.cpp index 006823df0b43..dcf02034fae4 100644 --- a/axmol/rhi/opengl/ProgramGL.cpp +++ b/axmol/rhi/opengl/ProgramGL.cpp @@ -229,7 +229,7 @@ void ProgramImpl::reflectUniformInfos() _maxLocation = -1; _activeUniformInfos.clear(); - yasio::basic_byte_buffer buffer; // buffer for name + tlx::basic_byte_buffer buffer; // buffer for name // OpenGL UBO: uloc[0]: block_offset, uloc[1]: offset in block diff --git a/axmol/ui/UIEditBox/UIEditBoxImpl-android.cpp b/axmol/ui/UIEditBox/UIEditBoxImpl-android.cpp index 8c2d124ed784..9b9f9171d66d 100644 --- a/axmol/ui/UIEditBox/UIEditBoxImpl-android.cpp +++ b/axmol/ui/UIEditBox/UIEditBoxImpl-android.cpp @@ -39,7 +39,7 @@ # include "axmol/ui/UIHelper.h" # include "axmol/base/Director.h" # include "axmol/platform/FileUtils.h" -# include "yasio/string_view.hpp" +# include "yasio/tlx/string_view.hpp" namespace ax { diff --git a/axmol/ui/UIWebView/UIWebViewImpl-android.cpp b/axmol/ui/UIWebView/UIWebViewImpl-android.cpp index 6131fabbec87..c278c0f3a5fe 100644 --- a/axmol/ui/UIWebView/UIWebViewImpl-android.cpp +++ b/axmol/ui/UIWebView/UIWebViewImpl-android.cpp @@ -35,7 +35,7 @@ #include "axmol/base/Director.h" #include "axmol/platform/FileUtils.h" #include "axmol/ui/UIHelper.h" -#include "yasio/string_view.hpp" +#include "yasio/tlx/string_view.hpp" static const char* className = "dev.axmol.lib.WebViewHelper"; diff --git a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp index d34e78bf4483..03d85299d303 100644 --- a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp +++ b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp @@ -157,6 +157,14 @@ TEST_SUITE("tlx/Containers") // crash on Linux(maybe others), crt not initalized properly yet. #define fu FileUtils::getInstance() + TEST_CASE("VectorTest") + { + tlx::vector buffer; + std::string messge = "aaaaaaaaaaaaaafbbbbbbbbbbbbbbbbbcccccccccdfefffffff"; + buffer.insert(buffer.end(), messge.begin(), messge.end()); + CHECK(buffer.size() == messge.size()); + } + TEST_CASE("FlatSetTest") { tlx::flat_set set1; From 1be4ce760fe290fc2dc8dbcc7c753bafe72ee0cc Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 1 Dec 2025 11:41:30 +0800 Subject: [PATCH 06/17] Fixup and preserve tlx::pod_vector semantic --- 3rdparty/yasio/yasio/tlx/array_buffer.hpp | 10 +- 3rdparty/yasio/yasio/tlx/memory.hpp | 108 +++++++++--------- 3rdparty/yasio/yasio/tlx/vector.hpp | 60 ++++++---- axmol/base/Data.cpp | 1 - axmol/base/ZipUtils.cpp | 1 + axmol/network/HttpCookie.cpp | 1 + axmol/platform/wasm/Application-wasm.cpp | 1 - axmol/tlx/vector.hpp | 17 ++- .../src/Particle3D/PU/PUMaterialManager.cpp | 6 +- extensions/SDFGen/src/SDFGen/SDFGen.cpp | 5 +- tests/fairygui-tests/Source/AppDelegate.h | 2 +- .../Source/axmol/tlx/ContainerTests.cpp | 87 +++++++++++--- 12 files changed, 201 insertions(+), 98 deletions(-) diff --git a/3rdparty/yasio/yasio/tlx/array_buffer.hpp b/3rdparty/yasio/yasio/tlx/array_buffer.hpp index 4c78d9e142ed..ad54d2bca354 100644 --- a/3rdparty/yasio/yasio/tlx/array_buffer.hpp +++ b/3rdparty/yasio/yasio/tlx/array_buffer.hpp @@ -7,6 +7,14 @@ namespace tlx { // alias: array_buffer +// Usage restriction: only valid for types that meet ALL of the following: +// 1. Trivially default constructible +// 2. Trivially destructible +// 3. Trivially copyable +// +// In other words, this alias is intended only for POD or standard-layout types, +// ensuring that zero-initialization and raw memory operations (e.g. memcpy, memset) +// are safe and well-defined. template > -using array_buffer = typename std::enable_if::value, ::tlx::vector<_Ty, _Alloc>>::type; +using array_buffer = typename std::enable_if::value, ::tlx::vector<_Ty, _Alloc, fill_policy::no_fill_trivial>>::type; } // namespace tlx diff --git a/3rdparty/yasio/yasio/tlx/memory.hpp b/3rdparty/yasio/yasio/tlx/memory.hpp index e223f6f8ffc6..1ba814f5c7f8 100644 --- a/3rdparty/yasio/yasio/tlx/memory.hpp +++ b/3rdparty/yasio/yasio/tlx/memory.hpp @@ -138,14 +138,14 @@ struct _Identity { template using identity_t = typename _Identity<_Ty>::type; -template +template class __uninitialized_backout_al { public: - using allocator_traits = typename std::allocator_traits; - using pointer = typename allocator_traits::pointer; - using value_type = typename allocator_traits::value_type; + using allocator_traits = typename std::allocator_traits<_Alloc>; + using pointer = typename allocator_traits::pointer; + using value_type = typename allocator_traits::value_type; - __uninitialized_backout_al(pointer dest, Alloc& al) : _dest(dest), _cur(dest), _alloc(al), _released(false) {} + __uninitialized_backout_al(pointer dest, _Alloc& al) : _dest(dest), _cur(dest), _alloc(al), _released(false) {} ~__uninitialized_backout_al() { @@ -153,7 +153,7 @@ class __uninitialized_backout_al { { for (auto p = _dest; p != _cur; ++p) { - std::allocator_traits::destroy(_alloc, p); + std::allocator_traits<_Alloc>::destroy(_alloc, p); } } } @@ -161,7 +161,7 @@ class __uninitialized_backout_al { template void _Emplace_back(Args&&... args) { - std::allocator_traits::construct(_alloc, _cur, std::forward(args)...); + std::allocator_traits<_Alloc>::construct(_alloc, _cur, std::forward(args)...); ++_cur; } @@ -174,7 +174,7 @@ class __uninitialized_backout_al { private: pointer _dest; pointer _cur; - Alloc& _alloc; + _Alloc& _alloc; bool _released; }; @@ -182,8 +182,8 @@ struct __value_init_tag { // tag to request value-initialization explicit __value_init_tag() = default; }; -template -using iter_ref_t = typename std::iterator_traits::reference; +template +using iter_ref_t = typename std::iterator_traits<_Iter>::reference; inline void __xlength_error(const char* what) { throw ::std::length_error(what); } @@ -191,17 +191,17 @@ inline void __xout_of_range(const char* what) { throw ::std::out_of_range(what); static_assert(std::is_same_v::value_type, int>); -template -inline constexpr bool is_pod_iterator_v = std::is_trivially_copyable_v::value_type>; +template +inline constexpr bool is_pod_iterator_v = std::is_trivially_copyable_v::value_type>; -template -inline constexpr bool bitcopy_assignable_v = std::is_trivially_copyable_v::value_type> && - std::is_same_v::value_type, typename std::pointer_traits::element_type>; +template +inline constexpr bool bitcopy_assignable_v = std::is_trivially_copyable_v::value_type> && + std::is_same_v::value_type, typename std::pointer_traits<_Ptr>::element_type>; -template -typename Alloc::pointer uninitialized_fill_n(typename Alloc::pointer first, size_t count, const typename Alloc::value_type& val, Alloc& alloc) +template +_Ptr uninitialized_fill_n(_Ptr first, size_t count, const typename _Alloc::value_type& val, _Alloc& alloc) { - using T = typename Alloc::value_type; + using T = typename _Alloc::value_type; if constexpr (std::is_trivially_copyable_v) { @@ -215,16 +215,16 @@ typename Alloc::pointer uninitialized_fill_n(typename Alloc::pointer first, size { for (size_t i = 0; i < count; ++i) { - std::allocator_traits::construct(alloc, first + i, val); + std::allocator_traits<_Alloc>::construct(alloc, first + i, val); } return first + count; } } -template -constexpr OutPtr uninitialized_move(InIt first, InIt last, OutPtr dest, Alloc& alloc) +template +constexpr _OutPtr uninitialized_move(_InIt first, _InIt last, _OutPtr dest, _Alloc& alloc) { - using T = typename Alloc::value_type; + using T = typename _Alloc::value_type; const auto count = static_cast(last - first); if constexpr (std::is_trivially_copyable_v) @@ -236,7 +236,7 @@ constexpr OutPtr uninitialized_move(InIt first, InIt last, OutPtr dest, Alloc& a } } - __uninitialized_backout_al backout{dest, alloc}; + __uninitialized_backout_al<_Alloc> backout{dest, alloc}; for (; first != last; ++first) { backout._Emplace_back(std::move(*first)); @@ -244,10 +244,10 @@ constexpr OutPtr uninitialized_move(InIt first, InIt last, OutPtr dest, Alloc& a return backout._Release(); } -template -constexpr OutPtr uninitialized_copy_n(InIt first, size_t count, OutPtr dest, Alloc& alloc) +template +constexpr _OutPtr uninitialized_copy_n(_InIt first, size_t count, _OutPtr dest, _Alloc& alloc) { - using T = typename Alloc::value_type; + using T = typename _Alloc::value_type; if constexpr (std::is_trivially_copyable_v) { @@ -256,7 +256,7 @@ constexpr OutPtr uninitialized_copy_n(InIt first, size_t count, OutPtr dest, All } else { - __uninitialized_backout_al backout{dest, alloc}; + __uninitialized_backout_al<_Alloc> backout{dest, alloc}; for (; count != 0; ++first, --count) { backout._Emplace_back(*first); @@ -265,10 +265,10 @@ constexpr OutPtr uninitialized_copy_n(InIt first, size_t count, OutPtr dest, All } } -template -typename Alloc::pointer uninitialized_copy(InIt first, InIt last, typename Alloc::pointer dest, Alloc& alloc) +template +_Ptr uninitialized_copy(_InIt first, _InIt last, _Ptr dest, _Alloc& alloc) { - using T = typename Alloc::value_type; + using T = typename _Alloc::value_type; const auto count = static_cast(last - first); @@ -279,7 +279,7 @@ typename Alloc::pointer uninitialized_copy(InIt first, InIt last, typename Alloc } else { - __uninitialized_backout_al backout{dest, alloc}; + __uninitialized_backout_al<_Alloc> backout{dest, alloc}; for (; first != last; ++first) { backout._Emplace_back(*first); @@ -288,33 +288,37 @@ typename Alloc::pointer uninitialized_copy(InIt first, InIt last, typename Alloc } } -template -constexpr void destroy_range(Ptr first, Ptr last, Alloc& alloc) noexcept +template +constexpr void destroy_range(Ptr first, Ptr last, _Alloc& alloc) noexcept { - using T = typename Alloc::value_type; + using T = typename _Alloc::value_type; if constexpr (!std::is_trivially_destructible_v) { for (; first != last; ++first) { - std::allocator_traits::destroy(alloc, std::to_address(first)); + std::allocator_traits<_Alloc>::destroy(alloc, std::to_address(first)); } } } -template -typename Alloc::pointer uninitialized_value_construct_n(typename Alloc::pointer first, size_t count, Alloc& alloc) +/* + * trivially_constructible types: Use memset to zero for + * non-trivially_constructible types: default constructor + */ +template +_Ptr uninitialized_value_construct_n(_Ptr first, size_t count, _Alloc& alloc) { - using T = typename Alloc::value_type; + using T = typename _Alloc::value_type; - if constexpr (std::is_trivially_constructible_v && std::is_trivially_destructible_v) + if constexpr (std::is_trivially_constructible_v) { ::memset(first, 0, count * sizeof(T)); return first + count; } else { - __uninitialized_backout_al backout{first, alloc}; + __uninitialized_backout_al<_Alloc> backout{first, alloc}; for (; count > 0; --count) { backout._Emplace_back(); @@ -323,7 +327,7 @@ typename Alloc::pointer uninitialized_value_construct_n(typename Alloc::pointer } } -template +template OutCtgIt copy_memmove_n(InCtgIt first, size_t count, OutCtgIt dest) { using T = typename std::iterator_traits::value_type; @@ -345,10 +349,10 @@ OutCtgIt copy_memmove_n(InCtgIt first, size_t count, OutCtgIt dest) } } -template -constexpr OutIt move_unchecked(InIt first, InIt last, OutIt dest) +template +constexpr _OutIt move_unchecked(_InIt first, _InIt last, _OutIt dest) { - using T = typename std::iterator_traits::value_type; + using T = typename std::iterator_traits<_InIt>::value_type; const auto count = static_cast(last - first); if constexpr (std::is_trivially_copyable_v) @@ -366,7 +370,7 @@ constexpr OutIt move_unchecked(InIt first, InIt last, OutIt dest) } } -template +template _CtgIt2 copy_backward_memmove(_CtgIt1 _First, _CtgIt1 _Last, _CtgIt2 _Dest) { // implement copy_backward-like function as memmove @@ -392,13 +396,13 @@ _CtgIt2 copy_backward_memmove(_CtgIt1 _First, _CtgIt1 _Last, _CtgIt2 _Dest) } } -template +template _BidIt2 copy_backward_memmove(std::move_iterator<_BidIt1> _First, std::move_iterator<_BidIt1> _Last, _BidIt2 _Dest) { return copy_backward_memmove(_First.base(), _Last.base(), _Dest); } -template +template _BidIt2 move_backward_unchecked(_BidIt1 _First, _BidIt1 _Last, _BidIt2 _Dest) { // move [_First, _Last) backwards to [..., _Dest) @@ -419,12 +423,12 @@ _BidIt2 move_backward_unchecked(_BidIt1 _First, _BidIt1 _Last, _BidIt2 _Dest) return _Dest; } -template -constexpr OutIt copy_n_unchecked4(InIt first, SizeTy count, OutIt dest) +template +constexpr _OutIt copy_n_unchecked4(_InIt first, _SizeTy count, _OutIt dest) { - using T = typename std::iterator_traits::value_type; + using T = typename std::iterator_traits<_InIt>::value_type; - static_assert(std::is_integral_v, "SizeTy must be integer-like"); + static_assert(std::is_integral_v<_SizeTy>, "must be integer-like"); if (count < 0) return dest; @@ -444,7 +448,7 @@ constexpr OutIt copy_n_unchecked4(InIt first, SizeTy count, OutIt dest) return dest; } -} // namespace yasio +} // namespace tlx #define _TLX_VERIFY_RANGE(cond, mesg) \ do \ diff --git a/3rdparty/yasio/yasio/tlx/vector.hpp b/3rdparty/yasio/yasio/tlx/vector.hpp index 55fa0b4bcebe..152e5d125117 100644 --- a/3rdparty/yasio/yasio/tlx/vector.hpp +++ b/3rdparty/yasio/yasio/tlx/vector.hpp @@ -272,7 +272,33 @@ struct _Vector_val { pointer _Myend; }; -template > +struct fill_policy { + enum enum_type + { + fill_always, + no_fill_trivial_ctor, + no_fill_trivial_dtor, + no_fill_trivial, + }; + + template + static constexpr bool is_no_auto_fill(fill_policy::enum_type policy) noexcept + { + switch (policy) + { + case fill_policy::no_fill_trivial_ctor: + return std::is_trivially_default_constructible_v<_Ty>; + case fill_policy::no_fill_trivial_dtor: + return std::is_trivially_destructible_v<_Ty>; + case fill_policy::no_fill_trivial: + return std::is_trivially_default_constructible_v<_Ty> && std::is_trivially_destructible_v<_Ty>; + default: // fill_always + return false; + } + } +}; + +template , fill_policy::enum_type _FillPolicy = fill_policy::fill_always> class vector { // varying size array of values private: template @@ -283,7 +309,7 @@ class vector { // varying size array of values using _Alty_traits = std::allocator_traits<_Alty>; public: - // static constexpr bool is_trivial = std::is_trivially_constructible_v<_Ty>::value || is_trivially_destructible_v<_Ty>; + static constexpr bool no_auto_fill = fill_policy::is_no_auto_fill<_Ty>(_FillPolicy); static_assert(std::is_object_v<_Ty>, "The C++ Standard forbids containers of non-object types " "because of [container.requirements]."); @@ -353,7 +379,7 @@ class vector { // varying size array of values { auto& _Al = _Target->_Getal(); auto& _Mylast = _Target->_Mypair._Myval2._Mylast; - destroy_range(_Destroyed_first, _Mylast, _Al); + _TLX destroy_range(_Destroyed_first, _Mylast, _Al); _Mylast = _Vaporized_first; } } @@ -616,17 +642,13 @@ class vector { // varying size array of values void attach_abi(pointer ptr, size_type len, size_type capacity = (size_type)-1) { + _Tidy(); auto& _My_data = _Mypair._Myval2; _My_data._Myfirst = ptr; _My_data._Mylast = ptr + len; _My_data._Myend = ptr + (capacity != (size_type)-1 ? capacity : len); } - void shrink_to_empty() - { - clear(); - shrink_to_fit(); - } #pragma endregion public: @@ -1076,7 +1098,7 @@ class vector { // varying size array of values { _Appended_last = _TLX uninitialized_fill_n(_Appended_first, _Newsize - _Oldsize, _Val, _Al); } - else + else if constexpr (!no_auto_fill) { _Appended_last = _TLX uninitialized_value_construct_n(_Appended_first, _Newsize - _Oldsize, _Al); } @@ -1106,7 +1128,7 @@ class vector { // varying size array of values if (_Newsize < _Oldsize) { // trim const pointer _Newlast = _Myfirst + _Newsize; - destroy_range(_Newlast, _Mylast, _Al); + _TLX destroy_range(_Newlast, _Mylast, _Al); _Mylast = _Newlast; return; } @@ -1122,13 +1144,9 @@ class vector { // varying size array of values const pointer _Oldlast = _Mylast; if constexpr (std::is_same_v<_Ty2, _Ty>) - { _Mylast = _TLX uninitialized_fill_n(_Oldlast, _Newsize - _Oldsize, _Val, _Al); - } - else - { + else if constexpr (!no_auto_fill) _Mylast = _TLX uninitialized_value_construct_n(_Oldlast, _Newsize - _Oldsize, _Al); - } } // if _Newsize == _Oldsize, do nothing; avoid invalidating iterators @@ -1283,7 +1301,7 @@ class vector { // varying size array of values if (_Firstptr != _Lastptr) { // something to do, invalidate iterators const pointer _Newlast = move_unchecked(_Lastptr, _Mylast, _Firstptr); - destroy_range(_Newlast, _Mylast, _Getal()); + _TLX destroy_range(_Newlast, _Mylast, _Getal()); _Mylast = _Newlast; } @@ -1304,7 +1322,7 @@ class vector { // varying size array of values return; } - destroy_range(_Myfirst, _Mylast, _Getal()); + _TLX destroy_range(_Myfirst, _Mylast, _Getal()); _Mylast = _Myfirst; } @@ -1633,13 +1651,13 @@ class vector { // varying size array of values }; #pragma region c++20 like std::erase -template -void erase(vector<_Ty, _Alloc>& cont, const _Ty& val) +template +void erase(vector<_Ty, _Alloc, _Policy>& cont, const _Ty& val) { cont.erase(std::remove(cont.begin(), cont.end(), val), cont.end()); } -template -void erase_if(vector<_Ty, _Alloc>& cont, _Pr pred) +template +void erase_if(vector<_Ty, _Alloc, _Policy>& cont, _Pr pred) { cont.erase(std::remove_if(cont.begin(), cont.end(), pred), cont.end()); } diff --git a/axmol/base/Data.cpp b/axmol/base/Data.cpp index 674ad314efc6..8654b60b68ed 100644 --- a/axmol/base/Data.cpp +++ b/axmol/base/Data.cpp @@ -108,7 +108,6 @@ void Data::fastSet(uint8_t* bytes, const ssize_t size) { AXASSERT(size >= 0, "fastSet size should be non-negative"); // AXASSERT(bytes, "bytes should not be nullptr"); - _impl.shrink_to_empty(); _impl.attach_abi(bytes, size); } diff --git a/axmol/base/ZipUtils.cpp b/axmol/base/ZipUtils.cpp index 52ec0bc01b4d..f094296acdc3 100644 --- a/axmol/base/ZipUtils.cpp +++ b/axmol/base/ZipUtils.cpp @@ -45,6 +45,7 @@ #include "axmol/base/Data.h" #include "axmol/base/Macros.h" #include "axmol/platform/FileUtils.h" +#include "yasio/tlx/string_view.hpp" #include #include diff --git a/axmol/network/HttpCookie.cpp b/axmol/network/HttpCookie.cpp index dda48cf0b30a..266430c54b40 100644 --- a/axmol/network/HttpCookie.cpp +++ b/axmol/network/HttpCookie.cpp @@ -35,6 +35,7 @@ #include #include +#include "yasio/tlx/string_view.hpp" #include "axmol/tlx/utility.hpp" #include "fmt/compile.h" diff --git a/axmol/platform/wasm/Application-wasm.cpp b/axmol/platform/wasm/Application-wasm.cpp index cb4d231fddb8..c483584c5207 100644 --- a/axmol/platform/wasm/Application-wasm.cpp +++ b/axmol/platform/wasm/Application-wasm.cpp @@ -37,7 +37,6 @@ THE SOFTWARE. # include "axmol/base/Utils.h" # include "axmol/platform/FileUtils.h" # include "axmol/platform/Device.h" -# include "yasio/utils.hpp" # include extern void axmol_wasm_app_exit(); diff --git a/axmol/tlx/vector.hpp b/axmol/tlx/vector.hpp index dc93fb46c861..09a4a8580150 100644 --- a/axmol/tlx/vector.hpp +++ b/axmol/tlx/vector.hpp @@ -23,10 +23,21 @@ ****************************************************************************/ #pragma once -#include "yasio/tlx/array_buffer.hpp" +#include "yasio/tlx/vector.hpp" +#include "yasio/tlx/buffer_alloc.hpp" namespace tlx { -template > -using pod_vector = _TLX array_buffer<_Ty, _Alloc>; +// alias: pod_vector +// Usage restriction: only valid for types that are BOTH: +// 1. Trivially destructible +// 2. Trivially copyable +// +// This ensures that raw memory operations (e.g. memcpy, memset) and +// skipping value-initialization are safe. In practice, this alias +// should be used only with POD or standard-layout types. +template > +using pod_vector = typename std::enable_if::value, + ::tlx::vector<_Ty, _Alloc, fill_policy::no_fill_trivial_dtor>>::type; + } // namespace tlx diff --git a/extensions/Particle3D/src/Particle3D/PU/PUMaterialManager.cpp b/extensions/Particle3D/src/Particle3D/PU/PUMaterialManager.cpp index 02bd1b746753..c99921f9cdad 100644 --- a/extensions/Particle3D/src/Particle3D/PU/PUMaterialManager.cpp +++ b/extensions/Particle3D/src/Particle3D/PU/PUMaterialManager.cpp @@ -45,6 +45,8 @@ # include "axmol/tlx/filesystem.hpp" #endif +#include "yasio/tlx/string_view.hpp" + namespace ax { @@ -210,9 +212,9 @@ bool PUMaterialCache::loadMaterialsFromSearchPaths(std::string_view fileFolder) for (const auto& entry : stdfs::recursive_directory_iterator(fileFolder)) { # if !defined(_WIN32) - if (entry.is_regular_file() && cxx20::ends_with(entry.path().native(), ".material"sv)) + if (entry.is_regular_file() && tlx::ends_with(entry.path().native(), ".material"sv)) # else - if (entry.is_regular_file() && cxx20::ends_with(entry.path().native(), L".material"sv)) + if (entry.is_regular_file() && tlx::ends_with(entry.path().native(), L".material"sv)) # endif { auto pathU8Str = entry.path().generic_u8string(); diff --git a/extensions/SDFGen/src/SDFGen/SDFGen.cpp b/extensions/SDFGen/src/SDFGen/SDFGen.cpp index ca78b1a52b22..835de1b16327 100644 --- a/extensions/SDFGen/src/SDFGen/SDFGen.cpp +++ b/extensions/SDFGen/src/SDFGen/SDFGen.cpp @@ -11,6 +11,7 @@ #include #include "axmol/base/JsonWriter.h" #include "yasio/tlx/chrono.hpp" +#include "yasio/tlx/string_view.hpp" NS_AX_EXT_BEGIN @@ -250,9 +251,9 @@ void SDFGen::refreshFontList() auto& contentPath = fu->getDefaultResourceRootPath(); for (auto& filePath : fileList) { - if (!cxx20::ic::ends_with(filePath, ".ttf") && !cxx20::ic::ends_with(filePath, ".ttc")) + if (!tlx::ic::ends_with(filePath, ".ttf") && !tlx::ic::ends_with(filePath, ".ttc")) continue; - if (cxx20::starts_with(filePath, contentPath)) + if (tlx::starts_with(filePath, contentPath)) _fontList.emplace_back(filePath.substr(contentPath.size())); else _fontList.emplace_back(std::move(filePath)); diff --git a/tests/fairygui-tests/Source/AppDelegate.h b/tests/fairygui-tests/Source/AppDelegate.h index e77f19c8a980..1246883d80ad 100644 --- a/tests/fairygui-tests/Source/AppDelegate.h +++ b/tests/fairygui-tests/Source/AppDelegate.h @@ -14,7 +14,7 @@ class AppDelegate : private ax::Application AppDelegate(); ~AppDelegate() override; - void initContextAttrs(); + void initContextAttrs() override; /** @brief Implement Director and Scene init code here. diff --git a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp index 03d85299d303..3bd638396fd4 100644 --- a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp +++ b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp @@ -21,8 +21,9 @@ template using my_flat_set = _TLX flat_set<_Tp, std::less<_Tp>, tlx::vector<_Tp>>; template -static constexpr bool vector_equals(const _Cont1& c1, const _Cont2& c2) +static constexpr bool sequence_container_equals(const _Cont1& c1, const _Cont2& c2) { + static_assert(std::is_same_v, "sequence_container_equals must have same value types"); return c1.size() == c2.size() && 0 == memcmp(c1.data(), c2.data(), c1.size() * sizeof(typename _Cont1::value_type)); } @@ -127,42 +128,100 @@ static void run_benchmark() keys[i] = dist(rng); } -#if _AX_STL_HAS_FLAT_CONTAINER - auto s4 = benchmark_set>("std::flat_set", keys); - auto m4 = benchmark_map>("std::flat_map", keys); -#endif auto s1 = benchmark_set>("std::set", keys); auto s2 = benchmark_set>("std::unordered_set", keys); auto s3 = benchmark_set>("tlx::hash_set", keys); auto s5 = benchmark_set>("tlx::flat_set", keys); auto s6 = benchmark_set>("my_flat_set", keys); +#if _AX_STL_HAS_FLAT_CONTAINER + auto s4 = benchmark_set>("std::flat_set", keys); +#endif auto m1 = benchmark_map>("std::map", keys); auto m2 = benchmark_map>("std::unordered_map", keys); auto m3 = benchmark_map>("tlx::hash_map", keys); auto m5 = benchmark_map>("tlx::flat_map", keys); +#if _AX_STL_HAS_FLAT_CONTAINER + auto m4 = benchmark_map>("std::flat_map", keys); +#endif std::sort(keys.begin(), keys.end()); keys.erase(std::unique(keys.begin(), keys.end()), keys.end()); - CHECK(vector_equals(keys, s5.keys())); - CHECK(vector_equals(keys, s6.keys())); + CHECK(sequence_container_equals(keys, s5.keys())); + CHECK(sequence_container_equals(keys, s6.keys())); } TEST_SUITE("tlx/Containers") { - // !!!Don't invoke FileUtils::getInstacne at here, it's dangerous due to - // The test suite function will invoke before entrypoint `main`, it will cause - // crash on Linux(maybe others), crt not initalized properly yet. #define fu FileUtils::getInstance() TEST_CASE("VectorTest") { - tlx::vector buffer; - std::string messge = "aaaaaaaaaaaaaafbbbbbbbbbbbbbbbbbcccccccccdfefffffff"; - buffer.insert(buffer.end(), messge.begin(), messge.end()); - CHECK(buffer.size() == messge.size()); + static int _dtor_invoke_counter = 0; + + struct NonTrivalCtor1 { + int value = 123; + }; + + struct TrivalCtor1 { + int value; + }; + + struct NonTrivialDtor1 { + ~NonTrivialDtor1() { + ++_dtor_invoke_counter; + if(ptr) + free(ptr); + } + void* ptr; + }; + + tlx::vector arr1; + std::string msg = "aaaaaaaaaaaaaafbbbbbbbbbbbbbbbbbcccccccccdfefffffff"; + arr1 += msg; + CHECK(sequence_container_equals(arr1, msg)); + + tlx::vector arr2; + arr2.resize(2); + CHECK((arr2[0].value == 123 && arr2[1].value == 123 && arr2.size() == 2)); + + // pod vector, no auto fill when dtor is trivial + tlx::pod_vector arr3; + arr3.resize(2); + CHECK((arr3[0].value != 123 && arr3[1].value != 123 && arr3.size() == 2)); + + // normal vector whti trival ctor types, shoud initialized to zero + tlx::vector arr4; + arr4.resize(2); + CHECK((arr4[0].value == 0 && arr4[1].value == 0)); + + // pod vector, no auto fill when dtor is trivial + // all extended values shoud preserve uninitialized + tlx::pod_vector arr5; + arr5.resize(2); + CHECK((arr5[0].value != 0 && arr5[1].value != 0)); + + arr5.resize(4, TrivalCtor1{39}); + CHECK((arr5[2].value == 39 && arr5[3].value == 39)); + + arr5.resize(128, TrivalCtor1{66}); + CHECK((arr5[2].value == 39 && arr5[3].value == 39)); + + CHECK((arr5[10].value == 66 && arr5[22].value == 66)); + + // shoud report compile error, non trivial dtors types can't use tlx::pod_vector + // tlx::pod_vector arr6; + + { + _dtor_invoke_counter = 0; + tlx::vector arr7; + + arr7.resize(9); + } + + CHECK(_dtor_invoke_counter == 9); } TEST_CASE("FlatSetTest") From 8f40fdec1daf30af6b8657dc1378f32684e39278 Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 1 Dec 2025 15:05:31 +0800 Subject: [PATCH 07/17] Unify tlx::split --- 3rdparty/yasio/yasio/bindings/yasio_ni.cpp | 2 +- 3rdparty/yasio/yasio/impl/mbedtls.hpp | 6 +- 3rdparty/yasio/yasio/impl/openssl.hpp | 6 +- 3rdparty/yasio/yasio/split.hpp | 127 ----- 3rdparty/yasio/yasio/tlx/split.hpp | 462 ++++++++++++++++++ axmol/2d/TMXXMLParser.cpp | 7 +- axmol/network/HttpCookie.cpp | 12 +- axmol/network/HttpRequest.h | 2 - axmol/platform/FileUtils.cpp | 3 +- axmol/platform/win32/FileUtils-win32.cpp | 2 +- axmol/platform/winrt/FileUtilsWinRT.cpp | 2 +- axmol/tlx/split.hpp | 26 + axmol/tlx/utility.hpp | 88 ---- .../manual/network/lua_xml_http_request.cpp | 2 +- 14 files changed, 510 insertions(+), 237 deletions(-) delete mode 100644 3rdparty/yasio/yasio/split.hpp create mode 100644 3rdparty/yasio/yasio/tlx/split.hpp create mode 100644 axmol/tlx/split.hpp diff --git a/3rdparty/yasio/yasio/bindings/yasio_ni.cpp b/3rdparty/yasio/yasio/bindings/yasio_ni.cpp index d2a5bcdd1fd8..15da35f14ffc 100644 --- a/3rdparty/yasio/yasio/bindings/yasio_ni.cpp +++ b/3rdparty/yasio/yasio/bindings/yasio_ni.cpp @@ -156,7 +156,7 @@ YASIO_NI_API void yasio_set_option(void* service_ptr, int opt, const char* pszAr std::string strArgs = pszArgs; std::array args; int argc = 0; - yasio::split_if(&strArgs.front(), ';', [&](char* s, char* e) { + tlx::split_if(&strArgs.front(), ';', [&](char* s, char* e) { if (e) { *e = '\0'; // to c style string args[argc++] = cxx17::string_view(s, e - s); diff --git a/3rdparty/yasio/yasio/impl/mbedtls.hpp b/3rdparty/yasio/yasio/impl/mbedtls.hpp index 450a4057532f..1174bd2f0911 100644 --- a/3rdparty/yasio/yasio/impl/mbedtls.hpp +++ b/3rdparty/yasio/yasio/impl/mbedtls.hpp @@ -31,7 +31,7 @@ SOFTWARE. #if YASIO_SSL_BACKEND == 2 -# include "yasio/split.hpp" +# include "yasio/tlx/split.hpp" YASIO__DECL yssl_ctx_st* yssl_ctx_new(const yssl_options& opts) { @@ -65,9 +65,9 @@ YASIO__DECL yssl_ctx_st* yssl_ctx_new(const yssl_options& opts) if (yasio__valid_str(opts.crtfile_)) // the cafile_ must be full path { int fail_count = 0; - yasio::split( + tlx::split( opts.crtfile_, ',', [&](char* first, char* last) { - yasio::split_term null_term(last); + tlx::split_term_guard null_term(last); if ((ret = ::mbedtls_x509_crt_parse_file(&ctx->cert, first)) != 0) { diff --git a/3rdparty/yasio/yasio/impl/openssl.hpp b/3rdparty/yasio/yasio/impl/openssl.hpp index f25eb2084d98..7cdd55907b4c 100644 --- a/3rdparty/yasio/yasio/impl/openssl.hpp +++ b/3rdparty/yasio/yasio/impl/openssl.hpp @@ -31,7 +31,7 @@ SOFTWARE. #if YASIO_SSL_BACKEND == 1 // OpenSSL -# include "yasio/split.hpp" +# include "yasio/tlx/split.hpp" // The ssl error mask (1 << 31), a little hack, but works # define YSSL_ERR_MASK 0x80000000 @@ -53,8 +53,8 @@ YASIO__DECL yssl_ctx_st* yssl_ctx_new(const yssl_options& opts) if (yasio__valid_str(opts.crtfile_)) { // CAfile for verify fail_count = 0; - yasio::split(opts.crtfile_, ',', [&](char* first, char* last) { - yasio::split_term null_term(last); + tlx::split(opts.crtfile_, ',', [&](char* first, char* last) { + tlx::split_term_guard null_term(last); # if defined(OPENSSL_VERSION_MAJOR) && (OPENSSL_VERSION_MAJOR >= 3) /* OpenSSL 3.0.0 has deprecated SSL_CTX_load_verify_locations */ diff --git a/3rdparty/yasio/yasio/split.hpp b/3rdparty/yasio/yasio/split.hpp deleted file mode 100644 index c6f505aba412..000000000000 --- a/3rdparty/yasio/yasio/split.hpp +++ /dev/null @@ -1,127 +0,0 @@ -////////////////////////////////////////////////////////////////////////////////////////// -// A multi-platform support c++11 library with focus on asynchronous socket I/O for any -// client application. -////////////////////////////////////////////////////////////////////////////////////////// -/* -The MIT License (MIT) - -Copyright (c) 2012-2025 HALX99 - -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. -*/ - -/* - * The standard split stub of yasio: - * The pred callback prototype: [](CStr first, CStr last) ->bool{ return true; } - * returns: - * true: want continue split - * false: abort split - * - */ - -#pragma once - -#include "yasio/tlx/string_view.hpp" -#include - -#if defined(_MSC_VER) -# pragma warning(push) -# pragma warning(disable : 4706) -#endif - -namespace yasio -{ -template -inline void split_if(_CStr s, typename std::remove_pointer<_CStr>::type delim, _Pred&& pred) -{ - auto _Start = s; // the start of every string - auto _Ptr = s; // source string iterator - while ((_Ptr = strchr(_Ptr, delim))) - { - if (_Start <= _Ptr && !pred(_Start, _Ptr)) - return; - _Start = _Ptr + 1; - ++_Ptr; - } - pred(_Start, nullptr); // last one, end is nullptr -} - -template -inline void split_if_n(_CStr s, size_t slen, typename std::remove_pointer<_CStr>::type delim, _Pred&& pred) -{ - auto _Start = s; // the start of every string - auto _Ptr = s; // source string iterator - auto _End = s + slen; - while ((_Ptr = strchr(_Ptr, delim))) - { - if (_Ptr >= _End) - break; - - if (_Start <= _Ptr && !pred(_Start, _Ptr)) - return; - _Start = _Ptr + 1; - ++_Ptr; - } - if (_Start <= _End) - pred(_Start, _End); -} - -template -inline void split(_CStr s, typename std::remove_pointer<_CStr>::type delim, _Func&& func) -{ - split_if(s, delim, [func](_CStr first, _CStr last) { - func(first, last); - return true; - }); -} - -template -inline void split_n(_CStr s, size_t slen, typename std::remove_pointer<_CStr>::type delim, _Func&& func) -{ - split_if_n(s, slen, delim, [func](_CStr first, _CStr last) { - func(first, last); - return true; - }); -} - -struct split_term { - split_term(char* end) - { - if (end) - { - this->val_ = *end; - *end = '\0'; - this->end_ = end; - } - } - ~split_term() - { - if (this->end_) - *this->end_ = this->val_; - } - -private: - char* end_ = nullptr; - char val_ = '\0'; -}; -} // namespace yasio - -#if defined(_MSC_VER) -# pragma warning(pop) -#endif diff --git a/3rdparty/yasio/yasio/tlx/split.hpp b/3rdparty/yasio/yasio/tlx/split.hpp new file mode 100644 index 000000000000..7430ca207251 --- /dev/null +++ b/3rdparty/yasio/yasio/tlx/split.hpp @@ -0,0 +1,462 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// A multi-platform support c++11 library with focus on asynchronous socket I/O for any +// client application. +////////////////////////////////////////////////////////////////////////////////////////// +/* +The MIT License (MIT) + +Copyright (c) 2012-2025 HALX99 + +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. +*/ + +/* + * The standard split stub of tlx: + * The pred callback prototype: [](CStr first, CStr last) ->bool{ return true; } + * returns: + * true: want continue split + * false: want end split + * + */ + +#pragma once + +#include +#include +#include +#include // strchr, strpbrk +#include // wcschr, wcspbrk +#include // std::distance +#include // std::to_address + +#if defined(__cpp_lib_ranges) +#include +#endif + +#if defined(_MSC_VER) +# pragma warning(push) +# pragma warning(disable : 4706) +#endif + +namespace tlx +{ + +template +struct has_random_access_iterator_category : std::false_type {}; + +template +struct has_random_access_iterator_category::iterator_category>> { + using cat = typename std::iterator_traits::iterator_category; + static constexpr bool value = std::is_base_of_v; +}; + +template +inline constexpr bool has_random_access_iterator_category_v = has_random_access_iterator_category>::value; + +template +struct has_data_and_size : std::false_type {}; + +template +struct has_data_and_size().data()), decltype(std::declval().size())>> : std::true_type {}; + +template +inline constexpr bool has_data_and_size_v = has_data_and_size>::value; + +template +inline constexpr bool is_contiguous_like_v = +#if defined(__cpp_lib_ranges) + std::ranges::contiguous_range> || +#endif + (has_data_and_size_v && has_random_access_iterator_category_v); + +// ----------------------------- +// element_of trait (robust) +// ----------------------------- +template +struct element_of; // primary undefined + +// If _Ty has value_type (containers, span, iterators with value_type), use it +template +struct element_of<_Ty, std::void_t::value_type>> { + using type = typename std::remove_cvref_t<_Ty>::value_type; +}; + +// Pointer specialization: keep cv of the pointee (so const char* -> const char) +template +struct element_of<_Ty*, void> { + using type = std::remove_cv_t<_Ty>; // keep cv on pointer handled by pointer type itself +}; + +// Special-case: string_view should map to const char (preserve const) +template <> +struct element_of { + using type = const char; +}; + +template <> +struct element_of { + using type = const wchar_t; +}; + +// Helper aliases +template +using element_of_t = typename element_of<_Ty>::type; + +// element_of_nocvref_t: evaluate element_of on remove_cvref_t<_Ty> +// useful for deducing delim/delims types from an input type +template +using element_of_nocvref_t = typename element_of>::type; + +// ----------------------------- +// is_span_of detection +// ----------------------------- +template +struct is_span_of : std::false_type {}; + +template +struct is_span_of> : std::true_type {}; + +template +inline constexpr bool is_span_of_v = is_span_of>::value; + +// ----------------------------- +// detail implementations +// ----------------------------- +namespace detail +{ + +template +struct split_traits_base; + +// narrow char +template <> +struct split_traits_base { + static const char* find_char(const char* s, char delim) { return std::strchr(s, delim); } + static const char* find_any(const char* s, const char* delims) { return std::strpbrk(s, delims); } + + static char* find_char(char* s, char delim) { return std::strchr(s, delim); } + static char* find_any(char* s, const char* delims) { return std::strpbrk(s, delims); } +}; + +// wide char +template <> +struct split_traits_base { + static const wchar_t* find_char(const wchar_t* s, wchar_t delim) { return std::wcschr(s, delim); } + static const wchar_t* find_any(const wchar_t* s, const wchar_t* delims) { return std::wcspbrk(s, delims); } + + static wchar_t* find_char(wchar_t* s, wchar_t delim) { return std::wcschr(s, delim); } + static wchar_t* find_any(wchar_t* s, const wchar_t* delims) { return std::wcspbrk(s, delims); } +}; + +template +using split_traits = split_traits_base>; + +// ----------------------------- +// split_if implementations +// ----------------------------- + +// pointer version: keep nullptr as end sentinel to avoid strlen +template +inline void split_if(Elem* s, Elem delim, Pred&& pred) +{ + Elem* start = s; + Elem* ptr = s; + while ((ptr = split_traits::find_char(ptr, delim))) + { + if (start <= ptr && !pred(start, ptr)) + return; + start = ptr + 1; + ++ptr; + } + // end sentinel: nullptr (caller wrapper must accept auto last) + pred(start, nullptr); +} + +// span version: Elem may be const-qualified; delim uses remove_cv_t +template +inline void split_if(std::span s, std::remove_cv_t delim, Pred&& pred) +{ + Elem* start = s.data(); + Elem* ptr = start; + Elem* end = start + s.size(); + while ((ptr = split_traits::find_char(ptr, delim))) + { + if (ptr >= end) + break; + if (start <= ptr && !pred(start, ptr)) + return; + start = ptr + 1; + ++ptr; + } + if (start <= end) + pred(start, end); +} + +// convenience span wrapper (callback style) +template +inline void split(std::span s, std::remove_cv_t delim, Fn&& func) +{ + split_if(s, delim, [func = std::forward(func)](Elem* f, Elem* l) { + func(f, l); + return true; + }); +} + +// ----------------------------- +// split_of_if implementations +// ----------------------------- + +// pointer version: delims is pointer to (possibly const) char type; end sentinel nullptr +template +inline void split_of_if(Elem* s, const std::remove_cv_t* delims, Pred&& pred) +{ + Elem* start = s; + Elem* ptr = s; + Elem delim = *delims; + while ((ptr = split_traits::find_any(ptr, delims))) + { + if (start <= ptr) + { + if (!pred(start, ptr, delim)) + return; + delim = *ptr; + } + start = ptr + 1; + ++ptr; + } + pred(start, nullptr, delim); +} + +// span version: delims is pointer to remove_cv_t +template +inline void split_of_if(std::span s, const std::remove_cv_t* delims, Pred&& pred) +{ + Elem* start = s.data(); + Elem* ptr = start; + Elem* end = start + s.size(); + Elem delim = *delims; + while ((ptr = split_traits::find_any(ptr, delims))) + { + if (ptr >= end) + break; + if (start <= ptr) + { + if (!pred(start, ptr, delim)) + return; + delim = *ptr; + } + start = ptr + 1; + ++ptr; + } + if (start <= end) + pred(start, end, delim); +} + +// convenience span wrapper (callback style) +template +inline void split_of(std::span s, const std::remove_cv_t* delims, Fn&& func) +{ + split_of_if(s, delims, [func = std::forward(func)](Elem* f, Elem* l, Elem d) { + func(f, l, d); + return true; + }); +} + +} // namespace detail + +// ----------------------------- +// external dispatching helpers +// ----------------------------- + +// split_if: accept string-like types, pointers, spans +template +inline void split_if(Str&& s, const element_of_nocvref_t delim, Pred&& pred) +{ + using Tp = std::remove_cvref_t; + + if constexpr (std::is_pointer_v) + { + // pointer (char*/wchar_t*) + detail::split_if(s, delim, std::forward(pred)); + } + else if constexpr (is_span_of_v) + { + detail::split_if(s, delim, std::forward(pred)); + } + else if constexpr (is_contiguous_like_v) + { + // Any type that exposes data() and size() (std::string, std::string_view, + // std::basic_string<...>, std::span<...> etc.) + using ElemPtr = decltype(std::declval().data()); // e.g. const char* + using Elem = std::remove_pointer_t; // preserves const + detail::split_if(std::span(s.data(), s.size()), delim, std::forward(pred)); + } + else + { + static_assert(sizeof(Tp) == 0, "Unsupported type for tlx::split_if"); + } +} + +// split_of_if: similar dispatch +template +inline void split_of_if(Str&& s, const element_of_nocvref_t* delims, Pred&& pred) +{ + using Tp = std::remove_cvref_t; + + if constexpr (std::is_pointer_v) + { + detail::split_of_if(s, delims, std::forward(pred)); + } + else if constexpr (is_span_of_v) + { + detail::split_of_if(s, delims, std::forward(pred)); + } + else if constexpr (is_contiguous_like_v) + { + // Any type that exposes data() and size() (std::string, std::string_view, + // std::basic_string<...>, std::span<...> etc.) + using ElemPtr = decltype(std::declval().data()); // e.g. const char* + using Elem = std::remove_pointer_t; // preserves const + detail::split_of_if(std::span(s.data(), s.size()), delims, std::forward(pred)); + } + else + { + static_assert(sizeof(Tp) == 0, "Unsupported type for tlx::split_of_if"); + } +} + +// ----------------------------- +// non-_if wrappers (callback style) +// note: wrapper lambdas accept `auto last` (not auto*) so they can receive nullptr +// ----------------------------- +template +inline void split(Str&& s, const element_of_nocvref_t delim, Fn&& func) +{ + split_if(std::forward(s), delim, [func = std::forward(func)](auto* first, auto last) { + func(first, last); + return true; + }); +} + +template +inline void split_of(Str&& s, const element_of_nocvref_t* delims, Fn&& func) +{ + split_of_if(std::forward(s), delims, [func = std::forward(func)](auto* first, auto last, auto delim) { + func(first, last, delim); + return true; + }); +} + +// ----------------------------- +// iterator/iterator-range overloads +// support arbitrary iterators; construct span from to_address(first) +// ensure element type matches the pointer returned by to_address +// ----------------------------- +template +inline void split(Iter first, Iter last, const element_of_nocvref_t delim, Fn&& func) +{ + // deduce pointer type from std::to_address(first) + using Ptr = decltype(std::to_address(first)); + using ElemSpan = std::remove_pointer_t>; // element type for span + auto n = std::distance(first, last); + // construct span with element type matching pointer returned by to_address + std::span sp(std::to_address(first), static_cast(n)); + detail::split_if(sp, delim, [func = std::forward(func)](ElemSpan* f, ElemSpan* l) { + func(f, l); + return true; + }); +} + +template +inline void split_of(Iter first, Iter last, const element_of_nocvref_t* delims, Fn&& func) +{ + using Ptr = decltype(std::to_address(first)); + using ElemSpan = std::remove_pointer_t>; + auto n = std::distance(first, last); + std::span sp(std::to_address(first), static_cast(n)); + detail::split_of_if(sp, delims, [func = std::forward(func)](ElemSpan* f, ElemSpan* l, ElemSpan d) { + func(f, l, d); + return true; + }); +} + +} // namespace tlx + +namespace tlx +{ +/// split_path +template +inline void split_path(_Elem* s, _Pred&& pred, _Fn&& func) +{ + _Elem* _Start = s; + _Elem* _Ptr = s; + while (pred(_Ptr)) + { + if (*_Ptr == _Elem('\\') || *_Ptr == _Elem('/')) + { + if (_Ptr != _Start) + { + auto _Ch = *_Ptr; + *_Ptr = _Elem('\0'); + bool brk = func(s); +#if defined(_WIN32) + *_Ptr = _Elem('\\'); +#else + *_Ptr = _Elem('/'); +#endif + if (brk) + return; + } + _Start = _Ptr + 1; + } + ++_Ptr; + } + if (_Start < _Ptr) + func(s); +} +} // namespace tlx + +namespace tlx +{ +// CLASS split_term_guard +struct split_term_guard { + split_term_guard(char* end) + { + if (end) + { + this->val_ = *end; + *end = '\0'; + this->end_ = end; + } + } + ~split_term_guard() + { + if (this->end_) + *this->end_ = this->val_; + } + +private: + char* end_ = nullptr; + char val_ = '\0'; +}; +} // namespace tlx + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif diff --git a/axmol/2d/TMXXMLParser.cpp b/axmol/2d/TMXXMLParser.cpp index ddc2361fee30..1923b32e1750 100644 --- a/axmol/2d/TMXXMLParser.cpp +++ b/axmol/2d/TMXXMLParser.cpp @@ -38,6 +38,7 @@ THE SOFTWARE. #include "axmol/base/Utils.h" #include "axmol/platform/FileUtils.h" #include "axmol/tlx/utility.hpp" +#include "axmol/tlx/split.hpp" #include #include @@ -735,11 +736,11 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name) TMXLayerInfo* layer = tmxMapInfo->getLayers().back(); tmxMapInfo->setStoringCharacters(false); - auto currentString = tmxMapInfo->getCurrentString(); + std::string_view currentString = tmxMapInfo->getCurrentString(); tlx::pod_vector tileGids; - tlx::split_cb(currentString, '\n', [&tileGids](const char* first, const char* last) { - tlx::split_cb(std::string_view{first, static_cast(last - first)}, ',', + tlx::split(currentString, '\n', [&tileGids](const char* first, const char* last) { + tlx::split(std::string_view{first, static_cast(last - first)}, ',', [&tileGids](const char* _first, const char* _last) { unsigned int gid{0}; std::from_chars(_first, _last, gid); diff --git a/axmol/network/HttpCookie.cpp b/axmol/network/HttpCookie.cpp index 266430c54b40..27e000ad89c6 100644 --- a/axmol/network/HttpCookie.cpp +++ b/axmol/network/HttpCookie.cpp @@ -36,7 +36,7 @@ #include #include "yasio/tlx/string_view.hpp" -#include "axmol/tlx/utility.hpp" +#include "axmol/tlx/split.hpp" #include "fmt/compile.h" namespace ax @@ -62,12 +62,12 @@ void HttpCookie::readFile() std::string inString = FileUtils::getInstance()->getStringFromFile(_cookieFileName); if (!inString.empty()) { - tlx::split_cb(&inString.front(), inString.length(), '\n', [this](char* s, char* e) { + tlx::split(inString, '\n', [this](char* s, char* e) { if (*s == '#') // skip comment return; int count = 0; CookieInfo cookieInfo; - tlx::split_cb(s, e - s, '\t', [&, this](char* ss, char* ee) { + tlx::split(std::span{s, static_cast(e - s)}, '\t', [&, this](char* ss, char* ee) { auto ch = *ee; // store *ee = '\0'; switch (count) @@ -161,7 +161,7 @@ bool HttpCookie::updateOrAddCookie(std::string_view cookie, const Uri& uri) unsigned int count = 0; CookieInfo info; - tlx::split_cb(cookie.data(), cookie.length(), ';', [&](const char* start, const char* end) { + tlx::split(cookie, ';', [&](const char* start, const char* end) { unsigned int count_ = 0; while (*start == ' ') ++start; // skip ws @@ -169,7 +169,7 @@ bool HttpCookie::updateOrAddCookie(std::string_view cookie, const Uri& uri) { std::string_view key; std::string_view value; - tlx::split_cb(start, end - start, '=', [&](const char* s, const char* e) { + tlx::split(start, end, '=', [&](const char* s, const char* e) { switch (++count_) { case 1: @@ -229,7 +229,7 @@ bool HttpCookie::updateOrAddCookie(std::string_view cookie, const Uri& uri) } else { // first is cookie name - tlx::split_cb(start, end - start, '=', [&](const char* s, const char* e) { + tlx::split(start, end, '=', [&](const char* s, const char* e) { switch (++count_) { case 1: diff --git a/axmol/network/HttpRequest.h b/axmol/network/HttpRequest.h index c8f4a59d7208..647217a01b73 100644 --- a/axmol/network/HttpRequest.h +++ b/axmol/network/HttpRequest.h @@ -210,7 +210,6 @@ class AX_DLL HttpRequest : public ConcurrentRefCountedBase * @param callback the HttpCompleteCallback function. */ void setCompleteCallback(const HttpCompleteCallback& callback) { _pCallback = callback; } - AX_DEPRECATED(2.9) void setResponseCallback(const HttpCompleteCallback& callback) { setCompleteCallback(callback); } /** * Get HttpCompleteCallback callback function. @@ -219,7 +218,6 @@ class AX_DLL HttpRequest : public ConcurrentRefCountedBase */ const HttpCompleteCallback& getCompleteCallback() const { return _pCallback; } - AX_DEPRECATED(2.9) const HttpCompleteCallback& getCallback() const { return getCompleteCallback(); } /** * @brief Set the data callback for handling received data chunks. diff --git a/axmol/platform/FileUtils.cpp b/axmol/platform/FileUtils.cpp index 4bf09e912952..6c9a486a3b20 100644 --- a/axmol/platform/FileUtils.cpp +++ b/axmol/platform/FileUtils.cpp @@ -51,6 +51,7 @@ THE SOFTWARE. #include "pugixml/pugixml.hpp" #include "axmol/tlx/filesystem.hpp" +#include "axmol/tlx/split.hpp" #if defined(_WIN32) inline stdfs::path toFspath(const std::string_view& pathSV) @@ -1030,7 +1031,7 @@ bool FileUtils::createDirectories(std::string_view path) const bool fail{false}; std::string mpath{path}; - tlx::splitpath_cb(&mpath.front(), [](char* ptr) { return *ptr != '\0'; }, [&fail](const char* subpath) { + tlx::split_path(&mpath.front(), [](char* ptr) { return *ptr != '\0'; }, [&fail](const char* subpath) { struct stat st; if (stat(subpath, &st) != 0) { diff --git a/axmol/platform/win32/FileUtils-win32.cpp b/axmol/platform/win32/FileUtils-win32.cpp index ae49cf32f552..feda4c0c258d 100644 --- a/axmol/platform/win32/FileUtils-win32.cpp +++ b/axmol/platform/win32/FileUtils-win32.cpp @@ -273,7 +273,7 @@ bool FileUtilsWin32::createDirectories(std::string_view dirPath) const bool fail = false; if ((GetFileAttributesW(path.c_str())) == INVALID_FILE_ATTRIBUTES) { - tlx::splitpath_cb(&path.front(), [](wchar_t* ptr) { return *ptr != '\0'; }, + tlx::split_path(&path.front(), [](wchar_t* ptr) { return *ptr != '\0'; }, [&dirPath, &fail](const wchar_t* subpath) { auto attribs = GetFileAttributesW(subpath); if (attribs == INVALID_FILE_ATTRIBUTES) diff --git a/axmol/platform/winrt/FileUtilsWinRT.cpp b/axmol/platform/winrt/FileUtilsWinRT.cpp index 5933c49126c5..1183796f726d 100644 --- a/axmol/platform/winrt/FileUtilsWinRT.cpp +++ b/axmol/platform/winrt/FileUtilsWinRT.cpp @@ -164,7 +164,7 @@ bool FileUtilsWinRT::createDirectories(std::string_view dirPath) const bool fail = false; if ((GetFileAttributesW(path.c_str())) == INVALID_FILE_ATTRIBUTES) { - tlx::splitpath_cb(&path.front(), [](wchar_t* ptr) { return *ptr != '\0'; }, + tlx::split_path(&path.front(), [](wchar_t* ptr) { return *ptr != '\0'; }, [&dirPath, &fail](const wchar_t* subpath) { auto attribs = GetFileAttributesW(subpath); if (attribs == INVALID_FILE_ATTRIBUTES) diff --git a/axmol/tlx/split.hpp b/axmol/tlx/split.hpp new file mode 100644 index 000000000000..ae0d73fc555a --- /dev/null +++ b/axmol/tlx/split.hpp @@ -0,0 +1,26 @@ +/**************************************************************************** + Copyright (c) 2019-present Axmol Engine contributors (see AUTHORS.md). + + https://axmol.dev/ + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ +#pragma once + +#include "yasio/tlx/split.hpp" diff --git a/axmol/tlx/utility.hpp b/axmol/tlx/utility.hpp index 89326b8ffb64..2c0e27b295cc 100644 --- a/axmol/tlx/utility.hpp +++ b/axmol/tlx/utility.hpp @@ -89,92 +89,4 @@ inline void resize_and_overrite(_SeqCont& cont, size_t size, _Operation op) { } } -template -inline void split_cb(_CStr s, size_t slen, typename std::remove_pointer<_CStr>::type delim, _Fn&& func) -{ - auto _Start = s; // the start of every string - auto _Ptr = s; // source string iterator - auto _End = s + slen; - while ((_Ptr = strchr(_Ptr, delim))) - { - if (_Ptr >= _End) - break; - - if (_Start <= _Ptr) - func(_Start, _Ptr); - _Start = _Ptr + 1; - ++_Ptr; - } - if (_Start <= _End) - func(_Start, _End); -} - -template -inline void split_of_cb(_CStr s, size_t slen, typename std::remove_const<_CStr>::type const delims, _Fty&& func) -{ - auto _Start = s; // the start of every string - auto _Ptr = s; // source string iterator - auto _End = s + slen; - auto _Delim = *delims; - while ((_Ptr = strpbrk(_Ptr, delims))) - { - if (_Ptr >= _End) - break; - - if (_Start <= _Ptr) - { - func(_Start, _Ptr, _Delim); - _Delim = *_Ptr; - } - _Start = _Ptr + 1; - ++_Ptr; - } - if (_Start <= _End) - func(_Start, _End, _Delim); -} - -template -inline void split_cb(std::string_view s, char delim, _Fn&& func) -{ - split_cb(s.data(), s.length(), delim, std::move(func)); -} - -template -inline void split_of_cb(std::string_view s, const char* delims, _Fn&& func) -{ - split_of_cb(s.data(), s.length(), delims, std::move(func)); -} - -template -inline void splitpath_cb(_Elem* s, _Pred&& pred, _Fn&& func) // will convert '\\' to '/' -{ - _Elem* _Start = s; // the start of every string - _Elem* _Ptr = s; // source string iterator - while (pred(_Ptr)) - { - if ('\\' == *_Ptr || '/' == *_Ptr) - { - if (_Ptr != _Start) - { - auto _Ch = *_Ptr; - *_Ptr = '\0'; - bool should_brk = func(s); -#if defined(_WIN32) - *_Ptr = '\\'; -#else // For unix linux like system. - *_Ptr = '/'; -#endif - if (should_brk) - return; - } - _Start = _Ptr + 1; - } - ++_Ptr; - } - if (_Start < _Ptr) - { - func(s); - } -} - } // namespace tlx diff --git a/extensions/scripting/lua-bindings/manual/network/lua_xml_http_request.cpp b/extensions/scripting/lua-bindings/manual/network/lua_xml_http_request.cpp index e462d13d05fa..bb79051a9bce 100644 --- a/extensions/scripting/lua-bindings/manual/network/lua_xml_http_request.cpp +++ b/extensions/scripting/lua-bindings/manual/network/lua_xml_http_request.cpp @@ -205,7 +205,7 @@ void LuaMinXmlHttpRequest::_setHttpRequestHeader() */ void LuaMinXmlHttpRequest::_sendRequest() { - _httpRequest->setResponseCallback([this](ax::network::HttpClient* sender, ax::network::HttpResponse* response) { + _httpRequest->setCompleteCallback([this](ax::network::HttpClient* sender, ax::network::HttpResponse* response) { if (_isAborted) return; auto tag = response->getHttpRequest()->getTag(); From e9949b79bc7e2e7ba5c1f6bb113837634b412f72 Mon Sep 17 00:00:00 2001 From: axmol-bot <116471739+axmol-bot@users.noreply.github.com> Date: Mon, 1 Dec 2025 07:06:45 +0000 Subject: [PATCH 08/17] Fixup --- axmol/2d/FontAtlas.cpp | 2 +- axmol/2d/ParticleSystem.cpp | 2 +- axmol/2d/TMXXMLParser.cpp | 2 +- axmol/3d/Animation3D.cpp | 12 ++++---- axmol/3d/Mesh.h | 4 +-- axmol/3d/MeshMaterial.h | 2 +- axmol/3d/MeshVertexIndexData.h | 2 +- axmol/3d/Terrain.cpp | 2 +- axmol/base/Director.cpp | 2 +- axmol/base/Scheduler.cpp | 2 +- axmol/base/Utils.cpp | 3 +- axmol/network/HttpRequest.h | 2 +- axmol/platform/FileUtils.cpp | 4 +-- axmol/platform/FileUtils.h | 2 +- axmol/platform/android/jni/JniHelper.h | 8 ++--- axmol/platform/win32/FileUtils-win32.cpp | 5 ++-- axmol/platform/winrt/FileUtilsWinRT.cpp | 3 +- axmol/rhi/ProgramState.h | 5 +--- axmol/ui/UIRichText.cpp | 2 +- .../src/Particle3D/PU/PUScriptCompiler.cpp | 2 +- .../cocostudio/src/cocostudio/SGUIReader.cpp | 4 +-- .../HttpClientTest/HttpClientTest.cpp | 30 +++++++++---------- .../Source/axmol/tlx/ContainerTests.cpp | 21 ++++++++----- 23 files changed, 60 insertions(+), 63 deletions(-) diff --git a/axmol/2d/FontAtlas.cpp b/axmol/2d/FontAtlas.cpp index 8b08f611459e..3c29447cc315 100644 --- a/axmol/2d/FontAtlas.cpp +++ b/axmol/2d/FontAtlas.cpp @@ -319,7 +319,7 @@ bool FontAtlas::findNewCharacters(const std::u32string& u32Text) if (_letterDefinitions.empty()) { - _newChars.insert(u32Text.begin(), u32Text.end()); + _newChars.insert(u32Text.begin(), u32Text.end()); } else { diff --git a/axmol/2d/ParticleSystem.cpp b/axmol/2d/ParticleSystem.cpp index ab352253b230..0aa7f3f5474c 100644 --- a/axmol/2d/ParticleSystem.cpp +++ b/axmol/2d/ParticleSystem.cpp @@ -647,7 +647,7 @@ bool ParticleSystem::initWithDictionary(const ValueMap& dictionary, std::string_ // Director::getInstance()->getTextureCache()->addUIImage() image = new Image(); const auto imageDataLen = deflated.size(); - bool isOK = image->initWithImageData(deflated.detach_abi(), imageDataLen, true); + bool isOK = image->initWithImageData(deflated.detach_abi(), imageDataLen, true); AXASSERT(isOK, "CCParticleSystem: error init image with Data"); AX_BREAK_IF(!isOK); diff --git a/axmol/2d/TMXXMLParser.cpp b/axmol/2d/TMXXMLParser.cpp index 1923b32e1750..199f690b78ef 100644 --- a/axmol/2d/TMXXMLParser.cpp +++ b/axmol/2d/TMXXMLParser.cpp @@ -741,7 +741,7 @@ void TMXMapInfo::endElement(void* /*ctx*/, const char* name) tlx::pod_vector tileGids; tlx::split(currentString, '\n', [&tileGids](const char* first, const char* last) { tlx::split(std::string_view{first, static_cast(last - first)}, ',', - [&tileGids](const char* _first, const char* _last) { + [&tileGids](const char* _first, const char* _last) { unsigned int gid{0}; std::from_chars(_first, _last, gid); tileGids.push_back(gid); diff --git a/axmol/3d/Animation3D.cpp b/axmol/3d/Animation3D.cpp index 0166b2806d33..79fc48ac1a95 100644 --- a/axmol/3d/Animation3D.cpp +++ b/axmol/3d/Animation3D.cpp @@ -124,9 +124,9 @@ bool Animation3D::init(const Animation3DData& data) continue; tlx::resize_and_transform(iter.second.begin(), iter.second.end(), keys, - [](const auto& keyIter) { return keyIter._time; }); + [](const auto& keyIter) { return keyIter._time; }); tlx::resize_and_transform(iter.second.begin(), iter.second.end(), values, - [](const auto& keyIter) { return keyIter._key; }); + [](const auto& keyIter) { return keyIter._key; }); curve->translateCurve = Curve::AnimationCurveVec3::create(&keys[0], &values[0].x, (int)keys.size()); if (curve->translateCurve) @@ -150,9 +150,9 @@ bool Animation3D::init(const Animation3DData& data) continue; tlx::resize_and_transform(iter.second.begin(), iter.second.end(), keys, - [](const auto& keyIter) { return keyIter._time; }); + [](const auto& keyIter) { return keyIter._time; }); tlx::resize_and_transform(iter.second.begin(), iter.second.end(), values, - [](const auto& keyIter) { return keyIter._key; }); + [](const auto& keyIter) { return keyIter._key; }); curve->rotCurve = Curve::AnimationCurveQuat::create(&keys[0], &values[0].x, (int)keys.size()); if (curve->rotCurve) @@ -176,9 +176,9 @@ bool Animation3D::init(const Animation3DData& data) continue; tlx::resize_and_transform(iter.second.begin(), iter.second.end(), keys, - [](const auto& keyIter) { return keyIter._time; }); + [](const auto& keyIter) { return keyIter._time; }); tlx::resize_and_transform(iter.second.begin(), iter.second.end(), values, - [](const auto& keyIter) { return keyIter._key; }); + [](const auto& keyIter) { return keyIter._key; }); curve->scaleCurve = Curve::AnimationCurveVec3::create(&keys[0], &values[0].x, (int)keys.size()); if (curve->scaleCurve) diff --git a/axmol/3d/Mesh.h b/axmol/3d/Mesh.h index c18d4721d96b..2cae83eb5743 100644 --- a/axmol/3d/Mesh.h +++ b/axmol/3d/Mesh.h @@ -282,8 +282,8 @@ class AX_DLL Mesh : public Object void setLightUniforms(Pass* pass, Scene* scene, const Vec4& color, unsigned int lightmask); void bindMeshCommand(); tlx::hash_map _textures; // textures that submesh is using - MeshSkin* _skin; // skin - bool _visible; // is the submesh visible + MeshSkin* _skin; // skin + bool _visible; // is the submesh visible bool _instancing; rhi::Buffer* _instanceTransformBuffer; diff --git a/axmol/3d/MeshMaterial.h b/axmol/3d/MeshMaterial.h index 7db6602b1774..49c782b46518 100644 --- a/axmol/3d/MeshMaterial.h +++ b/axmol/3d/MeshMaterial.h @@ -196,7 +196,7 @@ class MeshMaterialCache protected: static MeshMaterialCache* _cacheInstance; // cache instance - tlx::string_map _materials; // cached materials + tlx::string_map _materials; // cached materials }; // end of 3d group diff --git a/axmol/3d/MeshVertexIndexData.h b/axmol/3d/MeshVertexIndexData.h index cad6e504d8cc..121d024d9b8b 100644 --- a/axmol/3d/MeshVertexIndexData.h +++ b/axmol/3d/MeshVertexIndexData.h @@ -145,7 +145,7 @@ class AX_DLL MeshVertexData : public Object protected: rhi::Buffer* _vertexBuffer = nullptr; // vertex buffer ssize_t _sizePerVertex = -1; - Vector _indices; // index data + Vector _indices; // index data tlx::pod_vector _attribs; // vertex attributes int _vertexCount = 0; // vertex count diff --git a/axmol/3d/Terrain.cpp b/axmol/3d/Terrain.cpp index 0f56790ce3c9..50830e29dcc6 100644 --- a/axmol/3d/Terrain.cpp +++ b/axmol/3d/Terrain.cpp @@ -1316,7 +1316,7 @@ void Terrain::Chunk::calculateAABB() { tlx::pod_vector pos; tlx::resize_and_transform(_originalVertices.begin(), _originalVertices.end(), pos, - [](const auto& it) { return it._position; }); + [](const auto& it) { return it._position; }); _aabb.updateMinMax(&pos[0], pos.size()); } diff --git a/axmol/base/Director.cpp b/axmol/base/Director.cpp index a929ae2ef278..2579ec5ab26e 100644 --- a/axmol/base/Director.cpp +++ b/axmol/base/Director.cpp @@ -1122,7 +1122,7 @@ void Director::reset() MeshMaterial::releaseBuiltInMaterial(); MeshMaterial::releaseCachedMaterial(); #endif - + rhi::SamplerCache::destroyInstance(); } diff --git a/axmol/base/Scheduler.cpp b/axmol/base/Scheduler.cpp index e1aa499851cc..4a3c9f0fe4a7 100644 --- a/axmol/base/Scheduler.cpp +++ b/axmol/base/Scheduler.cpp @@ -351,7 +351,7 @@ void Scheduler::priorityIn(tlx::pod_vector& list, { auto sched = new SchedHandle(&list, callback, target, priority, paused); tlx::ordered_insert(list, sched, - [](const SchedHandle* lhs, const SchedHandle* rhs) { return lhs->priority < rhs->priority; }); + [](const SchedHandle* lhs, const SchedHandle* rhs) { return lhs->priority < rhs->priority; }); _schedIndexMap.emplace(target, sched); } diff --git a/axmol/base/Utils.cpp b/axmol/base/Utils.cpp index 277477dc4974..2acc4ae131a0 100644 --- a/axmol/base/Utils.cpp +++ b/axmol/base/Utils.cpp @@ -848,8 +848,7 @@ AX_DLL std::string base64Encode(const void* in, size_t inlen) * */ - tlx::resize_and_overrite(ret, n, - [in, inlen](char* out, size_t) { return ax::base64::encode(out, in, inlen); }); + tlx::resize_and_overrite(ret, n, [in, inlen](char* out, size_t) { return ax::base64::encode(out, in, inlen); }); return ret; } diff --git a/axmol/network/HttpRequest.h b/axmol/network/HttpRequest.h index 647217a01b73..425dc0a0a4f4 100644 --- a/axmol/network/HttpRequest.h +++ b/axmol/network/HttpRequest.h @@ -299,7 +299,7 @@ class AX_DLL HttpRequest : public ConcurrentRefCountedBase // properties Type _requestType; /// kHttpRequestGet, kHttpRequestPost or other enums std::string _url; /// target url that this request is sent to - tlx::sbyte_buffer _requestData; /// used for POST + tlx::sbyte_buffer _requestData; /// used for POST std::string _tag; /// user defined tag, to identify different requests in response callback ccHttpRequestCallback _pCallback; /// C++11 style callbacks HttpDataCallback _pDataCallback; diff --git a/axmol/platform/FileUtils.cpp b/axmol/platform/FileUtils.cpp index 6c9a486a3b20..263430bbe66d 100644 --- a/axmol/platform/FileUtils.cpp +++ b/axmol/platform/FileUtils.cpp @@ -856,10 +856,10 @@ bool FileUtils::isAbsolutePathInternal(std::string_view path) #if defined(_WIN32) // see also: https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file?redirectedfrom=MSDN return ((path.length() > 2 && ((raw[0] >= 'a' && raw[0] <= 'z') || (raw[0] >= 'A' && raw[0] <= 'Z')) && - raw[1] == ':') // Normal absolute path + raw[1] == ':') // Normal absolute path || tlx::starts_with(path, R"(\\?\)") // Win32 File Namespaces for Long Path || tlx::starts_with(path, R"(\\.\)") // Win32 Device Namespaces for device - || (raw[0] == '/' || raw[0] == '\\') // Current disk drive + || (raw[0] == '/' || raw[0] == '\\') // Current disk drive ); #else return (path.length() > 0 && raw[0] == '/'); diff --git a/axmol/platform/FileUtils.h b/axmol/platform/FileUtils.h index 84825f3ba62f..6b615423da9c 100644 --- a/axmol/platform/FileUtils.h +++ b/axmol/platform/FileUtils.h @@ -79,7 +79,7 @@ class ResizableBufferAdapter : public ResizableBuffer tlx::resize_and_overrite(*_cont, num_of_bytes, std::move(op)); else tlx::resize_and_overrite(*_cont, count_element(num_of_bytes), - [op_ = std::move(op)](void* out, size_t count) { + [op_ = std::move(op)](void* out, size_t count) { const auto num_of_bytes = op_(out, count * element_size); return count_element(num_of_bytes); }); diff --git a/axmol/platform/android/jni/JniHelper.h b/axmol/platform/android/jni/JniHelper.h index 96ca487d732f..20345aa94dfb 100644 --- a/axmol/platform/android/jni/JniHelper.h +++ b/axmol/platform/android/jni/JniHelper.h @@ -270,9 +270,7 @@ class AX_DLL JniHelper @return tlx::pod_vector */ template - static tlx::pod_vector callStaticFloatArrayMethod(const char* className, - const char* methodName, - Ts&&... xs) + static tlx::pod_vector callStaticFloatArrayMethod(const char* className, const char* methodName, Ts&&... xs) { ax::JniMethodInfo t; const char* signature = jni::TypeSignature(std::decay_t...)>{}(); @@ -313,9 +311,7 @@ class AX_DLL JniHelper @return tlx::pod_vector */ template - static tlx::pod_vector callStaticIntArrayMethod(const char* className, - const char* methodName, - Ts&&... xs) + static tlx::pod_vector callStaticIntArrayMethod(const char* className, const char* methodName, Ts&&... xs) { ax::JniMethodInfo t; const char* signature = jni::TypeSignature(std::decay_t...)>{}(); diff --git a/axmol/platform/win32/FileUtils-win32.cpp b/axmol/platform/win32/FileUtils-win32.cpp index feda4c0c258d..5d180404fd69 100644 --- a/axmol/platform/win32/FileUtils-win32.cpp +++ b/axmol/platform/win32/FileUtils-win32.cpp @@ -35,8 +35,7 @@ THE SOFTWARE. #include #include "ntcvt/ntcvt.hpp" - -#include "axmol/tlx/utility.hpp" +#include "axmol/tlx/split.hpp" namespace ax { @@ -274,7 +273,7 @@ bool FileUtilsWin32::createDirectories(std::string_view dirPath) const if ((GetFileAttributesW(path.c_str())) == INVALID_FILE_ATTRIBUTES) { tlx::split_path(&path.front(), [](wchar_t* ptr) { return *ptr != '\0'; }, - [&dirPath, &fail](const wchar_t* subpath) { + [&dirPath, &fail](const wchar_t* subpath) { auto attribs = GetFileAttributesW(subpath); if (attribs == INVALID_FILE_ATTRIBUTES) { diff --git a/axmol/platform/winrt/FileUtilsWinRT.cpp b/axmol/platform/winrt/FileUtilsWinRT.cpp index 1183796f726d..e8b27e5bf8e0 100644 --- a/axmol/platform/winrt/FileUtilsWinRT.cpp +++ b/axmol/platform/winrt/FileUtilsWinRT.cpp @@ -29,6 +29,7 @@ THE SOFTWARE. #include "axmol/platform/winrt/WinRTUtils.h" #include "axmol/platform/Common.h" #include "ntcvt/ntcvt.hpp" +#include "axmol/tlx/split.hpp" #include #include @@ -165,7 +166,7 @@ bool FileUtilsWinRT::createDirectories(std::string_view dirPath) const if ((GetFileAttributesW(path.c_str())) == INVALID_FILE_ATTRIBUTES) { tlx::split_path(&path.front(), [](wchar_t* ptr) { return *ptr != '\0'; }, - [&dirPath, &fail](const wchar_t* subpath) { + [&dirPath, &fail](const wchar_t* subpath) { auto attribs = GetFileAttributesW(subpath); if (attribs == INVALID_FILE_ATTRIBUTES) { diff --git a/axmol/rhi/ProgramState.h b/axmol/rhi/ProgramState.h index 03d141934352..d162f0824455 100644 --- a/axmol/rhi/ProgramState.h +++ b/axmol/rhi/ProgramState.h @@ -171,10 +171,7 @@ class AX_DLL ProgramState : public Object return _program->getVertexInputDesc(name); } - const tlx::string_map& getActiveVertexInputs() const - { - return _program->getActiveVertexInputs(); - } + const tlx::string_map& getActiveVertexInputs() const { return _program->getActiveVertexInputs(); } /* * Gets the inmutable vertex layout from _program diff --git a/axmol/ui/UIRichText.cpp b/axmol/ui/UIRichText.cpp index 044c20d9595b..7755ee0637f1 100644 --- a/axmol/ui/UIRichText.cpp +++ b/axmol/ui/UIRichText.cpp @@ -1182,7 +1182,7 @@ void MyXMLVisitor::setTagDescription(std::string_view tag, { // MyXMLVisitor::_tagTables[tag] = {isFontElement, std::move(handleVisitEnter), std::move(handleVisitExit)}; tlx::set_item(MyXMLVisitor::_tagTables, tag, - TagBehavior{isFontElement, std::move(handleVisitEnter), std::move(handleVisitExit)}); + TagBehavior{isFontElement, std::move(handleVisitEnter), std::move(handleVisitExit)}); } void MyXMLVisitor::removeTagDescription(std::string_view tag) diff --git a/extensions/Particle3D/src/Particle3D/PU/PUScriptCompiler.cpp b/extensions/Particle3D/src/Particle3D/PU/PUScriptCompiler.cpp index 86673ca1f15b..18598c260909 100644 --- a/extensions/Particle3D/src/Particle3D/PU/PUScriptCompiler.cpp +++ b/extensions/Particle3D/src/Particle3D/PU/PUScriptCompiler.cpp @@ -190,7 +190,7 @@ PUScriptCompiler::~PUScriptCompiler() } tlx::string_map::iterator PUScriptCompiler::compile(const PUConcreteNodeList& nodes, - std::string_view file) + std::string_view file) { if (nodes.empty()) return _compiledScripts.end(); diff --git a/extensions/cocostudio/src/cocostudio/SGUIReader.cpp b/extensions/cocostudio/src/cocostudio/SGUIReader.cpp index 5ae1ee83014d..fabac4375980 100644 --- a/extensions/cocostudio/src/cocostudio/SGUIReader.cpp +++ b/extensions/cocostudio/src/cocostudio/SGUIReader.cpp @@ -1645,10 +1645,10 @@ void WidgetPropertiesReader0300::setPropsForAllCustomWidgetFromJsonDictionary(st GUIReader* guiReader = GUIReader::getInstance(); tlx::string_map* object_map = guiReader->getParseObjectMap(); - Object* object = (*object_map)[classType]; + Object* object = (*object_map)[classType]; tlx::string_map* selector_map = guiReader->getParseCallBackMap(); - SEL_ParseEvent selector = (*selector_map)[classType]; + SEL_ParseEvent selector = (*selector_map)[classType]; if (object && selector) { diff --git a/tests/cpp-tests/Source/NetworkTest/HttpClientTest/HttpClientTest.cpp b/tests/cpp-tests/Source/NetworkTest/HttpClientTest/HttpClientTest.cpp index 70bbe0f0aac7..6cdff1623731 100644 --- a/tests/cpp-tests/Source/NetworkTest/HttpClientTest/HttpClientTest.cpp +++ b/tests/cpp-tests/Source/NetworkTest/HttpClientTest/HttpClientTest.cpp @@ -117,7 +117,7 @@ void HttpClientTest::onMenuGetTestClicked(ax::Object* sender) request->setUrl("https://just-make-this-request-failed.com"); request->setRequestType(HttpRequest::Type::GET); request->setHeaders(std::vector{CHROME_UA}); - request->setResponseCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); request->setTag("GET test2"); HttpClient::getInstance()->send(request); request->release(); @@ -130,7 +130,7 @@ void HttpClientTest::onMenuGetTestClicked(ax::Object* sender) request->setUrl("https://httpbin.org/ip"); request->setRequestType(HttpRequest::Type::GET); request->setHeaders(std::vector{CHROME_UA}); - request->setResponseCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); request->setTag("GET test3"); HttpClient::getInstance()->send(request); // don't forget to release it, pair to new @@ -143,7 +143,7 @@ void HttpClientTest::onMenuGetTestClicked(ax::Object* sender) request->setUrl("https://httpbin.org/get"); request->setRequestType(HttpRequest::Type::GET); request->setHeaders(std::vector{CHROME_UA}); - request->setResponseCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); request->setTag("GET test4"); HttpClient::getInstance()->send(request); request->release(); @@ -155,7 +155,7 @@ void HttpClientTest::onMenuGetTestClicked(ax::Object* sender) request->setUrl("https://github.com/yasio/yasio"); request->setRequestType(HttpRequest::Type::GET); request->setHeaders(std::vector{CHROME_UA}); - request->setResponseCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); request->setTag("GET test5"); HttpClient::getInstance()->send(request); request->release(); @@ -172,7 +172,7 @@ void HttpClientTest::onMenuPatchTestClicked(Object* sender) HttpRequest* request = new HttpRequest(); request->setUrl("https://httpbin.org/patch"); request->setRequestType(HttpRequest::Type::PATCH); - request->setResponseCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); // write the body data const char* bodyData = "visitor=axmol&TestSuite=Extensions Test/NetworkTest"; @@ -190,7 +190,7 @@ void HttpClientTest::onMenuPatchTestClicked(Object* sender) std::vector headers; headers.emplace_back("Content-Type: application/json; charset=utf-8"); request->setHeaders(headers); - request->setResponseCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); // write the post data const char* bodyData = "visitor=axmol&TestSuite=Extensions Test/NetworkTest"; @@ -212,7 +212,7 @@ void HttpClientTest::onMenuPostTestClicked(ax::Object* sender) request->setUrl("https://httpbin.org/post"); request->setRequestType(HttpRequest::Type::POST); request->setHeaders(std::vector{CHROME_UA}); - request->setResponseCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); // write the post data const char* postData = "visitor=axmol&TestSuite=Extensions Test/NetworkTest"; @@ -228,7 +228,7 @@ void HttpClientTest::onMenuPostTestClicked(ax::Object* sender) request->setUrl("https://httpbin.org/post"); request->setRequestType(HttpRequest::Type::POST); request->setHeaders(std::vector{CHROME_UA, "Content-Type: application/json; charset=utf-8"}); - request->setResponseCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); // write the post data const char* postData = "visitor=axmol&TestSuite=Extensions Test/NetworkTest"; @@ -247,7 +247,7 @@ void HttpClientTest::onMenuPostBinaryTestClicked(ax::Object* sender) HttpRequest* request = new HttpRequest(); request->setUrl("https://httpbin.org/post"); request->setRequestType(HttpRequest::Type::POST); - request->setResponseCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); // write the post data char postData[22] = "binary=hello\0\0cocos2d"; // including \0, the strings after \0 should not be cut in response @@ -267,7 +267,7 @@ void HttpClientTest::onMenuPutTestClicked(Object* sender) HttpRequest* request = new HttpRequest(); request->setUrl("https://httpbin.org/put"); request->setRequestType(HttpRequest::Type::PUT); - request->setResponseCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); // write the post data const char* postData = "visitor=axmol&TestSuite=Extensions Test/NetworkTest"; @@ -285,7 +285,7 @@ void HttpClientTest::onMenuPutTestClicked(Object* sender) std::vector headers; headers.emplace_back("Content-Type: application/json; charset=utf-8"); request->setHeaders(headers); - request->setResponseCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); // write the post data const char* postData = "visitor=axmol&TestSuite=Extensions Test/NetworkTest"; @@ -306,7 +306,7 @@ void HttpClientTest::onMenuDeleteTestClicked(Object* sender) HttpRequest* request = new HttpRequest(); request->setUrl("https://just-make-this-request-failed.com"); request->setRequestType(HttpRequest::Type::DELETE); - request->setResponseCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); request->setTag("DELETE test1"); HttpClient::getInstance()->send(request); request->release(); @@ -317,7 +317,7 @@ void HttpClientTest::onMenuDeleteTestClicked(Object* sender) HttpRequest* request = new HttpRequest(); request->setUrl("https://httpbin.org/delete"); request->setRequestType(HttpRequest::Type::DELETE); - request->setResponseCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientTest::onHttpRequestCompleted, this)); request->setTag("DELETE test2"); HttpClient::getInstance()->send(request); request->release(); @@ -420,7 +420,7 @@ void HttpClientClearRequestsTest::onMenuCancelAllClicked(ax::Object* sender) url << "https://axmol.dev/assets/img/logo.png?id=" << std::to_string(i); request->setUrl(url.str()); request->setRequestType(HttpRequest::Type::GET); - request->setResponseCallback(AX_CALLBACK_2(HttpClientClearRequestsTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientClearRequestsTest::onHttpRequestCompleted, this)); url.str(""); url << "TEST_" << std::to_string(i); @@ -449,7 +449,7 @@ void HttpClientClearRequestsTest::onMenuCancelSomeClicked(ax::Object* sender) url << "https://axmol.dev/assets/img/logo.png?id=" << std::to_string(i); request->setUrl(url.str()); request->setRequestType(HttpRequest::Type::GET); - request->setResponseCallback(AX_CALLBACK_2(HttpClientClearRequestsTest::onHttpRequestCompleted, this)); + request->setCompleteCallback(AX_CALLBACK_2(HttpClientClearRequestsTest::onHttpRequestCompleted, this)); url.str(""); if (i < 5) diff --git a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp index 3bd638396fd4..ab4284d9ca92 100644 --- a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp +++ b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp @@ -23,7 +23,8 @@ using my_flat_set = _TLX flat_set<_Tp, std::less<_Tp>, tlx::vector<_Tp>>; template static constexpr bool sequence_container_equals(const _Cont1& c1, const _Cont2& c2) { - static_assert(std::is_same_v, "sequence_container_equals must have same value types"); + static_assert(std::is_same_v, + "sequence_container_equals must have same value types"); return c1.size() == c2.size() && 0 == memcmp(c1.data(), c2.data(), c1.size() * sizeof(typename _Cont1::value_type)); } @@ -161,19 +162,23 @@ TEST_SUITE("tlx/Containers") { static int _dtor_invoke_counter = 0; - struct NonTrivalCtor1 { + struct NonTrivalCtor1 + { int value = 123; }; - struct TrivalCtor1 { + struct TrivalCtor1 + { int value; }; - struct NonTrivialDtor1 { - ~NonTrivialDtor1() { + struct NonTrivialDtor1 + { + ~NonTrivialDtor1() + { ++_dtor_invoke_counter; - if(ptr) - free(ptr); + if (ptr) + free(ptr); } void* ptr; }; @@ -212,7 +217,7 @@ TEST_SUITE("tlx/Containers") CHECK((arr5[10].value == 66 && arr5[22].value == 66)); // shoud report compile error, non trivial dtors types can't use tlx::pod_vector - // tlx::pod_vector arr6; + // tlx::pod_vector arr6; { _dtor_invoke_counter = 0; From e9a3adc8ae44f47640330f13a805511de4173fe5 Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 1 Dec 2025 16:48:59 +0800 Subject: [PATCH 09/17] Fixup --- axmol/network/HttpClient-wasm.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/axmol/network/HttpClient-wasm.cpp b/axmol/network/HttpClient-wasm.cpp index f9878a4c4210..4e03ca7b99ed 100644 --- a/axmol/network/HttpClient-wasm.cpp +++ b/axmol/network/HttpClient-wasm.cpp @@ -273,7 +273,7 @@ void HttpClient::onRequestComplete(emscripten_fetch_t* fetch) if (_httpClient) { // call back - const ccHttpRequestCallback& callback = request->getCallback(); + const auto& callback = request->getCompleteCallback(); if (callback) callback(_httpClient, response); response.reset(); From b010931a00183b647678d6389ce7141c8059bff8 Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 1 Dec 2025 18:45:49 +0800 Subject: [PATCH 10/17] fixup --- 3rdparty/yasio/yasio/tlx/split.hpp | 85 ++++++++++++++++++----------- 3rdparty/yasio/yasio/tlx/vector.hpp | 46 ++++++++++------ 2 files changed, 82 insertions(+), 49 deletions(-) diff --git a/3rdparty/yasio/yasio/tlx/split.hpp b/3rdparty/yasio/yasio/tlx/split.hpp index 7430ca207251..10e8963bcf48 100644 --- a/3rdparty/yasio/yasio/tlx/split.hpp +++ b/3rdparty/yasio/yasio/tlx/split.hpp @@ -46,7 +46,7 @@ SOFTWARE. #include // std::to_address #if defined(__cpp_lib_ranges) -#include +# include #endif #if defined(_MSC_VER) @@ -121,7 +121,7 @@ using element_of_t = typename element_of<_Ty>::type; // element_of_nocvref_t: evaluate element_of on remove_cvref_t<_Ty> // useful for deducing delim/delims types from an input type template -using element_of_nocvref_t = typename element_of>::type; +using element_of_nocvref_t = typename std::remove_cvref_t>>; // ----------------------------- // is_span_of detection @@ -136,48 +136,68 @@ template inline constexpr bool is_span_of_v = is_span_of>::value; // ----------------------------- -// detail implementations +// string_traits // ----------------------------- -namespace detail -{ - template -struct split_traits_base; +struct string_traits_base; // narrow char template <> -struct split_traits_base { - static const char* find_char(const char* s, char delim) { return std::strchr(s, delim); } - static const char* find_any(const char* s, const char* delims) { return std::strpbrk(s, delims); } +struct string_traits_base { + // Unsafe: requires null-terminated input string, since no explicit length is provided + static const char* find(const char* s, char delim) { return std::strchr(s, delim); } + static char* find(char* s, char delim) { return std::strchr(s, delim); } - static char* find_char(char* s, char delim) { return std::strchr(s, delim); } - static char* find_any(char* s, const char* delims) { return std::strpbrk(s, delims); } + static const char* find(const char* s, const char* delim) { return std::strstr(s, delim); } + static char* find(char* s, const char* delim) { return std::strstr(s, delim); } + + static const char* find_first_of(const char* s, const char* delims) { return std::strpbrk(s, delims); } + static char* find_first_of(char* s, const char* delims) { return std::strpbrk(s, delims); } + + // Safe: input string with length + static const char* find(const char* s, size_t n, char delim) { return static_cast(std::memchr(s, n, delim)); } + static char* find(char* s, size_t n, char delim) { return static_cast(std::memchr(s, n, delim)); } }; // wide char template <> -struct split_traits_base { - static const wchar_t* find_char(const wchar_t* s, wchar_t delim) { return std::wcschr(s, delim); } - static const wchar_t* find_any(const wchar_t* s, const wchar_t* delims) { return std::wcspbrk(s, delims); } +struct string_traits_base { + // Unsafe: + static wchar_t* find(wchar_t* s, wchar_t delim) { return std::wcschr(s, delim); } + static const wchar_t* find(const wchar_t* s, wchar_t delim) { return std::wcschr(s, delim); } + + static const wchar_t* find(const wchar_t* s, const wchar_t* delim) { return std::wcsstr(s, delim); } + static wchar_t* find(wchar_t* s, const wchar_t* delim) { return std::wcsstr(s, delim); } + + static const wchar_t* find_first_of(const wchar_t* s, const wchar_t* delims) { return std::wcspbrk(s, delims); } + static wchar_t* find_first_of(wchar_t* s, const wchar_t* delims) { return std::wcspbrk(s, delims); } - static wchar_t* find_char(wchar_t* s, wchar_t delim) { return std::wcschr(s, delim); } - static wchar_t* find_any(wchar_t* s, const wchar_t* delims) { return std::wcspbrk(s, delims); } + // Safe: input string with length + static const wchar_t* find(const wchar_t* s, size_t n, wchar_t delim) { return std::wmemchr(s, n, delim); } + static wchar_t* find(wchar_t* s, size_t n, wchar_t delim) { return std::wmemchr(s, n, delim); } }; template -using split_traits = split_traits_base>; +using string_traits = string_traits_base>; + +// ----------------------------- +// detail implementations +// ----------------------------- +namespace detail +{ // ----------------------------- // split_if implementations // ----------------------------- // pointer version: keep nullptr as end sentinel to avoid strlen +// unsafe stub template inline void split_if(Elem* s, Elem delim, Pred&& pred) { Elem* start = s; Elem* ptr = s; - while ((ptr = split_traits::find_char(ptr, delim))) + while ((ptr = string_traits::find(ptr, delim))) { if (start <= ptr && !pred(start, ptr)) return; @@ -195,7 +215,7 @@ inline void split_if(std::span s, std::remove_cv_t delim, Pred&& pre Elem* start = s.data(); Elem* ptr = start; Elem* end = start + s.size(); - while ((ptr = split_traits::find_char(ptr, delim))) + while ((ptr = string_traits::find(ptr, end - ptr, delim))) { if (ptr >= end) break; @@ -223,13 +243,14 @@ inline void split(std::span s, std::remove_cv_t delim, Fn&& func) // ----------------------------- // pointer version: delims is pointer to (possibly const) char type; end sentinel nullptr +// unsafe stub template inline void split_of_if(Elem* s, const std::remove_cv_t* delims, Pred&& pred) { Elem* start = s; Elem* ptr = s; - Elem delim = *delims; - while ((ptr = split_traits::find_any(ptr, delims))) + auto delim = *delims; + while ((ptr = string_traits::find_first_of(ptr, delims))) { if (start <= ptr) { @@ -245,13 +266,13 @@ inline void split_of_if(Elem* s, const std::remove_cv_t* delims, Pred&& pr // span version: delims is pointer to remove_cv_t template -inline void split_of_if(std::span s, const std::remove_cv_t* delims, Pred&& pred) +inline void split_of_if(std::span s, std::basic_string_view> delims, Pred&& pred) { Elem* start = s.data(); Elem* ptr = start; Elem* end = start + s.size(); - Elem delim = *delims; - while ((ptr = split_traits::find_any(ptr, delims))) + auto delim = *delims.data(); + while ((ptr = std::find_first_of(ptr, end, delims.begin(), delims.end()))) { if (ptr >= end) break; @@ -268,9 +289,9 @@ inline void split_of_if(std::span s, const std::remove_cv_t* delims, pred(start, end, delim); } -// convenience span wrapper (callback style) +// convenience span wrapper (callback style), [delim is string_iew] template -inline void split_of(std::span s, const std::remove_cv_t* delims, Fn&& func) +inline void split_of(std::span s, std::basic_string_view delims, Fn&& func) { split_of_if(s, delims, [func = std::forward(func)](Elem* f, Elem* l, Elem d) { func(f, l, d); @@ -284,9 +305,9 @@ inline void split_of(std::span s, const std::remove_cv_t* delims, Fn // external dispatching helpers // ----------------------------- -// split_if: accept string-like types, pointers, spans +// split_if: accept string-like types, pointers, spans [delim is char] template -inline void split_if(Str&& s, const element_of_nocvref_t delim, Pred&& pred) +inline void split_if(Str&& s, element_of_nocvref_t delim, Pred&& pred) { using Tp = std::remove_cvref_t; @@ -315,7 +336,7 @@ inline void split_if(Str&& s, const element_of_nocvref_t delim, Pred&& pred // split_of_if: similar dispatch template -inline void split_of_if(Str&& s, const element_of_nocvref_t* delims, Pred&& pred) +inline void split_of_if(Str&& s, std::basic_string_view> delims, Pred&& pred) { using Tp = std::remove_cvref_t; @@ -355,7 +376,7 @@ inline void split(Str&& s, const element_of_nocvref_t delim, Fn&& func) } template -inline void split_of(Str&& s, const element_of_nocvref_t* delims, Fn&& func) +inline void split_of(Str&& s, std::basic_string_view> delims, Fn&& func) { split_of_if(std::forward(s), delims, [func = std::forward(func)](auto* first, auto last, auto delim) { func(first, last, delim); @@ -384,7 +405,7 @@ inline void split(Iter first, Iter last, const element_of_nocvref_t delim, } template -inline void split_of(Iter first, Iter last, const element_of_nocvref_t* delims, Fn&& func) +inline void split_of(Iter first, Iter last, std::basic_string_view> delims, Fn&& func) { using Ptr = decltype(std::to_address(first)); using ElemSpan = std::remove_pointer_t>; diff --git a/3rdparty/yasio/yasio/tlx/vector.hpp b/3rdparty/yasio/yasio/tlx/vector.hpp index 152e5d125117..942b14fa23c7 100644 --- a/3rdparty/yasio/yasio/tlx/vector.hpp +++ b/3rdparty/yasio/yasio/tlx/vector.hpp @@ -857,32 +857,44 @@ class vector { // varying size array of values _TLX move_backward_unchecked(_Whereptr, _Oldlast - _Count, _Oldlast); _TLX destroy_range(_Whereptr, _Whereptr + _Count, _Al); - _TLX uninitialized_copy_n(std::move(_First), _Count, _Whereptr, _Al); - // glue the broken pieces back together + try + { + _TLX uninitialized_copy_n(std::move(_First), _Count, _Whereptr, _Al); + } + catch (...) + { + // glue the broken pieces back together - _Vaporization_guard _Guard{this, _Whereptr, _Oldlast, _Whereptr + _Count}; - _TLX uninitialized_move(_Whereptr + _Count, _Whereptr + 2 * _Count, _Whereptr, _Al); - _Guard._Target = nullptr; + _Vaporization_guard _Guard{this, _Whereptr, _Oldlast, _Whereptr + _Count}; + _TLX uninitialized_move(_Whereptr + _Count, _Whereptr + 2 * _Count, _Whereptr, _Al); + _Guard._Target = nullptr; - _TLX move_unchecked(_Whereptr + 2 * _Count, _Mylast, _Whereptr + _Count); - _TLX destroy_range(_Oldlast, _Mylast, _Al); - _Mylast = _Oldlast; + _TLX move_unchecked(_Whereptr + 2 * _Count, _Mylast, _Whereptr + _Count); + _TLX destroy_range(_Oldlast, _Mylast, _Al); + _Mylast = _Oldlast; + throw; + } } else { // affected elements don't overlap before/after const pointer _Relocated = _Whereptr + _Count; _Mylast = _TLX uninitialized_move(_Whereptr, _Oldlast, _Relocated, _Al); _TLX destroy_range(_Whereptr, _Oldlast, _Al); + try + { + _TLX uninitialized_copy_n(std::move(_First), _Count, _Whereptr, _Al); + // glue the broken pieces back together + } + catch (...) + { + _Vaporization_guard _Guard{this, _Whereptr, _Oldlast, _Relocated}; + _TLX uninitialized_move(_Relocated, _Mylast, _Whereptr, _Al); + _Guard._Target = nullptr; - _TLX uninitialized_copy_n(std::move(_First), _Count, _Whereptr, _Al); - // glue the broken pieces back together - - _Vaporization_guard _Guard{this, _Whereptr, _Oldlast, _Relocated}; - _TLX uninitialized_move(_Relocated, _Mylast, _Whereptr, _Al); - _Guard._Target = nullptr; - - _TLX destroy_range(_Relocated, _Mylast, _Al); - _Mylast = _Oldlast; + _TLX destroy_range(_Relocated, _Mylast, _Al); + _Mylast = _Oldlast; + throw; + } } } } From 91ee207a87790825b6585f43194665dbc3fca8db Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 1 Dec 2025 18:48:12 +0800 Subject: [PATCH 11/17] fixup --- 3rdparty/yasio/yasio/tlx/split.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/3rdparty/yasio/yasio/tlx/split.hpp b/3rdparty/yasio/yasio/tlx/split.hpp index 10e8963bcf48..51f718fd8ab0 100644 --- a/3rdparty/yasio/yasio/tlx/split.hpp +++ b/3rdparty/yasio/yasio/tlx/split.hpp @@ -121,7 +121,7 @@ using element_of_t = typename element_of<_Ty>::type; // element_of_nocvref_t: evaluate element_of on remove_cvref_t<_Ty> // useful for deducing delim/delims types from an input type template -using element_of_nocvref_t = typename std::remove_cvref_t>>; +using element_of_nocvref_t = std::remove_cvref_t>>; // ----------------------------- // is_span_of detection From b1fa0e6192312a0350ca851fd9ec5d556194320f Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 1 Dec 2025 19:34:24 +0800 Subject: [PATCH 12/17] fixup --- .../Source/axmol/base/VectorTests.cpp | 2 +- .../Source/axmol/tlx/ContainerTests.cpp | 18 +++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/tests/unit-tests/Source/axmol/base/VectorTests.cpp b/tests/unit-tests/Source/axmol/base/VectorTests.cpp index 91309e6390a3..ed5ce023f618 100644 --- a/tests/unit-tests/Source/axmol/base/VectorTests.cpp +++ b/tests/unit-tests/Source/axmol/base/VectorTests.cpp @@ -226,7 +226,7 @@ TEST_SUITE("base/Vector") // Sort Vector vecForSort = createVector(); - std::sort(vecForSort.begin(), vecForSort.end(), [](Node* a, Node* b) { return a->getTag() >= b->getTag(); }); + std::sort(vecForSort.begin(), vecForSort.end(), [](Node* a, Node* b) { return a->getTag() > b->getTag(); }); for (int i = 0; i < 20; ++i) { diff --git a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp index ab4284d9ca92..9360c6a89980 100644 --- a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp +++ b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp @@ -3,11 +3,17 @@ #include #if __has_include() -# include # include -# define _AX_STL_HAS_FLAT_CONTAINER 1 +# define _AX_STL_HAS_FLAT_MAP 1 +#else +# define _AX_STL_HAS_FLAT_MAP 0 +#endif + +#if __has_include() +# include +# define _AX_STL_HAS_FLAT_SET 1 #else -# define _AX_STL_HAS_FLAT_CONTAINER 0 +# define _AX_STL_HAS_FLAT_SET 0 #endif #include @@ -135,7 +141,7 @@ static void run_benchmark() auto s5 = benchmark_set>("tlx::flat_set", keys); auto s6 = benchmark_set>("my_flat_set", keys); -#if _AX_STL_HAS_FLAT_CONTAINER +#if _AX_STL_HAS_FLAT_SET auto s4 = benchmark_set>("std::flat_set", keys); #endif @@ -143,7 +149,7 @@ static void run_benchmark() auto m2 = benchmark_map>("std::unordered_map", keys); auto m3 = benchmark_map>("tlx::hash_map", keys); auto m5 = benchmark_map>("tlx::flat_map", keys); -#if _AX_STL_HAS_FLAT_CONTAINER +#if _AX_STL_HAS_FLAT_MAP auto m4 = benchmark_map>("std::flat_map", keys); #endif @@ -206,7 +212,9 @@ TEST_SUITE("tlx/Containers") // all extended values shoud preserve uninitialized tlx::pod_vector arr5; arr5.resize(2); +#ifndef __APPLE__ CHECK((arr5[0].value != 0 && arr5[1].value != 0)); +#endif arr5.resize(4, TrivalCtor1{39}); CHECK((arr5[2].value == 39 && arr5[3].value == 39)); From e71c0915e67d4a22fc5a50520e1113a5cb27fe7b Mon Sep 17 00:00:00 2001 From: halx99 Date: Mon, 1 Dec 2025 23:57:41 +0800 Subject: [PATCH 13/17] Fixup --- .../Source/axmol/tlx/ContainerTests.cpp | 84 ++++++++++++++++--- 1 file changed, 74 insertions(+), 10 deletions(-) diff --git a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp index 9360c6a89980..cd8f353abd33 100644 --- a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp +++ b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp @@ -23,6 +23,55 @@ #include "axmol/tlx/flat_set.hpp" #include "axmol/tlx/flat_map.hpp" +#if defined(_WIN32) || defined(_WIN64) + +# define __TRY(SIGID) if (true) +# define __CATCH else +# define __FINALLY if (true) +# define __ENDTRY + +#else // POSIX / Unix-like + +# include +# include + +static thread_local sigjmp_buf __doctest_jumpbuf; + +void __doctest_signal_handler(int sig) +{ + if (sig != SIGKILL) + ::siglongjmp(__doctest_jumpbuf, 1); // jump back to safe point +} + +# define __TRY(sig_num) \ + do \ + { \ + const auto __sig_num = sig_num; \ + struct sigaction sa{}; \ + sa.sa_handler = __doctest_signal_handler; \ + sigemptyset(&sa.sa_mask); \ + sa.sa_flags = 0; \ + sigaction(__sig_num, &sa, nullptr); \ + int __ret = sigsetjmp(__doctest_jumpbuf, 1); \ + if (__ret == 0) + +# define __CATCH else + +# define __FINALLY \ + { \ + struct sigaction sa_default{}; \ + sa_default.sa_handler = SIG_DFL; \ + sigemptyset(&sa_default.sa_mask); \ + sa_default.sa_flags = 0; \ + sigaction(__sig_num, &sa_default, nullptr); \ + } + +# define __ENDTRY \ + } \ + while (0) + +#endif + template using my_flat_set = _TLX flat_set<_Tp, std::less<_Tp>, tlx::vector<_Tp>>; @@ -189,6 +238,8 @@ TEST_SUITE("tlx/Containers") void* ptr; }; + ax::setLogFmtFlag(ax::LogFmtFlag::Full); + tlx::vector arr1; std::string msg = "aaaaaaaaaaaaaafbbbbbbbbbbbbbbbbbcccccccccdfefffffff"; arr1 += msg; @@ -198,24 +249,37 @@ TEST_SUITE("tlx/Containers") arr2.resize(2); CHECK((arr2[0].value == 123 && arr2[1].value == 123 && arr2.size() == 2)); - // pod vector, no auto fill when dtor is trivial - tlx::pod_vector arr3; + // normal vector whti trival ctor types, shoud initialized to zero + tlx::vector arr3; arr3.resize(2); - CHECK((arr3[0].value != 123 && arr3[1].value != 123 && arr3.size() == 2)); + CHECK((arr3[0].value == 0 && arr3[1].value == 0)); - // normal vector whti trival ctor types, shoud initialized to zero - tlx::vector arr4; - arr4.resize(2); - CHECK((arr4[0].value == 0 && arr4[1].value == 0)); + // while, if you run unittest with Xcode debugger, the debugger still raise exception + __TRY(SIGILL) + { + // pod vector, no auto fill when dtor is trivial + tlx::pod_vector arr4; + arr4.resize(2); + CHECK((arr4[0].value != 123 && arr4[1].value != 123 && arr4.size() == 2)); + AXLOGI("Access uninitialzed object membmer done (non optimized build or non-Apple platforms)"); + } + __CATCH + { + AXLOGI("Access uninitialzed object member raise SIGILL (optimized build on Apple platforms)"); + } + __FINALLY + { + ; + } + __ENDTRY; - // pod vector, no auto fill when dtor is trivial - // all extended values shoud preserve uninitialized tlx::pod_vector arr5; arr5.resize(2); + #ifndef __APPLE__ CHECK((arr5[0].value != 0 && arr5[1].value != 0)); #endif - + // we can safe access initialized member without exception catch arr5.resize(4, TrivalCtor1{39}); CHECK((arr5[2].value == 39 && arr5[3].value == 39)); From f05f7754e95be9a918b7665a43d3e10c9e328bba Mon Sep 17 00:00:00 2001 From: halx99 Date: Tue, 2 Dec 2025 01:25:49 +0800 Subject: [PATCH 14/17] Macos sigcheck (#6) * Refactor signal handling in ContainerTests Refactor signal handling macros and improve exception safety in tests. * Fix signal handling in ContainerTests.cpp * Log caught signals in doctest signal handler * fixup --- .../Source/axmol/tlx/ContainerTests.cpp | 72 +++++++++++-------- 1 file changed, 41 insertions(+), 31 deletions(-) diff --git a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp index cd8f353abd33..a18284d4fbee 100644 --- a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp +++ b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp @@ -25,9 +25,9 @@ #if defined(_WIN32) || defined(_WIN64) -# define __TRY(SIGID) if (true) -# define __CATCH else -# define __FINALLY if (true) +# define __TRY if (true) +# define __CATCH else +# define __FINALLY if (true) # define __ENDTRY #else // POSIX / Unix-like @@ -39,31 +39,40 @@ static thread_local sigjmp_buf __doctest_jumpbuf; void __doctest_signal_handler(int sig) { - if (sig != SIGKILL) - ::siglongjmp(__doctest_jumpbuf, 1); // jump back to safe point + AXLOGI("Caught signal: {}", sig); + ::siglongjmp(__doctest_jumpbuf, 1); // jump back to safe point } -# define __TRY(sig_num) \ +# define __TRY \ do \ { \ - const auto __sig_num = sig_num; \ struct sigaction sa{}; \ sa.sa_handler = __doctest_signal_handler; \ sigemptyset(&sa.sa_mask); \ sa.sa_flags = 0; \ - sigaction(__sig_num, &sa, nullptr); \ + for (int i = 1; i < NSIG; ++i) \ + { \ + if (i == SIGKILL || i == SIGSTOP) \ + continue; \ + sigaction(i, &sa, nullptr); \ + } \ int __ret = sigsetjmp(__doctest_jumpbuf, 1); \ if (__ret == 0) # define __CATCH else -# define __FINALLY \ - { \ - struct sigaction sa_default{}; \ - sa_default.sa_handler = SIG_DFL; \ - sigemptyset(&sa_default.sa_mask); \ - sa_default.sa_flags = 0; \ - sigaction(__sig_num, &sa_default, nullptr); \ +# define __FINALLY \ + { \ + struct sigaction sa_default{}; \ + sa_default.sa_handler = SIG_DFL; \ + sigemptyset(&sa_default.sa_mask); \ + sa_default.sa_flags = 0; \ + for (int i = 1; i < NSIG; ++i) \ + { \ + if (i == SIGKILL || i == SIGSTOP) \ + continue; \ + sigaction(i, &sa_default, nullptr); \ + } \ } # define __ENDTRY \ @@ -255,12 +264,28 @@ TEST_SUITE("tlx/Containers") CHECK((arr3[0].value == 0 && arr3[1].value == 0)); // while, if you run unittest with Xcode debugger, the debugger still raise exception - __TRY(SIGILL) + __TRY { // pod vector, no auto fill when dtor is trivial tlx::pod_vector arr4; arr4.resize(2); CHECK((arr4[0].value != 123 && arr4[1].value != 123 && arr4.size() == 2)); + + tlx::pod_vector arr5; + arr5.resize(2); + +#ifndef __APPLE__ + CHECK((arr5[0].value != 0 && arr5[1].value != 0)); +#endif + // we can safe access initialized member without exception catch + arr5.resize(4, TrivalCtor1{39}); + CHECK((arr5[2].value == 39 && arr5[3].value == 39)); + + arr5.resize(128, TrivalCtor1{66}); + CHECK((arr5[2].value == 39 && arr5[3].value == 39)); + + CHECK((arr5[10].value == 66 && arr5[22].value == 66)); + AXLOGI("Access uninitialzed object membmer done (non optimized build or non-Apple platforms)"); } __CATCH @@ -273,21 +298,6 @@ TEST_SUITE("tlx/Containers") } __ENDTRY; - tlx::pod_vector arr5; - arr5.resize(2); - -#ifndef __APPLE__ - CHECK((arr5[0].value != 0 && arr5[1].value != 0)); -#endif - // we can safe access initialized member without exception catch - arr5.resize(4, TrivalCtor1{39}); - CHECK((arr5[2].value == 39 && arr5[3].value == 39)); - - arr5.resize(128, TrivalCtor1{66}); - CHECK((arr5[2].value == 39 && arr5[3].value == 39)); - - CHECK((arr5[10].value == 66 && arr5[22].value == 66)); - // shoud report compile error, non trivial dtors types can't use tlx::pod_vector // tlx::pod_vector arr6; From 7084025d6664ed244d7772fe3a6a522886b8dd28 Mon Sep 17 00:00:00 2001 From: halx99 Date: Tue, 2 Dec 2025 12:14:04 +0800 Subject: [PATCH 15/17] Add split by string delimiter support for tlx::split --- 3rdparty/yasio/yasio/tlx/memory.hpp | 13 +- 3rdparty/yasio/yasio/tlx/split.hpp | 278 ++++++++------ 3rdparty/yasio/yasio/tlx/string.hpp | 18 +- 3rdparty/yasio/yasio/tlx/vector.hpp | 78 +--- tests/unit-tests/CMakeLists.txt | 1 + .../Source/axmol/tlx/SplitTests.cpp | 339 ++++++++++++++++++ 6 files changed, 536 insertions(+), 191 deletions(-) create mode 100644 tests/unit-tests/Source/axmol/tlx/SplitTests.cpp diff --git a/3rdparty/yasio/yasio/tlx/memory.hpp b/3rdparty/yasio/yasio/tlx/memory.hpp index 1ba814f5c7f8..a2c857b2c0cf 100644 --- a/3rdparty/yasio/yasio/tlx/memory.hpp +++ b/3rdparty/yasio/yasio/tlx/memory.hpp @@ -33,6 +33,7 @@ SOFTWARE. #include #include #include +#include #include "yasio/compiler/feature_test.hpp" @@ -450,17 +451,7 @@ constexpr _OutIt copy_n_unchecked4(_InIt first, _SizeTy count, _OutIt dest) } // namespace tlx -#define _TLX_VERIFY_RANGE(cond, mesg) \ - do \ - { \ - if (cond) \ - ; /* contextually convertible to bool paranoia */ \ - else \ - { \ - throw std::out_of_range(mesg); \ - } \ - \ - } while (false) +#define _TLX_VERIFY(cond, mesg) assert(cond && mesg) #define _TLX_INTERNAL_CHECK(cond) assert(cond) diff --git a/3rdparty/yasio/yasio/tlx/split.hpp b/3rdparty/yasio/yasio/tlx/split.hpp index 51f718fd8ab0..7ac175c92579 100644 --- a/3rdparty/yasio/yasio/tlx/split.hpp +++ b/3rdparty/yasio/yasio/tlx/split.hpp @@ -40,10 +40,13 @@ SOFTWARE. #include #include #include -#include // strchr, strpbrk -#include // wcschr, wcspbrk + #include // std::distance -#include // std::to_address +#include + +#include // strchr, strpbrk +#include // wcschr, wcspbrk +#include #if defined(__cpp_lib_ranges) # include @@ -54,6 +57,10 @@ SOFTWARE. # pragma warning(disable : 4706) #endif +#ifndef _TLX_VERIFY +# define _TLX_VERIFY(cond, mesg) assert(cond&& mesg) +#endif + namespace tlx { @@ -145,36 +152,36 @@ struct string_traits_base; template <> struct string_traits_base { // Unsafe: requires null-terminated input string, since no explicit length is provided - static const char* find(const char* s, char delim) { return std::strchr(s, delim); } - static char* find(char* s, char delim) { return std::strchr(s, delim); } + static const char* find(const char* s, char delim) { return ::strchr(s, delim); } + static char* find(char* s, char delim) { return ::strchr(s, delim); } - static const char* find(const char* s, const char* delim) { return std::strstr(s, delim); } - static char* find(char* s, const char* delim) { return std::strstr(s, delim); } + static const char* find(const char* s, const char* delim) { return ::strstr(s, delim); } + static char* find(char* s, const char* delim) { return ::strstr(s, delim); } - static const char* find_first_of(const char* s, const char* delims) { return std::strpbrk(s, delims); } - static char* find_first_of(char* s, const char* delims) { return std::strpbrk(s, delims); } + static const char* find_first_of(const char* s, const char* delims) { return ::strpbrk(s, delims); } + static char* find_first_of(char* s, const char* delims) { return ::strpbrk(s, delims); } // Safe: input string with length - static const char* find(const char* s, size_t n, char delim) { return static_cast(std::memchr(s, n, delim)); } - static char* find(char* s, size_t n, char delim) { return static_cast(std::memchr(s, n, delim)); } + static const char* find(const char* s, size_t n, char delim) { return static_cast(::memchr(s, delim, n)); } + static char* find(char* s, size_t n, char delim) { return static_cast(::memchr(s, delim, n)); } }; // wide char template <> struct string_traits_base { // Unsafe: - static wchar_t* find(wchar_t* s, wchar_t delim) { return std::wcschr(s, delim); } - static const wchar_t* find(const wchar_t* s, wchar_t delim) { return std::wcschr(s, delim); } + static wchar_t* find(wchar_t* s, wchar_t delim) { return ::wcschr(s, delim); } + static const wchar_t* find(const wchar_t* s, wchar_t delim) { return ::wcschr(s, delim); } - static const wchar_t* find(const wchar_t* s, const wchar_t* delim) { return std::wcsstr(s, delim); } - static wchar_t* find(wchar_t* s, const wchar_t* delim) { return std::wcsstr(s, delim); } + static const wchar_t* find(const wchar_t* s, const wchar_t* delim) { return ::wcsstr(s, delim); } + static wchar_t* find(wchar_t* s, const wchar_t* delim) { return ::wcsstr(s, delim); } - static const wchar_t* find_first_of(const wchar_t* s, const wchar_t* delims) { return std::wcspbrk(s, delims); } - static wchar_t* find_first_of(wchar_t* s, const wchar_t* delims) { return std::wcspbrk(s, delims); } + static const wchar_t* find_first_of(const wchar_t* s, const wchar_t* delims) { return ::wcspbrk(s, delims); } + static wchar_t* find_first_of(wchar_t* s, const wchar_t* delims) { return ::wcspbrk(s, delims); } // Safe: input string with length - static const wchar_t* find(const wchar_t* s, size_t n, wchar_t delim) { return std::wmemchr(s, n, delim); } - static wchar_t* find(wchar_t* s, size_t n, wchar_t delim) { return std::wmemchr(s, n, delim); } + static const wchar_t* find(const wchar_t* s, size_t n, wchar_t delim) { return ::wmemchr(s, delim, n); } + static wchar_t* find(wchar_t* s, size_t n, wchar_t delim) { return ::wmemchr(s, delim, n); } }; template @@ -187,55 +194,85 @@ namespace detail { // ----------------------------- -// split_if implementations +// split_until implementations // ----------------------------- -// pointer version: keep nullptr as end sentinel to avoid strlen +// split_until by char // unsafe stub template -inline void split_if(Elem* s, Elem delim, Pred&& pred) +inline void split_until(Elem* s, std::remove_cv_t delim, Pred&& pred) { Elem* start = s; Elem* ptr = s; while ((ptr = string_traits::find(ptr, delim))) { - if (start <= ptr && !pred(start, ptr)) + _TLX_VERIFY(start <= ptr, "tlx::split: out of range"); + if (pred(start, ptr)) return; - start = ptr + 1; - ++ptr; + start = ++ptr; } // end sentinel: nullptr (caller wrapper must accept auto last) pred(start, nullptr); } -// span version: Elem may be const-qualified; delim uses remove_cv_t +// split_until by char +// safe stub template -inline void split_if(std::span s, std::remove_cv_t delim, Pred&& pred) +inline void split_until(std::span s, std::remove_cv_t delim, Pred&& pred) { Elem* start = s.data(); Elem* ptr = start; Elem* end = start + s.size(); while ((ptr = string_traits::find(ptr, end - ptr, delim))) { - if (ptr >= end) - break; - if (start <= ptr && !pred(start, ptr)) + _TLX_VERIFY(start <= ptr, "tlx::split: out of range"); + if (pred(start, ptr)) return; - start = ptr + 1; - ++ptr; + start = ++ptr; } - if (start <= end) - pred(start, end); + _TLX_VERIFY(start <= end, "tlx::split: out of range"); + pred(start, end); } -// convenience span wrapper (callback style) -template -inline void split(std::span s, std::remove_cv_t delim, Fn&& func) +// split_until by string +// unsafe stub +template +inline void split_until(Elem* s, std::basic_string_view> delim, Pred&& pred) { - split_if(s, delim, [func = std::forward(func)](Elem* f, Elem* l) { - func(f, l); - return true; - }); + _TLX_VERIFY(!delim.empty(), "tlx::split: empty delimiter not allowed"); + + auto start = s; // the start of every string + auto ptr = s; // source string iterator + auto dlen = delim.size(); + while ((ptr = string_traits::find(ptr, delim.data()))) + { + _TLX_VERIFY(start <= ptr, "tlx::split: out of range"); + if (pred(start, ptr)) + return; + start = (ptr += dlen); + } + pred(start, nullptr); +} + +// split_until by string +template +inline void split_until(std::span s, std::basic_string_view> delim, Pred&& pred) +{ + _TLX_VERIFY(!delim.empty(), "tlx::split: empty delimiter not allowed"); + + auto start = s.data(); // the start of every string + auto ptr = start; // source string iterator + auto end = start + s.size(); + auto dlen = delim.size(); + while ((ptr = std::search(ptr, end, delim.begin(), delim.end())) != end) + { + _TLX_VERIFY(start <= ptr, "tlx::split: out of range"); + if (pred(start, ptr)) + return; + start = (ptr += dlen); + } + _TLX_VERIFY(start <= end, "tlx::split: out of range"); + pred(start, end); } // ----------------------------- @@ -245,58 +282,44 @@ inline void split(std::span s, std::remove_cv_t delim, Fn&& func) // pointer version: delims is pointer to (possibly const) char type; end sentinel nullptr // unsafe stub template -inline void split_of_if(Elem* s, const std::remove_cv_t* delims, Pred&& pred) +inline void split_of_until(Elem* s, std::basic_string_view> delims, Pred&& pred) { + _TLX_VERIFY(!delims.empty(), "tlx::split_of: empty delimiter not allowed"); + Elem* start = s; Elem* ptr = s; - auto delim = *delims; - while ((ptr = string_traits::find_first_of(ptr, delims))) + auto delim = delims[0]; + while ((ptr = string_traits::find_first_of(ptr, delims.data()))) { - if (start <= ptr) - { - if (!pred(start, ptr, delim)) - return; - delim = *ptr; - } - start = ptr + 1; - ++ptr; + _TLX_VERIFY(start <= ptr, "tlx::split_of: out of range"); + if (pred(start, ptr, delim)) + return; + delim = *ptr; + start = ++ptr; } pred(start, nullptr, delim); } // span version: delims is pointer to remove_cv_t template -inline void split_of_if(std::span s, std::basic_string_view> delims, Pred&& pred) +inline void split_of_until(std::span s, std::basic_string_view> delims, Pred&& pred) { + _TLX_VERIFY(!delims.empty(), "tlx::split_of: empty delimiter not allowed"); + Elem* start = s.data(); Elem* ptr = start; Elem* end = start + s.size(); auto delim = *delims.data(); - while ((ptr = std::find_first_of(ptr, end, delims.begin(), delims.end()))) + while ((ptr = std::find_first_of(ptr, end, delims.begin(), delims.end())) != end) { - if (ptr >= end) - break; - if (start <= ptr) - { - if (!pred(start, ptr, delim)) - return; - delim = *ptr; - } - start = ptr + 1; - ++ptr; + _TLX_VERIFY(start <= ptr, "tlx::split_of: out of range"); + if (pred(start, ptr, delim)) + return; + delim = *ptr; + start = ++ptr; } - if (start <= end) - pred(start, end, delim); -} - -// convenience span wrapper (callback style), [delim is string_iew] -template -inline void split_of(std::span s, std::basic_string_view delims, Fn&& func) -{ - split_of_if(s, delims, [func = std::forward(func)](Elem* f, Elem* l, Elem d) { - func(f, l, d); - return true; - }); + _TLX_VERIFY(start <= end, "tlx::split_of: out of range"); + pred(start, end, delim); } } // namespace detail @@ -305,20 +328,48 @@ inline void split_of(std::span s, std::basic_string_view delims, Fn& // external dispatching helpers // ----------------------------- -// split_if: accept string-like types, pointers, spans [delim is char] +// split_until: accept string-like types, pointers, spans [delim is char] +template +inline void split_until(Str&& s, element_of_nocvref_t delim, Pred&& pred) +{ + using Tp = std::remove_cvref_t; + + if constexpr (std::is_pointer_v) + { + // pointer (char*/wchar_t*) + detail::split_until(s, delim, std::forward(pred)); + } + else if constexpr (is_span_of_v) + { + detail::split_until(s, delim, std::forward(pred)); + } + else if constexpr (is_contiguous_like_v) + { + // Any type that exposes data() and size() (std::string, std::string_view, + // std::basic_string<...>, std::span<...> etc.) + using ElemPtr = decltype(std::declval().data()); // e.g. const char* + using Elem = std::remove_pointer_t; // preserves const + detail::split_until(std::span(s.data(), s.size()), delim, std::forward(pred)); + } + else + { + static_assert(sizeof(Tp) == 0, "Unsupported type for tlx::split_until"); + } +} + template -inline void split_if(Str&& s, element_of_nocvref_t delim, Pred&& pred) +inline void split_until(Str&& s, std::basic_string_view> delim, Pred&& pred) { using Tp = std::remove_cvref_t; if constexpr (std::is_pointer_v) { // pointer (char*/wchar_t*) - detail::split_if(s, delim, std::forward(pred)); + detail::split_until(s, delim, std::forward(pred)); } else if constexpr (is_span_of_v) { - detail::split_if(s, delim, std::forward(pred)); + detail::split_until(s, delim, std::forward(pred)); } else if constexpr (is_contiguous_like_v) { @@ -326,27 +377,27 @@ inline void split_if(Str&& s, element_of_nocvref_t delim, Pred&& pred) // std::basic_string<...>, std::span<...> etc.) using ElemPtr = decltype(std::declval().data()); // e.g. const char* using Elem = std::remove_pointer_t; // preserves const - detail::split_if(std::span(s.data(), s.size()), delim, std::forward(pred)); + detail::split_until(std::span(s.data(), s.size()), delim, std::forward(pred)); } else { - static_assert(sizeof(Tp) == 0, "Unsupported type for tlx::split_if"); + static_assert(sizeof(Tp) == 0, "Unsupported type for tlx::split_until"); } } -// split_of_if: similar dispatch +// split_of_until: similar dispatch template -inline void split_of_if(Str&& s, std::basic_string_view> delims, Pred&& pred) +inline void split_of_until(Str&& s, std::basic_string_view> delims, Pred&& pred) { using Tp = std::remove_cvref_t; if constexpr (std::is_pointer_v) { - detail::split_of_if(s, delims, std::forward(pred)); + detail::split_of_until(s, delims, std::forward(pred)); } else if constexpr (is_span_of_v) { - detail::split_of_if(s, delims, std::forward(pred)); + detail::split_of_until(s, delims, std::forward(pred)); } else if constexpr (is_contiguous_like_v) { @@ -354,11 +405,11 @@ inline void split_of_if(Str&& s, std::basic_string_view, std::span<...> etc.) using ElemPtr = decltype(std::declval().data()); // e.g. const char* using Elem = std::remove_pointer_t; // preserves const - detail::split_of_if(std::span(s.data(), s.size()), delims, std::forward(pred)); + detail::split_of_until(std::span(s.data(), s.size()), delims, std::forward(pred)); } else { - static_assert(sizeof(Tp) == 0, "Unsupported type for tlx::split_of_if"); + static_assert(sizeof(Tp) == 0, "Unsupported type for tlx::split_of_until"); } } @@ -367,20 +418,29 @@ inline void split_of_if(Str&& s, std::basic_string_view -inline void split(Str&& s, const element_of_nocvref_t delim, Fn&& func) +inline void split(Str&& s, element_of_nocvref_t delim, Fn&& func) +{ + split_until(std::forward(s), delim, [func = std::forward(func)](auto* first, auto last) { + func(first, last); + return false; + }); +} + +template +inline void split(Str&& s, std::basic_string_view> delim, Fn&& func) { - split_if(std::forward(s), delim, [func = std::forward(func)](auto* first, auto last) { + split_until(std::forward(s), delim, [func = std::forward(func)](auto* first, auto last) { func(first, last); - return true; + return false; }); } template inline void split_of(Str&& s, std::basic_string_view> delims, Fn&& func) { - split_of_if(std::forward(s), delims, [func = std::forward(func)](auto* first, auto last, auto delim) { + split_of_until(std::forward(s), delims, [func = std::forward(func)](auto* first, auto last, auto delim) { func(first, last, delim); - return true; + return false; }); } @@ -398,9 +458,9 @@ inline void split(Iter first, Iter last, const element_of_nocvref_t delim, auto n = std::distance(first, last); // construct span with element type matching pointer returned by to_address std::span sp(std::to_address(first), static_cast(n)); - detail::split_if(sp, delim, [func = std::forward(func)](ElemSpan* f, ElemSpan* l) { + detail::split_until(sp, delim, [func = std::forward(func)](ElemSpan* f, ElemSpan* l) { func(f, l); - return true; + return false; }); } @@ -411,9 +471,9 @@ inline void split_of(Iter first, Iter last, std::basic_string_view>; auto n = std::distance(first, last); std::span sp(std::to_address(first), static_cast(n)); - detail::split_of_if(sp, delims, [func = std::forward(func)](ElemSpan* f, ElemSpan* l, ElemSpan d) { + detail::split_of_until(sp, delims, [func = std::forward(func)](ElemSpan* f, ElemSpan* l, ElemSpan d) { func(f, l, d); - return true; + return false; }); } @@ -425,30 +485,30 @@ namespace tlx template inline void split_path(_Elem* s, _Pred&& pred, _Fn&& func) { - _Elem* _Start = s; - _Elem* _Ptr = s; - while (pred(_Ptr)) + _Elem* start = s; + _Elem* ptr = s; + while (pred(ptr)) { - if (*_Ptr == _Elem('\\') || *_Ptr == _Elem('/')) + if (*ptr == _Elem('\\') || *ptr == _Elem('/')) { - if (_Ptr != _Start) + if (ptr != start) { - auto _Ch = *_Ptr; - *_Ptr = _Elem('\0'); + auto _Ch = *ptr; + *ptr = _Elem('\0'); bool brk = func(s); #if defined(_WIN32) - *_Ptr = _Elem('\\'); + *ptr = _Elem('\\'); #else - *_Ptr = _Elem('/'); + *ptr = _Elem('/'); #endif if (brk) return; } - _Start = _Ptr + 1; + start = ptr + 1; } - ++_Ptr; + ++ptr; } - if (_Start < _Ptr) + if (start < ptr) func(s); } } // namespace tlx diff --git a/3rdparty/yasio/yasio/tlx/string.hpp b/3rdparty/yasio/yasio/tlx/string.hpp index 2e596dead8e7..2b274c98a4b7 100644 --- a/3rdparty/yasio/yasio/tlx/string.hpp +++ b/3rdparty/yasio/yasio/tlx/string.hpp @@ -149,7 +149,7 @@ class basic_string { { auto& st = _Mypair._Myval2; auto _Mylast = st._Mylast; - _TLX_VERIFY_RANGE(_Where >= st._Myfirst && _Where <= _Mylast && first <= last, "basic_string: out of range!"); + _TLX_VERIFY(_Where >= st._Myfirst && _Where <= _Mylast && first <= last, "basic_string: out of range!"); if (first != last) { auto insertion_pos = static_cast(std::distance(st._Myfirst, _Where)); @@ -180,7 +180,7 @@ class basic_string { { auto& st = _Mypair._Myval2; auto _Mylast = st._Mylast; - _TLX_VERIFY_RANGE(_Where >= st._Myfirst && _Where <= _Mylast, "basic_string: out of range!"); + _TLX_VERIFY(_Where >= st._Myfirst && _Where <= _Mylast, "basic_string: out of range!"); if (count) { auto insertion_pos = std::distance(st._Myfirst, _Where); @@ -243,7 +243,7 @@ class basic_string { { auto& st = _Mypair._Myval2; const auto _Mylast = st._Mylast; - _TLX_VERIFY_RANGE(_Where >= st._Myfirst && _Where < _Mylast, "basic_string: out of range!"); + _TLX_VERIFY(_Where >= st._Myfirst && _Where < _Mylast, "basic_string: out of range!"); st._Mylast = std::move(_Where + 1, _Mylast, _Where); // keep null terminator *_Mylast_ptr() = value_type(0); @@ -254,7 +254,7 @@ class basic_string { { auto& st = _Mypair._Myval2; const auto _Mylast = st._Mylast; - _TLX_VERIFY_RANGE((first <= last) && first >= st._Myfirst && last <= _Mylast, "basic_string: out of range!"); + _TLX_VERIFY((first <= last) && first >= st._Myfirst && last <= _Mylast, "basic_string: out of range!"); st._Mylast = std::move(last, _Mylast, first); // keep null terminator *_Mylast_ptr() = value_type(0); @@ -263,13 +263,13 @@ class basic_string { value_type& front() { - _TLX_VERIFY_RANGE(!empty(), "basic_string: out of range!"); + _TLX_VERIFY(!empty(), "basic_string: out of range!"); return *_Mypair._Myval2._Myfirst; } value_type& back() { - _TLX_VERIFY_RANGE(!empty(), "basic_string: out of range!"); + _TLX_VERIFY(!empty(), "basic_string: out of range!"); return *(_Mypair._Myval2._Mylast - 1); } @@ -299,12 +299,12 @@ class basic_string { reference operator[](size_type index) { return this->at(index); } const_reference at(size_type index) const { - _TLX_VERIFY_RANGE(index < this->size(), "basic_string: out of range!"); + _TLX_VERIFY(index < this->size(), "basic_string: out of range!"); return _Mypair._Myval2._Myfirst[index]; } reference at(size_type index) { - _TLX_VERIFY_RANGE(index < this->size(), "basic_string: out of range!"); + _TLX_VERIFY(index < this->size(), "basic_string: out of range!"); return _Mypair._Myval2._Myfirst[index]; } @@ -448,7 +448,7 @@ class basic_string { my_type& replace(const size_type _Off, size_type _Nx, const _Elem* const _Ptr, const size_type _Count) { // replace port from https://github.com/microsoft/stl auto& st = _Mypair._Myval2; - _TLX_VERIFY_RANGE(_Off < size(), "basic_string: out of range!"); + _TLX_VERIFY(_Off < size(), "basic_string: out of range!"); _Nx = (std::min)(_Nx, size() - _Off); if (_Nx == _Count) { // size doesn't change, so a single move does the trick diff --git a/3rdparty/yasio/yasio/tlx/vector.hpp b/3rdparty/yasio/yasio/tlx/vector.hpp index 942b14fa23c7..926e16963b7b 100644 --- a/3rdparty/yasio/yasio/tlx/vector.hpp +++ b/3rdparty/yasio/yasio/tlx/vector.hpp @@ -658,7 +658,8 @@ class vector { // varying size array of values auto _Whereptr = _Where._Ptr; auto& _My_data = _Mypair._Myval2; auto _Oldlast = _My_data._Mylast; - + _TLX_VERIFY(_Whereptr >= _My_data._Myfirst && _Oldlast >= _Whereptr, + "vector emplace iterator outside range"); if (_Oldlast != _My_data._Myend) { if (_Whereptr == _Oldlast) @@ -709,6 +710,8 @@ class vector { // varying size array of values const pointer _Oldfirst = _My_data._Myfirst; const pointer _Oldlast = _Mylast; + _TLX_VERIFY(_Whereptr >= _Oldfirst && _Oldlast >= _Whereptr, "vector insert iterator outside range"); + const auto _Whereoff = static_cast(_Whereptr - _Oldfirst); const auto _Unused_capacity = static_cast(_My_data._Myend - _Oldlast); const bool _One_at_back = _Count == 1 && _Whereptr == _Oldlast; @@ -935,21 +938,11 @@ class vector { // varying size array of values pointer& _Myfirst = _My_data._Myfirst; pointer& _Mylast = _My_data._Mylast; - constexpr bool _Nothrow_construct = std::is_nothrow_copy_constructible_v<_Ty>; - const auto _Oldcapacity = static_cast(_My_data._Myend - _Myfirst); if (_Newsize > _Oldcapacity) { // reallocate _Clear_and_reserve_geometric(_Newsize); - if constexpr (_Nothrow_construct) - { - _Mylast = _TLX uninitialized_fill_n(_Myfirst, _Newsize, _Val, _Al); - } - else - { - _Mylast = _TLX uninitialized_fill_n(_Myfirst, _Newsize, _Val, _Al); - } - + _Mylast = _TLX uninitialized_fill_n(_Myfirst, _Newsize, _Val, _Al); return; } @@ -957,14 +950,7 @@ class vector { // varying size array of values if (_Newsize > _Oldsize) { std::fill(_Myfirst, _Mylast, _Val); - if constexpr (_Nothrow_construct) - { - _Mylast = _TLX uninitialized_fill_n(_Mylast, _Newsize - _Oldsize, _Val, _Al); - } - else - { - _Mylast = _TLX uninitialized_fill_n(_Mylast, _Newsize - _Oldsize, _Val, _Al); - } + _Mylast = _TLX uninitialized_fill_n(_Mylast, _Newsize - _Oldsize, _Val, _Al); } else { @@ -986,20 +972,11 @@ class vector { // varying size array of values pointer& _Mylast = _My_data._Mylast; pointer& _Myend = _My_data._Myend; - constexpr bool _Nothrow_construct = std::is_nothrow_constructible_v<_Ty, iter_ref_t<_Iter>>; - const auto _Oldcapacity = static_cast(_Myend - _Myfirst); if (_Newsize > _Oldcapacity) { _Clear_and_reserve_geometric(_Newsize); - if constexpr (_Nothrow_construct) - { - _Mylast = _TLX uninitialized_copy_n(std::move(_First), _Newsize, _Myfirst, _Al); - } - else - { - _Mylast = _TLX uninitialized_copy_n(std::move(_First), _Newsize, _Myfirst, _Al); - } + _Mylast = _TLX uninitialized_copy_n(std::move(_First), _Newsize, _Myfirst, _Al); return; } @@ -1025,14 +1002,7 @@ class vector { // varying size array of values } } - if constexpr (_Nothrow_construct) - { - _Mylast = _TLX uninitialized_copy_n(std::move(_First), _Newsize - _Oldsize, _Mylast, _Al); - } - else - { - _Mylast = _TLX uninitialized_copy_n(std::move(_First), _Newsize - _Oldsize, _Mylast, _Al); - } + _Mylast = _TLX uninitialized_copy_n(std::move(_First), _Newsize - _Oldsize, _Mylast, _Al); } else { @@ -1405,12 +1375,14 @@ class vector { // varying size array of values constexpr _Ty& operator[](const size_type _Pos) noexcept /* strengthened */ { auto& _My_data = _Mypair._Myval2; + _TLX_VERIFY(_Pos < static_cast(_My_data._Mylast - _My_data._Myfirst), "vector subscript out of range"); return _My_data._Myfirst[_Pos]; } constexpr const _Ty& operator[](const size_type _Pos) const noexcept /* strengthened */ { auto& _My_data = _Mypair._Myval2; + _TLX_VERIFY(_Pos < static_cast(_My_data._Mylast - _My_data._Myfirst), "vector subscript out of range"); return _My_data._Myfirst[_Pos]; } @@ -1418,9 +1390,7 @@ class vector { // varying size array of values { auto& _My_data = _Mypair._Myval2; if (static_cast(_My_data._Mylast - _My_data._Myfirst) <= _Pos) - { _Xrange(); - } return _My_data._Myfirst[_Pos]; } @@ -1429,9 +1399,7 @@ class vector { // varying size array of values { auto& _My_data = _Mypair._Myval2; if (static_cast(_My_data._Mylast - _My_data._Myfirst) <= _Pos) - { _Xrange(); - } return _My_data._Myfirst[_Pos]; } @@ -1439,24 +1407,28 @@ class vector { // varying size array of values constexpr _Ty& front() noexcept /* strengthened */ { auto& _My_data = _Mypair._Myval2; + _TLX_VERIFY(_My_data._Myfirst != _My_data._Mylast, "front() called on empty vector"); return *_My_data._Myfirst; } constexpr const _Ty& front() const noexcept /* strengthened */ { auto& _My_data = _Mypair._Myval2; + _TLX_VERIFY(_My_data._Myfirst != _My_data._Mylast, "front() called on empty vector"); return *_My_data._Myfirst; } constexpr _Ty& back() noexcept /* strengthened */ { auto& _My_data = _Mypair._Myval2; + _TLX_VERIFY(_My_data._Myfirst != _My_data._Mylast, "back() called on empty vector"); return _My_data._Mylast[-1]; } constexpr const _Ty& back() const noexcept /* strengthened */ { auto& _My_data = _Mypair._Myval2; + _TLX_VERIFY(_My_data._Myfirst != _My_data._Mylast, "back() called on empty vector"); return _My_data._Mylast[-1]; } @@ -1610,21 +1582,11 @@ class vector { // varying size array of values pointer& _Myfirst = _My_data._Myfirst; pointer& _Mylast = _My_data._Mylast; - constexpr bool _Nothrow_construct = std::is_nothrow_move_constructible_v<_Ty>; - const auto _Oldcapacity = static_cast(_My_data._Myend - _Myfirst); if (_Newsize > _Oldcapacity) { _Clear_and_reserve_geometric(_Newsize); - if constexpr (_Nothrow_construct) - { - _Mylast = uninitialized_move(_First, _Last, _Myfirst, _Al); - } - else - { - _Mylast = uninitialized_move(_First, _Last, _Myfirst, _Al); - } - + _Mylast = uninitialized_move(_First, _Last, _Myfirst, _Al); return; } @@ -1633,15 +1595,7 @@ class vector { // varying size array of values { const pointer _Mid = _First + _Oldsize; move_unchecked(_First, _Mid, _Myfirst); - - if constexpr (_Nothrow_construct) - { - _Mylast = uninitialized_move(_Mid, _Last, _Mylast, _Al); - } - else - { - _Mylast = uninitialized_move(_Mid, _Last, _Mylast, _Al); - } + _Mylast = uninitialized_move(_Mid, _Last, _Mylast, _Al); } else { diff --git a/tests/unit-tests/CMakeLists.txt b/tests/unit-tests/CMakeLists.txt index 8abe2798b8ef..b0e97f4f68f7 100644 --- a/tests/unit-tests/CMakeLists.txt +++ b/tests/unit-tests/CMakeLists.txt @@ -51,6 +51,7 @@ set(GAME_SOURCE Source/axmol/ui/UIHelperTests.cpp Source/axmol/tlx/ContainerTests.cpp + Source/axmol/tlx/SplitTests.cpp ) diff --git a/tests/unit-tests/Source/axmol/tlx/SplitTests.cpp b/tests/unit-tests/Source/axmol/tlx/SplitTests.cpp new file mode 100644 index 000000000000..ef1fd655f907 --- /dev/null +++ b/tests/unit-tests/Source/axmol/tlx/SplitTests.cpp @@ -0,0 +1,339 @@ +#include +#include +#include +#include +#include "axmol/tlx/split.hpp" + +// ----------------------------- +// Helpers +// ----------------------------- + +// Collect results using tlx::split (char delimiter) +// Note: call the overload taking Str&& and char, not template hacks. +// using my_char_type = tlx::element_of_nocvref_t; +auto collect_tlx_split_unsafe(const char* s, char delim) +{ + std::vector results; + tlx::split(s, delim, [&](const char* first, const char* last) { + if (last) + results.emplace_back(first, last); + else + results.emplace_back(first); // nullptr means until end + }); + return results; +} +// Collect results using tlx::split (string_view delimiter) +auto collect_tlx_split_safe(std::string_view s, char delim) +{ + std::vector results; + tlx::split(s, delim, [&](const char* first, const char* last) { + if (last) + results.emplace_back(first, last); + else + results.emplace_back(first); + }); + return results; +} + +auto collect_tlx_split_unsafe(const char* s, std::string_view delim) +{ + std::vector results; + tlx::split(s, delim, [&](const char* first, const char* last) { + if (last) + results.emplace_back(first, last); + else + results.emplace_back(first); // nullptr means until end + }); + return results; +} + + +auto collect_tlx_split_safe(std::string_view s, std::string_view delim) +{ + std::vector results; + tlx::split(s, delim, [&](const char* first, const char* last) { + if (last) + results.emplace_back(first, last); + else + results.emplace_back(first); + }); + return results; +} + +// Collect results using tlx::split_of (multiple char delimiters) +auto collect_tlx_split_of_unsafe(const char* s, std::string_view delims) +{ + std::vector results; + tlx::split_of(s, delims, [&](const char* first, const char* last, char /*delim*/) { + if (last) + results.emplace_back(first, last); + else + results.emplace_back(first); + }); + return results; +} + +auto collect_tlx_split_of_safe(std::string_view s, std::string_view delims) +{ + std::vector results; + tlx::split_of(s, delims, [&](const char* first, const char* last, char /*delim*/) { + if (last) + results.emplace_back(first, last); + else + results.emplace_back(first); + }); + return results; +} + +// Collect results using std::views::split (single delimiter) +auto collect_std_split(const std::string& s, char delim) +{ + std::vector results; + for (auto&& sub : s | std::views::split(delim)) + { + results.emplace_back(sub.begin(), sub.end()); + } + return results; +} + +// Collect results using std::views::split (string_view delimiter) +auto collect_std_split_sv(const std::string& s, std::string_view delim) +{ + std::vector results; + for (auto&& sub : s | std::views::split(delim)) + { + results.emplace_back(sub.begin(), sub.end()); + } + return results; +} + +// Simulated std::split_of (multiple delimiters) +auto collect_std_split_of(const std::string& s, std::string_view delims) +{ + std::vector results; + std::string current; + for (char ch : s) + { + if (delims.find(ch) != std::string_view::npos) + { + results.push_back(current); + current.clear(); + } + else + { + current.push_back(ch); + } + } + results.push_back(current); + return results; +} + + +TEST_SUITE("tlx/SplitTests") +{ + + // ----------------------------- + // tlx::split vs std::views::split (char delimiter) + // ----------------------------- + + TEST_CASE("split basic (char delimiter)") + { + + std::string ssss = ""; + char delim = ','; + for (auto&& sub : ssss | std::views::split(delim)) + { + int fuck = 0; + } + + std::string s = "a,b,c"; + auto tlx_res = collect_tlx_split_unsafe(s.c_str(), ','); + auto std_res = collect_std_split(s, ','); + CHECK(tlx_res == std_res); + + tlx_res = collect_tlx_split_safe(s, ','); + CHECK(tlx_res == std_res); + } + + TEST_CASE("split empty input (char delimiter)") + { + std::string s; + auto tlx_res = collect_tlx_split_unsafe(s.c_str(), ','); + auto std_res = collect_std_split(s, ','); + CHECK(tlx_res.size() == 1); + + tlx_res = collect_tlx_split_safe(s, ','); + AXLOGI("c++ std::views::split empty input (char delimiter) subrange count: {}", std_res.size()); + CHECK(tlx_res.size() == 1); + } + + TEST_CASE("split leading delimiter (char delimiter)") + { + std::string s = ",a,b"; + auto tlx_res = collect_tlx_split_unsafe(s.c_str(), ','); + auto std_res = collect_std_split(s, ','); + CHECK(tlx_res == std_res); + + tlx_res = collect_tlx_split_safe(s, ','); + CHECK(tlx_res == std_res); + } + + TEST_CASE("split trailing delimiter (char delimiter)") + { + std::string s = "a,b,"; + auto tlx_res = collect_tlx_split_unsafe(s.c_str(), ','); + auto std_res = collect_std_split(s, ','); + CHECK(tlx_res == std_res); + + tlx_res = collect_tlx_split_safe(s.c_str(), ','); + CHECK(tlx_res == std_res); + } + + TEST_CASE("split consecutive delimiters (char delimiter)") + { + std::string s = "a,,b"; + auto tlx_res = collect_tlx_split_unsafe(s.c_str(), ','); + auto std_res = collect_std_split(s, ','); + CHECK(tlx_res == std_res); + + tlx_res = collect_tlx_split_safe(s, ','); + CHECK(tlx_res == std_res); + } + + // ----------------------------- + // tlx::split vs std::views::split (string_view delimiter) + // ----------------------------- + + TEST_CASE("split basic (string_view delimiter)") + { + std::string s = "a::b::c"; + std::string_view delim = "::"; + auto tlx_res = collect_tlx_split_safe(s, delim); + auto std_res = collect_std_split_sv(s, delim); + CHECK(tlx_res == std_res); + } + + TEST_CASE("split leading delimiter (string_view delimiter)") + { + std::string s = "::a::b"; + std::string_view delim = "::"; + auto tlx_res = collect_tlx_split_safe(s.c_str(), delim); + auto std_res = collect_std_split_sv(s, delim); + CHECK(tlx_res == std_res); + } + + TEST_CASE("split trailing delimiter (string_view delimiter)") + { + std::string s = "a::b::"; + std::string_view delim = "::"; + auto tlx_res = collect_tlx_split_safe(s.c_str(), delim); + auto std_res = collect_std_split_sv(s, delim); + CHECK(tlx_res == std_res); + } + + TEST_CASE("split consecutive delimiters (string_view delimiter)") + { + std::string s = "a::::b"; + std::string_view delim = "::"; + auto tlx_res = collect_tlx_split_safe(s.c_str(), delim); + auto std_res = collect_std_split_sv(s, delim); + CHECK(tlx_res == std_res); + } + + TEST_CASE("split empty input (string_view delimiter)") + { + std::string s; + std::string_view delim = "::"; + auto tlx_res = collect_tlx_split_safe(s.c_str(), delim); + auto std_res = collect_std_split_sv(s, delim); + + AXLOGI("c++ std::views::split empty input (string_view delimiter) subrange count: {}", std_res.size()); + CHECK(tlx_res.size() == 1); + } + + // ----------------------------- + // tlx::split iterator-range overload (char delimiter) vs std::views::split + // ----------------------------- + + TEST_CASE("split iterator range (char delimiter)") + { + std::string s = "x|y|z"; + std::vector tlx_res; + tlx::split(s.begin(), s.end(), '|', [&](const char* f, const char* l) { tlx_res.emplace_back(f, l); }); + auto std_res = collect_std_split(s, '|'); + CHECK(tlx_res == std_res); + } + + // ----------------------------- + // tlx::split_of vs simulated std_split_of (multiple delimiters) + // ----------------------------- + + TEST_CASE("split_of basic multiple delimiters") + { + std::string s = "a,b;c"; + auto tlx_res = collect_tlx_split_of_unsafe(s.c_str(), ",;"); + auto std_res = collect_std_split_of(s, ",;"); + CHECK(tlx_res == std_res); + + tlx_res = collect_tlx_split_of_safe(s, ",;"); + CHECK(tlx_res == std_res); + } + + TEST_CASE("split_of leading delimiter") + { + std::string s = ",a;b"; + auto tlx_res = collect_tlx_split_of_unsafe(s.c_str(), ",;"); + auto std_res = collect_std_split_of(s, ",;"); + CHECK(tlx_res == std_res); + + tlx_res = collect_tlx_split_of_safe(s, ",;"); + CHECK(tlx_res == std_res); + } + + TEST_CASE("split_of trailing delimiter") + { + std::string s = "a;b,"; + auto tlx_res = collect_tlx_split_of_unsafe(s.c_str(), ",;"); + auto std_res = collect_std_split_of(s, ",;"); + CHECK(tlx_res == std_res); + + tlx_res = collect_tlx_split_of_safe(s, ",;"); + CHECK(tlx_res == std_res); + } + + TEST_CASE("split_of consecutive delimiters") + { + std::string s = "a,,;b"; + auto tlx_res = collect_tlx_split_of_unsafe(s.c_str(), ",;"); + auto std_res = collect_std_split_of(s, ",;"); + CHECK(tlx_res == std_res); + + tlx_res = collect_tlx_split_of_safe(s, ",;"); + CHECK(tlx_res == std_res); + } + + TEST_CASE("split_of empty input") + { + std::string s; + auto tlx_res = collect_tlx_split_of_unsafe(s.c_str(), ",;"); + auto std_res = collect_std_split_of(s, ",;"); + CHECK(tlx_res == std_res); + tlx_res = collect_tlx_split_of_safe(s, ",;"); + + CHECK(tlx_res.size() == std_res.size()); + } + + // ----------------------------- + // tlx::split_of iterator-range overload vs simulated std_split_of + // ----------------------------- + + TEST_CASE("split_of iterator range (multiple delimiters)") + { + std::string s = "A,B;C,,;D,"; + std::vector tlx_res; + tlx::split_of(s.begin(), s.end(), std::string_view(",;"), + [&](const char* f, const char* l, char /*delim*/) { tlx_res.emplace_back(f, l); }); + auto std_res = collect_std_split_of(s, ",;"); + CHECK(tlx_res == std_res); + } +} From 84e60f1f73792fb67240986715a0bb19e13e46d7 Mon Sep 17 00:00:00 2001 From: halx99 Date: Tue, 2 Dec 2025 13:34:21 +0800 Subject: [PATCH 16/17] Implement tlx::vector operator== --- 3rdparty/yasio/yasio/tlx/vector.hpp | 34 +++++++++++++++++-- .../Source/axmol/tlx/ContainerTests.cpp | 21 ++++++------ .../Source/axmol/tlx/SplitTests.cpp | 4 +-- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/3rdparty/yasio/yasio/tlx/vector.hpp b/3rdparty/yasio/yasio/tlx/vector.hpp index 926e16963b7b..d130bc613cd7 100644 --- a/3rdparty/yasio/yasio/tlx/vector.hpp +++ b/3rdparty/yasio/yasio/tlx/vector.hpp @@ -658,8 +658,7 @@ class vector { // varying size array of values auto _Whereptr = _Where._Ptr; auto& _My_data = _Mypair._Myval2; auto _Oldlast = _My_data._Mylast; - _TLX_VERIFY(_Whereptr >= _My_data._Myfirst && _Oldlast >= _Whereptr, - "vector emplace iterator outside range"); + _TLX_VERIFY(_Whereptr >= _My_data._Myfirst && _Oldlast >= _Whereptr, "vector emplace iterator outside range"); if (_Oldlast != _My_data._Myend) { if (_Whereptr == _Oldlast) @@ -1616,6 +1615,36 @@ class vector { // varying size array of values __compressed_pair<_Alty, _Scary_val> _Mypair; }; +#pragma region operator== +template +inline constexpr bool operator==(const tlx::vector& lhs, const tlx::vector& rhs) +{ + if (lhs.size() != rhs.size()) + return false; + return std::equal(lhs.begin(), lhs.end(), rhs.begin()); +} + +template ::value && + !std::is_same>::value>> +inline constexpr bool operator==(const tlx::vector& lhs, const OtherContainer& rhs) +{ + if (lhs.size() != rhs.size()) + return false; + return std::equal(lhs.begin(), lhs.end(), rhs.begin()); +} + +template ::value && + !std::is_same>::value>> +inline constexpr bool operator==(const OtherContainer& lhs, const tlx::vector& rhs) +{ + if (lhs.size() != rhs.size()) + return false; + return std::equal(lhs.begin(), lhs.end(), rhs.begin()); +} +#pragma endregion + #pragma region c++20 like std::erase template void erase(vector<_Ty, _Alloc, _Policy>& cont, const _Ty& val) @@ -1664,3 +1693,4 @@ struct pointer_traits<_TLX sequence_iterator<_Myvec>> { static constexpr element_type* to_address(const pointer _Iter) noexcept { return std::to_address(_Iter._Ptr); } }; } // namespace std + diff --git a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp index a18284d4fbee..f389268fe0af 100644 --- a/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp +++ b/tests/unit-tests/Source/axmol/tlx/ContainerTests.cpp @@ -84,14 +84,6 @@ void __doctest_signal_handler(int sig) template using my_flat_set = _TLX flat_set<_Tp, std::less<_Tp>, tlx::vector<_Tp>>; -template -static constexpr bool sequence_container_equals(const _Cont1& c1, const _Cont2& c2) -{ - static_assert(std::is_same_v, - "sequence_container_equals must have same value types"); - return c1.size() == c2.size() && 0 == memcmp(c1.data(), c2.data(), c1.size() * sizeof(typename _Cont1::value_type)); -} - template static auto benchmark_set(const std::string& name, const std::vector& keys) { @@ -214,8 +206,8 @@ static void run_benchmark() std::sort(keys.begin(), keys.end()); keys.erase(std::unique(keys.begin(), keys.end()), keys.end()); - CHECK(sequence_container_equals(keys, s5.keys())); - CHECK(sequence_container_equals(keys, s6.keys())); + CHECK(keys == s5.keys()); + CHECK(keys == s6.keys()); } TEST_SUITE("tlx/Containers") @@ -249,10 +241,17 @@ TEST_SUITE("tlx/Containers") ax::setLogFmtFlag(ax::LogFmtFlag::Full); + std::list list0{'2', '3', '4', '5', 'b'}; + tlx::vector arr0; + arr0.reserve(list0.size()); + for (auto ch : list0) + arr0.emplace_back(ch); + CHECK(arr0 == list0); + tlx::vector arr1; std::string msg = "aaaaaaaaaaaaaafbbbbbbbbbbbbbbbbbcccccccccdfefffffff"; arr1 += msg; - CHECK(sequence_container_equals(arr1, msg)); + CHECK(arr1 == msg); tlx::vector arr2; arr2.resize(2); diff --git a/tests/unit-tests/Source/axmol/tlx/SplitTests.cpp b/tests/unit-tests/Source/axmol/tlx/SplitTests.cpp index ef1fd655f907..51e981d476b5 100644 --- a/tests/unit-tests/Source/axmol/tlx/SplitTests.cpp +++ b/tests/unit-tests/Source/axmol/tlx/SplitTests.cpp @@ -47,7 +47,6 @@ auto collect_tlx_split_unsafe(const char* s, std::string_view delim) return results; } - auto collect_tlx_split_safe(std::string_view s, std::string_view delim) { std::vector results; @@ -128,7 +127,6 @@ auto collect_std_split_of(const std::string& s, std::string_view delims) return results; } - TEST_SUITE("tlx/SplitTests") { @@ -140,7 +138,7 @@ TEST_SUITE("tlx/SplitTests") { std::string ssss = ""; - char delim = ','; + char delim = ','; for (auto&& sub : ssss | std::views::split(delim)) { int fuck = 0; From 595ac040f3e2b8a91fa73c5544e65d606a62b7a9 Mon Sep 17 00:00:00 2001 From: halx99 Date: Tue, 2 Dec 2025 13:54:52 +0800 Subject: [PATCH 17/17] Clean up comments in split.hpp [skip ci] Removed comments regarding the standard split stub of tlx. --- 3rdparty/yasio/yasio/tlx/split.hpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/3rdparty/yasio/yasio/tlx/split.hpp b/3rdparty/yasio/yasio/tlx/split.hpp index 7ac175c92579..41d933dedbdb 100644 --- a/3rdparty/yasio/yasio/tlx/split.hpp +++ b/3rdparty/yasio/yasio/tlx/split.hpp @@ -25,16 +25,6 @@ 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. */ - -/* - * The standard split stub of tlx: - * The pred callback prototype: [](CStr first, CStr last) ->bool{ return true; } - * returns: - * true: want continue split - * false: want end split - * - */ - #pragma once #include