/*
- * Copyright 2013 Facebook, Inc.
+ * Copyright 2013-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#ifndef FOLLY_LAZY_H_
-#define FOLLY_LAZY_H_
-#include <utility>
+#pragma once
+
#include <type_traits>
+#include <utility>
-#include "folly/Optional.h"
+#include <folly/Optional.h>
namespace folly {
* The value is created using folly::lazy, usually with a lambda, and
* its value is requested using operator().
*
- * Note that the value is not safe for current accesses by multiple
- * threads, even if you declare it const.
+ * Note that the value is not safe for concurrent accesses by multiple
+ * threads, even if you declare it const. See note below.
*
*
* Example Usage:
* value unnecessarily. Sharing with mutable lazies would also
* leave them with non-value semantics despite looking
* value-like.
+ *
+ * - Not thread safe for const accesses. Many use cases for lazy
+ * values are local variables on the stack, where multiple
+ * threads shouldn't even be able to reach the value. It still
+ * is useful to indicate/check that the value doesn't change with
+ * const, particularly when it is captured by a large family of
+ * lambdas. Adding internal synchronization seems like it would
+ * pessimize the most common use case in favor of less likely use
+ * cases.
+ *
*/
//////////////////////////////////////////////////////////////////////
namespace detail {
-template<class Func>
+template <class Func>
struct Lazy {
typedef typename std::result_of<Func()>::type result_type;
}
result_type& operator()() {
- if (!value_) value_ = func_();
+ if (!value_) {
+ value_ = func_();
+ }
return *value_;
}
-private:
+ private:
Optional<result_type> value_;
Func func_;
};
-}
+} // namespace detail
//////////////////////////////////////////////////////////////////////
-template<class Func>
+template <class Func>
detail::Lazy<typename std::remove_reference<Func>::type>
lazy(Func&& fun) {
return detail::Lazy<typename std::remove_reference<Func>::type>(
//////////////////////////////////////////////////////////////////////
-}
-
-#endif
+} // namespace folly