Commit 496a1139 authored by Hans Fugal's avatar Hans Fugal Committed by Pavlo Kushnir

folly::Unit docs and use lift in is_void_or_unit

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
parent d07aa05e
...@@ -16,22 +16,35 @@ ...@@ -16,22 +16,35 @@
#pragma once #pragma once
namespace folly { 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 { 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 { template <class T> struct Lift : public std::false_type {
using type = T; using type = T;
}; };
}; };
// Lift void into Unit.
template <> template <>
struct Unit::Lift<void> : public std::true_type { struct Unit::Lift<void> : public std::true_type {
using type = Unit; using type = Unit;
}; };
// Lift Unit into Unit (identity).
template <>
struct Unit::Lift<Unit> : public std::true_type {
using type = Unit;
};
template <class T> template <class T>
struct is_void_or_unit : public std::conditional< struct is_void_or_unit : public Unit::Lift<T>
std::is_void<T>::value || std::is_same<Unit, T>::value,
std::true_type,
std::false_type>::type
{}; {};
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment