summaryrefslogtreecommitdiff
path: root/starts/meaning-vm/concept.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'starts/meaning-vm/concept.hpp')
-rw-r--r--starts/meaning-vm/concept.hpp82
1 files changed, 27 insertions, 55 deletions
diff --git a/starts/meaning-vm/concept.hpp b/starts/meaning-vm/concept.hpp
index 981835f..ce76f5d 100644
--- a/starts/meaning-vm/concept.hpp
+++ b/starts/meaning-vm/concept.hpp
@@ -5,70 +5,42 @@
#include <string>
#include <vector>
-using cid = struct concept *;
+struct concept;
+template <typename T> struct value;
+
+struct ref
+{
+ ref(concept *p) : ptr(p) { }
+ operator concept*() const { return ptr; }
+
+ // helper names
+ ref(std::string);
+ operator std::string();
+ ref(char const * str) : ref(std::string(str)) { }
+
+ concept * ptr;
+};
struct concept
{
// a concept is made of concept-typed links to other concepts
- std::multimap<cid,cid> links;
- using array = std::vector<cid>;
-
- cid id();
- cid get(cid type); // returns first
- array getAll(cid type);
- void link(cid type, cid target);
- void unlink(cid type, cid target);
+ std::multimap<ref,ref,std::less<concept*>> links;
+ using array = std::vector<ref>;
+
+ ref id();
+ ref get(ref type); // returns first
+ array getAll(ref type);
+ void link(ref type, ref target);
+ void unlink(ref type, ref target);
};
template <typename T>
struct value : public concept, public T
{
- static value<T>& of(cid c)
+ value(T const & val) : T(val) {}
+ value(value<T> const & val) = default;
+ static value<T>& of(ref c)
{
- return *static_cast<value<T>*>(c);
+ return *static_cast<value<T>*>(c.ptr);
}
};
-
-cid concept::id()
-{
- return this;
-}
-
-cid concept::get(cid type)
-{
- auto result = links.equal_range(type);
- if (result.first == result.second) {
- throw std::out_of_range("no such concept link to get");
- }
- return result.first->second;
-}
-
-concept::array concept::getAll(cid type)
-{
- array ret;
- for (
- auto range = links.equal_range(type);
- range.first != range.second;
- ++ range.first
- ) {
- ret.push_back(range.first->second);
- }
- return ret;
-}
-
-void concept::link(cid type, cid target)
-{
- links.insert({type, target});
-}
-
-void concept::unlink(cid type, cid target)
-{
- auto ls = links.equal_range(type);
- for (auto l = ls.first; l != ls.second; ++ l) {
- if (l->second == target) {
- links.erase(l);
- return;
- }
- }
- throw std::out_of_range("no such concept link to erase");
-}