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

Generic supported concepts #1622

Merged
merged 3 commits into from
Feb 19, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions include/glaze/beve/read.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1546,13 +1546,15 @@ namespace glz
};
}

template <read_beve_supported T, class Buffer>
template <class T, class Buffer>
requires (read_supported<BEVE, T>)
[[nodiscard]] inline error_ctx read_beve(T&& value, Buffer&& buffer)
{
return read<opts{.format = BEVE}>(value, std::forward<Buffer>(buffer));
}

template <read_beve_supported T, class Buffer>
template <class T, class Buffer>
requires (read_supported<BEVE, T>)
[[nodiscard]] inline expected<T, error_ctx> read_beve(Buffer&& buffer)
{
T value{};
Expand All @@ -1563,7 +1565,8 @@ namespace glz
return value;
}

template <opts Opts = opts{}, read_beve_supported T>
template <opts Opts = opts{}, class T>
requires (read_supported<BEVE, T>)
[[nodiscard]] inline error_ctx read_file_beve(T& value, const sv file_name, auto&& buffer)
{
context ctx{};
Expand All @@ -1578,14 +1581,16 @@ namespace glz
return read<set_beve<Opts>()>(value, buffer, ctx);
}

template <read_beve_supported T, class Buffer>
template <class T, class Buffer>
requires (read_supported<BEVE, T>)
[[nodiscard]] inline error_ctx read_binary_untagged(T&& value, Buffer&& buffer)
{
return read<opts{.format = BEVE, .structs_as_arrays = true}>(std::forward<T>(value),
std::forward<Buffer>(buffer));
}

template <read_beve_supported T, class Buffer>
template <class T, class Buffer>
requires (read_supported<BEVE, T>)
[[nodiscard]] inline expected<T, error_ctx> read_binary_untagged(Buffer&& buffer)
{
T value{};
Expand All @@ -1596,7 +1601,8 @@ namespace glz
return value;
}

template <opts Opts = opts{}, read_beve_supported T>
template <opts Opts = opts{}, class T>
requires (read_supported<BEVE, T>)
[[nodiscard]] inline error_ctx read_file_beve_untagged(T& value, const std::string& file_name, auto&& buffer)
{
return read_file_beve<opt_true<Opts, &opts::structs_as_arrays>>(value, file_name, buffer);
Expand Down
21 changes: 14 additions & 7 deletions include/glaze/beve/write.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -910,26 +910,30 @@ namespace glz
};
}

template <write_beve_supported T, class Buffer>
template <class T, class Buffer>
requires (write_supported<BEVE, T>)
[[nodiscard]] error_ctx write_beve(T&& value, Buffer&& buffer)
{
return write<opts{.format = BEVE}>(std::forward<T>(value), std::forward<Buffer>(buffer));
}

template <opts Opts = opts{}, write_beve_supported T>
template <opts Opts = opts{}, class T>
requires (write_supported<BEVE, T>)
[[nodiscard]] glz::expected<std::string, error_ctx> write_beve(T&& value)
{
return write<set_beve<Opts>()>(std::forward<T>(value));
}

template <auto& Partial, write_beve_supported T, class Buffer>
template <auto& Partial, class T, class Buffer>
requires (write_supported<BEVE, T>)
[[nodiscard]] error_ctx write_beve(T&& value, Buffer&& buffer)
{
return write<Partial, opts{.format = BEVE}>(std::forward<T>(value), std::forward<Buffer>(buffer));
}

// requires file_name to be null terminated
template <opts Opts = opts{}, write_beve_supported T>
template <opts Opts = opts{}, class T>
requires (write_supported<BEVE, T>)
[[nodiscard]] error_ctx write_file_beve(T&& value, const sv file_name, auto&& buffer)
{
static_assert(sizeof(decltype(*buffer.data())) == 1);
Expand All @@ -951,20 +955,23 @@ namespace glz
return {};
}

template <write_beve_supported T, class Buffer>
template <class T, class Buffer>
requires (write_supported<BEVE, T>)
[[nodiscard]] error_ctx write_beve_untagged(T&& value, Buffer&& buffer)
{
return write<opts{.format = BEVE, .structs_as_arrays = true}>(std::forward<T>(value),
std::forward<Buffer>(buffer));
}

template <write_beve_supported T>
template <class T>
requires (write_supported<BEVE, T>)
[[nodiscard]] error_ctx write_beve_untagged(T&& value)
{
return write<opts{.format = BEVE, .structs_as_arrays = true}>(std::forward<T>(value));
}

template <opts Opts = opts{}, write_beve_supported T>
template <opts Opts = opts{}, class T>
requires (write_supported<BEVE, T>)
[[nodiscard]] error_ctx write_file_beve_untagged(T&& value, const std::string& file_name, auto&& buffer)
{
return write_file_beve<opt_true<Opts, &opts::structs_as_arrays>>(std::forward<T>(value), file_name, buffer);
Expand Down
4 changes: 4 additions & 0 deletions include/glaze/core/feature_test.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@

// Glaze Feature Test Macros

// v5.0.0 moves to more generic read_supported and write_supported concepts
// removes concepts like `read_json_supported` and uses `read_supported<JSON, T>`
#define glaze_v5_0_0_generic_supported

// v4.3.0 removed global glz::trace
#define glaze_v4_3_0_trace

Expand Down
82 changes: 4 additions & 78 deletions include/glaze/core/opts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
namespace glz
{
// format
// Built in formats must be less than 65536
// User defined formats can be 65536 to 4294967296
inline constexpr uint32_t INVALID = 0;
inline constexpr uint32_t BEVE = 1;
inline constexpr uint32_t JSON = 10;
Expand Down Expand Up @@ -341,85 +343,9 @@ namespace glz
struct skip_value;
}

template <class T>
concept write_beve_supported = requires { detail::to<BEVE, std::remove_cvref_t<T>>{}; };

template <class T>
concept read_beve_supported = requires { detail::from<BEVE, std::remove_cvref_t<T>>{}; };

template <class T>
concept write_json_supported = requires { detail::to<JSON, std::remove_cvref_t<T>>{}; };

template <class T>
concept read_json_supported = requires { detail::from<JSON, std::remove_cvref_t<T>>{}; };

template <class T>
concept write_ndjson_supported = requires { detail::to<NDJSON, std::remove_cvref_t<T>>{}; };

template <class T>
concept read_ndjson_supported = requires { detail::from<NDJSON, std::remove_cvref_t<T>>{}; };

template <class T>
concept write_toml_supported = requires { detail::to<TOML, std::remove_cvref_t<T>>{}; };

template <class T>
concept read_toml_supported = requires { detail::from<TOML, std::remove_cvref_t<T>>{}; };

template <class T>
concept write_csv_supported = requires { detail::to<CSV, std::remove_cvref_t<T>>{}; };

template <class T>
concept read_csv_supported = requires { detail::from<CSV, std::remove_cvref_t<T>>{}; };

template <uint32_t Format, class T>
consteval bool write_format_supported()
{
if constexpr (Format == BEVE) {
return write_beve_supported<T>;
}
else if constexpr (Format == JSON) {
return write_json_supported<T>;
}
else if constexpr (Format == NDJSON) {
return write_ndjson_supported<T>;
}
else if constexpr (Format == TOML) {
return write_toml_supported<T>;
}
else if constexpr (Format == CSV) {
return write_csv_supported<T>;
}
else {
static_assert(false_v<T>, "Glaze metadata is probably needed for your type");
}
}

template <uint32_t Format, class T>
consteval bool read_format_supported()
{
if constexpr (Format == BEVE) {
return read_beve_supported<T>;
}
else if constexpr (Format == JSON) {
return read_json_supported<T>;
}
else if constexpr (Format == NDJSON) {
return read_ndjson_supported<T>;
}
else if constexpr (Format == TOML) {
return read_toml_supported<T>;
}
else if constexpr (Format == CSV) {
return read_csv_supported<T>;
}
else {
static_assert(false_v<T>, "Glaze metadata is probably needed for your type");
}
}

template <uint32_t Format, class T>
concept write_supported = write_format_supported<Format, T>();
concept write_supported = requires { detail::to<Format, std::remove_cvref_t<T>>{}; };

template <uint32_t Format, class T>
concept read_supported = read_format_supported<Format, T>();
concept read_supported = requires { detail::from<Format, std::remove_cvref_t<T>>{}; };
}
9 changes: 6 additions & 3 deletions include/glaze/csv/read.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -649,21 +649,24 @@ namespace glz
};
}

template <uint32_t layout = rowwise, read_csv_supported T, class Buffer>
template <uint32_t layout = rowwise, class T, class Buffer>
requires (read_supported<CSV, T>)
[[nodiscard]] inline auto read_csv(T&& value, Buffer&& buffer)
{
return read<opts{.format = CSV, .layout = layout}>(value, std::forward<Buffer>(buffer));
}

template <uint32_t layout = rowwise, read_csv_supported T, class Buffer>
template <uint32_t layout = rowwise, class T, class Buffer>
requires (read_supported<CSV, T>)
[[nodiscard]] inline auto read_csv(Buffer&& buffer)
{
T value{};
read<opts{.format = CSV, .layout = layout}>(value, std::forward<Buffer>(buffer));
return value;
}

template <uint32_t layout = rowwise, read_csv_supported T, is_buffer Buffer>
template <uint32_t layout = rowwise, class T, is_buffer Buffer>
requires (read_supported<CSV, T>)
[[nodiscard]] inline error_ctx read_file_csv(T& value, const sv file_name, Buffer&& buffer)
{
context ctx{};
Expand Down
9 changes: 6 additions & 3 deletions include/glaze/csv/write.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -331,19 +331,22 @@ namespace glz
};
}

template <uint32_t layout = rowwise, write_csv_supported T, class Buffer>
template <uint32_t layout = rowwise, class T, class Buffer>
requires (write_supported<CSV, T>)
[[nodiscard]] auto write_csv(T&& value, Buffer&& buffer)
{
return write<opts{.format = CSV, .layout = layout}>(std::forward<T>(value), std::forward<Buffer>(buffer));
}

template <uint32_t layout = rowwise, write_csv_supported T>
template <uint32_t layout = rowwise, class T>
requires (write_supported<CSV, T>)
[[nodiscard]] expected<std::string, error_ctx> write_csv(T&& value)
{
return write<opts{.format = CSV, .layout = layout}>(std::forward<T>(value));
}

template <uint32_t layout = rowwise, write_csv_supported T>
template <uint32_t layout = rowwise, class T>
requires (write_supported<CSV, T>)
[[nodiscard]] error_ctx write_file_csv(T&& value, const std::string& file_name, auto&& buffer)
{
const auto ec = write<opts{.format = CSV, .layout = layout}>(std::forward<T>(value), buffer);
Expand Down
6 changes: 4 additions & 2 deletions include/glaze/json/json_t.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,8 @@ namespace glz
}
}

template <read_json_supported T>
template <class T>
requires (read_supported<JSON, T>)
[[nodiscard]] error_ctx read_json(T& value, const json_t& source)
{
auto buffer = source.dump();
Expand All @@ -360,7 +361,8 @@ namespace glz
}
}

template <read_json_supported T>
template <class T>
requires (read_supported<JSON, T>)
[[nodiscard]] expected<T, error_ctx> read_json(const json_t& source)
{
auto buffer = source.dump();
Expand Down
18 changes: 12 additions & 6 deletions include/glaze/json/ndjson.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,14 +257,16 @@ namespace glz
};
} // namespace detail

template <read_ndjson_supported T, class Buffer>
template <class T, class Buffer>
requires (read_supported<NDJSON, T>)
[[nodiscard]] auto read_ndjson(T& value, Buffer&& buffer)
{
context ctx{};
return read<opts{.format = NDJSON}>(value, std::forward<Buffer>(buffer), ctx);
}

template <read_ndjson_supported T, class Buffer>
template <class T, class Buffer>
requires (read_supported<NDJSON, T>)
[[nodiscard]] expected<T, error_ctx> read_ndjson(Buffer&& buffer)
{
T value{};
Expand All @@ -276,7 +278,8 @@ namespace glz
return unexpected(ec);
}

template <auto Opts = opts{.format = NDJSON}, read_ndjson_supported T>
template <auto Opts = opts{.format = NDJSON}, class T>
requires (read_supported<NDJSON, T>)
[[nodiscard]] error_ctx read_file_ndjson(T& value, const sv file_name)
{
context ctx{};
Expand All @@ -293,19 +296,22 @@ namespace glz
return read<Opts>(value, buffer, ctx);
}

template <write_ndjson_supported T, class Buffer>
template <class T, class Buffer>
requires (write_supported<NDJSON, T>)
[[nodiscard]] error_ctx write_ndjson(T&& value, Buffer&& buffer)
{
return write<opts{.format = NDJSON}>(std::forward<T>(value), std::forward<Buffer>(buffer));
}

template <write_ndjson_supported T>
template <class T>
requires (write_supported<NDJSON, T>)
[[nodiscard]] expected<std::string, error_ctx> write_ndjson(T&& value)
{
return write<opts{.format = NDJSON}>(std::forward<T>(value));
}

template <write_ndjson_supported T>
template <class T>
requires (write_supported<NDJSON, T>)
[[nodiscard]] error_ctx write_file_ndjson(T&& value, const std::string& file_name, auto&& buffer)
{
write<opts{.format = NDJSON}>(std::forward<T>(value), buffer);
Expand Down
Loading