add folly::as_const, like C++17's std::as_const
authorEric Niebler <eniebler@fb.com>
Sun, 8 Jan 2017 05:44:02 +0000 (21:44 -0800)
committerFacebook Github Bot <facebook-github-bot@users.noreply.github.com>
Sun, 8 Jan 2017 05:47:54 +0000 (21:47 -0800)
Summary: A one-liner from C++17, but a useful one. Const-qualifies an lvalue reference, avoiding the need for an awkward const_cast in some cases.

Reviewed By: yfeldblum

Differential Revision: D4389929

fbshipit-source-id: 1650c4901489eb0dd62fd9fa633b4a0da9f01954

folly/Utility.h
folly/test/UtilityTest.cpp

index a76925057362dadf7a3fbc48f16fd91f287a9b45..385ed34ac7d52b5329df8dc59aecc23400b4c4c9 100644 (file)
@@ -68,4 +68,32 @@ constexpr typename std::decay<T>::type copy(T&& value) noexcept(
     noexcept(typename std::decay<T>::type(std::forward<T>(value)))) {
   return std::forward<T>(value);
 }
+
+/**
+ * A simple helper for getting a constant reference to an object.
+ *
+ * Example:
+ *
+ *   std::vector<int> v{1,2,3};
+ *   // The following two lines are equivalent:
+ *   auto a = const_cast<const std::vector<int>&>(v).begin();
+ *   auto b = folly::as_const(v).begin();
+ *
+ * Like C++17's std::as_const. See http://wg21.link/p0007
+ */
+#if __cpp_lib_as_const || _MSC_VER
+
+/* using override */ using std::as_const
+
+#else
+
+template <class T>
+constexpr T const& as_const(T& t) noexcept {
+  return t;
+}
+
+template <class T>
+void as_const(T const&&) = delete;
+
+#endif
 }
index 337ade5a95fbba60e8df94856de8da6c34e59f39..df8fa5d23b8063bddf40bc7e84d336045f44fb16 100644 (file)
@@ -59,3 +59,19 @@ TEST_F(UtilityTest, copy_noexcept_spec) {
   EXPECT_FALSE(noexcept(folly::copy(thr)));
   EXPECT_TRUE(noexcept(folly::copy(std::move(thr)))); // note: does not copy
 }
+
+TEST_F(UtilityTest, as_const) {
+  struct S {
+    bool member() {
+      return false;
+    }
+    bool member() const {
+      return true;
+    }
+  };
+  S s;
+  EXPECT_FALSE(s.member());
+  EXPECT_TRUE(folly::as_const(s).member());
+  EXPECT_EQ(&s, &folly::as_const(s));
+  EXPECT_TRUE(noexcept(folly::as_const(s)));
+}