TARAXA
Loading...
Searching...
No Matches
lazy.hpp
Go to the documentation of this file.
1#pragma once
2
3#include <cassert>
4#include <functional>
5#include <mutex>
6#include <type_traits>
7
9using std::enable_if_t;
10using std::function;
11using std::is_invocable_v;
12using std::mutex;
13using std::remove_reference;
14using std::size_t;
15using std::unique_lock;
16
17// TODO [1657]: clean up this class - remove ned/delete, ideally remove whole Lazy class !!!
18template <typename Provider>
19class Lazy {
20 Provider* provider_ = nullptr;
21
22 public:
23 using val_t = typename remove_reference<decltype((*provider_)())>::type;
24
25 private:
26 val_t* val_ptr_ = nullptr;
27 mutex mu_;
28 bool initializing_ = false;
29
30 public:
31 Lazy(Provider const& provider) : provider_(new Provider(provider)) {}
32 Lazy(Provider&& provider) : provider_(new Provider(provider)) {}
34 if (provider_) {
35 delete provider_;
36 }
37 if (val_ptr_) {
38 delete val_ptr_;
39 }
40 }
41
43 if (val_ptr_) {
44 return val_ptr_;
45 }
46 unique_lock l(mu_);
47 if (val_ptr_) {
48 return val_ptr_;
49 }
50 // this will persist any error that happened during initialization
51 assert(!initializing_);
52 initializing_ = true;
53 val_ptr_ = new val_t((*provider_)());
54 delete provider_;
55 provider_ = nullptr;
56 initializing_ = false;
57 return val_ptr_;
58 }
59
60 val_t const* get() const { return const_cast<val_t const*>(const_cast<Lazy*>(this)->get()); }
61
62 val_t* operator->() { return get(); }
63 val_t const* operator->() const { return get(); }
64
65 val_t& operator*() { return *operator->(); }
66 val_t const& operator*() const { return *operator->(); }
67
68 // clang-format off
69 operator val_t&() { return operator*(); }
70 operator val_t const &() const { return operator*(); }
71 // clang-format on
72
73 template <typename T>
74 auto& operator[](T t) {
75 return operator*()[t];
76 }
77
78 template <typename T>
79 auto const& operator[](T t) const {
80 return operator*()[t];
81 }
82
83 template <typename T>
84 auto& operator=(T t) {
85 return operator*() = t;
86 }
87};
88
89template <typename T>
90using LazyVal = Lazy<function<T()>>;
91
92} // namespace taraxa::util::lazy
Definition lazy.hpp:19
val_t const * operator->() const
Definition lazy.hpp:63
~Lazy()
Definition lazy.hpp:33
mutex mu_
Definition lazy.hpp:27
Provider * provider_
Definition lazy.hpp:20
auto & operator=(T t)
Definition lazy.hpp:84
Lazy(Provider const &provider)
Definition lazy.hpp:31
auto const & operator[](T t) const
Definition lazy.hpp:79
val_t const * get() const
Definition lazy.hpp:60
val_t & operator*()
Definition lazy.hpp:65
val_t * get()
Definition lazy.hpp:42
auto & operator[](T t)
Definition lazy.hpp:74
val_t * val_ptr_
Definition lazy.hpp:26
Lazy(Provider &&provider)
Definition lazy.hpp:32
typename remove_reference< decltype((*provider_)())>::type val_t
Definition lazy.hpp:23
val_t const & operator*() const
Definition lazy.hpp:66
bool initializing_
Definition lazy.hpp:28
val_t * operator->()
Definition lazy.hpp:62
Definition lazy.hpp:8