#pragma once #include "maybe.h" #include "function.h" template class TLazyValueBase { public: using TInitializer = std::function; TLazyValueBase() = default; TLazyValueBase(TInitializer initializer) : Initializer(std::move(initializer)) { } bool WasLazilyInitialized() const noexcept { return ValueHolder.Defined(); } const T& GetRef() const { if (!WasLazilyInitialized()) { InitDefault(); } return *ValueHolder; } const T& operator*() const { return GetRef(); } const T* operator->() const { return &GetRef(); } void InitDefault() const { Y_ASSERT(Initializer); ValueHolder = Initializer(); } private: mutable TMaybe ValueHolder; TInitializer Initializer; }; // we need this to get implicit construction TLazyValue from lambda // and save default copy constructor and operator= for type TLazyValue template class TLazyValue: public TLazyValueBase { public: template TLazyValue(TArgs&&... args) : TLazyValueBase(std::forward(args)...) { } }; template TLazyValue> MakeLazy(F&& f) { return {std::forward(f)}; }