folly::Unit docs and use lift in is_void_or_unit
authorHans Fugal <fugalh@fb.com>
Wed, 27 May 2015 16:30:48 +0000 (09:30 -0700)
committerPavlo Kushnir <pavlo@fb.com>
Thu, 28 May 2015 00:54:21 +0000 (17:54 -0700)
Summary:
I'm not sure about the name Lift now. We are lifting, yes, but are we lifting into Unit, or into "can't be void because void is unit"? But LiftIntoNonVoid is a bit verbose. I'm totally open to other names or arrangements. We could also rename `is_void_or_unit`, but to what?

I reimplemented `is_void_or_unit` in terms of `Unit::Lift` because it's kinda cool but also to provide a little motivational example to the reader for why Lift exists in the first place.

Test Plan: Still builds and passes tests. Nothing significant depends on this yet.

Reviewed By: hannesr@fb.com

Subscribers: exa, folly-diffs@, jsedgwick, yfeldblum, chalfant

FB internal diff: D2102147

Tasks: 6847876

Signature: t1:2102147:1432742966:a03973a45882d3e9f6fa7158ef393b148cbe16fc

folly/futures/Unit.h

index a03d5202002857332234ac58158d18812c189bc1..9d67bf0fc68114e8cf4573bf8b6abd34758d48ed 100644 (file)
 #pragma once
 namespace folly {
 
+/// In functional programming, the degenerate case is often called "unit". In
+/// C++, "void" is often the best analogue, however because of the syntactic
+/// special-casing required for void it is a liability for template
+/// metaprogramming. So, instead of e.g. Future<void>, we have Future<Unit>.
+/// You can ignore the actual value, and we port some of the syntactic
+/// niceties like setValue() instead of setValue(Unit{}).
+// We will soon return Future<Unit> wherever we currently return Future<void>
+// #6847876
 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;
   };
 };
 
+// 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;
+};
+
 template <class T>
-struct is_void_or_unit : public std::conditional<
-  std::is_void<T>::value || std::is_same<Unit, T>::value,
-  std::true_type,
-  std::false_type>::type
+struct is_void_or_unit : public Unit::Lift<T>
 {};
 
 }