From 520119a6f6ed418b8ae45bfde8239bbb532562cd Mon Sep 17 00:00:00 2001 From: olpc user 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 ++--- starts/meaning-vm/level-1/ref.cpp | 2 +- starts/meaning-vm/level-1/ref.hpp | 13 ++-- starts/meaning-vm/level-1/sugar.hpp | 2 +- 11 files changed, 165 insertions(+), 116 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') 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 +#include + +namespace intellect { +namespace level0 { + +template 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 + vref vget(ref const & type) const { return p->template vget(type.p); } + + template + vref val() { return p->template val(); } + + 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 + struct mutated_it + { + mutated_it(It const & it) : it(it) { } + + using mutit = mutated_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 begin() { return array.begin(); } + mutated_it end() { return array.end(); } + + typename concept::array array; + }; + + struct links_t + { + mutated_it,typename decltype(concept::links)::iterator> begin() + { return links.begin(); } + mutated_it,typename decltype(concept::links)::iterator> end() + { return links.end(); } + + decltype(concept::links) & links; + }; +}; + +template typename vref, typename concept> +typename baseref::array baseref::getAll(ref const & type) const +{ + return {p->getAll(type.p)}; +} +template typename vref, typename concept> +typename baseref::links_t baseref::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(&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 #include @@ -12,26 +11,29 @@ namespace level0 { struct concept { // a concept is made of concept-typed links to other concepts - std::multimap links; - using array = std::vector; + std::multimap links; + using array = std::vector; - 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 - vref vget(ref const & type) const { return get(type); } + value* vget(concept* type) const { return static_cast*>(get(type)); } + + template + value* 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 @@ -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 -#include - -namespace intellect { -namespace level0 { - -template typename vref> -struct refmixin { - using links_t = std::multimap; - using array = std::vector; - - void link(ref const & type, ref const & target) { p()->link(conv(type), conv(target)); } - void unlink(ref const & type, ref const & target) { p()->unlink(conv(type), conv(target)); } - void unlink(ref const & type) { p()->unlink(conv(type)); } - - bool linked(ref const & type) const { return p()->linked(conv(type)); } - bool linked(ref const & type, ref const & target) const { return p()->linked(conv(type), conv(target)); } - - array getAll(ref const & type) const { return conv(p()->getAll(conv(type))); } - - links_t & links() const { return *(links_t*)&(p()->links); } - - ref get(ref const & type) const { return conv(p()->get(conv(type))); } - void set(ref const & type, ref const & target) { p()->set(conv(type), conv(target)); } - - template - vref vget(ref const & type) const { return conv>(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(this); } - using r = level0::ref; - template - 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 namespace intellect { namespace level0 { -struct ref : public refmixin +struct ref : public baseref { - 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 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 +struct ref : public level0::baseref { - ref(level0::ref const & other) : ref0(other) { } + using level0::baseref::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 vref name() const; - level0::ref & l0() { return ref0; } + level0::ref & l0() { return *reinterpret_cast(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(); } } } -- cgit v1.2.3