Simplify Unit
authorYedidya Feldblum <yfeldblum@fb.com>
Tue, 17 May 2016 22:27:43 +0000 (15:27 -0700)
committerFacebook Github Bot 8 <facebook-github-bot-8-bot@fb.com>
Tue, 17 May 2016 22:38:24 +0000 (15:38 -0700)
Summary:
[Folly] Simplify `Unit`.

Specifically:
* Make `Unit::Lift` and `Unit::Drop` simply be aliases to `std::conditional<...>`. No need for anything more complicated.
* Remove `is_void_or_unit`, which is unused and unnecessary.

Reviewed By: djwatson

Differential Revision: D3312481

fbshipit-source-id: 280d40aa8ef91c52f96a51b03e0a109d76c939ec

folly/futures/Unit.h
folly/futures/test/UnitTest.cpp

index 0335b8df8f793e7dacc436e2037f8e2d79bfb964..cb6a6566df41a57ead7ea60d940e338f639bc61c 100644 (file)
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
+
 #pragma once
+
+#include <type_traits>
+
 namespace folly {
 
 /// In functional programming, the degenerate case is often called "unit". In
@@ -23,45 +27,15 @@ namespace folly {
 /// You can ignore the actual value, and we port some of the syntactic
 /// niceties like setValue() instead of setValue(Unit{}).
 struct Unit {
-  /// Lift type T into Unit. This is the definition for all non-void types.
-  template <class T> struct Lift : public std::false_type {
-    using type = T;
-  };
-  template <class T> struct Drop : public std::false_type {
-    using type = T;
-  };
+  template <typename T>
+  using Lift = std::conditional<std::is_same<T, void>::value, Unit, T>;
+  template <typename T>
+  using Drop = std::conditional<std::is_same<T, Unit>::value, void, T>;
+
   bool operator==(const Unit& /*other*/) const { return true; }
   bool operator!=(const Unit& /*other*/) const { return false; }
 };
 
-// Lift void into Unit.
-template <>
-struct Unit::Lift<void> : public std::true_type {
-  using type = Unit;
-};
-
-// Lift Unit into Unit (identity).
-template <>
-struct Unit::Lift<Unit> : public std::true_type {
-  using type = Unit;
-};
-
-// Drop Unit into void.
-template <>
-struct Unit::Drop<Unit> : public std::true_type {
-  using type = void;
-};
-
-// Drop void into void (identity).
-template <>
-struct Unit::Drop<void> : public std::true_type {
-  using type = void;
-};
-
-template <class T>
-struct is_void_or_unit : public Unit::Lift<T>
-{};
-
 constexpr Unit unit {};
 
 }
index ea2359d68c9ac4fec8bf14ee91737c25a36e39c8..9eb74dc55e679a78cdc2d4674befb08dce52e8ad 100644 (file)
@@ -17,6 +17,7 @@
 #include <gtest/gtest.h>
 
 #include <folly/futures/Future.h>
+#include <folly/futures/Unit.h>
 
 using namespace folly;
 
@@ -34,47 +35,45 @@ TEST(Unit, operatorNe) {
   EXPECT_FALSE(Unit{} != Unit{});
 }
 
-TEST(Unit, voidOrUnit) {
-  EXPECT_TRUE(is_void_or_unit<Unit>::value);
-  EXPECT_TRUE(is_void_or_unit<Unit>::value);
-  EXPECT_FALSE(is_void_or_unit<int>::value);
-}
-
 TEST(Unit, promiseSetValue) {
   Promise<Unit> p;
   p.setValue();
 }
 
 TEST(Unit, liftInt) {
-  using Lifted = Unit::Lift<int>;
-  EXPECT_FALSE(Lifted::value);
-  auto v = std::is_same<int, Lifted::type>::value;
-  EXPECT_TRUE(v);
+  using lifted = Unit::Lift<int>;
+  using actual = std::is_same<int, lifted::type>;
+  EXPECT_TRUE(actual::value);
+}
+
+TEST(Unit, liftUnit) {
+  using lifted = Unit::Lift<Unit>;
+  using actual = std::is_same<Unit, lifted::type>;
+  EXPECT_TRUE(actual::value);
 }
 
 TEST(Unit, liftVoid) {
-  using Lifted = Unit::Lift<Unit>;
-  EXPECT_TRUE(Lifted::value);
-  auto v = std::is_same<Unit, Lifted::type>::value;
-  EXPECT_TRUE(v);
+  using lifted = Unit::Lift<void>;
+  using actual = std::is_same<Unit, lifted::type>;
+  EXPECT_TRUE(actual::value);
 }
 
 TEST(Unit, dropInt) {
-  using dropped = typename Unit::Drop<int>;
-  EXPECT_FALSE(dropped::value);
-  EXPECT_TRUE((std::is_same<int, dropped::type>::value));
+  using dropped = Unit::Drop<int>;
+  using actual = std::is_same<int, dropped::type>;
+  EXPECT_TRUE(actual::value);
 }
 
 TEST(Unit, dropUnit) {
-  using dropped = typename Unit::Drop<Unit>;
-  EXPECT_TRUE(dropped::value);
-  EXPECT_TRUE((std::is_void<dropped::type>::value));
+  using dropped = Unit::Drop<Unit>;
+  using actual = std::is_same<void, dropped::type>;
+  EXPECT_TRUE(actual::value);
 }
 
 TEST(Unit, dropVoid) {
-  using dropped = typename Unit::Drop<void>;
-  EXPECT_TRUE(dropped::value);
-  EXPECT_TRUE((std::is_void<dropped::type>::value));
+  using dropped = Unit::Drop<void>;
+  using actual = std::is_same<void, dropped::type>;
+  EXPECT_TRUE(actual::value);
 }
 
 TEST(Unit, futureToUnit) {