Skip to content

Commit

Permalink
Generic supported concepts (#1622)
Browse files Browse the repository at this point in the history
* Generic supported concepts

* Feature test for generic supported concepts

* Comment on built in format range
  • Loading branch information
stephenberry authored Feb 19, 2025
1 parent 680446d commit 34ed711
Show file tree
Hide file tree
Showing 13 changed files with 102 additions and 127 deletions.
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

0 comments on commit 34ed711

Please sign in to comment.