From 2e895ded10ed5f5b0d0145f4ac2a29513e7951ce Mon Sep 17 00:00:00 2001 From: sentomk Date: Sat, 20 Sep 2025 18:33:49 +0800 Subject: [PATCH 01/12] fix(core): pass tuple to match_builder::create, not to V constructor --- include/ptn/core/match_builder.hpp | 5 +++++ include/ptn/patternia.hpp | 6 +++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/include/ptn/core/match_builder.hpp b/include/ptn/core/match_builder.hpp index 3f7807e6..313c726b 100644 --- a/include/ptn/core/match_builder.hpp +++ b/include/ptn/core/match_builder.hpp @@ -108,6 +108,11 @@ namespace ptn::core { } public: + template + static constexpr auto create(TV &&v, Tuple &&cs) { + return match_builder( + std::forward(v), std::forward(cs), ctor_tag_t{}); + } // with template constexpr auto with(Pattern p, Handler h) & { diff --git a/include/ptn/patternia.hpp b/include/ptn/patternia.hpp index b46d4823..d83090b7 100644 --- a/include/ptn/patternia.hpp +++ b/include/ptn/patternia.hpp @@ -18,8 +18,8 @@ namespace ptn { constexpr auto match(T &&value) noexcept( std::is_nothrow_constructible_v, T &&>) { using V = std::decay_t; - return core::match_builder( - V(std::forward(value)), std::tuple<>{}, core::ctor_tag{}); + return core::match_builder::create( + V(std::forward(value)), std::tuple<>{}); } }; // namespace ptn @@ -31,7 +31,7 @@ namespace ptn { #if PTN_ENABLE_RELATIONAL_PATTERN // clang-format off -# include +#include // clang-format on #endif From 273640e2c61e5e6f8caa2e72e4825df159b1db54 Mon Sep 17 00:00:00 2001 From: sentomk Date: Sat, 20 Sep 2025 18:56:25 +0800 Subject: [PATCH 02/12] fix(core): make friend match declaration identical to patternia.hpp to avoid noexcept mismatch (clang) --- include/ptn/core/match_builder.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/ptn/core/match_builder.hpp b/include/ptn/core/match_builder.hpp index 313c726b..6d1a8d01 100644 --- a/include/ptn/core/match_builder.hpp +++ b/include/ptn/core/match_builder.hpp @@ -17,9 +17,9 @@ namespace ptn { /* free match function forward declaration */ - template + template constexpr auto - match(U &&) noexcept(std::is_nothrow_constructible_v, U &&>); + match(T &&) noexcept(std::is_nothrow_constructible_v, T &&>); } // namespace ptn namespace ptn::detail { @@ -91,9 +91,9 @@ namespace ptn::core { std::tuple cases_; using ctor_tag_t = ctor_tag; - template - friend constexpr auto ::ptn::match(U &&) noexcept( - std::is_nothrow_constructible_v, U &&>); + template + friend constexpr auto ::ptn::match(T &&) noexcept( + std::is_nothrow_constructible_v, T &&>); /* make all specializations of match_builder mutual friends */ template From ca2b759623b7d6e87ebe48857cb7464b0035cf59 Mon Sep 17 00:00:00 2001 From: sentomk Date: Sat, 20 Sep 2025 19:18:21 +0800 Subject: [PATCH 03/12] fix(core): remove noexcept from friend declaration of ptn::match to avoid exception-spec mismatch (clang) --- include/ptn/core/match_builder.hpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/ptn/core/match_builder.hpp b/include/ptn/core/match_builder.hpp index 6d1a8d01..c7f721d2 100644 --- a/include/ptn/core/match_builder.hpp +++ b/include/ptn/core/match_builder.hpp @@ -92,8 +92,7 @@ namespace ptn::core { using ctor_tag_t = ctor_tag; template - friend constexpr auto ::ptn::match(T &&) noexcept( - std::is_nothrow_constructible_v, T &&>); + friend constexpr auto ::ptn::match(T &&); /* make all specializations of match_builder mutual friends */ template From e724d0950af30fc3b3fc67d6abba50d3fb5b7748 Mon Sep 17 00:00:00 2001 From: sentomk Date: Sat, 20 Sep 2025 19:38:28 +0800 Subject: [PATCH 04/12] fix(core) --- include/ptn/core/match_builder.hpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/include/ptn/core/match_builder.hpp b/include/ptn/core/match_builder.hpp index c7f721d2..daed12c0 100644 --- a/include/ptn/core/match_builder.hpp +++ b/include/ptn/core/match_builder.hpp @@ -90,10 +90,6 @@ namespace ptn::core { TV value_; std::tuple cases_; using ctor_tag_t = ctor_tag; - - template - friend constexpr auto ::ptn::match(T &&); - /* make all specializations of match_builder mutual friends */ template friend class match_builder; @@ -107,10 +103,13 @@ namespace ptn::core { } public: - template - static constexpr auto create(TV &&v, Tuple &&cs) { + template +#if PTN_USE_CONCEPTS + requires std::constructible_from, Tuple> +#endif + static constexpr match_builder create(V &&v, Tuple &&cs) { return match_builder( - std::forward(v), std::forward(cs), ctor_tag_t{}); + std::forward(v), std::forward(cs), ctor_tag{}); } // with template From 38c57d8dd77eaa0945107cc1e82202b1c48a3efd Mon Sep 17 00:00:00 2001 From: sentomk Date: Sat, 20 Sep 2025 19:42:41 +0800 Subject: [PATCH 05/12] fix(core): replace the function-style cast with direct initialization using parentheses (MSVC) --- include/ptn/core/match_builder.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/ptn/core/match_builder.hpp b/include/ptn/core/match_builder.hpp index daed12c0..61df515f 100644 --- a/include/ptn/core/match_builder.hpp +++ b/include/ptn/core/match_builder.hpp @@ -108,7 +108,7 @@ namespace ptn::core { requires std::constructible_from, Tuple> #endif static constexpr match_builder create(V &&v, Tuple &&cs) { - return match_builder( + return match_builder( std::forward(v), std::forward(cs), ctor_tag{}); } // with From 3bc9f403866eda3a58c4082000b86dc6588fa50d Mon Sep 17 00:00:00 2001 From: sentomk Date: Sat, 20 Sep 2025 19:45:23 +0800 Subject: [PATCH 06/12] fix(core): replace the function-style cast with direct initialization using parentheses (MSVC) --- include/ptn/core/match_builder.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/ptn/core/match_builder.hpp b/include/ptn/core/match_builder.hpp index 61df515f..b08519e5 100644 --- a/include/ptn/core/match_builder.hpp +++ b/include/ptn/core/match_builder.hpp @@ -108,8 +108,8 @@ namespace ptn::core { requires std::constructible_from, Tuple> #endif static constexpr match_builder create(V &&v, Tuple &&cs) { - return match_builder( - std::forward(v), std::forward(cs), ctor_tag{}); + return match_builder{ + std::forward(v), std::forward(cs), ctor_tag{}}; } // with template From 90ddc3afc97262655abb0816725adf1ff4009db0 Mon Sep 17 00:00:00 2001 From: sentomk Date: Sat, 20 Sep 2025 20:08:21 +0800 Subject: [PATCH 07/12] fix(core): resolved error C2440: '' --- include/ptn/core/match_builder.hpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/include/ptn/core/match_builder.hpp b/include/ptn/core/match_builder.hpp index b08519e5..fb22a418 100644 --- a/include/ptn/core/match_builder.hpp +++ b/include/ptn/core/match_builder.hpp @@ -5,6 +5,7 @@ #include #include #include +#include #if PTN_USE_CONCEPTS #include @@ -103,13 +104,17 @@ namespace ptn::core { } public: - template + template #if PTN_USE_CONCEPTS requires std::constructible_from, Tuple> #endif - static constexpr match_builder create(V &&v, Tuple &&cs) { - return match_builder{ - std::forward(v), std::forward(cs), ctor_tag{}}; + static constexpr auto create(VArg &&v, Tuple &&cs) + -> ::ptn::core::match_builder, Cases...> { + using result_t = ::ptn::core::match_builder, Cases...>; + return result_t( + std::forward(v), + std::forward(cs), + ::ptn::core::ctor_tag{}); } // with template From d055dd2d62dc5477807f06e76a5894400d4eb275 Mon Sep 17 00:00:00 2001 From: sentomk Date: Sat, 20 Sep 2025 20:12:11 +0800 Subject: [PATCH 08/12] fix(core): resolved error C2440: '' --- include/ptn/core/match_builder.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/ptn/core/match_builder.hpp b/include/ptn/core/match_builder.hpp index fb22a418..59077157 100644 --- a/include/ptn/core/match_builder.hpp +++ b/include/ptn/core/match_builder.hpp @@ -111,10 +111,10 @@ namespace ptn::core { static constexpr auto create(VArg &&v, Tuple &&cs) -> ::ptn::core::match_builder, Cases...> { using result_t = ::ptn::core::match_builder, Cases...>; - return result_t( + return result_t{ std::forward(v), std::forward(cs), - ::ptn::core::ctor_tag{}); + ::ptn::core::ctor_tag{}}; } // with template From 54fc35fef7a3edfb52a62f0c73122bb4a76ca770 Mon Sep 17 00:00:00 2001 From: sentomk Date: Sat, 20 Sep 2025 20:45:15 +0800 Subject: [PATCH 09/12] fix(core): resolved error C2440: '' --- include/ptn/core/match_builder.hpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/ptn/core/match_builder.hpp b/include/ptn/core/match_builder.hpp index 59077157..d2016a64 100644 --- a/include/ptn/core/match_builder.hpp +++ b/include/ptn/core/match_builder.hpp @@ -111,10 +111,9 @@ namespace ptn::core { static constexpr auto create(VArg &&v, Tuple &&cs) -> ::ptn::core::match_builder, Cases...> { using result_t = ::ptn::core::match_builder, Cases...>; - return result_t{ - std::forward(v), - std::forward(cs), - ::ptn::core::ctor_tag{}}; + using cases_t = std::tuple; + using ctor_tag_t = typename result_t::ctor_tag_t; + return result_t(std::forward(v), cases_t{}, ctor_tag_t{}); } // with template From 3118c7384d33fb21cf1e02183ec84ca7dfda166f Mon Sep 17 00:00:00 2001 From: sentomk Date: Sat, 20 Sep 2025 21:00:47 +0800 Subject: [PATCH 10/12] fix(core): resolved error C2440: '' --- include/ptn/core/match_builder.hpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/include/ptn/core/match_builder.hpp b/include/ptn/core/match_builder.hpp index d2016a64..a3bd5d13 100644 --- a/include/ptn/core/match_builder.hpp +++ b/include/ptn/core/match_builder.hpp @@ -90,7 +90,7 @@ namespace ptn::core { class match_builder { TV value_; std::tuple cases_; - using ctor_tag_t = ctor_tag; + using ctor_tag_t = ptn::core::ctor_tag; /* make all specializations of match_builder mutual friends */ template friend class match_builder; @@ -104,17 +104,17 @@ namespace ptn::core { } public: - template #if PTN_USE_CONCEPTS - requires std::constructible_from, Tuple> + requires std::constructible_from, Tuple> #endif - static constexpr auto create(VArg &&v, Tuple &&cs) - -> ::ptn::core::match_builder, Cases...> { - using result_t = ::ptn::core::match_builder, Cases...>; - using cases_t = std::tuple; - using ctor_tag_t = typename result_t::ctor_tag_t; - return result_t(std::forward(v), cases_t{}, ctor_tag_t{}); + template + static constexpr auto create(VArg &&v, Tuple &&cs) + -> match_builder, Cases...> { + using result_t = match_builder, Cases...>; + return result_t{ + std::forward(v), std::forward(cs), ctor_tag{}}; } + // with template constexpr auto with(Pattern p, Handler h) & { From 402cba41712213646206f3fe8eb884027902a2e6 Mon Sep 17 00:00:00 2001 From: sentomk Date: Sat, 20 Sep 2025 21:28:07 +0800 Subject: [PATCH 11/12] fix(msvc): use brace-init in match_builder to avoid initializer-list ambiguity --- include/ptn/core/match_builder.hpp | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/include/ptn/core/match_builder.hpp b/include/ptn/core/match_builder.hpp index a3bd5d13..eecfc0af 100644 --- a/include/ptn/core/match_builder.hpp +++ b/include/ptn/core/match_builder.hpp @@ -104,35 +104,39 @@ namespace ptn::core { } public: + // Correctly place template & requires for create + template #if PTN_USE_CONCEPTS - requires std::constructible_from, Tuple> + requires std::constructible_from, Tuple> #endif - template - static constexpr auto create(VArg &&v, Tuple &&cs) - -> match_builder, Cases...> { + static constexpr auto create(VArg &&v, Tuple &&cs) + -> match_builder, Cases...> { using result_t = match_builder, Cases...>; + // Use brace-init + forward tuple to avoid MSVC initializer-list ambiguity return result_t{ std::forward(v), std::forward(cs), ctor_tag{}}; } - // with + // with (lvalue) template constexpr auto with(Pattern p, Handler h) & { using pair_t = std::pair; auto new_cases = std::tuple_cat( cases_, std::make_tuple(pair_t{std::move(p), std::move(h)})); - return match_builder( - value_, std::move(new_cases), ctor_tag_t{}); + // use brace-init to construct the returned match_builder + return match_builder{ + value_, std::move(new_cases), ctor_tag_t{}}; } + // with (rvalue) template constexpr auto with(Pattern p, Handler h) && { using pair_t = std::pair; auto new_cases = std::tuple_cat( std::move(cases_), std::make_tuple(pair_t{std::move(p), std::move(h)})); - return match_builder( - std::move(value_), std::move(new_cases), ctor_tag_t{}); + return match_builder{ + std::move(value_), std::move(new_cases), ctor_tag_t{}}; } // otherwise @@ -206,4 +210,4 @@ namespace ptn::core { return std::move(*this).with(std::move(e.pattern), std::move(e.handler)); } }; -} // namespace ptn::core \ No newline at end of file +} // namespace ptn::core From a3d18b292765edca026236dea5485870a93de537 Mon Sep 17 00:00:00 2001 From: sentomk Date: Sun, 21 Sep 2025 00:01:50 +0800 Subject: [PATCH 12/12] fix(msvc): use brace-init in match_builder to avoid initializer-list ambiguity --- include/ptn/core/match_builder.hpp | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/include/ptn/core/match_builder.hpp b/include/ptn/core/match_builder.hpp index eecfc0af..20d497f5 100644 --- a/include/ptn/core/match_builder.hpp +++ b/include/ptn/core/match_builder.hpp @@ -95,12 +95,13 @@ namespace ptn::core { template friend class match_builder; - template + template #if PTN_USE_CONCEPTS - requires std::constructible_from, Tuple> + requires std::constructible_from && + std::constructible_from, Tuple> #endif - explicit constexpr match_builder(TV &&v, Tuple &&cs, ctor_tag_t) - : value_(std::forward(v)), cases_(std::forward(cs)) { + explicit constexpr match_builder(TV2 &&v, Tuple &&cs, ctor_tag_t) + : value_(std::forward(v)), cases_(std::forward(cs)) { } public: @@ -112,9 +113,8 @@ namespace ptn::core { static constexpr auto create(VArg &&v, Tuple &&cs) -> match_builder, Cases...> { using result_t = match_builder, Cases...>; - // Use brace-init + forward tuple to avoid MSVC initializer-list ambiguity - return result_t{ - std::forward(v), std::forward(cs), ctor_tag{}}; + return result_t( + std::forward(v), std::forward(cs), ctor_tag{}); } // with (lvalue) @@ -124,8 +124,8 @@ namespace ptn::core { auto new_cases = std::tuple_cat( cases_, std::make_tuple(pair_t{std::move(p), std::move(h)})); // use brace-init to construct the returned match_builder - return match_builder{ - value_, std::move(new_cases), ctor_tag_t{}}; + return match_builder( + value_, std::move(new_cases), ctor_tag_t{}); } // with (rvalue) @@ -135,8 +135,8 @@ namespace ptn::core { auto new_cases = std::tuple_cat( std::move(cases_), std::make_tuple(pair_t{std::move(p), std::move(h)})); - return match_builder{ - std::move(value_), std::move(new_cases), ctor_tag_t{}}; + return match_builder( + std::move(value_), std::move(new_cases), ctor_tag_t{}); } // otherwise @@ -149,7 +149,8 @@ namespace ptn::core { decltype(ptn::detail::run_handler( std::declval &>(), std::declval()))>; R out{}; - bool done = false; + bool done = false; + auto try_one = [&](auto &c) { if (done) return;