Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Advanced Custom serialization? #1543

Closed
iAndyHD3 opened this issue Jan 3, 2025 · 4 comments
Closed

Advanced Custom serialization? #1543

iAndyHD3 opened this issue Jan 3, 2025 · 4 comments

Comments

@iAndyHD3
Copy link

iAndyHD3 commented Jan 3, 2025

I can't get this code to work, I'm probably doing it wrong but I can't figure out what my issue is (according to docs its like this?)

#include <glaze/glaze.hpp>

struct BaseSpecifier {};

struct MyValue : public BaseSpecifier
{
    int something;
};

template <class T> requires std::derived_from<T, BaseSpecifier>
struct glz::meta<T>
{
   static constexpr auto custom_write = true;
};

namespace glz::detail
{
    template <class T> requires std::derived_from<T, BaseSpecifier>
    struct to<JSON, T>
   {
      template <auto Opts>
      static void op(const T& map, auto&&... args) noexcept
      {
        write<JSON>::op<Opts>("test", args...);
      }
   };
}

int main()
{
    MyValue a;
    glz::write_json(a);
}

I get an error saying error: ambiguous template instantiation for 'struct glz::detail::to<10, MyValue>'

https://godbolt.org/z/rEKKWznM9

Also another question, my classes right now are a little bit weird set up, they work somewhat like this:

template<typename T>
struct SomeValue
{
    T value;
}

struct BaseSpecifier {};

struct MyValues : public BaseSpecifier
{
    SomeValue<int> a;
    SomeValue<bool> b;
    SomeValue<std::string> c;

Is it even possible to write an advanced serialization function? I have two ideas, but they are not great:

  • Iterate through all fields and use internal functions to write a map manually, the problem with this is that I have to take care of handling all options which isn't ideal.
  • Iterate through all fields, store them in a giant std::variant that contains all possible types of SomeValue specialization and store them in a std::vector<std::pair<std::string, std::variant>>>. This does work but I have to fix a few issues with creating the variant.

The other obvious option is using the generic object_t and I probably will end up using that

@iAndyHD3
Copy link
Author

iAndyHD3 commented Jan 3, 2025

update: generic object_t works great will probably keep that, but i need a fix for the base specifier thing

@stephenberry
Copy link
Owner

Thanks for bringing up this issue. std::derived_from is just not explicit enough to override the to specialization.

Here's a solution adding glaze_reflect = false; to MyValue: https://godbolt.org/z/6osKWcx71

The reason custom_write isn't working here is that is expects to work with a value defined in the glz::meta. But, this is probably a design flaw in Glaze and can be addressed.

@stephenberry
Copy link
Owner

stephenberry commented Jan 3, 2025

It should be easy to handle:

template<typename T>
struct SomeValue
{
    T value;
}

Here is a meta that should work:

template <class T>
struct glz::meta<SomeValue<T>>
{
   static constexpr auto value = &SomeValue<T>::value; // Tell Glaze to just use the underlying member pointer
};

Now if you write a glz::meta for types that use SomeValue everything should work fine. If SomeValue is aggregate initializable reflection should also work.

@iAndyHD3
Copy link
Author

iAndyHD3 commented Jan 4, 2025

Adding glaze_reflect = false; did indeed work, thanks. I'll reopen the issue if I have any more questions.

@iAndyHD3 iAndyHD3 closed this as completed Jan 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants