Skip to content

Commit 9b6cf61

Browse files
committed
Add test for std::optional
Closes #15
1 parent 077ae65 commit 9b6cf61

File tree

4 files changed

+169
-0
lines changed

4 files changed

+169
-0
lines changed

types/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Types
22

33
* [`fundamental`](fundamental): fundamental column types
4+
* [`optional`](optional): `std::optional` with different element types
45
* [`string`](string): `std::string` with all `[Split]Index{32,64}` column types
56
* [`variant`](variant): `std::variant` with `Switch` column type
67
* [`vector`](vector): `std::vector` with all `[Split]Index{32,64}` column types

types/optional/README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# `std::optional`
2+
3+
## Fields
4+
5+
* `Int32`: `std::int32_t`
6+
* `String`: `std::string`
7+
* `Variant`: `std::variant<std::int32_t, std::string>`
8+
* `Vector`: `std::vector<std::int32_t>`
9+
10+
with the default column types.
11+
12+
## Entries
13+
14+
1. Simple values
15+
2. No value
16+
3. Zero / empty values

types/optional/read.C

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#include <ROOT/REntry.hxx>
2+
#include <ROOT/RNTupleReader.hxx>
3+
4+
using ROOT::Experimental::REntry;
5+
using ROOT::Experimental::RNTupleReader;
6+
7+
#include <cstdint>
8+
#include <fstream>
9+
#include <optional>
10+
#include <ostream>
11+
#include <string>
12+
#include <string_view>
13+
#include <variant>
14+
#include <vector>
15+
16+
using VariantTy = std::variant<std::int32_t, std::string>;
17+
using VectorTy = std::vector<std::int32_t>;
18+
19+
template <typename T> static void PrintValue(const T &value, std::ostream &os);
20+
21+
template <> void PrintValue(const std::int32_t &value, std::ostream &os) {
22+
os << value;
23+
}
24+
25+
template <> void PrintValue(const std::string &value, std::ostream &os) {
26+
os << "\"" << value << "\"";
27+
}
28+
29+
template <> void PrintValue(const VariantTy &value, std::ostream &os) {
30+
if (value.index() == 0) {
31+
PrintValue(std::get<std::int32_t>(value), os);
32+
} else if (value.index() == 1) {
33+
PrintValue(std::get<std::string>(value), os);
34+
}
35+
}
36+
37+
template <> void PrintValue(const VectorTy &value, std::ostream &os) {
38+
os << "[";
39+
bool first = true;
40+
for (auto element : value) {
41+
if (first) {
42+
first = false;
43+
} else {
44+
os << ",";
45+
}
46+
os << "\n " << element;
47+
}
48+
if (!value.empty()) {
49+
os << "\n ";
50+
}
51+
os << "]";
52+
}
53+
54+
template <typename T>
55+
static void PrintOptionalValue(const REntry &entry, std::string_view name,
56+
std::ostream &os, bool last = false) {
57+
auto &value = *entry.GetPtr<std::optional<T>>(name);
58+
os << " \"" << name << "\": ";
59+
if (!value.has_value()) {
60+
os << "null";
61+
} else {
62+
PrintValue(*value, os);
63+
}
64+
if (!last) {
65+
os << ",";
66+
}
67+
os << "\n";
68+
}
69+
70+
void read(std::string_view input = "types.optional.root",
71+
std::string_view output = "types.optional.json") {
72+
std::ofstream os(std::string{output});
73+
os << "[\n";
74+
75+
auto reader = RNTupleReader::Open("ntpl", input);
76+
auto &entry = reader->GetModel().GetDefaultEntry();
77+
bool first = true;
78+
for (auto index : *reader) {
79+
reader->LoadEntry(index);
80+
81+
if (first) {
82+
first = false;
83+
} else {
84+
os << ",\n";
85+
}
86+
os << " {\n";
87+
88+
PrintOptionalValue<std::int32_t>(entry, "Int32", os);
89+
PrintOptionalValue<std::string>(entry, "String", os);
90+
PrintOptionalValue<VariantTy>(entry, "Variant", os);
91+
PrintOptionalValue<VectorTy>(entry, "Vector", os, /*last=*/true);
92+
93+
os << " }";
94+
// Newline is intentionally missing, may need to print a comma before the
95+
// next entry.
96+
}
97+
os << "\n";
98+
os << "]\n";
99+
}

types/optional/write.C

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#include <ROOT/RNTupleModel.hxx>
2+
#include <ROOT/RNTupleWriteOptions.hxx>
3+
#include <ROOT/RNTupleWriter.hxx>
4+
5+
using ROOT::Experimental::RNTupleModel;
6+
using ROOT::Experimental::RNTupleWriteOptions;
7+
using ROOT::Experimental::RNTupleWriter;
8+
9+
#include <cstdint>
10+
#include <memory>
11+
#include <optional>
12+
#include <string>
13+
#include <string_view>
14+
#include <variant>
15+
#include <vector>
16+
17+
using VariantTy = std::variant<std::int32_t, std::string>;
18+
using VectorTy = std::vector<std::int32_t>;
19+
20+
void write(std::string_view filename = "types.optional.root") {
21+
auto model = RNTupleModel::Create();
22+
23+
auto Int32 = model->MakeField<std::optional<std::int32_t>>("Int32");
24+
auto String = model->MakeField<std::optional<std::string>>("String");
25+
auto Variant = model->MakeField<std::optional<VariantTy>>("Variant");
26+
auto Vector = model->MakeField<std::optional<VectorTy>>("Vector");
27+
28+
RNTupleWriteOptions options;
29+
options.SetCompression(0);
30+
auto writer =
31+
RNTupleWriter::Recreate(std::move(model), "ntpl", filename, options);
32+
33+
// First entry: simple values
34+
*Int32 = 1;
35+
*String = "abc";
36+
*Variant = "def";
37+
*Vector = {1, 2, 3};
38+
writer->Fill();
39+
40+
// Second entry: no value
41+
Int32->reset();
42+
String->reset();
43+
Variant->reset();
44+
Vector->reset();
45+
writer->Fill();
46+
47+
// Third entry: zero / empty value
48+
*Int32 = 0;
49+
*String = "";
50+
*Variant = 0;
51+
*Vector = VectorTy{};
52+
writer->Fill();
53+
}

0 commit comments

Comments
 (0)