diff options
Diffstat (limited to 'include/erebos')
-rw-r--r-- | include/erebos/attach.h | 2 | ||||
-rw-r--r-- | include/erebos/contact.h | 47 | ||||
-rw-r--r-- | include/erebos/identity.h | 6 | ||||
-rw-r--r-- | include/erebos/list.h | 116 |
4 files changed, 170 insertions, 1 deletions
diff --git a/include/erebos/attach.h b/include/erebos/attach.h index 14e6af3..dab0110 100644 --- a/include/erebos/attach.h +++ b/include/erebos/attach.h @@ -39,7 +39,7 @@ template<class T> class Signed; struct AttachIdentity { - Stored<Signed<class IdentityData>> identity; + Stored<Signed<struct IdentityData>> identity; vector<vector<uint8_t>> keys; static AttachIdentity load(const Ref &); diff --git a/include/erebos/contact.h b/include/erebos/contact.h new file mode 100644 index 0000000..e56346a --- /dev/null +++ b/include/erebos/contact.h @@ -0,0 +1,47 @@ +#pragma once + +#include <erebos/identity.h> +#include <erebos/list.h> +#include <erebos/state.h> +#include <erebos/storage.h> + +#include <memory> +#include <optional> +#include <string> +#include <vector> + +namespace erebos { + +using std::optional; +using std::shared_ptr; +using std::string; +using std::vector; + +class Contact +{ +public: + Contact(const Contact &) = default; + Contact(Contact &&) = default; + Contact & operator=(const Contact &) = default; + Contact & operator=(Contact &&) = default; + + static List<Contact> prepend(const Storage &, Identity, List<Contact>); + + Identity identity() const; + optional<string> name() const; + + bool operator==(const Contact &) const; + bool operator!=(const Contact &) const; + + static List<Contact> loadList(const vector<Ref> &); + vector<Ref> refs() const; + +private: + struct Priv; + shared_ptr<Priv> p; + Contact(shared_ptr<Priv> p): p(p) {} +}; + +DECLARE_SHARED_TYPE(List<Contact>) + +} diff --git a/include/erebos/identity.h b/include/erebos/identity.h index d0b60d5..888f162 100644 --- a/include/erebos/identity.h +++ b/include/erebos/identity.h @@ -6,6 +6,10 @@ namespace erebos { using std::optional; +using std::vector; + +template<class T> class Signed; +struct IdentityData; class Identity { @@ -17,8 +21,10 @@ public: static std::optional<Identity> load(const Ref &); static std::optional<Identity> load(const std::vector<Ref> &); + static std::optional<Identity> load(const std::vector<Stored<Signed<IdentityData>>> &); std::vector<Ref> store() const; std::vector<Ref> store(const Storage & st) const; + const vector<Stored<Signed<IdentityData>>> & data() const; std::optional<std::string> name() const; std::optional<Identity> owner() const; diff --git a/include/erebos/list.h b/include/erebos/list.h new file mode 100644 index 0000000..f5f2d3f --- /dev/null +++ b/include/erebos/list.h @@ -0,0 +1,116 @@ +#pragma once + +#include <functional> +#include <memory> +#include <mutex> +#include <variant> + +namespace erebos { + +using std::function; +using std::make_shared; +using std::make_unique; +using std::move; +using std::shared_ptr; +using std::unique_ptr; +using std::variant; + +template<typename T> +class List +{ +public: + struct Nil { bool operator==(const Nil &) const { return true; } }; + struct Cons { + T head; List<T> tail; + bool operator==(const Cons & x) const { return head == x.head && tail == x.tail; } + }; + + List(); + List(const T head, List<T> tail); + + const T & front() const; + const List & tail() const; + + bool empty() const; + + bool operator==(const List<T> &) const; + bool operator!=(const List<T> &) const; + + List push_front(T x) const; + +private: + struct Priv; + shared_ptr<Priv> p; +}; + +template<typename T> +struct List<T>::Priv +{ + variant<Nil, Cons> value; + + function<void()> eval = {}; + mutable std::once_flag once = {}; +}; + +template<typename T> +List<T>::List(): + p(shared_ptr<Priv>(new Priv { Nil() })) +{ + std::call_once(p->once, [](){}); +} + +template<typename T> +List<T>::List(T head, List<T> tail): + p(shared_ptr<Priv>(new Priv { + Cons { move(head), move(tail) } + })) +{ + std::call_once(p->once, [](){}); +} + +template<typename T> +const T & List<T>::front() const +{ + std::call_once(p->once, p->eval); + return std::get<Cons>(p->value).head; +} + +template<typename T> +const List<T> & List<T>::tail() const +{ + std::call_once(p->once, p->eval); + return std::get<Cons>(p->value).tail; +} + +template<typename T> +bool List<T>::empty() const +{ + std::call_once(p->once, p->eval); + return std::holds_alternative<Nil>(p->value); +} + +template<typename T> +bool List<T>::operator==(const List<T> & other) const +{ + if (p == other.p) + return true; + + std::call_once(p->once, p->eval); + std::call_once(other.p->once, other.p->eval); + return p->value == other.p->value; + +} + +template<typename T> +bool List<T>::operator!=(const List<T> & other) const +{ + return !(*this == other); +} + +template<typename T> +List<T> List<T>::push_front(T x) const +{ + return List<T>(move(x), *this); +} + +} |