diff options
author | olpc user <olpc@xo-5d-f7-86.localdomain> | 2019-11-25 05:02:10 -0800 |
---|---|---|
committer | olpc user <olpc@xo-5d-f7-86.localdomain> | 2019-11-25 05:02:10 -0800 |
commit | 520119a6f6ed418b8ae45bfde8239bbb532562cd (patch) | |
tree | 6cc381877adb5ddfaf131415c64f87eca5649676 /starts/meaning-vm/level-0 | |
parent | cd03e291664cb102bde61d86a15f0add11809766 (diff) | |
download | standingwithresilience-520119a6f6ed418b8ae45bfde8239bbb532562cd.tar.gz standingwithresilience-520119a6f6ed418b8ae45bfde8239bbb532562cd.zip |
cleanup mixin pointer mess for refs
Diffstat (limited to 'starts/meaning-vm/level-0')
-rw-r--r-- | starts/meaning-vm/level-0/baseref.hpp | 105 | ||||
-rw-r--r-- | starts/meaning-vm/level-0/concept.cpp | 20 | ||||
-rw-r--r-- | starts/meaning-vm/level-0/concept.hpp | 28 | ||||
-rw-r--r-- | starts/meaning-vm/level-0/errors.hpp | 32 | ||||
-rw-r--r-- | starts/meaning-vm/level-0/memorystore.cpp | 2 | ||||
-rw-r--r-- | starts/meaning-vm/level-0/ref-mixin.hpp | 42 | ||||
-rw-r--r-- | starts/meaning-vm/level-0/ref.cpp | 20 | ||||
-rw-r--r-- | starts/meaning-vm/level-0/ref.hpp | 15 |
8 files changed, 157 insertions, 107 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; }; } |