From b78726b6f90b67d1e75db7e3dfb9962a1c5547ae Mon Sep 17 00:00:00 2001 From: Stephen Berry Date: Thu, 6 Feb 2025 13:38:22 -0600 Subject: [PATCH] Separate out opts --- include/glaze/core/opts.hpp | 65 +++++++++++++++++++++++---------- include/glaze/ext/cli_menu.hpp | 8 ++-- include/glaze/json/minify.hpp | 2 +- include/glaze/json/prettify.hpp | 2 +- include/glaze/json/skip.hpp | 8 ++-- include/glaze/util/parse.hpp | 16 ++++---- 6 files changed, 63 insertions(+), 38 deletions(-) diff --git a/include/glaze/core/opts.hpp b/include/glaze/core/opts.hpp index 7b17405764..03b9b025c3 100644 --- a/include/glaze/core/opts.hpp +++ b/include/glaze/core/opts.hpp @@ -49,7 +49,29 @@ namespace glz #define GLZ_NULL_TERMINATED true #endif - struct opts + // Options that Glaze internally manipulates + struct opts_internal + { + enum struct internal : uint32_t { + none = 0, + opening_handled = 1 << 0, // the opening character has been handled + closing_handled = 1 << 1, // the closing character has been handled + ws_handled = 1 << 2, // whitespace has already been parsed + no_header = 1 << 3, // whether or not a binary header is needed + disable_write_unknown = + 1 << 4, // whether to turn off writing unknown fields for a glz::meta specialized for unknown writing + is_padded = 1 << 5, // whether or not the read buffer is padded + disable_padding = 1 << 6, // to explicitly disable padding for contexts like includers + write_unchecked = 1 << 7 // the write buffer has sufficient space and does not need to be checked + }; + // Sufficient space is only applicable to writing certain types and based on the write_padding_bytes + + uint32_t internal{}; // default should be 0 + + [[nodiscard]] constexpr bool operator==(const opts_internal&) const noexcept = default; + }; + + struct opts : opts_internal { // USER CONFIGURABLE uint32_t format = JSON; @@ -96,31 +118,34 @@ namespace glz // glaze_object_t concepts bool_t concatenate = true; // Concatenates ranges of std::pair into single objects when writing + [[nodiscard]] constexpr bool operator==(const opts&) const noexcept = default; + }; + + // Special options for command line interface + struct opts_cli : opts + { bool_t hide_non_invocable = true; // Hides non-invocable members from the cli_menu (may be applied elsewhere in the future) - - enum struct internal : uint32_t { - none = 0, - opening_handled = 1 << 0, // the opening character has been handled - closing_handled = 1 << 1, // the closing character has been handled - ws_handled = 1 << 2, // whitespace has already been parsed - no_header = 1 << 3, // whether or not a binary header is needed - disable_write_unknown = - 1 << 4, // whether to turn off writing unknown fields for a glz::meta specialized for unknown writing - is_padded = 1 << 5, // whether or not the read buffer is padded - disable_padding = 1 << 6, // to explicitly disable padding for contexts like includers - write_unchecked = 1 << 7 // the write buffer has sufficient space and does not need to be checked - }; - // Sufficient space is only applicable to writing certain types and based on the write_padding_bytes - - // INTERNAL USE - uint32_t internal{}; // default should be 0 - - [[nodiscard]] constexpr bool operator==(const opts&) const noexcept = default; + + [[nodiscard]] constexpr bool operator==(const opts_cli&) const noexcept = default; }; #undef bool_t + consteval bool has_comments(auto&& Opts) { + if constexpr (requires { Opts.comments; }) + return Opts.comments; + else + return false; + } + + consteval bool hide_non_invocable(auto&& Opts) { + if constexpr (requires { Opts.hide_non_invocable; }) + return Opts.hide_non_invocable; + else + return true; // defaults to true + } + consteval bool has_opening_handled(opts o) { return o.internal & uint32_t(opts::internal::opening_handled); } consteval bool has_closing_handled(opts o) { return o.internal & uint32_t(opts::internal::closing_handled); } diff --git a/include/glaze/ext/cli_menu.hpp b/include/glaze/ext/cli_menu.hpp index f1a36a247a..11521e4327 100644 --- a/include/glaze/ext/cli_menu.hpp +++ b/include/glaze/ext/cli_menu.hpp @@ -54,7 +54,7 @@ namespace glz } } - template + template requires(detail::glaze_object_t || detail::reflectable) inline void run_cli_menu(T& value, cli_menu_boolean auto& show_menu) { @@ -154,7 +154,7 @@ namespace glz run_cli_menu(v, menu_boolean); } } - else if constexpr (Opts.hide_non_invocable) { + else if constexpr (hide_non_invocable(Opts)) { } else { static_assert(false_v, "Your function is not invocable or not concrete"); @@ -204,7 +204,7 @@ namespace glz else if constexpr (is_invocable_concrete>) { std::printf(" %d %.*s\n", uint32_t(I + 1), int(key.size()), key.data()); } - else if constexpr (Opts.hide_non_invocable) { + else if constexpr (hide_non_invocable(Opts)) { // do not print non-invocable member } else { @@ -251,7 +251,7 @@ namespace glz } } - template + template requires(detail::glaze_object_t || detail::reflectable) inline void run_cli_menu(T& value) { diff --git a/include/glaze/json/minify.hpp b/include/glaze/json/minify.hpp index cbfbab821f..937caaab1d 100644 --- a/include/glaze/json/minify.hpp +++ b/include/glaze/json/minify.hpp @@ -133,7 +133,7 @@ namespace glz break; } case Comment: { - if constexpr (Opts.comments) { + if constexpr (has_comments(Opts)) { const auto value = read_jsonc_comment(it, end); if (value.size()) [[likely]] { dump(value, b, ix); diff --git a/include/glaze/json/prettify.hpp b/include/glaze/json/prettify.hpp index 33b1008d44..974f9d3c1a 100644 --- a/include/glaze/json/prettify.hpp +++ b/include/glaze/json/prettify.hpp @@ -153,7 +153,7 @@ namespace glz break; } case Comment: { - if constexpr (Opts.comments) { + if constexpr (has_comments(Opts)) { const auto value = read_jsonc_comment(it, end); dump_not_empty(value, b, ix); break; diff --git a/include/glaze/json/skip.hpp b/include/glaze/json/skip.hpp index 6f355db120..b00312ddfc 100644 --- a/include/glaze/json/skip.hpp +++ b/include/glaze/json/skip.hpp @@ -11,11 +11,11 @@ namespace glz::detail struct skip_value { template - requires(not Opts.comments) + requires(not has_comments(Opts)) GLZ_ALWAYS_INLINE static void op(is_context auto&& ctx, auto&& it, auto&& end) noexcept; template - requires(bool(Opts.comments)) + requires(has_comments(Opts)) GLZ_ALWAYS_INLINE static void op(is_context auto&& ctx, auto&& it, auto&& end) noexcept; }; @@ -101,7 +101,7 @@ namespace glz::detail } template - requires(not Opts.comments) + requires(not has_comments(Opts)) GLZ_ALWAYS_INLINE void skip_value::op(is_context auto&& ctx, auto&& it, auto&& end) noexcept { if constexpr (not Opts.validate_skipped) { @@ -190,7 +190,7 @@ namespace glz::detail } template - requires(bool(Opts.comments)) + requires(has_comments(Opts)) GLZ_ALWAYS_INLINE void skip_value::op(is_context auto&& ctx, auto&& it, auto&& end) noexcept { if constexpr (not has_ws_handled(Opts)) { diff --git a/include/glaze/util/parse.hpp b/include/glaze/util/parse.hpp index 86c1361913..4814ed5416 100644 --- a/include/glaze/util/parse.hpp +++ b/include/glaze/util/parse.hpp @@ -538,7 +538,7 @@ namespace glz::detail #define GLZ_SKIP_WS(RETURN) \ if constexpr (!Opts.minified) { \ if constexpr (Opts.null_terminated) { \ - if constexpr (Opts.comments) { \ + if constexpr (has_comments(Opts)) { \ while (whitespace_comment_table[uint8_t(*it)]) { \ if (*it == '/') [[unlikely]] { \ skip_comment(ctx, it, end); \ @@ -558,7 +558,7 @@ namespace glz::detail } \ } \ else { \ - if constexpr (Opts.comments) { \ + if constexpr (has_comments(Opts)) { \ while (it < end && whitespace_comment_table[uint8_t(*it)]) { \ if (*it == '/') [[unlikely]] { \ skip_comment(ctx, it, end); \ @@ -593,7 +593,7 @@ namespace glz::detail { if constexpr (!Opts.minified) { if constexpr (Opts.null_terminated) { - if constexpr (Opts.comments) { + if constexpr (has_comments(Opts)) { while (whitespace_comment_table[uint8_t(*it)]) { if (*it == '/') [[unlikely]] { skip_comment(ctx, it, end); @@ -613,7 +613,7 @@ namespace glz::detail } } else { - if constexpr (Opts.comments) { + if constexpr (has_comments(Opts)) { while (it < end && whitespace_comment_table[uint8_t(*it)]) { if (*it == '/') [[unlikely]] { skip_comment(ctx, it, end); @@ -922,7 +922,7 @@ namespace glz::detail } template - requires(has_is_padded(Opts) && not bool(Opts.comments)) + requires(has_is_padded(Opts) && not has_comments(Opts)) GLZ_ALWAYS_INLINE void skip_until_closed(is_context auto&& ctx, auto&& it, auto&& end) noexcept { size_t depth = Depth; @@ -970,7 +970,7 @@ namespace glz::detail } template - requires(has_is_padded(Opts) && bool(Opts.comments)) + requires(has_is_padded(Opts) && has_comments(Opts)) GLZ_ALWAYS_INLINE void skip_until_closed(is_context auto&& ctx, auto&& it, auto&& end) noexcept { size_t depth = Depth; @@ -1025,7 +1025,7 @@ namespace glz::detail } template - requires(!has_is_padded(Opts) && not bool(Opts.comments)) + requires(!has_is_padded(Opts) && not has_comments(Opts)) GLZ_ALWAYS_INLINE void skip_until_closed(is_context auto&& ctx, auto&& it, auto&& end) noexcept { size_t depth = Depth; @@ -1109,7 +1109,7 @@ namespace glz::detail } template - requires(!has_is_padded(Opts) && bool(Opts.comments)) + requires(!has_is_padded(Opts) && has_comments(Opts)) GLZ_ALWAYS_INLINE void skip_until_closed(is_context auto&& ctx, auto&& it, auto&& end) noexcept { size_t depth = Depth;