#pragma once #include #include #include namespace nix { /* A simple non-nullable reference-counted pointer. Actually a wrapper around std::shared_ptr that prevents non-null constructions. */ template class ref { private: std::shared_ptr p; public: ref(const ref & r) : p(r.p) { } explicit ref(const std::shared_ptr & p) : p(p) { if (!p) throw std::invalid_argument("null pointer cast to ref"); } T* operator ->() const { return &*p; } T& operator *() const { return *p; } operator std::shared_ptr () { return p; } template operator ref () { return ref((std::shared_ptr) p); } private: template friend ref make_ref(Args&&... args); }; template inline ref make_ref(Args&&... args) { auto p = std::make_shared(std::forward(args)...); return ref(p); } }