From 6c58f1e095f7dbe1e7e1654c1807a76276a2f3f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Sat, 5 Jun 2021 23:10:24 +0200 Subject: Contact list in shared state --- include/erebos/attach.h | 2 +- include/erebos/contact.h | 47 +++++++++++++++++++ include/erebos/identity.h | 6 +++ include/erebos/list.h | 116 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 170 insertions(+), 1 deletion(-) create mode 100644 include/erebos/contact.h create mode 100644 include/erebos/list.h (limited to 'include/erebos') 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 Signed; struct AttachIdentity { - Stored> identity; + Stored> identity; vector> 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 +#include +#include +#include + +#include +#include +#include +#include + +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 prepend(const Storage &, Identity, List); + + Identity identity() const; + optional name() const; + + bool operator==(const Contact &) const; + bool operator!=(const Contact &) const; + + static List loadList(const vector &); + vector refs() const; + +private: + struct Priv; + shared_ptr p; + Contact(shared_ptr p): p(p) {} +}; + +DECLARE_SHARED_TYPE(List) + +} 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 Signed; +struct IdentityData; class Identity { @@ -17,8 +21,10 @@ public: static std::optional load(const Ref &); static std::optional load(const std::vector &); + static std::optional load(const std::vector>> &); std::vector store() const; std::vector store(const Storage & st) const; + const vector>> & data() const; std::optional name() const; std::optional 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 +#include +#include +#include + +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 +class List +{ +public: + struct Nil { bool operator==(const Nil &) const { return true; } }; + struct Cons { + T head; List tail; + bool operator==(const Cons & x) const { return head == x.head && tail == x.tail; } + }; + + List(); + List(const T head, List tail); + + const T & front() const; + const List & tail() const; + + bool empty() const; + + bool operator==(const List &) const; + bool operator!=(const List &) const; + + List push_front(T x) const; + +private: + struct Priv; + shared_ptr p; +}; + +template +struct List::Priv +{ + variant value; + + function eval = {}; + mutable std::once_flag once = {}; +}; + +template +List::List(): + p(shared_ptr(new Priv { Nil() })) +{ + std::call_once(p->once, [](){}); +} + +template +List::List(T head, List tail): + p(shared_ptr(new Priv { + Cons { move(head), move(tail) } + })) +{ + std::call_once(p->once, [](){}); +} + +template +const T & List::front() const +{ + std::call_once(p->once, p->eval); + return std::get(p->value).head; +} + +template +const List & List::tail() const +{ + std::call_once(p->once, p->eval); + return std::get(p->value).tail; +} + +template +bool List::empty() const +{ + std::call_once(p->once, p->eval); + return std::holds_alternative(p->value); +} + +template +bool List::operator==(const List & 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 +bool List::operator!=(const List & other) const +{ + return !(*this == other); +} + +template +List List::push_front(T x) const +{ + return List(move(x), *this); +} + +} -- cgit v1.2.3