summaryrefslogtreecommitdiff
path: root/starts/meaning-vm/level-0/baseref.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'starts/meaning-vm/level-0/baseref.hpp')
-rw-r--r--starts/meaning-vm/level-0/baseref.hpp105
1 files changed, 105 insertions, 0 deletions
diff --git a/starts/meaning-vm/level-0/baseref.hpp b/starts/meaning-vm/level-0/baseref.hpp
new file mode 100644
index 0000000..c888021
--- /dev/null
+++ b/starts/meaning-vm/level-0/baseref.hpp
@@ -0,0 +1,105 @@
+#pragma once
+
+#include "common.hpp"
+#include "errors.hpp"
+
+#include <map>
+#include <vector>
+
+namespace intellect {
+namespace level0 {
+
+template <typename ref, template<typename> typename vref, typename concept>
+class baseref {
+ struct array; struct links_t;
+public:
+ baseref(concept *p)
+ : p(p)
+ {
+ if (p == 0) {
+ throw null_reference();
+ }
+ }
+
+ void link(ref const & type, ref const & target) { p->link(type.p, target.p); }
+ void unlink(ref const & type, ref const & target) { p->unlink(type.p, target.p); }
+ void unlink(ref const & type) { p->unlink(type.p); }
+
+ bool linked(ref const & type) const { return p->linked(type.p); }
+ bool linked(ref const & type, ref const & target) const { return p->linked(type.p, target.p); }
+
+ ref get(ref const & type) const { return p->get(type.p); }
+ void set(ref const & type, ref const & target) { p->set(type.p, target.p); }
+
+ array getAll(ref const & type) const;
+ links_t links() const;
+
+ template <typename T>
+ vref<T> vget(ref const & type) const { return p->template vget<T>(type.p); }
+
+ template <typename T>
+ vref<T> val() { return p->template val<T>(); }
+
+ operator concept*() const { return p; }
+ concept*& ptr() { return p; }
+ concept* const & ptr() const { return p; }
+
+ bool operator==(ref const & other) const { return self.p == other.p; }
+ bool operator!=(ref const & other) const { return self.p == other.p; }
+ bool operator<(ref const & other) const { return self.p < other.p; }
+
+protected:
+ concept * p;
+
+private:
+ template <typename val, typename It>
+ struct mutated_it
+ {
+ mutated_it(It const & it) : it(it) { }
+
+ using mutit = mutated_it<val, It>;
+
+ mutit & operator++() { ++ self.it; return self; }
+ mutit operator++(int i) { return self.it.operator++(i); }
+ bool operator==(mutit const & other) const { return self.it == other.it; }
+ bool operator!=(mutit const & other) const { return self.it != other.it; }
+
+ val & operator*() { return *(val*)&self.it.operator*(); }
+ val & operator->() { return *(val*)&self.it.operator->(); }
+
+ private:
+ It it;
+ };
+
+ struct array
+ {
+ mutated_it<ref,typename concept::array::iterator> begin() { return array.begin(); }
+ mutated_it<ref,typename concept::array::iterator> end() { return array.end(); }
+
+ typename concept::array array;
+ };
+
+ struct links_t
+ {
+ mutated_it<std::pair<ref,ref>,typename decltype(concept::links)::iterator> begin()
+ { return links.begin(); }
+ mutated_it<std::pair<ref,ref>,typename decltype(concept::links)::iterator> end()
+ { return links.end(); }
+
+ decltype(concept::links) & links;
+ };
+};
+
+template <typename ref, template<typename> typename vref, typename concept>
+typename baseref<ref,vref,concept>::array baseref<ref,vref,concept>::getAll(ref const & type) const
+{
+ return {p->getAll(type.p)};
+}
+template <typename ref, template<typename> typename vref, typename concept>
+typename baseref<ref,vref,concept>::links_t baseref<ref,vref,concept>::links() const
+{
+ return {p->links};
+}
+
+}
+}