lazy_value.h 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #pragma once
  2. #include "maybe.h"
  3. #include "function.h"
  4. template <class T>
  5. class TLazyValueBase {
  6. public:
  7. using TInitializer = std::function<T()>;
  8. TLazyValueBase() = default;
  9. TLazyValueBase(TInitializer initializer)
  10. : Initializer(std::move(initializer))
  11. {
  12. }
  13. bool WasLazilyInitialized() const noexcept {
  14. return ValueHolder.Defined();
  15. }
  16. const T& GetRef() const {
  17. if (!WasLazilyInitialized()) {
  18. InitDefault();
  19. }
  20. return *ValueHolder;
  21. }
  22. const T& operator*() const {
  23. return GetRef();
  24. }
  25. const T* operator->() const {
  26. return &GetRef();
  27. }
  28. void InitDefault() const {
  29. Y_ASSERT(Initializer);
  30. ValueHolder = Initializer();
  31. }
  32. private:
  33. mutable TMaybe<T> ValueHolder;
  34. TInitializer Initializer;
  35. };
  36. // we need this to get implicit construction TLazyValue from lambda
  37. // and save default copy constructor and operator= for type TLazyValue
  38. template <class T>
  39. class TLazyValue: public TLazyValueBase<T> {
  40. public:
  41. template <typename... TArgs>
  42. TLazyValue(TArgs&&... args)
  43. : TLazyValueBase<T>(std::forward<TArgs>(args)...)
  44. {
  45. }
  46. };
  47. template <typename F>
  48. TLazyValue<TFunctionResult<F>> MakeLazy(F&& f) {
  49. return {std::forward<F>(f)};
  50. }