CGRA-ME
Functional.h
Go to the documentation of this file.
1 /*******************************************************************************
2  * The software programs comprising "CGRA-ME" and the documentation provided
3  * with them are copyright by its authors and the University of Toronto. Only
4  * non-commercial, not-for-profit use of this software is permitted without ex-
5  * plicit permission. This software is provided "as is" with no warranties or
6  * guarantees of support. See the LICENCE for more details. You should have re-
7  * ceived a copy of the full licence along with this software. If not, see
8  * <http://cgra-me.ece.utoronto.ca/license/>.
9  ******************************************************************************/
10 
11 #ifndef UTILITY_FUNCTIONAL_H__
12 #define UTILITY_FUNCTIONAL_H__
13 
14 #include <memory>
15 #include <mutex>
16 
17 // forward declarations
18 template<typename,typename> struct LazyPointer;
19 
38 template<
39  typename Gen,
40  typename Value = std::remove_cv_t<std::remove_reference_t<decltype(std::declval<Gen>()())>>
41 >
42 auto lazy_pointer(Gen&& g) {
43  return LazyPointer<Gen,Value>(std::forward<Gen>(g));
44 }
45 
46 template<
47  typename Gen,
48  typename Value_ = std::remove_cv_t<std::remove_reference_t<decltype(std::declval<Gen>()())>>
49 >
50 struct LazyPointer {
51  using Value = Value_;
52 
53  template<typename G>
54  LazyPointer(G&& g) : gen(std::forward<G>(g)) { }
55 
57  : gen(std::move(src.gen))
58  , storage(std::move(src.storage))
59  { }
60 
62  gen = std::move(rhs.gen);
63  storage = std::move(rhs.storage);
64  }
65 
66  Value& operator*() { resolve(); return *storage; }
67  const Value& operator*() const { resolve(); return *storage; }
68 
69  Value* operator->() { resolve(); return storage.get(); }
70  const Value* operator->() const { resolve(); return storage.get(); }
71 
72  bool isResolved() const { return (bool)storage; }
73 
74  void resolve() const {
75  if (storage) { return; }
76  call_once(is_resolved, [this]{
77  storage = std::make_unique<Value>(gen());
78  });
79  }
80 
81 private:
82  mutable Gen gen;
83  mutable std::unique_ptr<Value> storage = nullptr;
84  mutable std::once_flag is_resolved = {};
85 };
86 
87 struct AlwaysFalse {
88  template<typename... T>
89  bool operator()(T&&...) { return false; }
90 };
91 
92 struct AlwaysTrue {
93  template<typename... T>
94  bool operator()(T&&...) { return true; }
95 };
96 
97 struct DoNothing {
98  template<typename... T>
99  void operator()(T&&...) { return; }
100 };
101 
107 template<typename T>
108 auto returnsIfEqualTo(T t) {
109  return [t=std::move(t)](auto& q) { return t == q; };
110 }
111 
112 #endif /* UTILITY_FUNCTIONAL_H__ */
LazyPointer::operator->
const Value * operator->() const
Definition: Functional.h:70
DoNothing::operator()
void operator()(T &&...)
Definition: Functional.h:99
LazyPointer::is_resolved
std::once_flag is_resolved
Definition: Functional.h:84
LazyPointer::isResolved
bool isResolved() const
Definition: Functional.h:72
LazyPointer::operator*
Value & operator*()
Definition: Functional.h:66
LazyPointer::operator*
const Value & operator*() const
Definition: Functional.h:67
LazyPointer::resolve
void resolve() const
Definition: Functional.h:74
AlwaysTrue
Definition: Functional.h:92
returnsIfEqualTo
auto returnsIfEqualTo(T t)
Definition: Functional.h:108
LazyPointer::operator->
Value * operator->()
Definition: Functional.h:69
AlwaysFalse::operator()
bool operator()(T &&...)
Definition: Functional.h:89
LazyPointer::gen
Gen gen
Definition: Functional.h:82
AlwaysTrue::operator()
bool operator()(T &&...)
Definition: Functional.h:94
LazyPointer::LazyPointer
LazyPointer(LazyPointer &&src)
Definition: Functional.h:56
DoNothing
Definition: Functional.h:97
lazy_pointer
auto lazy_pointer(Gen &&g)
Definition: Functional.h:42
LazyPointer::storage
std::unique_ptr< Value > storage
Definition: Functional.h:83
LazyPointer::operator=
LazyPointer & operator=(LazyPointer &&rhs)
Definition: Functional.h:61
LazyPointer
Definition: Functional.h:18
AlwaysFalse
Definition: Functional.h:87
LazyPointer::LazyPointer
LazyPointer(G &&g)
Definition: Functional.h:54
LazyPointer::Value
Value_ Value
Definition: Functional.h:51