summaryrefslogtreecommitdiff
path: root/include/erebos
diff options
context:
space:
mode:
Diffstat (limited to 'include/erebos')
-rw-r--r--include/erebos/attach.h2
-rw-r--r--include/erebos/contact.h47
-rw-r--r--include/erebos/identity.h6
-rw-r--r--include/erebos/list.h116
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);
+}
+
+}