glaze icon indicating copy to clipboard operation
glaze copied to clipboard

Support std::variant<...,std::variant<...> >

Open shiretu opened this issue 1 year ago • 2 comments

Hi all,

Here is a patch that allows us to support variant of variant, each having tagged keys:

diff --git a/include/glaze/json/read.hpp b/include/glaze/json/read.hpp
index d13ef99..d8b91b8 100644
--- a/include/glaze/json/read.hpp
+++ b/include/glaze/json/read.hpp
@@ -2239,9 +2239,14 @@ namespace glz
                                        [&](auto&& v) {
                                           using V = std::decay_t<decltype(v)>;
                                           constexpr bool is_object = glaze_object_t<V> || reflectable<V>;
-                                          if constexpr (is_object) {
-                                             from_json<V>::template op<opening_handled<Opts>(), tag_literal>(v, ctx, it,
-                                                                                                             end);
+                                          if constexpr (is_variant<V>) {
+                                             from_json<V>::template op<Options>(v, ctx, std::prev(it), end);
+                                          }
+                                          else {
+                                             if constexpr (is_object) {
+                                                from_json<V>::template op<opening_handled<Opts>(), tag_literal>(
+                                                   v, ctx, it, end);
+                                             }
                                           }
                                        },
                                        value);

shiretu avatar Jun 13 '24 15:06 shiretu

More info:

using subscribed = std::variant<subscribed_v4_orderbook, subscribed_v4_subaccounts>;
template <> struct glz::meta<subscribed> {
  static constexpr std::string_view tag = "channel";
  static constexpr auto ids = std::array{"v4_orderbook", "v4_subaccounts"};
};

using ws_message_type = std::variant<connected, subscribed, channel_data>;
template <> struct glz::meta<ws_message_type> {
  static constexpr std::string_view tag = "type";
  static constexpr auto ids = std::array{"connected", "subscribed", "channel_data"};
};

that work properly now: it switches on type and then on channel

shiretu avatar Jun 13 '24 15:06 shiretu

created this PR: https://github.com/stephenberry/glaze/pull/1098 which also includes fixes for issue https://github.com/stephenberry/glaze/issues/1096

shiretu avatar Jun 13 '24 21:06 shiretu

I don't think nested variant support is a good idea. It is better to use glz::generic for these more dynamic cases. A tree of compile time map building feels dangerously complex.

stephenberry avatar Nov 10 '25 04:11 stephenberry