correct usage of namespace std for coroutines_trait specialization
[folly.git] / folly / Lazy.h
index 2b18ea7b84b36fdb9588c96a87d0f949a8bf6009..ff115f3f3d3af233e35bada0678546385e399f87 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2013 Facebook, Inc.
+ * Copyright 2017 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 {
 
@@ -35,8 +35,8 @@ 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:
@@ -70,13 +70,23 @@ namespace folly {
  *      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;
 
@@ -97,20 +107,22 @@ struct Lazy {
   }
 
   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>(
@@ -120,6 +132,4 @@ lazy(Func&& fun) {
 
 //////////////////////////////////////////////////////////////////////
 
-}
-
-#endif
+} // namespace folly