-
Notifications
You must be signed in to change notification settings - Fork 124
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
implement skip writing out default #1438
base: main
Are you sure you want to change the base?
implement skip writing out default #1438
Conversation
This is awesome! Thanks for tackling this desired feature of skipping default values. I look forward to merging this, but I want to walk through the code changes carefully first. But, your changes look great! I don't think I want to make a breaking change at this point (so I appreciate your approach), but I'll open a discussion for Glaze v5 for breaking changes that would be helpful for clarity. |
I am glad you like it. However, from the github action run , there is a race condition in repe_test which I don't think is introduced by my change. You may need to tackle it. |
@huangminghuang, yes I saw that race condition recently and need to tackle it. It's not from your code. |
@huangminghuang, I just made a change to your pull request that allocates a Now, we should be able to avoid the |
One other aspect of this pull request that we might want to change is the behavior of the This requires some more work, but I think it will be worth it in the long run. If you don't feel comfortable tackling this, I can work on it when I have time. But, it would be great if you were able to mimic the behavior of the other options and get global behavior working. |
struct deduct_default_t | ||
{}; | ||
|
||
template <auto MemPtr, auto Default, class T> | ||
bool is_default(const T& val) | ||
{ | ||
if constexpr (std::same_as<std::decay_t<decltype(Default)>, deduct_default_t>) { | ||
return val.*MemPtr == T{}.*MemPtr; | ||
static thread_local auto defaulted = T{}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe the thread_local
is unnecessary because C++ requires static variable initialization to be thread safe since C++11. The statement might be better as follows.
static const auto defaulted = T{}.*MemPtr;
return val.*MemPtr == defaulted;
I expected the compiler can be smart enough not to construct unused data members this way; however, based on my experiment on compiler explorer, no compiler can do that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are correct, because we aren't changing state, we can have a single, global static variable. I'm just used to requiring thread_local
for mutation. We can also make it const
.
I think we should consider the semantic carefully about this. The current design is to use |
I agree, any general option for skipping defaults would need an opt-out option, like you've noted with glz::custom. |
Motivation
The primary goal of this feature is to mimic protobuf behavior, where fields with default values are omitted from the wire format. Additionally, a new printout option allows users to override this behavior if they wish to include fields with default values. To support this flexibility, the
skip_null_members flag
in Opts has been redefined as a bitmask, allowing independent control over skipping null and default values.Key Changes
custom
Wrapper: Thecustom
wrapper now enables users to define a function that determines whether a field should be omitted based on specific conditions. An associated bitmask has been introduced to allow compile-time checks, which control whether user-defined functions should be evaluated based on theOpts::skip_null_members
setting during serialization.skip_write_default
Wrapper: Askip_write_default
wrapper provides a concise way to skip fields with default values, streamlining the setup for this common use case.Note
This feature can be used to resolve IS #1410