/* This file is part of Strawberry. Copyright 2016, John Maguire Strawberry is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Strawberry is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Strawberry. If not, see . */ #ifndef LAZY_H #define LAZY_H #include #include // Helper for lazy initialisation of objects. // Usage: // Lazy my_lazy_object([]() { return new Foo; }); template class Lazy { public: explicit Lazy(std::function init) : init_(init) {} // Convenience constructor that will lazily default construct the object. Lazy() : init_([]() { return new T; }) {} T* get() const { CheckInitialised(); return ptr_.get(); } typename std::add_lvalue_reference::type operator*() const { CheckInitialised(); return *ptr_; } T* operator->() const { return get(); } // Returns true if the object is not yet initialised. explicit operator bool() const { return ptr_; } // Deletes the underlying object and will re-run the initialisation function // if the object is requested again. void reset() { ptr_.reset(nullptr); } private: void CheckInitialised() const { if (!ptr_) { ptr_.reset(init_()); } } const std::function init_; mutable std::unique_ptr ptr_; }; #endif // LAZY_H