2019-09-07 13:16:18 +01:00
|
|
|
|
//! impl bool {}
|
|
|
|
|
|
|
2019-09-07 15:49:27 +01:00
|
|
|
|
impl bool {
|
2021-07-05 22:50:26 -04:00
|
|
|
|
/// Returns `Some(t)` if the `bool` is [`true`](../std/keyword.true.html),
|
|
|
|
|
|
/// or `None` otherwise.
|
2019-09-07 15:49:27 +01:00
|
|
|
|
///
|
2022-09-01 17:32:00 +01:00
|
|
|
|
/// Arguments passed to `then_some` are eagerly evaluated; if you are
|
|
|
|
|
|
/// passing the result of a function call, it is recommended to use
|
2022-09-01 16:09:25 +01:00
|
|
|
|
/// [`then`], which is lazily evaluated.
|
2022-09-01 17:32:00 +01:00
|
|
|
|
///
|
2022-09-01 16:09:25 +01:00
|
|
|
|
/// [`then`]: bool::then
|
2022-09-01 17:32:00 +01:00
|
|
|
|
///
|
2019-09-07 15:49:27 +01:00
|
|
|
|
/// # Examples
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ```
|
2019-12-06 12:18:32 +00:00
|
|
|
|
/// assert_eq!(false.then_some(0), None);
|
|
|
|
|
|
/// assert_eq!(true.then_some(0), Some(0));
|
2019-09-07 15:49:27 +01:00
|
|
|
|
/// ```
|
2022-09-21 23:23:14 -04:00
|
|
|
|
///
|
2022-09-21 17:07:50 -04:00
|
|
|
|
/// ```
|
|
|
|
|
|
/// let mut a = 0;
|
|
|
|
|
|
/// let mut function_with_side_effects = || { a += 1; };
|
2022-09-21 23:23:14 -04:00
|
|
|
|
///
|
2022-09-21 17:07:50 -04:00
|
|
|
|
/// true.then_some(function_with_side_effects());
|
|
|
|
|
|
/// false.then_some(function_with_side_effects());
|
2022-09-21 23:23:14 -04:00
|
|
|
|
///
|
|
|
|
|
|
/// // `a` is incremented twice because the value passed to `then_some` is
|
|
|
|
|
|
/// // evaluated eagerly.
|
2022-09-21 17:07:50 -04:00
|
|
|
|
/// assert_eq!(a, 2);
|
|
|
|
|
|
/// ```
|
2022-05-02 01:12:35 -07:00
|
|
|
|
#[stable(feature = "bool_to_option", since = "1.62.0")]
|
2019-09-07 15:49:27 +01:00
|
|
|
|
#[inline]
|
2023-04-16 07:20:26 +00:00
|
|
|
|
pub fn then_some<T>(self, t: T) -> Option<T> {
|
2019-12-06 20:18:12 -08:00
|
|
|
|
if self { Some(t) } else { None }
|
2019-09-07 15:49:27 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-07-05 22:50:26 -04:00
|
|
|
|
/// Returns `Some(f())` if the `bool` is [`true`](../std/keyword.true.html),
|
|
|
|
|
|
/// or `None` otherwise.
|
2019-09-07 15:49:27 +01:00
|
|
|
|
///
|
|
|
|
|
|
/// # Examples
|
|
|
|
|
|
///
|
|
|
|
|
|
/// ```
|
2019-12-06 12:18:32 +00:00
|
|
|
|
/// assert_eq!(false.then(|| 0), None);
|
|
|
|
|
|
/// assert_eq!(true.then(|| 0), Some(0));
|
2019-09-07 15:49:27 +01:00
|
|
|
|
/// ```
|
2022-09-21 23:23:14 -04:00
|
|
|
|
///
|
2022-09-21 17:07:50 -04:00
|
|
|
|
/// ```
|
|
|
|
|
|
/// let mut a = 0;
|
2022-09-21 23:23:14 -04:00
|
|
|
|
///
|
2022-09-21 17:07:50 -04:00
|
|
|
|
/// true.then(|| { a += 1; });
|
|
|
|
|
|
/// false.then(|| { a += 1; });
|
2022-09-21 23:23:14 -04:00
|
|
|
|
///
|
|
|
|
|
|
/// // `a` is incremented once because the closure is evaluated lazily by
|
2022-09-21 17:07:50 -04:00
|
|
|
|
/// // `then`.
|
2022-09-22 02:12:06 -04:00
|
|
|
|
/// assert_eq!(a, 1);
|
2022-09-21 17:07:50 -04:00
|
|
|
|
/// ```
|
2024-12-03 09:20:34 +02:00
|
|
|
|
#[doc(alias = "then_with")]
|
2020-11-22 13:25:19 +00:00
|
|
|
|
#[stable(feature = "lazy_bool_to_option", since = "1.50.0")]
|
2024-09-18 22:01:52 +01:00
|
|
|
|
#[cfg_attr(not(test), rustc_diagnostic_item = "bool_then")]
|
2019-09-07 15:49:27 +01:00
|
|
|
|
#[inline]
|
2023-04-16 07:20:26 +00:00
|
|
|
|
pub fn then<T, F: FnOnce() -> T>(self, f: F) -> Option<T> {
|
2019-12-06 20:18:12 -08:00
|
|
|
|
if self { Some(f()) } else { None }
|
2019-09-07 15:49:27 +01:00
|
|
|
|
}
|
2024-12-06 15:05:14 +01:00
|
|
|
|
|
|
|
|
|
|
/// Returns either `true_val` or `false_val` depending on the value of
|
2024-12-09 13:22:39 +01:00
|
|
|
|
/// `self`, with a hint to the compiler that `self` is unlikely
|
2024-12-06 15:05:14 +01:00
|
|
|
|
/// to be correctly predicted by a CPU’s branch predictor.
|
|
|
|
|
|
///
|
2024-12-09 13:22:39 +01:00
|
|
|
|
/// This method is functionally equivalent to
|
2024-12-06 15:05:14 +01:00
|
|
|
|
/// ```ignore (this is just for illustrative purposes)
|
2024-12-09 13:22:39 +01:00
|
|
|
|
/// fn select_unpredictable<T>(b: bool, true_val: T, false_val: T) -> T {
|
|
|
|
|
|
/// if b { true_val } else { false_val }
|
|
|
|
|
|
/// }
|
2024-12-06 15:05:14 +01:00
|
|
|
|
/// ```
|
|
|
|
|
|
/// but might generate different assembly. In particular, on platforms with
|
|
|
|
|
|
/// a conditional move or select instruction (like `cmov` on x86 or `csel`
|
|
|
|
|
|
/// on ARM) the optimizer might use these instructions to avoid branches,
|
|
|
|
|
|
/// which can benefit performance if the branch predictor is struggling
|
|
|
|
|
|
/// with predicting `condition`, such as in an implementation of binary
|
|
|
|
|
|
/// search.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// Note however that this lowering is not guaranteed (on any platform) and
|
|
|
|
|
|
/// should not be relied upon when trying to write constant-time code. Also
|
|
|
|
|
|
/// be aware that this lowering might *decrease* performance if `condition`
|
|
|
|
|
|
/// is well-predictable. It is advisable to perform benchmarks to tell if
|
|
|
|
|
|
/// this function is useful.
|
|
|
|
|
|
///
|
|
|
|
|
|
/// # Examples
|
|
|
|
|
|
///
|
|
|
|
|
|
/// Distribute values evenly between two buckets:
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
/// #![feature(select_unpredictable)]
|
|
|
|
|
|
///
|
|
|
|
|
|
/// use std::hash::BuildHasher;
|
|
|
|
|
|
///
|
|
|
|
|
|
/// fn append<H: BuildHasher>(hasher: &H, v: i32, bucket_one: &mut Vec<i32>, bucket_two: &mut Vec<i32>) {
|
|
|
|
|
|
/// let hash = hasher.hash_one(&v);
|
|
|
|
|
|
/// let bucket = (hash % 2 == 0).select_unpredictable(bucket_one, bucket_two);
|
|
|
|
|
|
/// bucket.push(v);
|
|
|
|
|
|
/// }
|
|
|
|
|
|
/// # let hasher = std::collections::hash_map::RandomState::new();
|
|
|
|
|
|
/// # let mut bucket_one = Vec::new();
|
|
|
|
|
|
/// # let mut bucket_two = Vec::new();
|
|
|
|
|
|
/// # append(&hasher, 42, &mut bucket_one, &mut bucket_two);
|
|
|
|
|
|
/// # assert_eq!(bucket_one.len() + bucket_two.len(), 1);
|
|
|
|
|
|
/// ```
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
|
#[unstable(feature = "select_unpredictable", issue = "133962")]
|
|
|
|
|
|
pub fn select_unpredictable<T>(self, true_val: T, false_val: T) -> T {
|
|
|
|
|
|
crate::intrinsics::select_unpredictable(self, true_val, false_val)
|
|
|
|
|
|
}
|
2019-09-07 15:49:27 +01:00
|
|
|
|
}
|