summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorolpc user <olpc@xo-5d-f7-86.localdomain>2019-11-25 05:02:10 -0800
committerolpc user <olpc@xo-5d-f7-86.localdomain>2019-11-25 05:02:10 -0800
commit520119a6f6ed418b8ae45bfde8239bbb532562cd (patch)
tree6cc381877adb5ddfaf131415c64f87eca5649676
parentcd03e291664cb102bde61d86a15f0add11809766 (diff)
downloadstandingwithresilience-520119a6f6ed418b8ae45bfde8239bbb532562cd.tar.gz
standingwithresilience-520119a6f6ed418b8ae45bfde8239bbb532562cd.zip
cleanup mixin pointer mess for refs
-rw-r--r--starts/meaning-vm/level-0/baseref.hpp105
-rw-r--r--starts/meaning-vm/level-0/concept.cpp20
-rw-r--r--starts/meaning-vm/level-0/concept.hpp28
-rw-r--r--starts/meaning-vm/level-0/errors.hpp32
-rw-r--r--starts/meaning-vm/level-0/memorystore.cpp2
-rw-r--r--starts/meaning-vm/level-0/ref-mixin.hpp42
-rw-r--r--starts/meaning-vm/level-0/ref.cpp20
-rw-r--r--starts/meaning-vm/level-0/ref.hpp15
-rw-r--r--starts/meaning-vm/level-1/ref.cpp2
-rw-r--r--starts/meaning-vm/level-1/ref.hpp13
-rw-r--r--starts/meaning-vm/level-1/sugar.hpp2
11 files changed, 165 insertions, 116 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};
+}
+
+}
+}
diff --git a/starts/meaning-vm/level-0/concept.cpp b/starts/meaning-vm/level-0/concept.cpp
index dace7df..dde48c2 100644
--- a/starts/meaning-vm/level-0/concept.cpp
+++ b/starts/meaning-vm/level-0/concept.cpp
@@ -5,17 +5,17 @@ using namespace intellect::level0;
#define selfref const_cast<concept*>(&self)
-ref concept::id()
+concept* concept::id()
{
return this;
}
-void concept::link(ref const & type, ref const & target)
+void concept::link(concept* type, concept* target)
{
links.insert({type, target});
}
-void concept::unlink(ref const & type, ref const & target)
+void concept::unlink(concept* type, concept* target)
{
auto ls = links.equal_range(type);
for (auto l = ls.first; l != ls.second; ++ l) {
@@ -27,7 +27,7 @@ void concept::unlink(ref const & type, ref const & target)
throw no_such_link_type_target(selfref, type, target);
}
-void concept::unlink(ref const & type)
+void concept::unlink(concept* type)
{
auto ls = links.equal_range(type);
if (ls.first == ls.second) {
@@ -41,14 +41,14 @@ void concept::unlink(ref const & type)
links.erase(ls.first);
}
-bool concept::linked(ref const & type) const
+bool concept::linked(concept* type) const
{
return links.count(type) > 0;
}
-bool concept::linked(ref const & type, ref const & target) const
+bool concept::linked(concept* type, concept* target) const
{
- for (ref const & t : getAll(type)) {
+ for (concept* t : getAll(type)) {
if (t == target) {
return true;
}
@@ -56,7 +56,7 @@ bool concept::linked(ref const & type, ref const & target) const
return false;
}
-concept::array concept::getAll(ref const & type) const
+concept::array concept::getAll(concept* type) const
{
array ret;
for (
@@ -69,7 +69,7 @@ concept::array concept::getAll(ref const & type) const
return ret;
}
-ref concept::get(ref const & type) const
+concept* concept::get(concept* type) const
{
auto result = links.equal_range(type);
if (result.first == result.second) {
@@ -83,7 +83,7 @@ ref concept::get(ref const & type) const
return result.first->second;
}
-void concept::set(ref const & type, ref const & target)
+void concept::set(concept* type, concept* target)
{
if (linked(type)) {
throw link_type_not_unique(selfref, type);
diff --git a/starts/meaning-vm/level-0/concept.hpp b/starts/meaning-vm/level-0/concept.hpp
index dc3221b..3bd1609 100644
--- a/starts/meaning-vm/level-0/concept.hpp
+++ b/starts/meaning-vm/level-0/concept.hpp
@@ -1,7 +1,6 @@
#pragma once
#include "common.hpp"
-#include "ref.hpp"
#include <map>
#include <vector>
@@ -12,26 +11,29 @@ namespace level0 {
struct concept
{
// a concept is made of concept-typed links to other concepts
- std::multimap<ref,ref> links;
- using array = std::vector<ref>;
+ std::multimap<concept*,concept*> links;
+ using array = std::vector<concept*>;
- ref id();
+ concept* id();
- void link(ref const & type, ref const & target);
- void unlink(ref const & type, ref const & target);
- void unlink(ref const & type);
+ void link(concept* type, concept* target);
+ void unlink(concept* type, concept* target);
+ void unlink(concept* type);
- bool linked(ref const & type) const;
- bool linked(ref const & type, ref const & target) const;
+ bool linked(concept* type) const;
+ bool linked(concept* type, concept* target) const;
- array getAll(ref const & type) const;
+ array getAll(concept* type) const;
// get and set enforce that only 1 link of a given type is present
- ref get(ref const & type) const;
- void set(ref const & type, ref const & target);
+ concept* get(concept* type) const;
+ void set(concept* type, concept* target);
template <typename T>
- vref<T> vget(ref const & type) const { return get(type); }
+ value<T>* vget(concept* type) const { return static_cast<value<T>*>(get(type)); }
+
+ template <typename T>
+ value<T>* val() { return this; }
};
}
diff --git a/starts/meaning-vm/level-0/errors.hpp b/starts/meaning-vm/level-0/errors.hpp
index c052c69..d46eef7 100644
--- a/starts/meaning-vm/level-0/errors.hpp
+++ b/starts/meaning-vm/level-0/errors.hpp
@@ -1,5 +1,5 @@
#pragma once
-#include "ref.hpp"
+#include "concept.hpp"
#include <stdexcept>
@@ -8,62 +8,62 @@ namespace level0 {
struct no_such_link_type : public std::out_of_range
{
- no_such_link_type(ref source, ref type)
+ no_such_link_type(concept* source, concept* type)
: std::out_of_range("no such concept link type"),
source(source),
type(type)
{ }
- ref const source;
- ref const type;
+ concept* const source;
+ concept* const type;
};
struct no_such_link_type_target : public std::out_of_range
{
- no_such_link_type_target(ref source, ref type, ref target)
+ no_such_link_type_target(concept* source, concept* type, concept* target)
: std::out_of_range("no such concept link type and target"),
source(source),
type(type),
target(type)
{ }
- ref const source;
- ref const type;
- ref const target;
+ concept* const source;
+ concept* const type;
+ concept* const target;
};
struct link_type_not_unique : public std::invalid_argument
{
- link_type_not_unique(ref source, ref type)
+ link_type_not_unique(concept* source, concept* type)
: std::invalid_argument("more than one such concept link type"),
source(source),
type(type)
{ }
- ref const source;
- ref const type;
+ concept* const source;
+ concept* const type;
};
struct still_referenced_by : public std::invalid_argument
{
- still_referenced_by(ref topic, ref referrer)
+ still_referenced_by(concept* topic, concept* referrer)
: std::invalid_argument("concept is still referenced"),
topic(topic),
referrer(referrer)
{ }
- ref const topic;
- ref const referrer;
+ concept* const topic;
+ concept* const referrer;
};
struct no_such_concept : public std::invalid_argument
{
- no_such_concept(ref topic)
+ no_such_concept(concept* topic)
: std::invalid_argument("no such concept reference"),
topic(topic)
{ }
- ref const topic;
+ concept* const topic;
};
struct null_reference : public std::invalid_argument
diff --git a/starts/meaning-vm/level-0/memorystore.cpp b/starts/meaning-vm/level-0/memorystore.cpp
index 7ff5e42..7018418 100644
--- a/starts/meaning-vm/level-0/memorystore.cpp
+++ b/starts/meaning-vm/level-0/memorystore.cpp
@@ -24,7 +24,7 @@ static concept* referenced(ref r) {
if (r2 == r) {
continue;
}
- for (auto & l : r2->links) {
+ for (auto & l : r2.links()) {
if (ref(l.first) == r) {
return r2;
}
diff --git a/starts/meaning-vm/level-0/ref-mixin.hpp b/starts/meaning-vm/level-0/ref-mixin.hpp
deleted file mode 100644
index 15e5abe..0000000
--- a/starts/meaning-vm/level-0/ref-mixin.hpp
+++ /dev/null
@@ -1,42 +0,0 @@
-#pragma once
-
-#include <map>
-#include <vector>
-
-namespace intellect {
-namespace level0 {
-
-template <typename ref, template<typename> typename vref>
-struct refmixin {
- using links_t = std::multimap<ref, ref>;
- using array = std::vector<ref>;
-
- void link(ref const & type, ref const & target) { p()->link(conv<r>(type), conv<r>(target)); }
- void unlink(ref const & type, ref const & target) { p()->unlink(conv<r>(type), conv<r>(target)); }
- void unlink(ref const & type) { p()->unlink(conv<r>(type)); }
-
- bool linked(ref const & type) const { return p()->linked(conv<r>(type)); }
- bool linked(ref const & type, ref const & target) const { return p()->linked(conv<r>(type), conv<r>(target)); }
-
- array getAll(ref const & type) const { return conv<array>(p()->getAll(conv<r>(type))); }
-
- links_t & links() const { return *(links_t*)&(p()->links); }
-
- ref get(ref const & type) const { return conv<ref>(p()->get(conv<r>(type))); }
- void set(ref const & type, ref const & target) { p()->set(conv<r>(type), conv<r>(target)); }
-
- template <typename T>
- vref<T> vget(ref const & type) const { return conv<vref<T>>(get(type)); }
-
- 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(); }
-
-private:
- inline concept * p() const { return *conv<concept**>(this); }
- using r = level0::ref;
- template <typename OUT, typename IN>
- static inline OUT conv(IN r) { return *(OUT*)&r; }
-};
-}
-}
diff --git a/starts/meaning-vm/level-0/ref.cpp b/starts/meaning-vm/level-0/ref.cpp
index f468456..d4758bd 100644
--- a/starts/meaning-vm/level-0/ref.cpp
+++ b/starts/meaning-vm/level-0/ref.cpp
@@ -6,25 +6,17 @@
using namespace intellect::level0;
-ref::ref(concept *p)
-: ptr(p)
-{
- if (p == 0) {
- throw null_reference();
- }
-}
-
std::string ref::dump(ref skipmarkertype, ref skipmarkertarget)
{
- if (self->linked(skipmarkertype, skipmarkertarget)) {
+ if (self.linked(skipmarkertype, skipmarkertarget)) {
return {};
}
- std::string ret = std::to_string((unsigned long)ptr) + ":\n";
- for (auto & link : self->links) {
- ret += " " + std::to_string((unsigned long)link.first.ptr) + ": " + std::to_string((unsigned long)link.second.ptr) + "\n";
+ std::string ret = std::to_string((unsigned long)ptr()) + ":\n";
+ for (auto & link : self.links()) {
+ ret += " " + std::to_string((unsigned long)link.first.ptr()) + ": " + std::to_string((unsigned long)link.second.ptr()) + "\n";
}
- self->link(skipmarkertype, skipmarkertarget);
- for (auto & link : self->links) {
+ self.link(skipmarkertype, skipmarkertarget);
+ for (auto & link : self.links()) {
if (link.first == skipmarkertype && link.second == skipmarkertarget) {
continue;
}
diff --git a/starts/meaning-vm/level-0/ref.hpp b/starts/meaning-vm/level-0/ref.hpp
index abe3897..87a37c6 100644
--- a/starts/meaning-vm/level-0/ref.hpp
+++ b/starts/meaning-vm/level-0/ref.hpp
@@ -1,29 +1,22 @@
#pragma once
#include "common.hpp"
-#include "ref-mixin.hpp"
+#include "baseref.hpp"
#include <string>
namespace intellect {
namespace level0 {
-struct ref : public refmixin<ref, vref>
+struct ref : public baseref<ref, vref, concept>
{
- ref(concept *p);
- ref(ref const & other) : ref(other.ptr) { }
- ref & operator=(ref const & other) { self.ptr = other.ptr; return self; }
- operator concept*() const { return ptr; }
- concept* operator->() const { return ptr; }
- concept & deref() { return *ptr; }
+ ref(concept *p) : baseref(p) { }
+ ref & operator=(ref const & other) { self.p = other.p; return self; }
ref & l0() { return self; }
ref const & l0() const { return self; }
std::string dump(ref skipmarkertype, ref skipmarkertarget);
-
-private:
- concept * ptr;
};
}
diff --git a/starts/meaning-vm/level-1/ref.cpp b/starts/meaning-vm/level-1/ref.cpp
index 045e879..b593f81 100644
--- a/starts/meaning-vm/level-1/ref.cpp
+++ b/starts/meaning-vm/level-1/ref.cpp
@@ -45,7 +45,7 @@ level0::ref getnamed(std::string const & name)
}
ref::ref(std::string const & name)
-: ref0((level0::concept*)getnamed(name))
+: baseref(getnamed(name).ptr())
{ }
vref<std::string> ref::name() const
diff --git a/starts/meaning-vm/level-1/ref.hpp b/starts/meaning-vm/level-1/ref.hpp
index 40eee20..8a7394e 100644
--- a/starts/meaning-vm/level-1/ref.hpp
+++ b/starts/meaning-vm/level-1/ref.hpp
@@ -1,15 +1,17 @@
#pragma once
#include "common.hpp"
+#include "../level-0/baseref.hpp"
#include "../level-0/ref.hpp"
-#include "../level-0/ref-mixin.hpp"
namespace intellect {
namespace level1 {
-struct ref : public level0::refmixin<ref,vref>
+struct ref : public level0::baseref<ref,vref,level0::concept>
{
- ref(level0::ref const & other) : ref0(other) { }
+ using level0::baseref<ref,vref,level0::concept>::baseref;
+ ref(level0::concept * p) : baseref(p) { }
+ ref(level0::ref const & other) : baseref(other.ptr()) { }
ref(std::string const & name);
ref(const char *name) : ref(std::string(name)) { }
ref(bool b) : ref(b ? "true" : "false") { }
@@ -20,14 +22,11 @@ struct ref : public level0::refmixin<ref,vref>
vref<std::string> name() const;
- level0::ref & l0() { return ref0; }
+ level0::ref & l0() { return *reinterpret_cast<level0::ref*>(this); }
ref & l1() { return self; }
ref const & l1() const { return self; }
std::string dump(ref skipmarkertype, ref skipmarkertarget);
-private:
-
- level0::ref ref0;
};
}
diff --git a/starts/meaning-vm/level-1/sugar.hpp b/starts/meaning-vm/level-1/sugar.hpp
index c2fa4f9..9d439e5 100644
--- a/starts/meaning-vm/level-1/sugar.hpp
+++ b/starts/meaning-vm/level-1/sugar.hpp
@@ -27,7 +27,7 @@ namespace internal {
if (name[name.size() - 1] == ',') {
name = name.substr(0, name.size() - 1);
}
- refptrs[i]->l0() = ref(name).l0();
+ refptrs[i]->ptr() = ref(name).ptr();
}
}
}