]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/include/seastar/util/lazy.hh
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / seastar / include / seastar / util / lazy.hh
1 /*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18 /*
19 * Copyright (C) 2016 Cloudius Systems, Ltd.
20 */
21 #pragma once
22
23 #include <ostream>
24
25 /// \addtogroup logging
26 /// @{
27
28 namespace seastar {
29
30 /// \brief This class is a wrapper for a lazy evaluation of a value.
31 ///
32 /// The value is evaluated by a functor that gets no parameters, which is
33 /// provided to a lazy_value constructor.
34 ///
35 /// The instance may be created only using seastar::value_of helper function.
36 ///
37 /// The evaluation is triggered by operator().
38 template<typename Func>
39 class lazy_eval {
40 private:
41 Func _func;
42
43 private:
44 lazy_eval(Func&& f) : _func(std::forward<Func>(f)) {}
45
46 public:
47 /// \brief Evaluate a value.
48 ///
49 /// \return the evaluated value
50 auto operator()() {
51 return _func();
52 }
53
54 /// \brief Evaluate a value (const version).
55 ///
56 /// \return the evaluated value
57 auto operator()() const {
58 return _func();
59 }
60
61 template <typename F>
62 friend lazy_eval<F> value_of(F&& func);
63 };
64
65
66 /// Create a seastar::lazy_eval object that will use a given functor for
67 /// evaluating a value when the evaluation is triggered.
68 ///
69 /// The actual evaluation is triggered by applying a () operator on a
70 /// returned object.
71 ///
72 /// \param Func a type of a func
73 /// \param func func a functor to evaluate the value
74 ///
75 /// \return a lazy_eval object that may be used for evaluating a value
76 template <typename Func>
77 inline lazy_eval<Func> value_of(Func&& func) {
78 return lazy_eval<Func>(std::forward<Func>(func));
79 }
80
81 /// \brief This struct is a wrapper for lazy dereferencing a pointer.
82 ///
83 /// In particular this is to be used in situations where the value of a
84 /// pointer has to be converted to string in a lazy manner. Since
85 /// pointers can be null adding a check at the point of calling the
86 /// log function for example, will introduce an unnecessary branch in
87 /// potentially useless code. Using lazy_deref this check can be
88 /// deferred to the point where the code is actually evaluated.
89 template <typename T>
90 struct lazy_deref_wrapper {
91 const T& p;
92
93 constexpr lazy_deref_wrapper(const T& p) : p(p) {
94 }
95 };
96
97 /// Create a seastar::lazy_deref_wrapper object.
98 ///
99 /// The actual dereferencing will happen when the object is inserted
100 /// into a stream. The pointer is not copied, only a reference is saved
101 /// to it. Smart pointers are supported as well.
102 ///
103 /// \param p a raw pointer or a smart pointer
104 ///
105 /// \return a lazy_deref_wrapper object
106 template <typename T>
107 lazy_deref_wrapper<T>
108 lazy_deref(const T& p) {
109 return lazy_deref_wrapper<T>(p);
110 }
111
112 }
113
114 namespace std {
115 /// Output operator for a seastar::lazy_eval<Func>
116 /// This would allow printing a seastar::lazy_eval<Func> as if it's a regular
117 /// value.
118 ///
119 /// For example:
120 ///
121 /// `logger.debug("heavy eval result:{}", seastar::value_of([&] { return <heavy evaluation>; }));`
122 ///
123 /// (If a logging level is lower than "debug" the evaluation will not take place.)
124 ///
125 /// \tparam Func a functor type
126 /// \param os ostream to print to
127 /// \param lf a reference to a lazy_eval<Func> to be printed
128 ///
129 /// \return os
130 template <typename Func>
131 ostream& operator<<(ostream& os, const seastar::lazy_eval<Func>& lf) {
132 return os << lf();
133 }
134
135 template <typename Func>
136 ostream& operator<<(ostream& os, seastar::lazy_eval<Func>& lf) {
137 return os << lf();
138 }
139
140 template <typename Func>
141 ostream& operator<<(ostream& os, seastar::lazy_eval<Func>&& lf) {
142 return os << lf();
143 }
144
145 template <typename T>
146 ostream& operator<<(ostream& os, seastar::lazy_deref_wrapper<T> ld) {
147 if (ld.p) {
148 return os << *ld.p;
149 }
150
151 return os << "null";
152 }
153 }
154 /// @}