88#include < type_traits>
99#include < utility>
1010
11+ #include " ds_mysql/name_reflection.hpp"
1112#include " ds_mysql/sql_temporal.hpp"
1213#include " ds_mysql/varchar_field.hpp"
1314
@@ -24,99 +25,6 @@ struct column_field_tag {};
2425template <typename Tag, typename T>
2526struct column_field ;
2627
27- // ===================================================================
28- // detail::tag_to_column_name<Tag>
29- // ===================================================================
30-
31- namespace detail {
32-
33- template <typename >
34- inline constexpr bool dependent_false_v = false ;
35-
36- /* *
37- * min_find_pos — returns the earlier of two string_view::find() positions.
38- * Treats npos as "not found": if only one is valid it is returned; if neither
39- * is valid npos is returned.
40- */
41- [[nodiscard]] constexpr std::size_t min_find_pos (std::size_t p1, std::size_t p2) noexcept {
42- constexpr auto npos = std::string_view::npos;
43- return (p1 != npos && p2 != npos) ? (p1 < p2 ? p1 : p2) : (p1 != npos ? p1 : p2);
44- }
45-
46- /* *
47- * strip_type_qualifiers — given a raw type-name substring from a compiler
48- * function-signature intrinsic, returns the final unqualified identifier:
49- *
50- * - (MSVC only) strips a leading 'struct ' or 'class ' keyword
51- * - strips any leading namespace/scope qualifier up to the last '::'
52- *
53- * Example inputs → outputs:
54- * "struct `anonymous-namespace'::ticker_tag" → "ticker_tag" (MSVC)
55- * "(anonymous namespace)::ticker_tag" → "ticker_tag" (GCC/Clang)
56- * "child_table_cascade" → "child_table_cascade"
57- */
58- [[nodiscard]] constexpr std::string_view strip_type_qualifiers (std::string_view name) noexcept {
59- #if defined(_MSC_VER)
60- if (name.starts_with (" struct " ))
61- name = name.substr (7 );
62- else if (name.starts_with (" class " ))
63- name = name.substr (6 );
64- #endif
65- auto const scope = name.rfind (" ::" );
66- if (scope != std::string_view::npos && scope + 2 < name.size ())
67- name = name.substr (scope + 2 );
68- return name;
69- }
70-
71- /* *
72- * tag_to_column_name<Tag> — derive a SQL column name from a tag type at compile time.
73- *
74- * Extracts the unqualified type name of Tag and strips a trailing "_tag" suffix:
75- *
76- * tag_to_column_name<id_tag>() → "id"
77- * tag_to_column_name<ticker_tag>() → "ticker"
78- * tag_to_column_name<my_col>() → "my_col"
79- */
80- template <typename Tag>
81- consteval std::string_view tag_to_column_name () noexcept {
82- #if defined(__clang__) || defined(__GNUC__)
83- constexpr std::string_view sig = __PRETTY_FUNCTION__;
84- constexpr std::string_view key = " Tag = " ;
85- #elif defined(_MSC_VER)
86- constexpr std::string_view sig = __FUNCSIG__;
87- constexpr std::string_view key = " tag_to_column_name<" ;
88- #else
89- static_assert (dependent_false_v<Tag>, " tag_to_column_name requires Clang, GCC, or MSVC" );
90- return {};
91- #endif
92- constexpr auto npos = std::string_view::npos;
93- constexpr auto key_pos = sig.find (key);
94- if constexpr (key_pos == npos) {
95- static_assert (dependent_false_v<Tag>, " Failed to parse Tag name from compiler function signature" );
96- return {};
97- }
98- constexpr auto start = key_pos + key.size ();
99- #if defined(_MSC_VER)
100- // MSVC __FUNCSIG__: "...tag_to_column_name<struct `anonymous-namespace'::tag>(void)..."
101- // The tag type ends at '>' (template arg close); '(' is a secondary fallback.
102- constexpr auto end = min_find_pos (sig.find (' >' , start), sig.find (' (' , start));
103- #else
104- constexpr auto end = min_find_pos (sig.find (' ;' , start), sig.find (' ]' , start));
105- #endif
106- if constexpr (end == npos || end <= start) {
107- static_assert (dependent_false_v<Tag>, " Failed to locate end of Tag name in compiler function signature" );
108- return {};
109- }
110- auto name = strip_type_qualifiers (sig.substr (start, end - start));
111- constexpr std::string_view suffix = " _tag" ;
112- if (name.size () > suffix.size () && name.substr (name.size () - suffix.size ()) == suffix) {
113- return name.substr (0 , name.size () - suffix.size ());
114- }
115- return name;
116- }
117-
118- } // namespace detail
119-
12028// ===================================================================
12129// column_field_detail — internal base specializations
12230//
0 commit comments