From 821c5d75784e8cae2bf30bb7a3e759de580d44cb Mon Sep 17 00:00:00 2001 From: Sarang Masti Date: Mon, 29 Dec 2014 14:39:03 -0800 Subject: [PATCH] Allow conversion from a type T to itself Summary: same as title Test Plan: - fbconfig -r folly && fbmake runtests Reviewed By: andrei.alexandrescu@fb.com Subscribers: folly-diffs@ FB internal diff: D1754577 Signature: t1:1754577:1419618119:4c1a59cd19b23de9a9f6574341944e5e80530d62 --- folly/Conv.h | 50 ++++++++++++++++++++++++----------------- folly/test/ConvTest.cpp | 30 +++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 20 deletions(-) diff --git a/folly/Conv.h b/folly/Conv.h index def3d872..4d6fb0dd 100644 --- a/folly/Conv.h +++ b/folly/Conv.h @@ -53,6 +53,22 @@ namespace folly { +/** + * The identity conversion function. + * to(T) returns itself for all types T. + */ +template +typename std::enable_if::value, Tgt>::type +to(const Src & value) { + return value; +} + +template +typename std::enable_if::value, Tgt>::type +to(Src && value) { + return std::move(value); +} + /******************************************************************************* * Integral to integral ******************************************************************************/ @@ -64,7 +80,9 @@ namespace folly { */ template typename std::enable_if< - std::is_integral::value && std::is_integral::value, + std::is_integral::value + && std::is_integral::value + && !std::is_same::value, Tgt>::type to(const Src & value) { /* static */ if (std::numeric_limits::max() @@ -90,7 +108,9 @@ to(const Src & value) { template typename std::enable_if< - std::is_floating_point::value && std::is_floating_point::value, + std::is_floating_point::value + && std::is_floating_point::value + && !std::is_same::value, Tgt>::type to(const Src & value) { /* static */ if (std::numeric_limits::max() < @@ -819,20 +839,6 @@ toAppendDelimFit(const Delimiter& delim, const Ts&... vs) { template void toAppendDelimFit(const De&, const Ts&) {} -/** - * to(SomeString str) or to(StringPiece str) returns - * itself. As both std::string and folly::fbstring use Copy-on-Write, it's much - * more efficient by avoiding copying the underlying char array. - */ -template -typename std::enable_if< - (IsSomeString::value - || std::is_same::value) - && std::is_same::value, Tgt>::type -to(const Src & value) { - return value; -} - /** * to(v1, v2, ...) uses toAppend() (see below) as back-end * for all types. @@ -1403,13 +1409,15 @@ to(const Src & value) { // std::underlying_type became available by gcc 4.7.0 template -typename std::enable_if::value, Tgt>::type +typename std::enable_if< + std::is_enum::value && !std::is_same::value, Tgt>::type to(const Src & value) { return to(static_cast::type>(value)); } template -typename std::enable_if::value, Tgt>::type +typename std::enable_if< + std::is_enum::value && !std::is_same::value, Tgt>::type to(const Src & value) { return static_cast(to::type>(value)); } @@ -1417,7 +1425,8 @@ to(const Src & value) { #else template -typename std::enable_if::value, Tgt>::type +typename std::enable_if< + std::is_enum::value && !std::is_same::value, Tgt>::type to(const Src & value) { /* static */ if (Src(-1) < 0) { /* static */ if (sizeof(Src) <= sizeof(int)) { @@ -1435,7 +1444,8 @@ to(const Src & value) { } template -typename std::enable_if::value, Tgt>::type +typename std::enable_if< + std::is_enum::value && !std::is_same::value, Tgt>::type to(const Src & value) { /* static */ if (Tgt(-1) < 0) { /* static */ if (sizeof(Tgt) <= sizeof(int)) { diff --git a/folly/test/ConvTest.cpp b/folly/test/ConvTest.cpp index 31cd9eda..ad44421b 100644 --- a/folly/test/ConvTest.cpp +++ b/folly/test/ConvTest.cpp @@ -34,6 +34,36 @@ static uint32_t u32; static int64_t s64; static uint64_t u64; +// Test to(T) +TEST(Conv, Type2Type) { + int intV = 42; + EXPECT_EQ(to(intV), 42); + + float floatV = 4.2; + EXPECT_EQ(to(floatV), 4.2f); + + double doubleV = 0.42; + EXPECT_EQ(to(doubleV), 0.42); + + std::string stringV = "StdString"; + EXPECT_EQ(to(stringV), "StdString"); + + folly::fbstring fbStrV = "FBString"; + EXPECT_EQ(to(fbStrV), "FBString"); + + folly::StringPiece spV("StringPiece"); + EXPECT_EQ(to(spV), "StringPiece"); + + // Rvalues + EXPECT_EQ(to(42), 42); + EXPECT_EQ(to(4.2f), 4.2f); + EXPECT_EQ(to(.42), .42); + EXPECT_EQ(to(std::string("Hello")), "Hello"); + EXPECT_EQ(to(folly::fbstring("hello")), "hello"); + EXPECT_EQ(to(folly::StringPiece("Forty Two")), + "Forty Two"); +} + TEST(Conv, Integral2Integral) { // Same size, different signs s64 = numeric_limits::max(); -- 2.34.1