Skip to content

Commit eefcbd6

Browse files
RSDK-8828 Remove integer type from ProtoValue (#292)
Signed-off-by: dependabot[bot] <[email protected]> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
1 parent 32b31fa commit eefcbd6

File tree

5 files changed

+55
-82
lines changed

5 files changed

+55
-82
lines changed

src/viam/sdk/common/proto_value.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,28 @@ namespace sdk {
88
using google::protobuf::Struct;
99
using google::protobuf::Value;
1010

11-
ProtoValue::ProtoValue() noexcept : ProtoValue(nullptr) {}
11+
ProtoValue::ProtoValue() noexcept : ProtoValue(nullptr, nullptr) {}
12+
ProtoValue::ProtoValue(std::nullptr_t) noexcept : ProtoValue() {}
13+
ProtoValue::ProtoValue(bool b) noexcept : ProtoValue(b, nullptr) {}
14+
ProtoValue::ProtoValue(int i) noexcept : ProtoValue(static_cast<double>(i)) {}
15+
ProtoValue::ProtoValue(double d) noexcept : ProtoValue(d, nullptr) {}
16+
ProtoValue::ProtoValue(std::string s) noexcept : ProtoValue(std::move(s), nullptr) {}
17+
18+
template <typename Val, typename>
19+
ProtoValue::ProtoValue(std::vector<Val> v) noexcept(
20+
std::is_nothrow_move_constructible<std::vector<Val>>{})
21+
: ProtoValue(std::move(v), 0) {}
22+
23+
template <typename Val, typename>
24+
ProtoValue::ProtoValue(std::unordered_map<std::string, Val> s) noexcept(
25+
std::is_nothrow_move_constructible<std::unordered_map<std::string, Val>>{})
26+
: ProtoValue(std::move(s), 0) {}
1227

1328
template <typename T>
14-
ProtoValue::ProtoValue(T t) noexcept(std::is_nothrow_move_constructible<T>{})
29+
ProtoValue::ProtoValue(T t, std::nullptr_t) noexcept(std::is_nothrow_move_constructible<T>{})
1530
: vtable_{model<T>::vtable_}, self_{std::move(t)} {}
1631

1732
// -- explicit instantiations of by-value constructors -- //
18-
template ProtoValue::ProtoValue(std::nullptr_t) noexcept;
19-
template ProtoValue::ProtoValue(bool) noexcept;
20-
template ProtoValue::ProtoValue(int) noexcept;
21-
template ProtoValue::ProtoValue(double) noexcept;
22-
template ProtoValue::ProtoValue(std::string) noexcept(
23-
std::is_nothrow_move_constructible<std::string>{});
2433
template ProtoValue::ProtoValue(ProtoList) noexcept(
2534
std::is_nothrow_move_constructible<ProtoList>{});
2635
template ProtoValue::ProtoValue(ProtoStruct m) noexcept(
@@ -117,11 +126,9 @@ std::enable_if_t<std::is_scalar<T>{}, T> ProtoValue::get_unchecked() const {
117126
}
118127

119128
template bool& ProtoValue::get_unchecked<bool>();
120-
template int& ProtoValue::get_unchecked<int>();
121129
template double& ProtoValue::get_unchecked<double>();
122130

123131
template bool ProtoValue::get_unchecked<bool>() const;
124-
template int ProtoValue::get_unchecked<int>() const;
125132
template double ProtoValue::get_unchecked<double>() const;
126133

127134
template <typename T>
@@ -255,10 +262,6 @@ void to_proto(bool b, Value* v) {
255262
v->set_bool_value(b);
256263
}
257264

258-
void to_proto(int i, Value* v) {
259-
v->set_number_value(i);
260-
}
261-
262265
void to_proto(double d, Value* v) {
263266
v->set_number_value(d);
264267
}

src/viam/sdk/common/proto_value.hpp

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -53,26 +53,42 @@ struct all_moves_noexcept
5353
class ProtoValue {
5454
public:
5555
/// @brief Type discriminator constants for possible values stored in a ProtoValue.
56-
enum Kind {
57-
k_null = 0,
58-
k_bool = 1,
59-
k_double = 2,
60-
k_string = 3,
61-
k_list = 4,
62-
k_struct = 5,
63-
k_int = 6
64-
};
56+
enum Kind { k_null = 0, k_bool = 1, k_double = 2, k_string = 3, k_list = 4, k_struct = 5 };
6557

6658
/// @brief Construct a null object.
6759
ProtoValue() noexcept;
6860

69-
/// @brief Construct a nonempty object.
70-
template <typename T>
71-
ProtoValue(T t) noexcept(std::is_nothrow_move_constructible<T>{});
61+
/// @name Value constructors.
62+
/// @brief Constructors which initialize a ProtoValue holding its argument.
63+
/// @{
64+
65+
ProtoValue(std::nullptr_t) noexcept;
66+
67+
ProtoValue(bool b) noexcept;
68+
69+
/// @brief Construct a double object upcast from constructor argument.
70+
ProtoValue(int i) noexcept;
71+
72+
ProtoValue(double d) noexcept;
73+
74+
ProtoValue(std::string s) noexcept;
7275

7376
/// @brief Deduction helper constructor for string from string literal
7477
ProtoValue(const char* str);
7578

79+
/// @brief Construct from a ProtoList.
80+
template <typename Val = ProtoValue,
81+
typename = std::enable_if_t<std::is_same<Val, ProtoValue>{}>>
82+
ProtoValue(std::vector<Val>) noexcept(std::is_nothrow_move_constructible<std::vector<Val>>{});
83+
84+
/// @brief Construct from a ProtoStruct.
85+
template <typename Val = ProtoValue,
86+
typename = std::enable_if_t<std::is_same<Val, ProtoValue>{}>>
87+
ProtoValue(std::unordered_map<std::string, Val>) noexcept(
88+
std::is_nothrow_move_constructible<std::unordered_map<std::string, Val>>{});
89+
90+
/// @}
91+
7692
/// @brief Move construct this from other, leaving other in its unspecified-but-valid moved from
7793
/// state.
7894
ProtoValue(ProtoValue&& other) noexcept(proto_value_details::all_moves_noexcept{});
@@ -125,12 +141,12 @@ class ProtoValue {
125141
T const* get() const;
126142

127143
/// @brief Return a reference to the underlying T, without checking.
128-
/// @tparam T a bool, int, or double
144+
/// @tparam T a bool or double
129145
template <typename T>
130146
std::enable_if_t<std::is_scalar<T>{}, T&> get_unchecked();
131147

132148
/// @brief Return the underlying T by value, without checking.
133-
/// @tparam T a bool, int, or double.
149+
/// @tparam T a bool or double.
134150
template <typename T>
135151
std::enable_if_t<std::is_scalar<T>{}, T> get_unchecked() const;
136152

@@ -204,7 +220,6 @@ class ProtoValue {
204220
using BufType = std::aligned_union_t<0,
205221
std::nullptr_t,
206222
bool,
207-
int,
208223
double,
209224
std::string,
210225
std::vector<void*>,
@@ -257,6 +272,11 @@ class ProtoValue {
257272

258273
ProtoValue(const google::protobuf::Value* value);
259274

275+
// Helper template for the explicit versions above.
276+
// Includes nullptr_t as a tag type so we can let the other constructors delegate.
277+
template <typename T>
278+
ProtoValue(T t, std::nullptr_t) noexcept(std::is_nothrow_move_constructible<T>{});
279+
260280
vtable vtable_;
261281
storage self_;
262282
};
@@ -275,24 +295,16 @@ using ProtoList = std::vector<ProtoValue>;
275295
using ProtoStruct = std::unordered_map<std::string, ProtoValue>;
276296

277297
// -- Template specialization declarations of by-value constructors -- //
278-
extern template ProtoValue::ProtoValue(std::nullptr_t) noexcept;
279-
extern template ProtoValue::ProtoValue(bool) noexcept;
280-
extern template ProtoValue::ProtoValue(int) noexcept;
281-
extern template ProtoValue::ProtoValue(double) noexcept;
282-
extern template ProtoValue::ProtoValue(std::string) noexcept(
283-
std::is_nothrow_move_constructible<std::string>{});
284298
extern template ProtoValue::ProtoValue(ProtoList) noexcept(
285299
std::is_nothrow_move_constructible<ProtoList>{});
286300
extern template ProtoValue::ProtoValue(ProtoStruct m) noexcept(
287301
std::is_nothrow_move_constructible<ProtoStruct>{});
288302

289303
// -- Template specialization declarations of get_unchecked: POD types -- //
290304
extern template bool& ProtoValue::get_unchecked<bool>();
291-
extern template int& ProtoValue::get_unchecked<int>();
292305
extern template double& ProtoValue::get_unchecked<double>();
293306

294307
extern template bool ProtoValue::get_unchecked<bool>() const;
295-
extern template int ProtoValue::get_unchecked<int>() const;
296308
extern template double ProtoValue::get_unchecked<double>() const;
297309

298310
// -- Template specialization declarations of get_unchecked: string and recursive types -- //
@@ -310,7 +322,6 @@ extern template ProtoStruct&& ProtoValue::get_unchecked<ProtoStruct>() &&;
310322

311323
void to_proto(std::nullptr_t, google::protobuf::Value* v);
312324
void to_proto(bool b, google::protobuf::Value* v);
313-
void to_proto(int i, google::protobuf::Value* v);
314325
void to_proto(double d, google::protobuf::Value* v);
315326
void to_proto(std::string s, google::protobuf::Value* v);
316327
void to_proto(const ProtoList& vec, google::protobuf::Value* v);
@@ -371,11 +382,6 @@ struct kind<bool> {
371382
using type = KindConstant<ProtoValue::Kind::k_bool>;
372383
};
373384

374-
template <>
375-
struct kind<int> {
376-
using type = KindConstant<ProtoValue::Kind::k_int>;
377-
};
378-
379385
template <>
380386
struct kind<double> {
381387
using type = KindConstant<ProtoValue::Kind::k_double>;

src/viam/sdk/common/proto_value_visit.hpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@ auto visit(Visitor&& visitor, ProtoValue& value)
2424
switch (value.kind()) {
2525
case ProtoValue::Kind::k_bool:
2626
return std::forward<Visitor>(visitor)(value.get_unchecked<bool>());
27-
case ProtoValue::Kind::k_int:
28-
return std::forward<Visitor>(visitor)(value.get_unchecked<int>());
2927
case ProtoValue::Kind::k_double:
3028
return std::forward<Visitor>(visitor)(value.get_unchecked<double>());
3129
case ProtoValue::Kind::k_string:
@@ -47,8 +45,6 @@ auto visit(Visitor&& visitor, const ProtoValue& value)
4745
switch (value.kind()) {
4846
case ProtoValue::Kind::k_bool:
4947
return std::forward<Visitor>(visitor)(value.get_unchecked<bool>());
50-
case ProtoValue::Kind::k_int:
51-
return std::forward<Visitor>(visitor)(value.get_unchecked<int>());
5248
case ProtoValue::Kind::k_double:
5349
return std::forward<Visitor>(visitor)(value.get_unchecked<double>());
5450
case ProtoValue::Kind::k_string:
@@ -70,8 +66,6 @@ auto visit(Visitor&& visitor, ProtoValue&& value)
7066
switch (value.kind()) {
7167
case ProtoValue::Kind::k_bool:
7268
return std::forward<Visitor>(visitor)(std::move(value.get_unchecked<bool>()));
73-
case ProtoValue::Kind::k_int:
74-
return std::forward<Visitor>(visitor)(std::move(value.get_unchecked<int>()));
7569
case ProtoValue::Kind::k_double:
7670
return std::forward<Visitor>(visitor)(std::move(value.get_unchecked<double>()));
7771
case ProtoValue::Kind::k_string:

src/viam/sdk/tests/test_proto_value.cpp

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -38,32 +38,9 @@ BOOST_AUTO_TEST_CASE(test_object_equality) {
3838

3939
// heterogeneous arithmetic types do not "inuitively" compare equal
4040
BOOST_CHECK(!(ProtoValue(false) == ProtoValue(0)));
41-
BOOST_CHECK(!(ProtoValue(0) == ProtoValue(0.0)));
42-
43-
// roundtrip integer conversion is not idempotent because the integer gets coerced to a double
44-
{
45-
ProtoValue i5(5);
46-
auto int_roundtrip = ProtoValue::from_proto(to_proto(i5));
47-
BOOST_CHECK(i5.kind() == ProtoValue::Kind::k_int);
48-
BOOST_CHECK(i5.is_a<int>());
49-
50-
BOOST_CHECK(int_roundtrip.kind() == ProtoValue::Kind::k_double);
51-
BOOST_CHECK(int_roundtrip.is_a<double>());
52-
53-
BOOST_CHECK(!(i5 == int_roundtrip));
54-
BOOST_CHECK(int_roundtrip == ProtoValue(5.0));
55-
56-
ProtoValue i5_copy(i5);
57-
BOOST_CHECK(i5_copy == i5);
58-
59-
ProtoValue i5_move(std::move(i5));
60-
BOOST_CHECK(i5_copy == i5_move);
61-
BOOST_CHECK(i5.is_a<int>());
62-
}
6341

6442
auto test_cases = std::make_tuple(
6543
std::make_pair(true, false),
66-
/* integer not included, see above */
6744
std::make_pair(6.0, 7.5),
6845
std::make_pair(std::string("string"), std::string("different")),
6946
std::make_pair(ProtoList({ProtoValue{"asdf"}}),
@@ -82,7 +59,6 @@ BOOST_AUTO_TEST_CASE(test_object_equality) {
8259
ProtoValue v1(test_pair.first);
8360
BOOST_CHECK(v1.kind() == kind);
8461
BOOST_CHECK(v1.is_a<test_type>());
85-
BOOST_CHECK(!v1.get<int>());
8662

8763
{
8864
const test_type* ptr = v1.get<test_type>();
@@ -182,7 +158,9 @@ BOOST_AUTO_TEST_CASE(test_unchecked_access) {
182158
ProtoStruct{{"int", 5}, {"double", 6.0}}));
183159

184160
tuple_for_each(std::tuple_cat(scalar_tests, nonscalar_tests), [](auto test_pair) {
185-
using test_type = typename decltype(test_pair)::first_type;
161+
using first_type = typename decltype(test_pair)::first_type;
162+
using test_type = std::conditional_t<std::is_same<first_type, int>{}, double, first_type>;
163+
186164
const test_type first = test_pair.first;
187165
const test_type second = test_pair.second;
188166

@@ -249,9 +227,6 @@ BOOST_AUTO_TEST_CASE(test_nested_objects) {
249227
void set_proto_value(Value& val, bool b) {
250228
val.set_bool_value(b);
251229
}
252-
void set_proto_value(Value& val, int i) {
253-
val.set_number_value(i);
254-
}
255230
void set_proto_value(Value& val, double d) {
256231
val.set_number_value(d);
257232
}

src/viam/sdk/tests/test_proto_value_visit.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,6 @@ struct rvalue_visitor {
9595
return kind == ProtoValue::Kind::k_bool;
9696
}
9797

98-
bool operator()(int&&) && {
99-
return kind == ProtoValue::Kind::k_int;
100-
}
101-
10298
bool operator()(double&&) && {
10399
return kind == ProtoValue::Kind::k_double;
104100
}
@@ -133,7 +129,6 @@ BOOST_AUTO_TEST_CASE(test_visitor) {
133129
auto test_cases = std::make_tuple(
134130
std::make_pair(ProtoValue::Kind::k_null, nullptr),
135131
std::make_pair(ProtoValue::Kind::k_bool, true),
136-
std::make_pair(ProtoValue::Kind::k_int, 5),
137132
std::make_pair(ProtoValue::Kind::k_double, 12.345),
138133
std::make_pair(ProtoValue::Kind::k_string, "meow"),
139134
std::make_pair(ProtoValue::Kind::k_list, ProtoList({{ProtoValue(1), ProtoValue("woof")}})),

0 commit comments

Comments
 (0)