blob: a45e1802ff7c4f7fba4896a18ac17909e711cb78 [file] [log] [blame]
Brian Silvermanf7bd1c22015-12-24 16:07:11 -08001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2015. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in the root directory of */
5/* the project. */
6/*----------------------------------------------------------------------------*/
7
8#ifndef NT_VALUE_H_
9#define NT_VALUE_H_
10
11#include <cassert>
12#include <memory>
13#include <string>
14#include <type_traits>
15#include <vector>
16
17#include "llvm/ArrayRef.h"
18#include "llvm/StringRef.h"
19
20#include "ntcore_c.h"
21
22namespace nt {
23
24using llvm::ArrayRef;
25using llvm::StringRef;
26
27/** NetworkTables Entry Value */
28class Value {
29 struct private_init {};
30
31 public:
32 Value();
33 Value(NT_Type type, const private_init&);
34 ~Value();
35
36 NT_Type type() const { return m_val.type; }
37 const NT_Value& value() const { return m_val; }
38 unsigned long long last_change() const { return m_val.last_change; }
39
40 /*
41 * Type Checkers
42 */
43 bool IsBoolean() const { return m_val.type == NT_BOOLEAN; }
44 bool IsDouble() const { return m_val.type == NT_DOUBLE; }
45 bool IsString() const { return m_val.type == NT_STRING; }
46 bool IsRaw() const { return m_val.type == NT_RAW; }
47 bool IsRpc() const { return m_val.type == NT_RPC; }
48 bool IsBooleanArray() const { return m_val.type == NT_BOOLEAN_ARRAY; }
49 bool IsDoubleArray() const { return m_val.type == NT_DOUBLE_ARRAY; }
50 bool IsStringArray() const { return m_val.type == NT_STRING_ARRAY; }
51
52 /*
53 * Type-Safe Getters
54 */
55 bool GetBoolean() const {
56 assert(m_val.type == NT_BOOLEAN);
57 return m_val.data.v_boolean != 0;
58 }
59 double GetDouble() const {
60 assert(m_val.type == NT_DOUBLE);
61 return m_val.data.v_double;
62 }
63 StringRef GetString() const {
64 assert(m_val.type == NT_STRING);
65 return m_string;
66 }
67 StringRef GetRaw() const {
68 assert(m_val.type == NT_RAW);
69 return m_string;
70 }
71 StringRef GetRpc() const {
72 assert(m_val.type == NT_RPC);
73 return m_string;
74 }
75 ArrayRef<int> GetBooleanArray() const {
76 assert(m_val.type == NT_BOOLEAN_ARRAY);
77 return ArrayRef<int>(m_val.data.arr_boolean.arr,
78 m_val.data.arr_boolean.size);
79 }
80 ArrayRef<double> GetDoubleArray() const {
81 assert(m_val.type == NT_DOUBLE_ARRAY);
82 return ArrayRef<double>(m_val.data.arr_double.arr,
83 m_val.data.arr_double.size);
84 }
85 ArrayRef<std::string> GetStringArray() const {
86 assert(m_val.type == NT_STRING_ARRAY);
87 return m_string_array;
88 }
89
90 static std::shared_ptr<Value> MakeBoolean(bool value) {
91 auto val = std::make_shared<Value>(NT_BOOLEAN, private_init());
92 val->m_val.data.v_boolean = value;
93 return val;
94 }
95 static std::shared_ptr<Value> MakeDouble(double value) {
96 auto val = std::make_shared<Value>(NT_DOUBLE, private_init());
97 val->m_val.data.v_double = value;
98 return val;
99 }
100 static std::shared_ptr<Value> MakeString(StringRef value) {
101 auto val = std::make_shared<Value>(NT_STRING, private_init());
102 val->m_string = value;
103 val->m_val.data.v_string.str = const_cast<char*>(val->m_string.c_str());
104 val->m_val.data.v_string.len = val->m_string.size();
105 return val;
106 }
107#ifdef _MSC_VER
108 template <typename T, typename = std::enable_if_t<std::is_same<T, std::string>>>
109#else
110 template <typename T,
111 typename std::enable_if<std::is_same<T, std::string>::value>::type>
112#endif
113 static std::shared_ptr<Value> MakeString(T&& value) {
114 auto val = std::make_shared<Value>(NT_STRING, private_init());
115 val->m_string = std::move(value);
116 val->m_val.data.v_string.str = const_cast<char*>(val->m_string.c_str());
117 val->m_val.data.v_string.len = val->m_string.size();
118 return val;
119 }
120 static std::shared_ptr<Value> MakeRaw(StringRef value) {
121 auto val = std::make_shared<Value>(NT_RAW, private_init());
122 val->m_string = value;
123 val->m_val.data.v_raw.str = const_cast<char*>(val->m_string.c_str());
124 val->m_val.data.v_raw.len = val->m_string.size();
125 return val;
126 }
127#ifdef _MSC_VER
128 template <typename T, typename = std::enable_if_t<std::is_same<T, std::string>>>
129#else
130 template <typename T,
131 typename std::enable_if<std::is_same<T, std::string>::value>::type>
132#endif
133 static std::shared_ptr<Value> MakeRaw(T&& value) {
134 auto val = std::make_shared<Value>(NT_RAW, private_init());
135 val->m_string = std::move(value);
136 val->m_val.data.v_raw.str = const_cast<char*>(val->m_string.c_str());
137 val->m_val.data.v_raw.len = val->m_string.size();
138 return val;
139 }
140 static std::shared_ptr<Value> MakeRpc(StringRef value) {
141 auto val = std::make_shared<Value>(NT_RPC, private_init());
142 val->m_string = value;
143 val->m_val.data.v_raw.str = const_cast<char*>(val->m_string.c_str());
144 val->m_val.data.v_raw.len = val->m_string.size();
145 return val;
146 }
147 template <typename T>
148 static std::shared_ptr<Value> MakeRpc(T&& value) {
149 auto val = std::make_shared<Value>(NT_RPC, private_init());
150 val->m_string = std::move(value);
151 val->m_val.data.v_raw.str = const_cast<char*>(val->m_string.c_str());
152 val->m_val.data.v_raw.len = val->m_string.size();
153 return val;
154 }
155
156 static std::shared_ptr<Value> MakeBooleanArray(ArrayRef<int> value);
157 static std::shared_ptr<Value> MakeDoubleArray(ArrayRef<double> value);
158 static std::shared_ptr<Value> MakeStringArray(ArrayRef<std::string> value);
159
160 // Note: This function moves the values out of the vector.
161 static std::shared_ptr<Value> MakeStringArray(
162 std::vector<std::string>&& value);
163
164 Value(const Value&) = delete;
165 Value& operator=(const Value&) = delete;
166 friend bool operator==(const Value& lhs, const Value& rhs);
167
168 private:
169 NT_Value m_val;
170 std::string m_string;
171 std::vector<std::string> m_string_array;
172};
173
174bool operator==(const Value& lhs, const Value& rhs);
175inline bool operator!=(const Value& lhs, const Value& rhs) {
176 return !(lhs == rhs);
177}
178
179} // namespace nt
180
181#endif // NT_VALUE_H_