Skip to content

Commit a91c84c

Browse files
committed
Add test for std::unique_ptr
Closes #16
1 parent 214168e commit a91c84c

File tree

4 files changed

+243
-0
lines changed

4 files changed

+243
-0
lines changed

types/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
* [`fundamental`](fundamental): fundamental column types
44
* [`optional`](optional): `std::optional` with different element types
55
* [`string`](string): `std::string` with all `[Split]Index{32,64}` column types
6+
* [`unique_ptr`](unique_ptr): `std::unique_ptr` with different element types
67
* [`variant`](variant): `std::variant` with `Switch` column type
78
* [`vector`](vector): `std::vector` with all `[Split]Index{32,64}` column types

types/unique_ptr/README.md

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# `std::unique_ptr`
2+
3+
## Fields
4+
5+
* `[Split]Index{32,64}`: `std::unique_ptr<std::int32_t>`
6+
* with the corresponding column type for the first (principal) column
7+
* `String`: `std::unique_ptr<std::string>`
8+
* `Variant`: `std::unique_ptr<std::variant<std::int32_t, std::string>>`
9+
* `VectorInt32`: `std::unique_ptr<std::vector<std::int32_t>>`
10+
* `VectorPtr`: `std::vector<std::unique_ptr<std::int32_t>>>`
11+
12+
with otherwise the default column types.
13+
14+
## Entries
15+
16+
1. Simple values
17+
2. No value
18+
3. Zero / empty values

types/unique_ptr/read.C

+130
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
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 <ostream>
10+
#include <string>
11+
#include <string_view>
12+
#include <variant>
13+
#include <vector>
14+
15+
using VariantTy = std::variant<std::int32_t, std::string>;
16+
using VectorInt32Ty = std::vector<std::int32_t>;
17+
18+
template <typename T> static void PrintValue(const T &value, std::ostream &os);
19+
20+
template <> void PrintValue(const std::int32_t &value, std::ostream &os) {
21+
os << value;
22+
}
23+
24+
template <> void PrintValue(const std::string &value, std::ostream &os) {
25+
os << "\"" << value << "\"";
26+
}
27+
28+
template <> void PrintValue(const VariantTy &value, std::ostream &os) {
29+
if (value.index() == 0) {
30+
PrintValue(std::get<std::int32_t>(value), os);
31+
} else if (value.index() == 1) {
32+
PrintValue(std::get<std::string>(value), os);
33+
}
34+
}
35+
36+
template <> void PrintValue(const VectorInt32Ty &value, std::ostream &os) {
37+
os << "[";
38+
bool first = true;
39+
for (auto element : value) {
40+
if (first) {
41+
first = false;
42+
} else {
43+
os << ",";
44+
}
45+
os << "\n " << element;
46+
}
47+
if (!value.empty()) {
48+
os << "\n ";
49+
}
50+
os << "]";
51+
}
52+
53+
template <typename T>
54+
static void PrintUniquePtrValue(const REntry &entry, std::string_view name,
55+
std::ostream &os, bool last = false) {
56+
auto &value = *entry.GetPtr<std::unique_ptr<T>>(name);
57+
os << " \"" << name << "\": ";
58+
if (!value) {
59+
os << "null";
60+
} else {
61+
PrintValue(*value, os);
62+
}
63+
if (!last) {
64+
os << ",";
65+
}
66+
os << "\n";
67+
}
68+
69+
static void PrintVectorPtrValue(const REntry &entry, std::string_view name,
70+
std::ostream &os, bool last = false) {
71+
auto &value = *entry.GetPtr<std::vector<std::unique_ptr<std::int32_t>>>(name);
72+
os << " \"" << name << "\": [";
73+
bool first = true;
74+
for (auto &&element : value) {
75+
if (first) {
76+
first = false;
77+
} else {
78+
os << ",";
79+
}
80+
os << "\n ";
81+
if (!element) {
82+
os << "null";
83+
} else {
84+
os << *element;
85+
}
86+
}
87+
if (!value.empty()) {
88+
os << "\n ";
89+
}
90+
os << "]";
91+
if (!last) {
92+
os << ",";
93+
}
94+
os << "\n";
95+
}
96+
97+
void read(std::string_view input = "types.unique_ptr.root",
98+
std::string_view output = "types.unique_ptr.json") {
99+
std::ofstream os(std::string{output});
100+
os << "[\n";
101+
102+
auto reader = RNTupleReader::Open("ntpl", input);
103+
auto &entry = reader->GetModel().GetDefaultEntry();
104+
bool first = true;
105+
for (auto index : *reader) {
106+
reader->LoadEntry(index);
107+
108+
if (first) {
109+
first = false;
110+
} else {
111+
os << ",\n";
112+
}
113+
os << " {\n";
114+
115+
PrintUniquePtrValue<std::int32_t>(entry, "Index32", os);
116+
PrintUniquePtrValue<std::int32_t>(entry, "Index64", os);
117+
PrintUniquePtrValue<std::int32_t>(entry, "SplitIndex32", os);
118+
PrintUniquePtrValue<std::int32_t>(entry, "SplitIndex64", os);
119+
PrintUniquePtrValue<std::string>(entry, "String", os);
120+
PrintUniquePtrValue<VariantTy>(entry, "Variant", os);
121+
PrintUniquePtrValue<VectorInt32Ty>(entry, "VectorInt32", os);
122+
PrintVectorPtrValue(entry, "VectorPtr", os, /*last=*/true);
123+
124+
os << " }";
125+
// Newline is intentionally missing, may need to print a comma before the
126+
// next entry.
127+
}
128+
os << "\n";
129+
os << "]\n";
130+
}

types/unique_ptr/write.C

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#include <ROOT/RField.hxx>
2+
#include <ROOT/RNTupleModel.hxx>
3+
#include <ROOT/RNTupleUtil.hxx>
4+
#include <ROOT/RNTupleWriteOptions.hxx>
5+
#include <ROOT/RNTupleWriter.hxx>
6+
7+
using ROOT::Experimental::EColumnType;
8+
using ROOT::Experimental::RField;
9+
using ROOT::Experimental::RNTupleModel;
10+
using ROOT::Experimental::RNTupleWriteOptions;
11+
using ROOT::Experimental::RNTupleWriter;
12+
13+
#include <cstdint>
14+
#include <memory>
15+
#include <string>
16+
#include <string_view>
17+
#include <variant>
18+
#include <vector>
19+
20+
using PtrInt32Ty = std::unique_ptr<std::int32_t>;
21+
using VariantTy = std::variant<std::int32_t, std::string>;
22+
using VectorInt32Ty = std::vector<std::int32_t>;
23+
24+
static std::shared_ptr<PtrInt32Ty> MakeIntField(RNTupleModel &model,
25+
std::string_view name,
26+
EColumnType indexType) {
27+
auto field = std::make_unique<RField<PtrInt32Ty>>(name);
28+
field->SetColumnRepresentatives({{indexType}});
29+
model.AddField(std::move(field));
30+
return model.GetDefaultEntry().GetPtr<PtrInt32Ty>(name);
31+
}
32+
33+
void write(std::string_view filename = "types.unique_ptr.root") {
34+
auto model = RNTupleModel::Create();
35+
36+
// Non-split index encoding
37+
auto Index32 = MakeIntField(*model, "Index32", EColumnType::kIndex32);
38+
auto Index64 = MakeIntField(*model, "Index64", EColumnType::kIndex64);
39+
40+
// Split index encoding
41+
auto SplitIndex32 =
42+
MakeIntField(*model, "SplitIndex32", EColumnType::kSplitIndex32);
43+
auto SplitIndex64 =
44+
MakeIntField(*model, "SplitIndex64", EColumnType::kSplitIndex64);
45+
46+
auto String = model->MakeField<std::unique_ptr<std::string>>("String");
47+
auto Variant = model->MakeField<std::unique_ptr<VariantTy>>("Variant");
48+
auto VectorInt32 =
49+
model->MakeField<std::unique_ptr<VectorInt32Ty>>("VectorInt32");
50+
auto VectorPtr =
51+
model->MakeField<std::vector<std::unique_ptr<std::int32_t>>>("VectorPtr");
52+
53+
RNTupleWriteOptions options;
54+
options.SetCompression(0);
55+
auto writer =
56+
RNTupleWriter::Recreate(std::move(model), "ntpl", filename, options);
57+
58+
// First entry: simple values
59+
*Index32 = std::make_unique<std::int32_t>(1);
60+
*Index64 = std::make_unique<std::int32_t>(2);
61+
*SplitIndex32 = std::make_unique<std::int32_t>(3);
62+
*SplitIndex64 = std::make_unique<std::int32_t>(4);
63+
*String = std::make_unique<std::string>("abc");
64+
*Variant = std::make_unique<VariantTy>("def");
65+
*VectorInt32 = std::make_unique<VectorInt32Ty>();
66+
**VectorInt32 = {1, 2, 3};
67+
VectorPtr->push_back(std::make_unique<std::int32_t>(4));
68+
VectorPtr->push_back(std::make_unique<std::int32_t>(5));
69+
VectorPtr->push_back(std::make_unique<std::int32_t>(6));
70+
writer->Fill();
71+
72+
// Second entry: no value
73+
Index32->reset();
74+
Index64->reset();
75+
SplitIndex32->reset();
76+
SplitIndex64->reset();
77+
String->reset();
78+
Variant->reset();
79+
VectorInt32->reset();
80+
VectorPtr->clear();
81+
VectorPtr->push_back(nullptr);
82+
writer->Fill();
83+
84+
// Third entry: zero / empty value
85+
*Index32 = std::make_unique<std::int32_t>(0);
86+
*Index64 = std::make_unique<std::int32_t>(0);
87+
*SplitIndex32 = std::make_unique<std::int32_t>(0);
88+
*SplitIndex64 = std::make_unique<std::int32_t>(0);
89+
*String = std::make_unique<std::string>("");
90+
*Variant = std::make_unique<VariantTy>(0);
91+
*VectorInt32 = std::make_unique<VectorInt32Ty>();
92+
VectorPtr->clear();
93+
writer->Fill();
94+
}

0 commit comments

Comments
 (0)