improve nf7::Value interface
This commit is contained in:
parent
e927179176
commit
50f270b571
@ -46,15 +46,15 @@ void PushValue(lua_State* L, const nf7::Value& v) noexcept {
|
|||||||
struct Visitor final {
|
struct Visitor final {
|
||||||
lua_State* L;
|
lua_State* L;
|
||||||
const nf7::Value& v;
|
const nf7::Value& v;
|
||||||
auto operator()(Value::Pulse) noexcept { lua_pushnil(L); }
|
auto operator()(Value::Pulse) noexcept { lua_pushnil(L); }
|
||||||
auto operator()(Value::Boolean) noexcept { lua_pushboolean(L, v.boolean()); }
|
auto operator()(Value::Boolean) noexcept { lua_pushboolean(L, v.boolean()); }
|
||||||
auto operator()(Value::Integer) noexcept { lua_pushinteger(L, v.integer()); }
|
auto operator()(Value::Integer) noexcept { lua_pushinteger(L, v.integer()); }
|
||||||
auto operator()(Value::Scalar) noexcept { lua_pushnumber(L, v.scalar()); }
|
auto operator()(Value::Scalar) noexcept { lua_pushnumber(L, v.scalar()); }
|
||||||
auto operator()(Value::String) noexcept { lua_pushstring(L, v.string().c_str()); }
|
auto operator()(Value::String) noexcept { lua_pushstring(L, v.string().c_str()); }
|
||||||
auto operator()(Value::Vector) noexcept { PushVector(L, v.vector()); }
|
auto operator()(Value::ConstVector) noexcept { PushVector(L, v.vector()); }
|
||||||
auto operator()(Value::DataPtr) noexcept { lua_pushnil(L); }
|
auto operator()(Value::DataPtr) noexcept { lua_pushnil(L); }
|
||||||
|
|
||||||
auto operator()(Value::Tuple) noexcept {
|
auto operator()(Value::ConstTuple) noexcept {
|
||||||
const auto& tup = *v.tuple();
|
const auto& tup = *v.tuple();
|
||||||
lua_createtable(L, 0, 0);
|
lua_createtable(L, 0, 0);
|
||||||
size_t arridx = 0;
|
size_t arridx = 0;
|
||||||
|
108
common/value.hh
108
common/value.hh
@ -62,31 +62,26 @@ class Value {
|
|||||||
Value& operator=(Scalar v) noexcept { value_ = v; return *this; }
|
Value& operator=(Scalar v) noexcept { value_ = v; return *this; }
|
||||||
Value(Boolean v) noexcept : value_(v) { }
|
Value(Boolean v) noexcept : value_(v) { }
|
||||||
Value& operator=(Boolean v) noexcept { value_ = v; return *this; }
|
Value& operator=(Boolean v) noexcept { value_ = v; return *this; }
|
||||||
|
|
||||||
Value(std::string_view v) noexcept : value_(std::string {v}) { }
|
Value(std::string_view v) noexcept : value_(std::string {v}) { }
|
||||||
Value& operator=(std::string_view v) noexcept { value_ = std::string(v); return *this; }
|
Value& operator=(std::string_view v) noexcept { value_ = std::string(v); return *this; }
|
||||||
Value(String&& v) noexcept : value_(std::move(v)) { }
|
Value(String&& v) noexcept : value_(std::move(v)) { }
|
||||||
Value& operator=(String&& v) noexcept { value_ = std::move(v); return *this; }
|
Value& operator=(String&& v) noexcept { value_ = std::move(v); return *this; }
|
||||||
Value(const Vector& v) noexcept { value_ = v; }
|
|
||||||
Value& operator=(const Vector& v) noexcept { value_ = v; return *this; }
|
Value(const Vector& v) noexcept : value_(v? v: std::make_shared<std::vector<uint8_t>>()) { }
|
||||||
Value(Vector&& v) noexcept { value_ = std::move(v); }
|
Value& operator=(const Vector& v) noexcept { value_ = v? v: std::make_shared<std::vector<uint8_t>>(); return *this; }
|
||||||
Value& operator=(Vector&& v) noexcept { value_ = std::move(v); return *this; }
|
Value(const ConstVector& v) noexcept : value_(v? std::const_pointer_cast<std::vector<uint8_t>>(v): std::make_shared<std::vector<uint8_t>>()) { }
|
||||||
Value(const ConstVector& v) noexcept { value_ = std::const_pointer_cast<std::vector<uint8_t>>(v); }
|
Value& operator=(const ConstVector& v) noexcept { value_ = v? std::const_pointer_cast<std::vector<uint8_t>>(v): std::make_shared<std::vector<uint8_t>>(); return *this; }
|
||||||
Value& operator=(const ConstVector& v) noexcept { value_ = std::const_pointer_cast<std::vector<uint8_t>>(v); return *this; }
|
Value(std::vector<uint8_t>&& v) noexcept : value_(std::make_shared<std::vector<uint8_t>>(std::move(v))) { }
|
||||||
Value(std::vector<uint8_t>&& v) noexcept { value_ = std::make_shared<std::vector<uint8_t>>(std::move(v)); }
|
|
||||||
Value& operator=(std::vector<uint8_t>&& v) noexcept { value_ = std::make_shared<std::vector<uint8_t>>(std::move(v)); return *this; }
|
Value& operator=(std::vector<uint8_t>&& v) noexcept { value_ = std::make_shared<std::vector<uint8_t>>(std::move(v)); return *this; }
|
||||||
Value(const Tuple& v) noexcept : value_(v) { }
|
|
||||||
Value& operator=(const Tuple& v) noexcept { value_ = v; return *this; }
|
Value(const Tuple& v) noexcept : value_(v? v: std::make_shared<std::vector<TuplePair>>()) { }
|
||||||
Value(Tuple&& v) noexcept : value_(std::move(v)) { }
|
Value& operator=(const Tuple& v) noexcept { value_ = v? v: std::make_shared<std::vector<TuplePair>>(); return *this; }
|
||||||
Value& operator=(Tuple&& v) noexcept { value_ = std::move(v); return *this; }
|
Value(const ConstTuple& v) noexcept : value_(v? v: std::make_shared<std::vector<TuplePair>>()) { }
|
||||||
Value(std::vector<TuplePair>&& p) noexcept { value_ = std::make_shared<std::vector<TuplePair>>(std::move(p)); }
|
Value& operator=(const ConstTuple& v) noexcept { value_ = v? v: std::make_shared<std::vector<TuplePair>>(); return *this; }
|
||||||
|
Value(std::vector<TuplePair>&& p) noexcept : value_(std::make_shared<std::vector<TuplePair>>(std::move(p))) { }
|
||||||
Value& operator=(std::vector<TuplePair>&& p) noexcept { value_ = std::make_shared<std::vector<TuplePair>>(std::move(p)); return *this; }
|
Value& operator=(std::vector<TuplePair>&& p) noexcept { value_ = std::make_shared<std::vector<TuplePair>>(std::move(p)); return *this; }
|
||||||
Value(std::vector<nf7::Value>&& v) noexcept {
|
Value(std::vector<nf7::Value>&& v) noexcept { *this = std::move(v); }
|
||||||
std::vector<TuplePair> pairs;
|
|
||||||
pairs.reserve(v.size());
|
|
||||||
std::transform(v.begin(), v.end(), std::back_inserter(pairs),
|
|
||||||
[](auto& x) { return TuplePair {"", std::move(x)}; });
|
|
||||||
value_ = std::make_shared<std::vector<TuplePair>>(std::move(pairs));
|
|
||||||
}
|
|
||||||
Value& operator=(std::vector<nf7::Value>&& v) noexcept {
|
Value& operator=(std::vector<nf7::Value>&& v) noexcept {
|
||||||
std::vector<TuplePair> pairs;
|
std::vector<TuplePair> pairs;
|
||||||
pairs.reserve(v.size());
|
pairs.reserve(v.size());
|
||||||
@ -95,6 +90,7 @@ class Value {
|
|||||||
value_ = std::make_shared<std::vector<TuplePair>>(std::move(pairs));
|
value_ = std::make_shared<std::vector<TuplePair>>(std::move(pairs));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Value(const DataPtr& v) noexcept : value_(v) { }
|
Value(const DataPtr& v) noexcept : value_(v) { }
|
||||||
Value& operator=(const DataPtr& v) noexcept { value_ = v; return *this; }
|
Value& operator=(const DataPtr& v) noexcept { value_ = v; return *this; }
|
||||||
Value(DataPtr&& v) noexcept : value_(std::move(v)) { }
|
Value(DataPtr&& v) noexcept : value_(std::move(v)) { }
|
||||||
@ -109,16 +105,16 @@ class Value {
|
|||||||
bool isInteger() const noexcept { return std::holds_alternative<Integer>(value_); }
|
bool isInteger() const noexcept { return std::holds_alternative<Integer>(value_); }
|
||||||
bool isScalar() const noexcept { return std::holds_alternative<Scalar>(value_); }
|
bool isScalar() const noexcept { return std::holds_alternative<Scalar>(value_); }
|
||||||
bool isString() const noexcept { return std::holds_alternative<String>(value_); }
|
bool isString() const noexcept { return std::holds_alternative<String>(value_); }
|
||||||
bool isVector() const noexcept { return std::holds_alternative<Vector>(value_); }
|
bool isVector() const noexcept { return std::holds_alternative<ConstVector>(value_); }
|
||||||
bool isTuple() const noexcept { return std::holds_alternative<Tuple>(value_); }
|
bool isTuple() const noexcept { return std::holds_alternative<ConstTuple>(value_); }
|
||||||
bool isData() const noexcept { return std::holds_alternative<DataPtr>(value_); }
|
bool isData() const noexcept { return std::holds_alternative<DataPtr>(value_); }
|
||||||
|
|
||||||
Integer integer() const { return get<Integer>(); }
|
Integer integer() const { return get<Integer>(); }
|
||||||
Boolean boolean() const { return get<Boolean>(); }
|
Boolean boolean() const { return get<Boolean>(); }
|
||||||
Scalar scalar() const { return get<Scalar>(); }
|
Scalar scalar() const { return get<Scalar>(); }
|
||||||
const String& string() const { return get<String>(); }
|
const String& string() const { return get<String>(); }
|
||||||
const ConstVector vector() const { return get<Vector>(); }
|
const ConstVector& vector() const { return get<ConstVector>(); }
|
||||||
const ConstTuple tuple() const { return get<Tuple>(); }
|
const ConstTuple& tuple() const { return get<ConstTuple>(); }
|
||||||
const DataPtr& data() const { return get<DataPtr>(); }
|
const DataPtr& data() const { return get<DataPtr>(); }
|
||||||
|
|
||||||
template <typename N>
|
template <typename N>
|
||||||
@ -158,7 +154,7 @@ class Value {
|
|||||||
return itr < tup.end()? itr->second:
|
return itr < tup.end()? itr->second:
|
||||||
throw IncompatibleException("unknown tuple field: "+std::string {name});
|
throw IncompatibleException("unknown tuple field: "+std::string {name});
|
||||||
}
|
}
|
||||||
const Value& tupleOr(auto idx, const Value& v) const noexcept {
|
Value tupleOr(auto idx, const Value& v) const noexcept {
|
||||||
try {
|
try {
|
||||||
return tuple(idx);
|
return tuple(idx);
|
||||||
} catch (nf7::Exception&) {
|
} catch (nf7::Exception&) {
|
||||||
@ -176,20 +172,20 @@ class Value {
|
|||||||
Scalar& scalar() { return get<Scalar>(); }
|
Scalar& scalar() { return get<Scalar>(); }
|
||||||
String& string() { return get<String>(); }
|
String& string() { return get<String>(); }
|
||||||
|
|
||||||
Vector vectorUniq() { return getUniq<Vector>(); }
|
Vector vectorUniq() { return getUniq<ConstVector>(); }
|
||||||
Tuple tupleUniq() { return getUniq<Tuple>(); }
|
Tuple tupleUniq() { return getUniq<ConstTuple>(); }
|
||||||
|
|
||||||
const char* typeName() const noexcept {
|
const char* typeName() const noexcept {
|
||||||
struct Visitor final {
|
struct Visitor final {
|
||||||
public:
|
public:
|
||||||
auto operator()(Pulse) noexcept { return "pulse"; }
|
auto operator()(Pulse) noexcept { return "pulse"; }
|
||||||
auto operator()(Boolean) noexcept { return "boolean"; }
|
auto operator()(Boolean) noexcept { return "boolean"; }
|
||||||
auto operator()(Integer) noexcept { return "integer"; }
|
auto operator()(Integer) noexcept { return "integer"; }
|
||||||
auto operator()(Scalar) noexcept { return "scalar"; }
|
auto operator()(Scalar) noexcept { return "scalar"; }
|
||||||
auto operator()(String) noexcept { return "string"; }
|
auto operator()(String) noexcept { return "string"; }
|
||||||
auto operator()(Vector) noexcept { return "vector"; }
|
auto operator()(ConstVector) noexcept { return "vector"; }
|
||||||
auto operator()(Tuple) noexcept { return "tuple"; }
|
auto operator()(ConstTuple) noexcept { return "tuple"; }
|
||||||
auto operator()(DataPtr) noexcept { return "data"; }
|
auto operator()(DataPtr) noexcept { return "data"; }
|
||||||
};
|
};
|
||||||
return Visit(Visitor{});
|
return Visit(Visitor{});
|
||||||
}
|
}
|
||||||
@ -201,7 +197,7 @@ class Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::variant<Pulse, Boolean, Integer, Scalar, String, Vector, Tuple, DataPtr> value_;
|
std::variant<Pulse, Boolean, Integer, Scalar, String, ConstVector, ConstTuple, DataPtr> value_;
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
@ -218,12 +214,12 @@ class Value {
|
|||||||
throw IncompatibleException(st.str());
|
throw IncompatibleException(st.str());
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T getUniq() {
|
std::shared_ptr<typename std::remove_const<typename T::element_type>::type> getUniq() {
|
||||||
auto v = std::move(get<T>());
|
auto v = std::move(get<T>());
|
||||||
if (v.use_count() == 1) {
|
if (v.use_count() == 1) {
|
||||||
return v;
|
return std::const_pointer_cast<typename std::remove_const<typename T::element_type>::type>(v);
|
||||||
} else {
|
} else {
|
||||||
return std::make_shared<typename T::element_type>(*v);
|
return std::make_shared<typename std::remove_const<typename T::element_type>::type>(*v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -298,6 +294,22 @@ struct serializer<
|
|||||||
throw nf7::DeserializeException("cannot deserialize Value::Vector");
|
throw nf7::DeserializeException("cannot deserialize Value::Vector");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
template <size_t F>
|
||||||
|
struct serializer<
|
||||||
|
type_prop::not_a_fundamental,
|
||||||
|
ser_case::use_internal_serializer,
|
||||||
|
F,
|
||||||
|
nf7::Value::ConstVector> {
|
||||||
|
public:
|
||||||
|
template <typename Archive>
|
||||||
|
static Archive& save(Archive&, const nf7::Value::ConstVector&) {
|
||||||
|
throw nf7::Exception("cannot serialize Value::Vector");
|
||||||
|
}
|
||||||
|
template <typename Archive>
|
||||||
|
static Archive& load(Archive&, nf7::Value::ConstVector&) {
|
||||||
|
throw nf7::DeserializeException("cannot deserialize Value::Vector");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <size_t F>
|
template <size_t F>
|
||||||
struct serializer<
|
struct serializer<
|
||||||
@ -317,6 +329,26 @@ struct serializer<
|
|||||||
return ar;
|
return ar;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
template <size_t F>
|
||||||
|
struct serializer<
|
||||||
|
type_prop::not_a_fundamental,
|
||||||
|
ser_case::use_internal_serializer,
|
||||||
|
F,
|
||||||
|
nf7::Value::ConstTuple> {
|
||||||
|
public:
|
||||||
|
template <typename Archive>
|
||||||
|
static Archive& save(Archive& ar, const nf7::Value::ConstTuple& tup) {
|
||||||
|
ar(*tup);
|
||||||
|
return ar;
|
||||||
|
}
|
||||||
|
template <typename Archive>
|
||||||
|
static Archive& load(Archive& ar, nf7::Value::ConstTuple& tup) {
|
||||||
|
auto ptr = std::make_shared<std::vector<nf7::Value::TuplePair>>();
|
||||||
|
ar(*ptr);
|
||||||
|
tup = std::move(ptr);
|
||||||
|
return ar;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template <size_t F>
|
template <size_t F>
|
||||||
struct serializer<
|
struct serializer<
|
||||||
|
Loading…
x
Reference in New Issue
Block a user