From 520119a6f6ed418b8ae45bfde8239bbb532562cd Mon Sep 17 00:00:00 2001
From: olpc user <olpc@xo-5d-f7-86.localdomain>
Date: Mon, 25 Nov 2019 05:02:10 -0800
Subject: cleanup mixin pointer mess for refs

---
 starts/meaning-vm/level-0/baseref.hpp     | 105 ++++++++++++++++++++++++++++++
 starts/meaning-vm/level-0/concept.cpp     |  20 +++---
 starts/meaning-vm/level-0/concept.hpp     |  28 ++++----
 starts/meaning-vm/level-0/errors.hpp      |  32 ++++-----
 starts/meaning-vm/level-0/memorystore.cpp |   2 +-
 starts/meaning-vm/level-0/ref-mixin.hpp   |  42 ------------
 starts/meaning-vm/level-0/ref.cpp         |  20 ++----
 starts/meaning-vm/level-0/ref.hpp         |  15 ++---
 8 files changed, 157 insertions(+), 107 deletions(-)
 create mode 100644 starts/meaning-vm/level-0/baseref.hpp
 delete mode 100644 starts/meaning-vm/level-0/ref-mixin.hpp

(limited to 'starts/meaning-vm/level-0')

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;
 };
 
 }
-- 
cgit v1.2.3