Squashed 'third_party/ntcore_2016/' content from commit d8de5e4
Change-Id: Id4839f41b6a620d8bae58dcf1710016671cc4992
git-subtree-dir: third_party/ntcore_2016
git-subtree-split: d8de5e4f19e612e7102172c0dbf152ce82d3d63a
diff --git a/include/nt_Value.h b/include/nt_Value.h
new file mode 100644
index 0000000..a45e180
--- /dev/null
+++ b/include/nt_Value.h
@@ -0,0 +1,181 @@
+/*----------------------------------------------------------------------------*/
+/* Copyright (c) FIRST 2015. All Rights Reserved. */
+/* Open Source Software - may be modified and shared by FRC teams. The code */
+/* must be accompanied by the FIRST BSD license file in the root directory of */
+/* the project. */
+/*----------------------------------------------------------------------------*/
+
+#ifndef NT_VALUE_H_
+#define NT_VALUE_H_
+
+#include <cassert>
+#include <memory>
+#include <string>
+#include <type_traits>
+#include <vector>
+
+#include "llvm/ArrayRef.h"
+#include "llvm/StringRef.h"
+
+#include "ntcore_c.h"
+
+namespace nt {
+
+using llvm::ArrayRef;
+using llvm::StringRef;
+
+/** NetworkTables Entry Value */
+class Value {
+ struct private_init {};
+
+ public:
+ Value();
+ Value(NT_Type type, const private_init&);
+ ~Value();
+
+ NT_Type type() const { return m_val.type; }
+ const NT_Value& value() const { return m_val; }
+ unsigned long long last_change() const { return m_val.last_change; }
+
+ /*
+ * Type Checkers
+ */
+ bool IsBoolean() const { return m_val.type == NT_BOOLEAN; }
+ bool IsDouble() const { return m_val.type == NT_DOUBLE; }
+ bool IsString() const { return m_val.type == NT_STRING; }
+ bool IsRaw() const { return m_val.type == NT_RAW; }
+ bool IsRpc() const { return m_val.type == NT_RPC; }
+ bool IsBooleanArray() const { return m_val.type == NT_BOOLEAN_ARRAY; }
+ bool IsDoubleArray() const { return m_val.type == NT_DOUBLE_ARRAY; }
+ bool IsStringArray() const { return m_val.type == NT_STRING_ARRAY; }
+
+ /*
+ * Type-Safe Getters
+ */
+ bool GetBoolean() const {
+ assert(m_val.type == NT_BOOLEAN);
+ return m_val.data.v_boolean != 0;
+ }
+ double GetDouble() const {
+ assert(m_val.type == NT_DOUBLE);
+ return m_val.data.v_double;
+ }
+ StringRef GetString() const {
+ assert(m_val.type == NT_STRING);
+ return m_string;
+ }
+ StringRef GetRaw() const {
+ assert(m_val.type == NT_RAW);
+ return m_string;
+ }
+ StringRef GetRpc() const {
+ assert(m_val.type == NT_RPC);
+ return m_string;
+ }
+ ArrayRef<int> GetBooleanArray() const {
+ assert(m_val.type == NT_BOOLEAN_ARRAY);
+ return ArrayRef<int>(m_val.data.arr_boolean.arr,
+ m_val.data.arr_boolean.size);
+ }
+ ArrayRef<double> GetDoubleArray() const {
+ assert(m_val.type == NT_DOUBLE_ARRAY);
+ return ArrayRef<double>(m_val.data.arr_double.arr,
+ m_val.data.arr_double.size);
+ }
+ ArrayRef<std::string> GetStringArray() const {
+ assert(m_val.type == NT_STRING_ARRAY);
+ return m_string_array;
+ }
+
+ static std::shared_ptr<Value> MakeBoolean(bool value) {
+ auto val = std::make_shared<Value>(NT_BOOLEAN, private_init());
+ val->m_val.data.v_boolean = value;
+ return val;
+ }
+ static std::shared_ptr<Value> MakeDouble(double value) {
+ auto val = std::make_shared<Value>(NT_DOUBLE, private_init());
+ val->m_val.data.v_double = value;
+ return val;
+ }
+ static std::shared_ptr<Value> MakeString(StringRef value) {
+ auto val = std::make_shared<Value>(NT_STRING, private_init());
+ val->m_string = value;
+ val->m_val.data.v_string.str = const_cast<char*>(val->m_string.c_str());
+ val->m_val.data.v_string.len = val->m_string.size();
+ return val;
+ }
+#ifdef _MSC_VER
+ template <typename T, typename = std::enable_if_t<std::is_same<T, std::string>>>
+#else
+ template <typename T,
+ typename std::enable_if<std::is_same<T, std::string>::value>::type>
+#endif
+ static std::shared_ptr<Value> MakeString(T&& value) {
+ auto val = std::make_shared<Value>(NT_STRING, private_init());
+ val->m_string = std::move(value);
+ val->m_val.data.v_string.str = const_cast<char*>(val->m_string.c_str());
+ val->m_val.data.v_string.len = val->m_string.size();
+ return val;
+ }
+ static std::shared_ptr<Value> MakeRaw(StringRef value) {
+ auto val = std::make_shared<Value>(NT_RAW, private_init());
+ val->m_string = value;
+ val->m_val.data.v_raw.str = const_cast<char*>(val->m_string.c_str());
+ val->m_val.data.v_raw.len = val->m_string.size();
+ return val;
+ }
+#ifdef _MSC_VER
+ template <typename T, typename = std::enable_if_t<std::is_same<T, std::string>>>
+#else
+ template <typename T,
+ typename std::enable_if<std::is_same<T, std::string>::value>::type>
+#endif
+ static std::shared_ptr<Value> MakeRaw(T&& value) {
+ auto val = std::make_shared<Value>(NT_RAW, private_init());
+ val->m_string = std::move(value);
+ val->m_val.data.v_raw.str = const_cast<char*>(val->m_string.c_str());
+ val->m_val.data.v_raw.len = val->m_string.size();
+ return val;
+ }
+ static std::shared_ptr<Value> MakeRpc(StringRef value) {
+ auto val = std::make_shared<Value>(NT_RPC, private_init());
+ val->m_string = value;
+ val->m_val.data.v_raw.str = const_cast<char*>(val->m_string.c_str());
+ val->m_val.data.v_raw.len = val->m_string.size();
+ return val;
+ }
+ template <typename T>
+ static std::shared_ptr<Value> MakeRpc(T&& value) {
+ auto val = std::make_shared<Value>(NT_RPC, private_init());
+ val->m_string = std::move(value);
+ val->m_val.data.v_raw.str = const_cast<char*>(val->m_string.c_str());
+ val->m_val.data.v_raw.len = val->m_string.size();
+ return val;
+ }
+
+ static std::shared_ptr<Value> MakeBooleanArray(ArrayRef<int> value);
+ static std::shared_ptr<Value> MakeDoubleArray(ArrayRef<double> value);
+ static std::shared_ptr<Value> MakeStringArray(ArrayRef<std::string> value);
+
+ // Note: This function moves the values out of the vector.
+ static std::shared_ptr<Value> MakeStringArray(
+ std::vector<std::string>&& value);
+
+ Value(const Value&) = delete;
+ Value& operator=(const Value&) = delete;
+ friend bool operator==(const Value& lhs, const Value& rhs);
+
+ private:
+ NT_Value m_val;
+ std::string m_string;
+ std::vector<std::string> m_string_array;
+};
+
+bool operator==(const Value& lhs, const Value& rhs);
+inline bool operator!=(const Value& lhs, const Value& rhs) {
+ return !(lhs == rhs);
+}
+
+} // namespace nt
+
+#endif // NT_VALUE_H_