improve nf7::Value interface

This commit is contained in:
falsycat 2022-10-21 12:49:48 +09:00
parent e927179176
commit 50f270b571
2 changed files with 78 additions and 46 deletions

View File

@ -51,10 +51,10 @@ void PushValue(lua_State* L, const nf7::Value& v) noexcept {
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;

View File

@ -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,8 +172,8 @@ 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 {
@ -187,8 +183,8 @@ class Value {
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<