From 0621bb32bf0284e458ad9a77bfb13460ad61ba66 Mon Sep 17 00:00:00 2001 From: cadons Date: Sun, 30 Aug 2026 22:57:51 +0200 Subject: [PATCH] fix(craft): delete copy ops on classes holding unique_ptr maps MSVC's __declspec(dllexport) (DOCRAFT_LIB, active when DOCRAFT_BUILD_SHARED_LIBS is set) forces instantiation of every public member of an exported class, including implicitly-defined copy constructor/assignment. std::unordered_map>'s own copy assignment isn't SFINAE-disabled based on value_type (a pre-C++20 container quirk), so the implicit copy ops on DocraftLoomTagHandlerRegistry and DocraftCraftLanguageParser were never deleted at the type level -- only broken when actually instantiated. GCC/Clang's static-lib builds never instantiate unused implicit members, so this only surfaces on a Windows/MSVC shared-lib build (error C2679 trying to copy-assign the unique_ptr-valued map). Neither class is ever copied (registry is a singleton; the parser is always used as a local) -- explicitly deleting copy ctor/assignment on both fixes the DLL export instantiation without changing any call site. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_015RjTSLobQWMZq8DcFyDZoG --- docraft/include/docraft/craft/docraft_craft_language_parser.h | 3 +++ .../docraft/loom/craft/docraft_loom_tag_handler_registry.h | 3 +++ 2 files changed, 6 insertions(+) diff --git a/docraft/include/docraft/craft/docraft_craft_language_parser.h b/docraft/include/docraft/craft/docraft_craft_language_parser.h index cbdfb2b..08b0771 100644 --- a/docraft/include/docraft/craft/docraft_craft_language_parser.h +++ b/docraft/include/docraft/craft/docraft_craft_language_parser.h @@ -49,6 +49,9 @@ namespace docraft::craft { ~DocraftCraftLanguageParser() = default; + DocraftCraftLanguageParser(const DocraftCraftLanguageParser&) = delete; + DocraftCraftLanguageParser& operator=(const DocraftCraftLanguageParser&) = delete; + /** * @brief Parses craft language source (a single root element) as a string. * @param craft_language_source XML source as string. diff --git a/docraft/include/docraft/loom/craft/docraft_loom_tag_handler_registry.h b/docraft/include/docraft/loom/craft/docraft_loom_tag_handler_registry.h index 186db06..d4f9eaf 100644 --- a/docraft/include/docraft/loom/craft/docraft_loom_tag_handler_registry.h +++ b/docraft/include/docraft/loom/craft/docraft_loom_tag_handler_registry.h @@ -37,6 +37,9 @@ namespace docraft::loom::craft { public: static DocraftLoomTagHandlerRegistry& instance(); + DocraftLoomTagHandlerRegistry(const DocraftLoomTagHandlerRegistry&) = delete; + DocraftLoomTagHandlerRegistry& operator=(const DocraftLoomTagHandlerRegistry&) = delete; + void register_handler(const std::string& tag, std::unique_ptr handler); /**