2 * Copyright 2013 Facebook, Inc.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include <type_traits>
22 #include "folly/Optional.h"
26 //////////////////////////////////////////////////////////////////////
29 * Lazy -- for delayed initialization of a value. The value's
30 * initialization will be computed on demand at its first use, but
31 * will not be recomputed if its value is requested again. The value
32 * may still be mutated after its initialization if the lazy is not
35 * The value is created using folly::lazy, usually with a lambda, and
36 * its value is requested using operator().
38 * Note that the value is not safe for current accesses by multiple
39 * threads, even if you declare it const.
45 * auto const val = folly::lazy([&]{
46 * return something_expensive(blah());
53 * useMaybeAgain(val());
55 * // Unneeded in this branch.
62 * - operator() is used to request the value instead of an implicit
63 * conversion because the slight syntactic overhead in common
64 * seems worth the increased clarity.
66 * - Lazy values do not model CopyConstructible because it is
67 * unclear what semantics would be desirable. Either copies
68 * should share the cached value (adding overhead to cases that
69 * don't need to support copies), or they could recompute the
70 * value unnecessarily. Sharing with mutable lazies would also
71 * leave them with non-value semantics despite looking
75 //////////////////////////////////////////////////////////////////////
81 typedef typename std::result_of<Func()>::type result_type;
83 explicit Lazy(Func&& f) : func_(std::move(f)) {}
84 explicit Lazy(Func& f) : func_(f) {}
87 : value_(std::move(o.value_))
88 , func_(std::move(o.func_))
91 Lazy(const Lazy&) = delete;
92 Lazy& operator=(const Lazy&) = delete;
93 Lazy& operator=(Lazy&&) = delete;
95 const result_type& operator()() const {
96 return const_cast<Lazy&>(*this)();
99 result_type& operator()() {
100 if (!value_) value_ = func_();
105 Optional<result_type> value_;
111 //////////////////////////////////////////////////////////////////////
114 detail::Lazy<typename std::remove_reference<Func>::type>
116 return detail::Lazy<typename std::remove_reference<Func>::type>(
117 std::forward<Func>(fun)
121 //////////////////////////////////////////////////////////////////////