From d306698600507674c4c9b79d62d4e2841659fbde Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Fri, 23 May 2025 10:04:43 +0200 Subject: [PATCH 1/3] Fix order of types in README --- types/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/types/README.md b/types/README.md index 0d8d046..5a12b00 100644 --- a/types/README.md +++ b/types/README.md @@ -1,8 +1,8 @@ # Types * [`fundamental`](fundamental): fundamental column types - * [`optional`](optional): `std::optional` with different element types * [`multiset`](multiset): `std::multiset` with all `[Split]Index{32,64}` column types + * [`optional`](optional): `std::optional` with different element types * [`set`](set): `std::set` with all `[Split]Index{32,64}` column types * [`string`](string): `std::string` with all `[Split]Index{32,64}` column types * [`unique_ptr`](unique_ptr): `std::unique_ptr` with different element types From 595cb6b934e8594edc01991b17d7e4dd3afc0b0b Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Fri, 2 May 2025 10:42:07 +0200 Subject: [PATCH 2/3] Add test for std::pair Closes #17 --- types/README.md | 1 + types/pair/README.md | 15 +++++ types/pair/read.C | 133 +++++++++++++++++++++++++++++++++++++++++++ types/pair/write.C | 50 ++++++++++++++++ 4 files changed, 199 insertions(+) create mode 100644 types/pair/README.md create mode 100644 types/pair/read.C create mode 100644 types/pair/write.C diff --git a/types/README.md b/types/README.md index 5a12b00..7acf3b7 100644 --- a/types/README.md +++ b/types/README.md @@ -3,6 +3,7 @@ * [`fundamental`](fundamental): fundamental column types * [`multiset`](multiset): `std::multiset` with all `[Split]Index{32,64}` column types * [`optional`](optional): `std::optional` with different element types + * [`pair`](pair): `std::pair` with different element types * [`set`](set): `std::set` with all `[Split]Index{32,64}` column types * [`string`](string): `std::string` with all `[Split]Index{32,64}` column types * [`unique_ptr`](unique_ptr): `std::unique_ptr` with different element types diff --git a/types/pair/README.md b/types/pair/README.md new file mode 100644 index 0000000..a32cff1 --- /dev/null +++ b/types/pair/README.md @@ -0,0 +1,15 @@ +# `std::pair` + +## Fields + + * `Int32_String`: `std::pair` + * `Variant_Vector`: `std::pair, std::vector>` + * `Pair`: `std::pair, std::int32_t>` + * `VectorPair`: `std::vector>` + +with the default column types. + +## Entries + +1. Simple values +2. Zero / empty values diff --git a/types/pair/read.C b/types/pair/read.C new file mode 100644 index 0000000..ab5e2b4 --- /dev/null +++ b/types/pair/read.C @@ -0,0 +1,133 @@ +#include +#include + +using ROOT::Experimental::REntry; +using ROOT::Experimental::RNTupleReader; + +#include +#include +#include +#include +#include +#include +#include +#include + +using Pair_Int32_String = std::pair; +using Variant = std::variant; +using VectorInt32 = std::vector; + +template static void PrintValue(const T &value, std::ostream &os); + +template <> void PrintValue(const std::int32_t &value, std::ostream &os) { + os << value; +} + +template <> void PrintValue(const std::string &value, std::ostream &os) { + os << "\"" << value << "\""; +} + +template <> void PrintValue(const Variant &value, std::ostream &os) { + if (value.index() == 0) { + PrintValue(std::get(value), os); + } else if (value.index() == 1) { + PrintValue(std::get(value), os); + } +} + +template <> void PrintValue(const VectorInt32 &value, std::ostream &os) { + os << "["; + bool first = true; + for (auto element : value) { + if (first) { + first = false; + } else { + os << ","; + } + os << "\n " << element; + } + if (!value.empty()) { + os << "\n "; + } + os << "]"; +} + +template <> void PrintValue(const Pair_Int32_String &value, std::ostream &os) { + os << "[\n"; + os << " " << value.first << ",\n"; + os << " \"" << value.second << "\"\n"; + os << " ]"; +} + +template +static void PrintPairValue(const REntry &entry, std::string_view name, + std::ostream &os, bool last = false) { + auto &value = *entry.GetPtr>(name); + os << " \"" << name << "\": [\n"; + os << " "; + PrintValue(value.first, os); + os << ",\n"; + os << " "; + PrintValue(value.second, os); + os << "\n"; + os << " ]"; + if (!last) { + os << ","; + } + os << "\n"; +} + +static void PrintVectorPairValue(const REntry &entry, std::string_view name, + std::ostream &os, bool last = false) { + auto &value = *entry.GetPtr>(name); + os << " \"" << name << "\": ["; + bool first = true; + for (auto &&element : value) { + if (first) { + first = false; + } else { + os << ","; + } + os << "\n "; + PrintValue(element, os); + } + if (!value.empty()) { + os << "\n "; + } + os << "]"; + if (!last) { + os << ","; + } + os << "\n"; +} + +void read(std::string_view input = "types.pair.root", + std::string_view output = "types.pair.json") { + std::ofstream os(std::string{output}); + os << "[\n"; + + auto reader = RNTupleReader::Open("ntpl", input); + auto &entry = reader->GetModel().GetDefaultEntry(); + bool first = true; + for (auto index : *reader) { + reader->LoadEntry(index); + + if (first) { + first = false; + } else { + os << ",\n"; + } + os << " {\n"; + + PrintPairValue(entry, "Int32_String", os); + PrintPairValue(entry, "Variant_Vector", os); + PrintPairValue(entry, "Pair", os); + PrintVectorPairValue(entry, "VectorPair", os, /*last=*/true); + + os << " }"; + // Newline is intentionally missing, may need to print a comma before the + // next entry. + } + os << "\n"; + os << "]\n"; +} diff --git a/types/pair/write.C b/types/pair/write.C new file mode 100644 index 0000000..8c25f11 --- /dev/null +++ b/types/pair/write.C @@ -0,0 +1,50 @@ +#include +#include +#include + +using ROOT::Experimental::RNTupleModel; +using ROOT::Experimental::RNTupleWriteOptions; +using ROOT::Experimental::RNTupleWriter; + +#include +#include +#include +#include +#include +#include +#include + +using Pair_Int32_String = std::pair; +using Variant = std::variant; +using VectorInt32 = std::vector; + +void write(std::string_view filename = "types.pair.root") { + auto model = RNTupleModel::Create(); + + auto Int32_String = model->MakeField("Int32_String"); + auto Variant_Vector = + model->MakeField>("Variant_Vector"); + auto Pair = + model->MakeField>("Pair"); + auto VectorPair = + model->MakeField>("VectorPair"); + + RNTupleWriteOptions options; + options.SetCompression(0); + auto writer = + RNTupleWriter::Recreate(std::move(model), "ntpl", filename, options); + + // First entry: simple values + *Int32_String = {1, "abc"}; + *Variant_Vector = {"def", {2, 3, 4}}; + *Pair = {{5, "ghi"}, 6}; + *VectorPair = {{7, "jkl"}, {8, "mno"}}; + writer->Fill(); + + // Second entry: zero / empty values + *Int32_String = {0, ""}; + *Variant_Vector = {0, {}}; + *Pair = {{0, ""}, 0}; + *VectorPair = {}; + writer->Fill(); +} From 1dd3efb2fa033c8a34155e39ec9b8796769e371e Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Fri, 2 May 2025 10:55:13 +0200 Subject: [PATCH 3/3] Add test for std::tuple Closes #18 --- types/README.md | 1 + types/tuple/README.md | 15 ++++ types/tuple/read.C | 161 ++++++++++++++++++++++++++++++++++++++++++ types/tuple/write.C | 51 +++++++++++++ 4 files changed, 228 insertions(+) create mode 100644 types/tuple/README.md create mode 100644 types/tuple/read.C create mode 100644 types/tuple/write.C diff --git a/types/README.md b/types/README.md index 7acf3b7..86d3158 100644 --- a/types/README.md +++ b/types/README.md @@ -6,6 +6,7 @@ * [`pair`](pair): `std::pair` with different element types * [`set`](set): `std::set` with all `[Split]Index{32,64}` column types * [`string`](string): `std::string` with all `[Split]Index{32,64}` column types + * [`tuple`](tuple): `std::tuple` with different element types * [`unique_ptr`](unique_ptr): `std::unique_ptr` with different element types * [`unordered_multiset`](unordered_multiset): `std::unordered_multiset` with all `[Split]Index{32,64}` column types * [`unordered_set`](unordered_set): `std::unordered_set` with all `[Split]Index{32,64}` column types diff --git a/types/tuple/README.md b/types/tuple/README.md new file mode 100644 index 0000000..28b71d3 --- /dev/null +++ b/types/tuple/README.md @@ -0,0 +1,15 @@ +# `std::tuple` + +## Fields + + * `Int32_String_Vector`: `std::tuple>` + * `Variant`: `std::tuple>` + * `Tuple`: `std::tuple>` + * `VectorTuple`: `std::vector>` + +with the default column types. + +## Entries + +1. Simple values +2. Zero / empty values diff --git a/types/tuple/read.C b/types/tuple/read.C new file mode 100644 index 0000000..854753a --- /dev/null +++ b/types/tuple/read.C @@ -0,0 +1,161 @@ +#include +#include + +using ROOT::Experimental::REntry; +using ROOT::Experimental::RNTupleReader; + +#include +#include +#include +#include +#include +#include +#include +#include + +using Tuple_Int32_String = std::tuple; +using VectorInt32 = std::vector; + +template static void PrintValue(const T &value, std::ostream &os); + +template <> void PrintValue(const std::int32_t &value, std::ostream &os) { + os << value; +} + +template <> void PrintValue(const std::string &value, std::ostream &os) { + os << "\"" << value << "\""; +} + +template <> void PrintValue(const VectorInt32 &value, std::ostream &os) { + os << "["; + bool first = true; + for (auto element : value) { + if (first) { + first = false; + } else { + os << ","; + } + os << "\n " << element; + } + if (!value.empty()) { + os << "\n "; + } + os << "]"; +} + +template <> void PrintValue(const Tuple_Int32_String &value, std::ostream &os) { + os << "[\n"; + os << " " << std::get<0>(value) << ",\n"; + os << " \"" << std::get<1>(value) << "\"\n"; + os << " ]"; +} + +static void PrintTupleValue(const REntry &entry, std::string_view name, + std::ostream &os, bool last = false) { + auto &value = + *entry.GetPtr>(name); + os << " \"" << name << "\": [\n"; + os << " "; + PrintValue(std::get<0>(value), os); + os << ",\n"; + os << " "; + PrintValue(std::get<1>(value), os); + os << ",\n"; + os << " "; + PrintValue(std::get<2>(value), os); + os << "\n"; + os << " ]"; + if (!last) { + os << ","; + } + os << "\n"; +} + +static void PrintVariantValue(const REntry &entry, std::string_view name, + std::ostream &os, bool last = false) { + auto &value = + *entry.GetPtr>>(name); + os << " \"" << name << "\": [\n"; + os << " "; + auto &variant = std::get<0>(value); + if (variant.index() == 0) { + PrintValue(std::get(variant), os); + } else if (variant.index() == 1) { + PrintValue(std::get(variant), os); + } + os << "\n"; + os << " ]"; + if (!last) { + os << ","; + } + os << "\n"; +} + +static void PrintNestedValue(const REntry &entry, std::string_view name, + std::ostream &os, bool last = false) { + auto &value = *entry.GetPtr>(name); + os << " \"" << name << "\": [\n"; + os << " "; + PrintValue(std::get<0>(value), os); + os << "\n"; + os << " ]"; + if (!last) { + os << ","; + } + os << "\n"; +} + +static void PrintVectorTupleValue(const REntry &entry, std::string_view name, + std::ostream &os, bool last = false) { + auto &value = *entry.GetPtr>(name); + os << " \"" << name << "\": ["; + bool first = true; + for (auto &&element : value) { + if (first) { + first = false; + } else { + os << ","; + } + os << "\n "; + PrintValue(element, os); + } + if (!value.empty()) { + os << "\n "; + } + os << "]"; + if (!last) { + os << ","; + } + os << "\n"; +} + +void read(std::string_view input = "types.tuple.root", + std::string_view output = "types.tuple.json") { + std::ofstream os(std::string{output}); + os << "[\n"; + + auto reader = RNTupleReader::Open("ntpl", input); + auto &entry = reader->GetModel().GetDefaultEntry(); + bool first = true; + for (auto index : *reader) { + reader->LoadEntry(index); + + if (first) { + first = false; + } else { + os << ",\n"; + } + os << " {\n"; + + PrintTupleValue(entry, "Int32_String_Vector", os); + PrintVariantValue(entry, "Variant", os); + PrintNestedValue(entry, "Tuple", os); + PrintVectorTupleValue(entry, "VectorTuple", os, /*last=*/true); + + os << " }"; + // Newline is intentionally missing, may need to print a comma before the + // next entry. + } + os << "\n"; + os << "]\n"; +} diff --git a/types/tuple/write.C b/types/tuple/write.C new file mode 100644 index 0000000..9005211 --- /dev/null +++ b/types/tuple/write.C @@ -0,0 +1,51 @@ +#include +#include +#include + +using ROOT::Experimental::RNTupleModel; +using ROOT::Experimental::RNTupleWriteOptions; +using ROOT::Experimental::RNTupleWriter; + +#include +#include +#include +#include +#include +#include +#include + +using Tuple_Int32_String = std::tuple; +using VectorInt32 = std::vector; + +void write(std::string_view filename = "types.tuple.root") { + auto model = RNTupleModel::Create(); + + auto Int32_String_Vector = + model->MakeField>( + "Int32_String_Vector"); + auto Variant = + model->MakeField>>( + "Variant"); + auto Tuple = model->MakeField>("Tuple"); + auto VectorTuple = + model->MakeField>("VectorTuple"); + + RNTupleWriteOptions options; + options.SetCompression(0); + auto writer = + RNTupleWriter::Recreate(std::move(model), "ntpl", filename, options); + + // First entry: simple values + *Int32_String_Vector = {1, "abc", {2, 3, 4}}; + *Variant = {"def"}; + *Tuple = {{5, "ghi"}}; + *VectorTuple = {{6, "jkl"}, {7, "mno"}}; + writer->Fill(); + + // Second entry: zero / empty values + *Int32_String_Vector = {0, "", {}}; + *Variant = {0}; + *Tuple = {{0, ""}}; + *VectorTuple = {}; + writer->Fill(); +}