Iterator over interpreter::Struct

This commit is contained in:
Olivier Goffart 2021-03-18 15:07:38 +01:00
parent a3d0f3155d
commit 8a14c4fa25
2 changed files with 68 additions and 6 deletions

View file

@ -62,16 +62,63 @@ public:
Struct(InputIterator begin, Struct(InputIterator begin,
InputIterator end); // Creates InputIterator end); // Creates
// Value::Struct // Value::Struct
#endif
// FIXME: this probably miss a lot of iterator api
struct iterator struct iterator
{ {
//... iterator API to key/value pairs using value_type = std::pair<std::string_view, const Value &>;
} private:
cbindgen_private::StructIteratorOpaque inner;
const Value *v = nullptr;
std::string_view k;
friend Struct;
explicit iterator(cbindgen_private::StructIteratorOpaque inner) : inner(inner) {
next();
}
// construct a end iterator
iterator() = default;
void next() {
auto next = cbindgen_private::sixtyfps_interpreter_struct_iterator_next(&inner);
v = reinterpret_cast<const Value *>(next.v);
k = std::string_view(reinterpret_cast<char *>(next.k.ptr), next.k.len);
if (!v) {
cbindgen_private::sixtyfps_interpreter_struct_iterator_destructor(&inner);
}
}
public:
~iterator() {
if (v) {
cbindgen_private::sixtyfps_interpreter_struct_iterator_destructor(&inner);
}
}
// FIXME i believe iterator are supposed to be copy constructible
iterator(const iterator &) = delete;
iterator &operator=(const iterator &) = delete;
iterator(iterator &&) = default;
iterator &operator=(iterator &&) = default;
iterator &operator++() {
if (v)
next();
return *this;
}
value_type operator*() const {
return {k, *v};
}
friend bool operator==(const iterator&a, const iterator&b) {
return a.v == b.v;
}
friend bool operator!=(const iterator&a, const iterator&b) {
return a.v != b.v;
}
};
iterator iterator begin() const {
begin() const; return iterator(cbindgen_private::sixtyfps_interpreter_struct_make_iter(&inner));
iterator end() const; }
#endif iterator end() const {
return iterator();
}
inline std::optional<Value> get_field(std::string_view name) const; inline std::optional<Value> get_field(std::string_view name) const;
inline void set_field(std::string_view name, const Value &value); inline void set_field(std::string_view name, const Value &value);

View file

@ -172,4 +172,19 @@ SCENARIO("Struct API")
REQUIRE(value.to_string().has_value()); REQUIRE(value.to_string().has_value());
REQUIRE(value.to_string().value() == "Hallo"); REQUIRE(value.to_string().value() == "Hallo");
int count = 0;
for (auto [k, value] : struc) {
REQUIRE(count == 0);
count ++;
REQUIRE(k == "field_a");
REQUIRE(value.to_string().value() == "Hallo");
}
struc.set_field("field_b", Value(sixtyfps::SharedString("World")));
std::map<std::string, sixtyfps::SharedString> map;
for (auto [k, value] : struc) map[std::string(k)] = *value.to_string();
REQUIRE(map == std::map<std::string, sixtyfps::SharedString>{ {"field_a", sixtyfps::SharedString("Hallo") }, {"field_b", sixtyfps::SharedString("World") } });
} }