Viam C++ SDK current
Loading...
Searching...
No Matches
proto_value_visit.hpp
1#pragma once
2
3#include <type_traits>
4
5#include <viam/sdk/common/proto_value.hpp>
6
7namespace viam {
8namespace sdk {
9
10// It might seem that we could write these all with a single template, but this ends up requiring
11// some annoying gymnastics with type traits that only saves around 15 lines. For more info see
12// https://github.com/boostorg/json/issues/952 and the linked PR with the fix.
13
20
21template <typename Visitor>
22auto visit(Visitor&& visitor, ProtoValue& value)
23 -> decltype(std::forward<Visitor>(visitor)(std::declval<std::nullptr_t&>())) {
24 switch (value.kind()) {
25 case ProtoValue::Kind::k_bool:
26 return std::forward<Visitor>(visitor)(value.get_unchecked<bool>());
27 case ProtoValue::Kind::k_double:
28 return std::forward<Visitor>(visitor)(value.get_unchecked<double>());
29 case ProtoValue::Kind::k_string:
30 return std::forward<Visitor>(visitor)(value.get_unchecked<std::string>());
31 case ProtoValue::Kind::k_list:
32 return std::forward<Visitor>(visitor)(value.get_unchecked<ProtoList>());
33 case ProtoValue::Kind::k_struct:
34 return std::forward<Visitor>(visitor)(value.get_unchecked<ProtoStruct>());
35 case ProtoValue::Kind::k_null: {
36 auto np = nullptr;
37 return std::forward<Visitor>(visitor)(np);
38 }
39 }
40}
41
42template <typename Visitor>
43auto visit(Visitor&& visitor, const ProtoValue& value)
44 -> decltype(std::forward<Visitor>(visitor)(std::declval<const std::nullptr_t&>())) {
45 switch (value.kind()) {
46 case ProtoValue::Kind::k_bool:
47 return std::forward<Visitor>(visitor)(value.get_unchecked<bool>());
48 case ProtoValue::Kind::k_double:
49 return std::forward<Visitor>(visitor)(value.get_unchecked<double>());
50 case ProtoValue::Kind::k_string:
51 return std::forward<Visitor>(visitor)(value.get_unchecked<std::string>());
52 case ProtoValue::Kind::k_list:
53 return std::forward<Visitor>(visitor)(value.get_unchecked<ProtoList>());
54 case ProtoValue::Kind::k_struct:
55 return std::forward<Visitor>(visitor)(value.get_unchecked<ProtoStruct>());
56 case ProtoValue::Kind::k_null: {
57 const auto np = nullptr;
58 return std::forward<Visitor>(visitor)(np);
59 }
60 }
61}
62
63template <typename Visitor>
64auto visit(Visitor&& visitor, ProtoValue&& value)
65 -> decltype(std::forward<Visitor>(visitor)(std::declval<std::nullptr_t&&>())) {
66 switch (value.kind()) {
67 case ProtoValue::Kind::k_bool:
68 return std::forward<Visitor>(visitor)(std::move(value.get_unchecked<bool>()));
69 case ProtoValue::Kind::k_double:
70 return std::forward<Visitor>(visitor)(std::move(value.get_unchecked<double>()));
71 case ProtoValue::Kind::k_string:
72 return std::forward<Visitor>(visitor)(std::move(value.get_unchecked<std::string>()));
73 case ProtoValue::Kind::k_list:
74 return std::forward<Visitor>(visitor)(std::move(value.get_unchecked<ProtoList>()));
75 case ProtoValue::Kind::k_struct:
76 return std::forward<Visitor>(visitor)(std::move(value.get_unchecked<ProtoStruct>()));
77 case ProtoValue::Kind::k_null:
78 return std::forward<Visitor>(visitor)(std::nullptr_t());
79 }
80}
81
83
84} // namespace sdk
85} // namespace viam