2015-06-21 21:02:10 -07:00
|
|
|
/*----------------------------------------------------------------------------*/
|
|
|
|
|
/* 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_
|
|
|
|
|
|
2015-06-28 21:52:06 -07:00
|
|
|
#include <cassert>
|
2015-06-29 23:08:35 -07:00
|
|
|
#include <vector>
|
2015-06-21 21:02:10 -07:00
|
|
|
|
2015-06-28 21:52:06 -07:00
|
|
|
#include "ntcore.h"
|
2015-06-21 21:02:10 -07:00
|
|
|
|
2015-06-28 21:52:06 -07:00
|
|
|
#include "llvm/ArrayRef.h"
|
|
|
|
|
#include "llvm/StringRef.h"
|
|
|
|
|
|
|
|
|
|
namespace ntimpl {
|
|
|
|
|
|
2015-07-12 11:24:34 -07:00
|
|
|
class Message;
|
2015-07-03 13:29:31 -07:00
|
|
|
class StringValueTest;
|
2015-06-28 21:52:06 -07:00
|
|
|
class Storage;
|
|
|
|
|
class Value;
|
2015-07-03 13:29:31 -07:00
|
|
|
class ValueTest;
|
2015-07-04 23:10:59 -07:00
|
|
|
class WireDecoder;
|
2015-06-28 21:52:06 -07:00
|
|
|
|
2015-06-28 21:56:20 -07:00
|
|
|
/*
|
|
|
|
|
* C++ wrapper class around NT_String.
|
|
|
|
|
*/
|
2015-06-28 21:52:06 -07:00
|
|
|
class StringValue : private NT_String {
|
2015-07-12 11:24:34 -07:00
|
|
|
friend class Message;
|
2015-07-03 13:29:31 -07:00
|
|
|
friend class StringValueTest;
|
2015-06-28 21:52:06 -07:00
|
|
|
friend class Value;
|
2015-07-04 23:10:59 -07:00
|
|
|
friend class WireDecoder;
|
2015-06-28 21:52:06 -07:00
|
|
|
public:
|
|
|
|
|
StringValue() { NT_InitString(this); }
|
2015-07-04 23:10:59 -07:00
|
|
|
explicit StringValue(llvm::StringRef val);
|
2015-06-28 21:52:06 -07:00
|
|
|
~StringValue() { NT_DisposeString(this); }
|
|
|
|
|
|
|
|
|
|
operator llvm::StringRef() const { return llvm::StringRef(str, len); }
|
2015-06-28 21:56:20 -07:00
|
|
|
|
|
|
|
|
StringValue(const StringValue&) = delete;
|
|
|
|
|
StringValue& operator=(const StringValue&) = delete;
|
2015-06-29 23:08:35 -07:00
|
|
|
|
|
|
|
|
StringValue(StringValue&& other) {
|
|
|
|
|
str = other.str;
|
|
|
|
|
len = other.len;
|
|
|
|
|
other.str = nullptr;
|
|
|
|
|
other.len = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
StringValue& operator=(StringValue&& other) {
|
|
|
|
|
if (this != &other) {
|
|
|
|
|
NT_DisposeString(this);
|
|
|
|
|
str = other.str;
|
|
|
|
|
len = other.len;
|
|
|
|
|
other.str = nullptr;
|
|
|
|
|
other.len = 0;
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
2015-06-28 21:52:06 -07:00
|
|
|
};
|
|
|
|
|
|
2015-07-04 23:10:59 -07:00
|
|
|
inline bool operator==(const StringValue& lhs, const StringValue& rhs) {
|
|
|
|
|
return llvm::StringRef(lhs) == llvm::StringRef(rhs);
|
|
|
|
|
}
|
|
|
|
|
inline bool operator!=(const StringValue& lhs, const StringValue& rhs) {
|
|
|
|
|
return llvm::StringRef(lhs) != llvm::StringRef(rhs);
|
|
|
|
|
}
|
|
|
|
|
inline bool operator==(llvm::StringRef lhs, const StringValue& rhs) {
|
|
|
|
|
return lhs == llvm::StringRef(rhs);
|
|
|
|
|
}
|
|
|
|
|
inline bool operator!=(llvm::StringRef lhs, const StringValue& rhs) {
|
|
|
|
|
return lhs != llvm::StringRef(rhs);
|
|
|
|
|
}
|
|
|
|
|
inline bool operator==(const StringValue& lhs, llvm::StringRef rhs) {
|
|
|
|
|
return llvm::StringRef(lhs) == rhs;
|
|
|
|
|
}
|
|
|
|
|
inline bool operator!=(const StringValue& lhs, llvm::StringRef rhs) {
|
|
|
|
|
return llvm::StringRef(lhs) != rhs;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-28 21:56:20 -07:00
|
|
|
/*
|
|
|
|
|
* C++ wrapper class around NT_Value.
|
|
|
|
|
*/
|
2015-06-28 21:52:06 -07:00
|
|
|
class Value : private NT_Value {
|
2015-07-12 11:24:34 -07:00
|
|
|
friend class Message;
|
2015-06-28 21:52:06 -07:00
|
|
|
friend class Storage;
|
2015-07-12 11:24:34 -07:00
|
|
|
friend class ValueTest;
|
2015-07-04 23:10:59 -07:00
|
|
|
friend class WireDecoder;
|
2015-06-28 21:52:06 -07:00
|
|
|
public:
|
|
|
|
|
Value() { NT_InitValue(this); }
|
|
|
|
|
~Value() { NT_DisposeValue(this); }
|
|
|
|
|
|
|
|
|
|
// A little ugly, as it hides the identically-named NT_Value::type.
|
|
|
|
|
NT_Type type() const { return NT_Value::type; }
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Type-Safe Getters
|
|
|
|
|
*/
|
|
|
|
|
bool GetBoolean() const {
|
|
|
|
|
assert(NT_Value::type == NT_BOOLEAN);
|
|
|
|
|
return data.v_boolean;
|
|
|
|
|
}
|
|
|
|
|
double GetDouble() const {
|
|
|
|
|
assert(NT_Value::type == NT_DOUBLE);
|
|
|
|
|
return data.v_double;
|
|
|
|
|
}
|
|
|
|
|
llvm::StringRef GetString() const {
|
|
|
|
|
assert(NT_Value::type == NT_STRING);
|
|
|
|
|
return static_cast<const StringValue&>(data.v_string);
|
|
|
|
|
}
|
|
|
|
|
llvm::StringRef GetRaw() const {
|
|
|
|
|
assert(NT_Value::type == NT_RAW);
|
|
|
|
|
return static_cast<const StringValue&>(data.v_raw);
|
|
|
|
|
}
|
|
|
|
|
llvm::ArrayRef<int> GetBooleanArray() const {
|
|
|
|
|
assert(NT_Value::type == NT_BOOLEAN_ARRAY);
|
|
|
|
|
return llvm::ArrayRef<int>(data.arr_boolean.arr, data.arr_boolean.size);
|
|
|
|
|
}
|
|
|
|
|
llvm::ArrayRef<double> GetDoubleArray() const {
|
|
|
|
|
assert(NT_Value::type == NT_DOUBLE_ARRAY);
|
|
|
|
|
return llvm::ArrayRef<double>(data.arr_double.arr, data.arr_double.size);
|
|
|
|
|
}
|
|
|
|
|
llvm::ArrayRef<StringValue> GetStringArray() const {
|
2015-07-03 13:29:31 -07:00
|
|
|
assert(NT_Value::type == NT_STRING_ARRAY);
|
2015-06-28 21:52:06 -07:00
|
|
|
return llvm::ArrayRef<StringValue>(
|
|
|
|
|
static_cast<StringValue*>(data.arr_string.arr), data.arr_string.size);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Type-Safe Setters
|
|
|
|
|
*/
|
2015-06-29 23:08:35 -07:00
|
|
|
void SetBoolean(bool value) {
|
|
|
|
|
if (NT_Value::type != NT_BOOLEAN) {
|
|
|
|
|
NT_DisposeValue(this);
|
|
|
|
|
NT_Value::type = NT_BOOLEAN;
|
|
|
|
|
}
|
|
|
|
|
data.v_boolean = value ? 1 : 0;
|
2015-06-28 21:52:06 -07:00
|
|
|
}
|
2015-06-29 23:08:35 -07:00
|
|
|
void SetDouble(double value) {
|
|
|
|
|
if (NT_Value::type != NT_DOUBLE) {
|
|
|
|
|
NT_DisposeValue(this);
|
|
|
|
|
NT_Value::type = NT_DOUBLE;
|
|
|
|
|
}
|
|
|
|
|
data.v_double = value;
|
2015-06-28 21:52:06 -07:00
|
|
|
}
|
2015-06-29 23:08:35 -07:00
|
|
|
void SetString(llvm::StringRef value) { SetString(StringValue(value)); }
|
|
|
|
|
void SetString(StringValue&& value) {
|
|
|
|
|
if (NT_Value::type != NT_STRING) {
|
|
|
|
|
NT_DisposeValue(this);
|
|
|
|
|
data.v_string.str = nullptr;
|
|
|
|
|
data.v_string.len = 0;
|
|
|
|
|
NT_Value::type = NT_STRING;
|
|
|
|
|
}
|
2015-07-03 13:29:31 -07:00
|
|
|
static_cast<StringValue&>(data.v_string) = std::move(value);
|
2015-06-28 21:52:06 -07:00
|
|
|
}
|
2015-06-29 23:08:35 -07:00
|
|
|
void SetRaw(llvm::StringRef value) { SetRaw(StringValue(value)); }
|
|
|
|
|
void SetRaw(StringValue&& value) {
|
|
|
|
|
if (NT_Value::type != NT_RAW) {
|
|
|
|
|
NT_DisposeValue(this);
|
|
|
|
|
data.v_raw.str = nullptr;
|
|
|
|
|
data.v_raw.len = 0;
|
|
|
|
|
NT_Value::type = NT_RAW;
|
|
|
|
|
}
|
2015-07-03 13:29:31 -07:00
|
|
|
static_cast<StringValue&>(data.v_raw) = std::move(value);
|
2015-06-29 23:08:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SetBooleanArray(llvm::ArrayRef<int> value);
|
|
|
|
|
void SetDoubleArray(llvm::ArrayRef<double> value);
|
|
|
|
|
|
|
|
|
|
// Note: This function moves the values out of the vector.
|
|
|
|
|
void SetStringArray(std::vector<StringValue>& value);
|
2015-06-28 21:52:06 -07:00
|
|
|
|
|
|
|
|
Value(const Value&) = delete;
|
|
|
|
|
Value& operator=(const Value&) = delete;
|
|
|
|
|
|
2015-06-29 23:08:35 -07:00
|
|
|
Value(Value&& other) {
|
|
|
|
|
NT_Value::type = static_cast<NT_Value&>(other).type;
|
|
|
|
|
last_change = other.last_change;
|
|
|
|
|
data = other.data;
|
|
|
|
|
static_cast<NT_Value&>(other).type = NT_UNASSIGNED;
|
|
|
|
|
other.last_change = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Value& operator=(Value&& other) {
|
|
|
|
|
if (this != &other) {
|
|
|
|
|
NT_DisposeValue(this);
|
|
|
|
|
NT_Value::type = static_cast<NT_Value&>(other).type;
|
|
|
|
|
last_change = other.last_change;
|
|
|
|
|
data = other.data;
|
|
|
|
|
static_cast<NT_Value&>(other).type = NT_UNASSIGNED;
|
|
|
|
|
other.last_change = 0;
|
|
|
|
|
}
|
|
|
|
|
return *this;
|
|
|
|
|
}
|
|
|
|
|
|
2015-06-28 21:52:06 -07:00
|
|
|
friend bool operator==(const Value& lhs, const Value& rhs);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bool operator==(const Value& lhs, const Value& rhs);
|
2015-07-03 13:29:31 -07:00
|
|
|
inline bool operator!=(const Value& lhs, const Value& rhs) {
|
|
|
|
|
return !(lhs == rhs);
|
|
|
|
|
}
|
2015-06-28 21:52:06 -07:00
|
|
|
|
|
|
|
|
} // namespace ntimpl
|
2015-06-21 21:02:10 -07:00
|
|
|
|
2015-06-25 22:57:43 -07:00
|
|
|
#endif // NT_VALUE_H_
|