Annotations draft
This commit is contained in:
parent
9c5368b69b
commit
3c76819687
|
@ -27,4 +27,5 @@ TEST(BinaryReader, ReadSamples) {
|
||||||
BinaryReader<> r(f, &GenericEmbedded::wrap);
|
BinaryReader<> r(f, &GenericEmbedded::wrap);
|
||||||
auto v = r.next();
|
auto v = r.next();
|
||||||
ASSERT_TRUE(v);
|
ASSERT_TRUE(v);
|
||||||
|
BinaryWriter(cerr) << *v;
|
||||||
}
|
}
|
|
@ -79,7 +79,6 @@ namespace Preserves {
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<Value<T>> _next(bool& end_sentinel) {
|
boost::optional<Value<T>> _next(bool& end_sentinel) {
|
||||||
more:
|
|
||||||
end_sentinel = false;
|
end_sentinel = false;
|
||||||
auto tag = BinaryTag(i.get());
|
auto tag = BinaryTag(i.get());
|
||||||
// std::cout << "tag " << std::hex << int(tag) << " pos " << i.tellg() - 1 << std::endl;
|
// std::cout << "tag " << std::hex << int(tag) << " pos " << i.tellg() - 1 << std::endl;
|
||||||
|
@ -90,9 +89,11 @@ namespace Preserves {
|
||||||
case BinaryTag::Float: return next_float().map(Value<T>::from_float);
|
case BinaryTag::Float: return next_float().map(Value<T>::from_float);
|
||||||
case BinaryTag::Double: return next_double().map(Value<T>::from_double);
|
case BinaryTag::Double: return next_double().map(Value<T>::from_double);
|
||||||
case BinaryTag::End: end_sentinel = true; return boost::none;
|
case BinaryTag::End: end_sentinel = true; return boost::none;
|
||||||
case BinaryTag::Annotation:
|
case BinaryTag::Annotation: return next().flat_map([&](Value<T> const& ann) -> boost::optional<Value<T>> {
|
||||||
if (!next()) return boost::none;
|
return next().flat_map([&](Value<T> const& v) -> boost::optional<Value<T>> {
|
||||||
goto more;
|
return v.annotate(ann);
|
||||||
|
});
|
||||||
|
});
|
||||||
case BinaryTag::Embedded:
|
case BinaryTag::Embedded:
|
||||||
return BinaryReader<GenericEmbedded>(i, &GenericEmbedded::wrap)
|
return BinaryReader<GenericEmbedded>(i, &GenericEmbedded::wrap)
|
||||||
.next().map(decodeEmbedded).map(Value<T>::from_embedded);
|
.next().map(decodeEmbedded).map(Value<T>::from_embedded);
|
||||||
|
|
|
@ -269,6 +269,88 @@ namespace Preserves {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class AnnotatedValue: public ValueImpl<T> {
|
||||||
|
Value<T> underlying;
|
||||||
|
std::vector<Value<T>> anns;
|
||||||
|
|
||||||
|
friend class ValueImpl<T>;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Value<T> internal_annotate(std::shared_ptr<ValueImpl<T>> const& self, Value<T> const &ann) {
|
||||||
|
if (self.use_count() == 1) {
|
||||||
|
anns.push_back(ann);
|
||||||
|
return self;
|
||||||
|
} else {
|
||||||
|
auto a = std::make_shared<AnnotatedValue<T>>(underlying);
|
||||||
|
a->anns.insert(a->anns.end(), anns.begin(), anns.end());
|
||||||
|
a->anns.push_back(ann);
|
||||||
|
return Value<T>(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
AnnotatedValue(Value<T> const& v) : underlying(v) {}
|
||||||
|
|
||||||
|
ValueKind value_kind() const override { return underlying.value_kind(); }
|
||||||
|
bool is_mutable() const override { return underlying.is_mutable(); }
|
||||||
|
|
||||||
|
boost::optional<bool> as_bool() const override { return underlying.as_bool(); }
|
||||||
|
boost::optional<float> as_float() const override { return underlying.as_float(); }
|
||||||
|
boost::optional<double> as_double() const override { return underlying.as_double(); }
|
||||||
|
boost::optional<uint64_t> as_unsigned() const override { return underlying.as_unsigned(); }
|
||||||
|
boost::optional<int64_t> as_signed() const override { return underlying.as_signed(); }
|
||||||
|
boost::optional<std::vector<uint8_t> const&> as_bignum() const override { return underlying.as_bignum(); }
|
||||||
|
boost::optional<std::string const&> as_string() const override { return underlying.as_string(); }
|
||||||
|
boost::optional<std::vector<uint8_t> const&> as_bytes() const override { return underlying.as_bytes(); }
|
||||||
|
boost::optional<std::string const&> as_symbol() const override { return underlying.as_symbol(); }
|
||||||
|
boost::optional<Record<T> const&> as_record() const override { return underlying.as_record(); }
|
||||||
|
boost::optional<std::vector<Value<T>> const&> as_sequence() const override { return underlying.as_sequence(); }
|
||||||
|
boost::optional<std::set<Value<T>> const&> as_set() const override { return underlying.as_set(); }
|
||||||
|
boost::optional<std::map<Value<T>,Value<T>> const&> as_dictionary() const override { return underlying.as_dictionary(); }
|
||||||
|
boost::optional<std::shared_ptr<T>> as_embedded() const override { return underlying.as_embedded(); }
|
||||||
|
|
||||||
|
boost::optional<Value<T>> label() const override { return underlying.label(); }
|
||||||
|
size_t size() const override { return underlying.size(); }
|
||||||
|
bool contains(Value<T> const& key) const override { return underlying.contains(key); }
|
||||||
|
boost::optional<Value<T>> get(Value<T> const& key) const override { return underlying.get(key); }
|
||||||
|
boost::optional<Value<T>> get(size_t index) const override { return underlying.get(index); }
|
||||||
|
|
||||||
|
bool add(Value<T> const& item) override {
|
||||||
|
return underlying->add(item);
|
||||||
|
}
|
||||||
|
bool set(Value<T> const& key, Value<T> const& value) override {
|
||||||
|
return underlying->set(key, value);
|
||||||
|
}
|
||||||
|
bool set(size_t index, Value<T> const& value) override {
|
||||||
|
return underlying->set(index, value);
|
||||||
|
}
|
||||||
|
bool erase(Value<T> const& key) override {
|
||||||
|
return underlying->erase(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::optional<std::vector<Value<T>> const&> annotations() const override {
|
||||||
|
return anns;
|
||||||
|
}
|
||||||
|
|
||||||
|
BinaryWriter& write(BinaryWriter &w) const override {
|
||||||
|
for (auto& v : anns) { w << BinaryTag::Annotation << v; }
|
||||||
|
return w << underlying;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Value<T> Value<T>::annotate(Value<T> const& ann) const {
|
||||||
|
return p->internal_annotate(p, ann);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Value<T> ValueImpl<T>::internal_annotate(std::shared_ptr<ValueImpl<T>> const& self, Value<T> const &ann) {
|
||||||
|
auto a = std::make_shared<AnnotatedValue<T>>(Value<T>(self));
|
||||||
|
a->anns.push_back(ann);
|
||||||
|
return Value<T>(a);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Value<T> Value<T>::from_bool(bool b)
|
Value<T> Value<T>::from_bool(bool b)
|
||||||
{
|
{
|
||||||
|
|
|
@ -148,6 +148,9 @@ namespace Preserves {
|
||||||
boost::optional<std::shared_ptr<T>> as_embedded() const;
|
boost::optional<std::shared_ptr<T>> as_embedded() const;
|
||||||
std::shared_ptr<T> to_embedded() const { return as_embedded().value(); }
|
std::shared_ptr<T> to_embedded() const { return as_embedded().value(); }
|
||||||
|
|
||||||
|
Value annotate(Value const& ann) const;
|
||||||
|
boost::optional<std::vector<Value> const&> annotations() const;
|
||||||
|
|
||||||
boost::optional<Value> label() const;
|
boost::optional<Value> label() const;
|
||||||
size_t size() const;
|
size_t size() const;
|
||||||
bool contains(Value const& key) const;
|
bool contains(Value const& key) const;
|
||||||
|
@ -161,6 +164,10 @@ namespace Preserves {
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ValueImpl {
|
class ValueImpl {
|
||||||
|
protected:
|
||||||
|
virtual Value<T> internal_annotate(std::shared_ptr<ValueImpl<T>> const& self, Value<T> const& ann);
|
||||||
|
|
||||||
|
friend class Value<T>;
|
||||||
public:
|
public:
|
||||||
virtual ~ValueImpl() {}
|
virtual ~ValueImpl() {}
|
||||||
|
|
||||||
|
@ -201,6 +208,8 @@ namespace Preserves {
|
||||||
throw std::runtime_error("Cannot erase item in Preserves value");
|
throw std::runtime_error("Cannot erase item in Preserves value");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual boost::optional<std::vector<Value<T>> const&> annotations() const { return boost::none; }
|
||||||
|
|
||||||
virtual BinaryWriter& write(BinaryWriter& w) const = 0;
|
virtual BinaryWriter& write(BinaryWriter& w) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -227,6 +236,9 @@ namespace Preserves {
|
||||||
PRESERVES_DELEGATE_CAST(std::shared_ptr<T>, as_embedded);
|
PRESERVES_DELEGATE_CAST(std::shared_ptr<T>, as_embedded);
|
||||||
#undef PRESERVES_DELEGATE_CAST
|
#undef PRESERVES_DELEGATE_CAST
|
||||||
|
|
||||||
|
template <typename T> boost::optional<Value<T>> Value<T>::label() const { return p->label(); }
|
||||||
|
template <typename T> bool Value<T>::contains(Value const& key) const { return p->contains(key); }
|
||||||
|
template <typename T> boost::optional<Value<T>> Value<T>::get(Value<T> const& key) const { return p->get(key); }
|
||||||
template <typename T> boost::optional<Value<T>> Value<T>::get(size_t index) const { return p->get(index); }
|
template <typename T> boost::optional<Value<T>> Value<T>::get(size_t index) const { return p->get(index); }
|
||||||
template <typename T> size_t Value<T>::size() const { return p->size(); }
|
template <typename T> size_t Value<T>::size() const { return p->size(); }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue