From: Yedidya Feldblum Date: Thu, 30 Nov 2017 06:13:39 +0000 (-0800) Subject: Some fixes for custom conversions of enums X-Git-Tag: v2017.12.04.00~11 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=96ac8f8ff0c9bc9446eede119fdfee0fe7feaba3;p=folly.git Some fixes for custom conversions of enums Summary: [Folly] Some fixes for custom conversions of enums. Of note, `to` was defined for enum -> all conversions, including enum -> string conversions, but we actually want enum -> string conversions to be done via ADL-discovered toAppend. Reviewed By: ot Differential Revision: D6411250 fbshipit-source-id: 852b64309e6adf1c68e5153635cb29632e2d86d4 --- diff --git a/folly/Conv.h b/folly/Conv.h index 5a9e0069..a545816d 100644 --- a/folly/Conv.h +++ b/folly/Conv.h @@ -1546,7 +1546,8 @@ Tgt to(StringPiece* src) { template typename std::enable_if< - std::is_enum::value && !std::is_same::value, + std::is_enum::value && !std::is_same::value && + !std::is_convertible::value, Expected>::type tryTo(const Src& value) { using I = typename std::underlying_type::type; @@ -1555,7 +1556,8 @@ tryTo(const Src& value) { template typename std::enable_if< - std::is_enum::value && !std::is_same::value, + !std::is_convertible::valuea && + std::is_enum::value && !std::is_same::value, Expected>::type tryTo(const Src& value) { using I = typename std::underlying_type::type; @@ -1564,7 +1566,8 @@ tryTo(const Src& value) { template typename std::enable_if< - std::is_enum::value && !std::is_same::value, + std::is_enum::value && !std::is_same::value && + !std::is_convertible::value, Tgt>::type to(const Src& value) { return to(static_cast::type>(value)); @@ -1572,7 +1575,7 @@ to(const Src& value) { template typename std::enable_if< - !IsSomeString::value && std::is_enum::value && + !std::is_convertible::value && std::is_enum::value && !std::is_same::value, Tgt>::type to(const Src& value) { diff --git a/folly/test/ConvTest.cpp b/folly/test/ConvTest.cpp index 0f7b3669..8fe065b0 100644 --- a/folly/test/ConvTest.cpp +++ b/folly/test/ConvTest.cpp @@ -1239,6 +1239,22 @@ size_t estimateSpaceNeeded(const Dimensions&in) { return 2000 + folly::estimateSpaceNeeded(in.w) + folly::estimateSpaceNeeded(in.h); } + +enum class SmallEnum {}; + +Expected parseTo(StringPiece in, SmallEnum& out) { + out = {}; + if (in == "SmallEnum") { + return in.removePrefix(in), in; + } else { + return makeUnexpected(ConversionCode::STRING_TO_FLOAT_ERROR); + } +} + +template +void toAppend(SmallEnum, String* result) { + folly::toAppend("SmallEnum", result); +} } // namespace my TEST(Conv, custom_kkproviders) { @@ -1254,6 +1270,14 @@ TEST(Conv, custom_kkproviders) { EXPECT_EQ("7x8|7x8", str); } +TEST(conv, custom_enumclass) { + EXPECT_EQ(my::SmallEnum{}, folly::to("SmallEnum")); + EXPECT_EQ(my::SmallEnum{}, folly::tryTo("SmallEnum").value()); + auto str = to(my::SmallEnum{}); + toAppend("|", my::SmallEnum{}, &str); + EXPECT_EQ("SmallEnum|SmallEnum", str); +} + TEST(Conv, TryToThenWithVoid) { auto x = tryTo("42").then([](int) {}); EXPECT_TRUE(x.hasValue());