summaryrefslogtreecommitdiff
path: root/include/erebos/storage.h
diff options
context:
space:
mode:
authorRoman Smrž <roman.smrz@seznam.cz>2023-06-17 21:58:32 +0200
committerRoman Smrž <roman.smrz@seznam.cz>2023-06-18 22:41:23 +0200
commite7d6aafd3c9353d9e6169ca775cf1dae618238cd (patch)
tree6df8f296d7db8dd9e7d23f5774009ccc5ee269a7 /include/erebos/storage.h
parent2130d07cbf91e016fd21a730a8449dd4bd34a093 (diff)
Storage: iterable type for record item list
Diffstat (limited to 'include/erebos/storage.h')
-rw-r--r--include/erebos/storage.h187
1 files changed, 137 insertions, 50 deletions
diff --git a/include/erebos/storage.h b/include/erebos/storage.h
index 3a3073d..32049db 100644
--- a/include/erebos/storage.h
+++ b/include/erebos/storage.h
@@ -40,8 +40,12 @@ template<typename T> class Head;
using std::bind;
using std::call_once;
using std::make_unique;
+using std::monostate;
using std::move;
+using std::optional;
+using std::shared_ptr;
using std::string;
+using std::variant;
using std::vector;
class PartialStorage
@@ -222,54 +226,8 @@ template<class S>
class RecordT
{
public:
- class Item {
- public:
- struct UnknownType
- {
- std::string type;
- std::string value;
- };
-
- struct Empty {};
-
- typedef std::variant<
- std::monostate,
- Empty,
- int,
- std::string,
- std::vector<uint8_t>,
- ZonedTime,
- UUID,
- typename S::Ref,
- UnknownType> Variant;
-
- Item(const std::string & name):
- Item(name, std::monostate()) {}
- Item(const std::string & name, Variant value):
- name(name), value(value) {}
- template<typename T>
- Item(const std::string & name, const Stored<T> & value):
- Item(name, value.ref()) {}
-
- Item(const Item &) = default;
- Item & operator=(const Item &) = delete;
-
- operator bool() const;
-
- std::optional<Empty> asEmpty() const;
- std::optional<int> asInteger() const;
- std::optional<std::string> asText() const;
- std::optional<std::vector<uint8_t>> asBinary() const;
- std::optional<ZonedTime> asDate() const;
- std::optional<UUID> asUUID() const;
- std::optional<typename S::Ref> asRef() const;
- std::optional<UnknownType> asUnknown() const;
-
- template<typename T> std::optional<Stored<T>> as() const;
-
- const std::string name;
- const Variant value;
- };
+ class Item;
+ class Items;
private:
RecordT(const std::shared_ptr<std::vector<Item>> & ptr):
@@ -280,10 +238,10 @@ public:
RecordT(std::vector<Item> &&);
std::vector<uint8_t> encode() const;
- const std::vector<Item> & items() const;
+ Items items() const;
Item item(const std::string & name) const;
Item operator[](const std::string & name) const;
- std::vector<Item> items(const std::string & name) const;
+ Items items(const std::string & name) const;
private:
friend ObjectT<S>;
@@ -295,6 +253,123 @@ private:
const std::shared_ptr<const std::vector<Item>> ptr;
};
+template<class S>
+class RecordT<S>::Item
+{
+public:
+ struct UnknownType
+ {
+ string type;
+ string value;
+ };
+
+ struct Empty {};
+
+ using Integer = int;
+ using Text = string;
+ using Binary = vector<uint8_t>;
+ using Date = ZonedTime;
+ using UUID = erebos::UUID;
+ using Ref = typename S::Ref;
+
+ using Variant = variant<
+ monostate,
+ Empty,
+ int,
+ string,
+ vector<uint8_t>,
+ ZonedTime,
+ UUID,
+ typename S::Ref,
+ UnknownType>;
+
+ Item(const string & name):
+ Item(name, monostate()) {}
+ Item(const string & name, Variant value):
+ name(name), value(value) {}
+ template<typename T>
+ Item(const string & name, const Stored<T> & value):
+ Item(name, value.ref()) {}
+
+ Item(const Item &) = default;
+ Item & operator=(const Item &) = delete;
+
+ operator bool() const;
+
+ optional<Empty> asEmpty() const;
+ optional<Integer> asInteger() const;
+ optional<Text> asText() const;
+ optional<Binary> asBinary() const;
+ optional<Date> asDate() const;
+ optional<UUID> asUUID() const;
+ optional<Ref> asRef() const;
+ optional<UnknownType> asUnknown() const;
+
+ template<typename T> optional<Stored<T>> as() const;
+
+ const string name;
+ const Variant value;
+};
+
+template<class S>
+class RecordT<S>::Items
+{
+public:
+ using Empty = typename Item::Empty;
+ using Integer = typename Item::Integer;
+ using Text = typename Item::Text;
+ using Binary = typename Item::Binary;
+ using Date = typename Item::Date;
+ using UUID = typename Item::UUID;
+ using Ref = typename Item::Ref;
+ using UnknownType = typename Item::UnknownType;
+
+ Items(shared_ptr<const vector<Item>> items);
+ Items(shared_ptr<const vector<Item>> items, string filter);
+
+ class Iterator
+ {
+ Iterator(const Items & source, size_t idx);
+ friend Items;
+ public:
+ using iterator_category = std::forward_iterator_tag;
+ using value_type = Item;
+ using difference_type = ssize_t;
+ using pointer = const Item *;
+ using reference = const Item &;
+
+ Iterator(const Iterator &) = default;
+ ~Iterator() = default;
+ Iterator & operator=(const Iterator &) = default;
+ Iterator & operator++();
+ value_type operator*() const { return (*source.items)[idx]; }
+ bool operator==(const Iterator & other) const { return idx == other.idx; }
+ bool operator!=(const Iterator & other) const { return idx != other.idx; }
+
+ private:
+ const Items & source;
+ size_t idx;
+ };
+
+ Iterator begin() const;
+ Iterator end() const;
+
+ vector<Empty> asEmpty() const;
+ vector<Integer> asInteger() const;
+ vector<Text> asText() const;
+ vector<Binary> asBinary() const;
+ vector<Date> asDate() const;
+ vector<UUID> asUUID() const;
+ vector<Ref> asRef() const;
+ vector<UnknownType> asUnknown() const;
+
+ template<typename T> vector<Stored<T>> as() const;
+
+private:
+ const shared_ptr<const vector<Item>> items;
+ const optional<string> filter;
+};
+
extern template class RecordT<Storage>;
extern template class RecordT<PartialStorage>;
@@ -367,6 +442,18 @@ std::optional<Stored<T>> RecordT<S>::Item::as() const
return std::nullopt;
}
+template<class S>
+template<typename T>
+vector<Stored<T>> RecordT<S>::Items::as() const
+{
+ auto refs = asRef();
+ vector<Stored<T>> res;
+ res.reserve(refs.size());
+ for (const auto & ref : refs)
+ res.push_back(Stored<T>::load(ref));
+ return res;
+}
+
class Generation
{
public: