Skip to content

Commit cf25928

Browse files
C++ std::optional Specific Encoder and Decoder
1 parent 64ac2cd commit cf25928

2 files changed

Lines changed: 54 additions & 0 deletions

File tree

lang/c++/include/avro/Specific.hh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "array"
2323
#include <algorithm>
2424
#include <map>
25+
#include <optional>
2526
#include <string>
2627
#include <vector>
2728

@@ -165,6 +166,44 @@ struct codec_traits<double> {
165166
}
166167
};
167168

169+
/**
170+
* codec_traits for Avro optional.
171+
*/
172+
template<typename T>
173+
struct codec_traits<std::optional<T>> {
174+
/**
175+
* Encodes a given value.
176+
*/
177+
static void encode(Encoder &e, const std::optional<T> &b) {
178+
if (b) {
179+
e.encodeUnionIndex(1);
180+
avro::encode(e, b.value());
181+
} else {
182+
e.encodeUnionIndex(0);
183+
e.encodeNull();
184+
}
185+
}
186+
187+
/**
188+
* Decodes into a given value.
189+
*/
190+
static void decode(Decoder &d, std::optional<T> &s) {
191+
size_t n = d.decodeUnionIndex();
192+
if (n >= 2) { throw avro::Exception("Union index too big"); }
193+
switch (n) {
194+
case 0: {
195+
d.decodeNull();
196+
s = std::nullopt;
197+
} break;
198+
case 1: {
199+
T t;
200+
avro::decode(d, t);
201+
s.emplace(t);
202+
} break;
203+
}
204+
}
205+
};
206+
168207
/**
169208
* codec_traits for Avro string.
170209
*/

lang/c++/test/SpecificTests.cc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
using std::array;
2626
using std::map;
27+
using std::optional;
2728
using std::string;
2829
using std::unique_ptr;
2930
using std::vector;
@@ -127,6 +128,18 @@ void testDouble() {
127128
BOOST_CHECK_CLOSE(b, n, 0.00000001);
128129
}
129130

131+
void testNonEmptyOptional() {
132+
optional<int64_t> n = -109;
133+
optional<int64_t> b = encodeAndDecode(n);
134+
BOOST_CHECK_EQUAL(b.value(), n.value());
135+
}
136+
137+
void testEmptyOptional() {
138+
optional<int64_t> n;
139+
optional<int64_t> b = encodeAndDecode(n);
140+
BOOST_CHECK(!b.has_value());
141+
}
142+
130143
void testString() {
131144
string n = "abc";
132145
string b = encodeAndDecode(n);
@@ -191,6 +204,8 @@ init_unit_test_suite(int /*argc*/, char * /*argv*/[]) {
191204
ts->add(BOOST_TEST_CASE(avro::specific::testLong));
192205
ts->add(BOOST_TEST_CASE(avro::specific::testFloat));
193206
ts->add(BOOST_TEST_CASE(avro::specific::testDouble));
207+
ts->add(BOOST_TEST_CASE(avro::specific::testNonEmptyOptional));
208+
ts->add(BOOST_TEST_CASE(avro::specific::testEmptyOptional));
194209
ts->add(BOOST_TEST_CASE(avro::specific::testString));
195210
ts->add(BOOST_TEST_CASE(avro::specific::testBytes));
196211
ts->add(BOOST_TEST_CASE(avro::specific::testFixed));

0 commit comments

Comments
 (0)