#pragma once #include "common.hpp" #include "errors.hpp" #include "memorystore.hpp" #include #include namespace intellect { namespace level0 { template class baseref { struct array; struct links_t; public: baseref(concept *p) : p(p) { if (p == 0) { throw null_reference(); } } baseref & operator=(concept *p) { self.p = p; return self; } 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 ref link(Ref... refspack) { std::initializer_list refs{refspack...}; for (auto it = refs.begin(); it != refs.end();) { ref type = *it++; ref target = *it++; link(type, target); } return ptr(); } template T& vget(ref const & type) const { return p->vget(type.p); } template void vset(ref const & type, T const & v) { p->set(type.p, level0::alloc(v)); } template T& val() { return p->val(); } template void val(T const & v) { p->val(v); } operator concept*() const { return p; } concept*& ptr() { return p; } concept* const & ptr() const { return p; } operator level0::ref &() { return *reinterpret_cast(this); } operator level1::ref &() { return *reinterpret_cast(this); } operator level2::ref &() { return *reinterpret_cast(this); } operator level3::ref &() { return *reinterpret_cast(this); } operator level4::ref &() { return *reinterpret_cast(this); } operator level5::ref &() { return *reinterpret_cast(this); } 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 baseref::array baseref::getAll(ref const & type) const { return {p->getAll(type.p)}; } template typename baseref::links_t baseref::links() const { return {p->links}; } } }