From 302fc80f638783d17cd3b496284a535044241297 Mon Sep 17 00:00:00 2001 From: olpc user Date: Thu, 21 Nov 2019 06:17:34 -0500 Subject: simple c++ refs --- starts/meaning-vm/concept.hpp | 74 +++++++++++++++++++++++++++++++++++++++++++ starts/meaning-vm/helpers.hpp | 49 ++++++++++++++++++++++++++++ starts/meaning-vm/main.cpp | 12 +++++++ starts/meaning-vm/makefile | 4 +++ 4 files changed, 139 insertions(+) create mode 100644 starts/meaning-vm/concept.hpp create mode 100644 starts/meaning-vm/helpers.hpp create mode 100644 starts/meaning-vm/main.cpp create mode 100644 starts/meaning-vm/makefile diff --git a/starts/meaning-vm/concept.hpp b/starts/meaning-vm/concept.hpp new file mode 100644 index 0000000..981835f --- /dev/null +++ b/starts/meaning-vm/concept.hpp @@ -0,0 +1,74 @@ +#pragma once + +#include +#include +#include +#include + +using cid = struct concept *; + +struct concept +{ + // a concept is made of concept-typed links to other concepts + std::multimap links; + using array = std::vector; + + cid id(); + cid get(cid type); // returns first + array getAll(cid type); + void link(cid type, cid target); + void unlink(cid type, cid target); +}; + +template +struct value : public concept, public T +{ + static value& of(cid c) + { + return *static_cast*>(c); + } +}; + +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"); +} diff --git a/starts/meaning-vm/helpers.hpp b/starts/meaning-vm/helpers.hpp new file mode 100644 index 0000000..f21952a --- /dev/null +++ b/starts/meaning-vm/helpers.hpp @@ -0,0 +1,49 @@ +#include "concept.hpp" + +// Makes string values interchangeable with the concepts +// they name. +template<> +struct value : public concept, public std::string +{ + //using std::string::basic_string; + value(std::string); + value(cid); + operator cid(); + static value& of(cid c) + { + return *static_cast(c); + } +}; + +using str = value; + +cid operator"" _c(const char* str, std::size_t len) +{ + return value({str,len}); +} + +#include + +concept namesByConcept; +std::unordered_map,concept,std::hash> conceptsByName; + +value::value(std::string s) +: std::string(s) +{ } + +value::value(cid c) +: std::string(of(namesByConcept.get(c))) +{ } + +value::operator cid() +{ + try { + return &conceptsByName.at(*this); + } catch (std::out_of_range) { + auto insertion = conceptsByName.emplace(*this, concept()); + cid con = &insertion.first->second; + cid nam = const_cast((const cid)&insertion.first->first); + namesByConcept.link(con, nam); + return con; + } +} diff --git a/starts/meaning-vm/main.cpp b/starts/meaning-vm/main.cpp new file mode 100644 index 0000000..8fb4c64 --- /dev/null +++ b/starts/meaning-vm/main.cpp @@ -0,0 +1,12 @@ +#include "concept.hpp" +#include "helpers.hpp" + +using namespace std; + +#include + +int main() +{ + cid concept = "concept"_c; + cout << str(concept) << endl; +} diff --git a/starts/meaning-vm/makefile b/starts/meaning-vm/makefile new file mode 100644 index 0000000..eb47570 --- /dev/null +++ b/starts/meaning-vm/makefile @@ -0,0 +1,4 @@ +CXXFLAGS=-std=c++11 -ggdb + +main: main.cpp +aain.cpp: *.hpp -- cgit v1.2.3