Skip to content

Support free function pointers in glz::custom - #2687

Open
stephenberry wants to merge 1 commit into
mainfrom
free-function-custom
Open

Support free function pointers in glz::custom#2687
stephenberry wants to merge 1 commit into
mainfrom
free-function-custom

Conversation

@stephenberry

Copy link
Copy Markdown
Owner

Resolves #2639

Free functions can now be used with glz::custom, following the same conventions as lambdas: the object is the first argument, the decoded input is the second, and an optional glz::context& third argument enables custom error handling. A free function with a non-void return acts as a getter, so reading decodes into the returned reference and writing serializes the returned value.

struct free_func_counter
{
   int count{};
};

void counter_read(free_func_counter& obj, int val) { obj.count = val; }
int counter_write(const free_func_counter& obj) { return obj.count; }

template <>
struct glz::meta<free_func_counter>
{
   static constexpr auto value = object("count", custom<counter_read, counter_write>);
};

Implementation notes

  • invocable_args_t/invocable_result_t now dispatch through a new invocable_traits_for selector that handles function objects via decltype(&T::operator()) and free function pointers directly. Its primary template is intentionally empty so the aliases remain SFINAE-friendly for other types (e.g. std::function member pointers inspected inside std::enable_if_t conditions), matching the previous alias behavior.
  • is_invocable_concrete is deliberately unchanged (it still means "callable with a concrete operator()"), so the dispatch chains in registry.hpp, cli_menu.hpp, and constraint.hpp are unaffected. The places that support free functions (custom.hpp, custom_meta.hpp, reflect.hpp) opt in explicitly with is_function_ptr_invocable.
  • The custom read dispatch routes non-void concrete callables to the reference-read path instead of a blanket static_assert, so reference-returning free functions (and now concrete lambdas) work as read-side getters.
  • custom_read_input_type recognizes free function setters, enabling variant type deduction and JSON schema generation for them, on par with lambdas.

Tests

New free_function_custom_tests suite in json_test covering: basic free read/write, the glz::context& read and write forms with custom error messages, mixing a free function with a member pointer, string inputs including escape round-tripping, and a reference-returning free function. Also verified compile-compatibility for registry member-function endpoints, registry function-pointer endpoints, whole-value custom over std::function members inside variants and schema generation, and cli_menu structs with multi-argument function pointer members.

Free functions can now be used with glz::custom, following the same
conventions as lambdas: the object is the first argument, the decoded
input is the second, and an optional glz::context& third argument
enables custom error handling. A non-void return acts as a getter,
reading into the returned reference.

- invocable_args_t/invocable_result_t now dispatch through
  invocable_traits_for, which handles function objects via
  decltype(&T::operator()) and free function pointers directly. The
  primary template is empty so the aliases stay SFINAE-friendly for
  other types (e.g. std::function member pointers inspected inside
  std::enable_if_t).
- is_invocable_concrete is unchanged, so registry, cli_menu, and
  constraint dispatch are unaffected; custom.hpp, custom_meta.hpp, and
  reflect.hpp opt into function pointers explicitly via
  is_function_ptr_invocable.
- custom read dispatch routes non-void concrete callables to the
  reference-read path instead of static_asserting, so reference-
  returning free functions and concrete lambdas work as getters.
- custom_read_input_type recognizes free function setters, enabling
  variant deduction and JSON schema generation for them.

Closes #2639
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

Successfully merging this pull request may close these issues.

free functions support for glz::custom

1 participant