From 87efa7eedee6e11a9c6083726a2de855891052b0 Mon Sep 17 00:00:00 2001 From: Eric Niebler Date: Mon, 5 Dec 2016 12:51:19 -0800 Subject: [PATCH] Reformulate constexpr_min and constexpr_max to achieve stability in sorting as described in http://stepanovpapers.com/notes.pdf Summary: There is a famous long-standing "bug" in the standard library regarding the semantics of min and max wrt values that are equivalent wrt op< but not equal. Let's not make the same mistake with constexpr_min and constexpr_max. Reviewed By: yfeldblum, luciang, Orvid, ot Differential Revision: D4269635 fbshipit-source-id: 19b464c949dc0cf07afb08eaf657ae8b242ca42d --- folly/portability/Constexpr.h | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/folly/portability/Constexpr.h b/folly/portability/Constexpr.h index 16b6458f..dc21a7d3 100755 --- a/folly/portability/Constexpr.h +++ b/folly/portability/Constexpr.h @@ -22,14 +22,20 @@ namespace folly { +// TLDR: Prefer using operator< for ordering. And when +// a and b are equivalent objects, we return b to make +// sorting stable. +// See http://stepanovpapers.com/notes.pdf for details. template constexpr T constexpr_max(T a, T b) { - return a > b ? a : b; + return b < a ? a : b; } +// When a and b are equivalent objects, we return a to +// make sorting stable. template constexpr T constexpr_min(T a, T b) { - return a < b ? a : b; + return b < a ? b : a; } namespace detail { @@ -67,7 +73,7 @@ struct constexpr_abs_helper< return t < static_cast(0) ? -t : t; } }; -} +} // namespace detail template constexpr auto constexpr_abs(T t) -- 2.34.1