#pragma once #include #include #include #include template struct vref; struct concept; template struct value; struct statementcallref; struct ref { ref(concept *p) : ptr(p) { if (p == 0) throw std::logic_error("null reference"); } concept* operator->() { return ptr; } concept const * operator->() const { return ptr; } bool operator==(ref const & that) const { return this->ptr == that.ptr; } bool operator!=(ref const & that) const { return this->ptr != that.ptr; } bool operator<(ref const &) const { throw std::logic_error("ref has redefined syntax sugar: do not use in containers"); } // for helpers, mostly names ref(std::string const &); ref(char const * str) : ref(std::string(str)) { } ref(bool b) : ref(b ? "true" : "false") { } ref() : ref("nothing") { } vref name() const; operator const char *() const; // helper linking syntax sugar statementcallref operator=(ref that); //ref operator<<(ref target); ref operator[](ref links); bool isa(ref what) const; bool isan(ref what) const; concept * ptr; /* // destructor handles evaluating refs as statements ~ref() noexcept; ref(ref & that); ref(ref && that) noexcept; void destatement(); */ }; template struct vref { vref(value *p) : ptr(p) { } value* operator->() { return ptr; } operator T const &() const { return *ptr; } vref(T const & val); vref(ref const & that) : ptr(static_cast*>(that.ptr)) { } operator ref() { return ptr; } // for use by containers //bool operator<(ref const & that) const { return ptr < that.ptr; } value * ptr; }; struct concept { // a concept is made of concept-typed links to other concepts std::multimap links; using array = std::vector; ref id(); bool linked(ref const & type) const; bool linked(ref const & type, ref const & target) const; ref get(ref const & type, bool quick = false) const; // returns first template vref vget(ref const & type, bool quick = false) const { return get(type, quick); } array getAll(ref const & type) const; void link(ref const & type, ref const & target); void unlink(ref const & type, ref const & target); void unlink(ref const & type); }; template struct value : public concept { value(T const & val) : data(val) { } value(value const & val) = default; static value& of(ref c) { return *static_cast*>(c.ptr); } operator T&() { return data; } operator T const &() const { return data; } T data; };