Skip to content

Commit 3c63466

Browse files
16bit-ykikoclaude
andcommitted
fix(serde): fix MSVC compatibility in alias_storage and struct_info_node
- Nest if constexpr instead of else-if to prevent MSVC from evaluating discarded branch conditions that reference typename field_t::attrs - Use forward-declared struct_info_node with inline static const definition after virtual_schema to avoid MSVC C2737 error Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent c94511a commit 3c63466

File tree

1 file changed

+32
-42
lines changed

1 file changed

+32
-42
lines changed

include/eventide/serde/schema/virtual_schema.h

Lines changed: 32 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -347,43 +347,33 @@ struct unwrap_annotated<T> {
347347
// ===================================================================
348348

349349
template <typename T, std::size_t I>
350+
consteval bool has_alias_attr() {
351+
using field_t = refl::field_type<T, I>;
352+
if constexpr(!serde::has_attrs<field_t>) {
353+
return false;
354+
} else {
355+
return serde::detail::tuple_any_of_v<typename field_t::attrs, serde::is_alias_attr>;
356+
}
357+
}
358+
359+
// Primary template: field has no alias attribute.
360+
template <typename T, std::size_t I, bool HasAlias = has_alias_attr<T, I>()>
350361
struct alias_storage {
351-
constexpr static bool has_alias = [] {
352-
using field_t = refl::field_type<T, I>;
353-
if constexpr(!serde::has_attrs<field_t>) {
354-
return false;
355-
} else {
356-
return serde::detail::tuple_any_of_v<typename field_t::attrs, serde::is_alias_attr>;
357-
}
358-
}();
362+
constexpr static bool has_alias = false;
363+
constexpr static std::size_t count = 0;
364+
constexpr static std::array<std::string_view, 0> names = {};
365+
};
359366

360-
constexpr static std::size_t count = [] {
361-
using field_t = refl::field_type<T, I>;
362-
if constexpr(!serde::has_attrs<field_t>) {
363-
return std::size_t{0};
364-
} else if constexpr(!serde::detail::tuple_any_of_v<typename field_t::attrs,
365-
serde::is_alias_attr>) {
366-
return std::size_t{0};
367-
} else {
368-
using alias_attr =
369-
serde::detail::tuple_find_t<typename field_t::attrs, serde::is_alias_attr>;
370-
return alias_attr::names.size();
371-
}
372-
}();
367+
// Specialization: field has an alias attribute — safe to access field_t::attrs.
368+
template <typename T, std::size_t I>
369+
struct alias_storage<T, I, true> {
370+
constexpr static bool has_alias = true;
373371

374-
constexpr static auto names = [] {
375-
using field_t = refl::field_type<T, I>;
376-
if constexpr(!serde::has_attrs<field_t>) {
377-
return std::array<std::string_view, 0>{};
378-
} else if constexpr(!serde::detail::tuple_any_of_v<typename field_t::attrs,
379-
serde::is_alias_attr>) {
380-
return std::array<std::string_view, 0>{};
381-
} else {
382-
using alias_attr =
383-
serde::detail::tuple_find_t<typename field_t::attrs, serde::is_alias_attr>;
384-
return alias_attr::names;
385-
}
386-
}();
372+
using field_t = refl::field_type<T, I>;
373+
using alias_attr = serde::detail::tuple_find_t<typename field_t::attrs, serde::is_alias_attr>;
374+
375+
constexpr static std::size_t count = alias_attr::names.size();
376+
constexpr static auto names = alias_attr::names;
387377
};
388378

389379
// ===================================================================
@@ -641,12 +631,10 @@ struct enum_values_as_i64 {
641631
}();
642632
};
643633

644-
/// Declaration onlyaddress known, value defined after virtual_schema.
634+
/// Forward declarationfull definition (with initializer) after virtual_schema.
645635
/// Breaks self-referential constexpr cycles via declaration/definition separation.
646636
template <typename V, typename Config>
647-
struct struct_info_node {
648-
const static struct_type_info value;
649-
};
637+
struct struct_info_node;
650638

651639
} // namespace detail
652640

@@ -793,10 +781,12 @@ struct virtual_schema {
793781
namespace detail {
794782

795783
template <typename V, typename Config>
796-
const struct_type_info struct_info_node<V, Config>::value = {
797-
{type_kind::structure, refl::type_name<V>()},
798-
{virtual_schema<V, Config>::fields.data(), virtual_schema<V, Config>::count},
799-
virtual_schema<V, Config>::is_trivially_copyable,
784+
struct struct_info_node {
785+
const inline static struct_type_info value = {
786+
{type_kind::structure, refl::type_name<V>()},
787+
{virtual_schema<V, Config>::fields.data(), virtual_schema<V, Config>::count},
788+
virtual_schema<V, Config>::is_trivially_copyable,
789+
};
800790
};
801791

802792
} // namespace detail

0 commit comments

Comments
 (0)