namespace folly {
+/**
+ * The identity conversion function.
+ * to<T>(T) returns itself for all types T.
+ */
+template <class Tgt, class Src>
+typename std::enable_if<std::is_same<Tgt, Src>::value, Tgt>::type
+to(const Src & value) {
+ return value;
+}
+
+template <class Tgt, class Src>
+typename std::enable_if<std::is_same<Tgt, Src>::value, Tgt>::type
+to(Src && value) {
+ return std::move(value);
+}
+
/*******************************************************************************
* Integral to integral
******************************************************************************/
*/
template <class Tgt, class Src>
typename std::enable_if<
- std::is_integral<Src>::value && std::is_integral<Tgt>::value,
+ std::is_integral<Src>::value
+ && std::is_integral<Tgt>::value
+ && !std::is_same<Tgt, Src>::value,
Tgt>::type
to(const Src & value) {
/* static */ if (std::numeric_limits<Tgt>::max()
template <class Tgt, class Src>
typename std::enable_if<
- std::is_floating_point<Tgt>::value && std::is_floating_point<Src>::value,
+ std::is_floating_point<Tgt>::value
+ && std::is_floating_point<Src>::value
+ && !std::is_same<Tgt, Src>::value,
Tgt>::type
to(const Src & value) {
/* static */ if (std::numeric_limits<Tgt>::max() <
template <class De, class Ts>
void toAppendDelimFit(const De&, const Ts&) {}
-/**
- * to<SomeString>(SomeString str) or to<StringPiece>(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 <class Tgt, class Src>
-typename std::enable_if<
- (IsSomeString<Tgt>::value
- || std::is_same<Tgt, folly::StringPiece>::value)
- && std::is_same<Tgt, Src>::value, Tgt>::type
-to(const Src & value) {
- return value;
-}
-
/**
* to<SomeString>(v1, v2, ...) uses toAppend() (see below) as back-end
* for all types.
// std::underlying_type became available by gcc 4.7.0
template <class Tgt, class Src>
-typename std::enable_if<std::is_enum<Src>::value, Tgt>::type
+typename std::enable_if<
+ std::is_enum<Src>::value && !std::is_same<Src, Tgt>::value, Tgt>::type
to(const Src & value) {
return to<Tgt>(static_cast<typename std::underlying_type<Src>::type>(value));
}
template <class Tgt, class Src>
-typename std::enable_if<std::is_enum<Tgt>::value, Tgt>::type
+typename std::enable_if<
+ std::is_enum<Tgt>::value && !std::is_same<Src, Tgt>::value, Tgt>::type
to(const Src & value) {
return static_cast<Tgt>(to<typename std::underlying_type<Tgt>::type>(value));
}
#else
template <class Tgt, class Src>
-typename std::enable_if<std::is_enum<Src>::value, Tgt>::type
+typename std::enable_if<
+ std::is_enum<Src>::value && !std::is_same<Src, Tgt>::value, Tgt>::type
to(const Src & value) {
/* static */ if (Src(-1) < 0) {
/* static */ if (sizeof(Src) <= sizeof(int)) {
}
template <class Tgt, class Src>
-typename std::enable_if<std::is_enum<Tgt>::value, Tgt>::type
+typename std::enable_if<
+ std::is_enum<Tgt>::value && !std::is_same<Src, Tgt>::value, Tgt>::type
to(const Src & value) {
/* static */ if (Tgt(-1) < 0) {
/* static */ if (sizeof(Tgt) <= sizeof(int)) {
static int64_t s64;
static uint64_t u64;
+// Test to<T>(T)
+TEST(Conv, Type2Type) {
+ int intV = 42;
+ EXPECT_EQ(to<int>(intV), 42);
+
+ float floatV = 4.2;
+ EXPECT_EQ(to<float>(floatV), 4.2f);
+
+ double doubleV = 0.42;
+ EXPECT_EQ(to<double>(doubleV), 0.42);
+
+ std::string stringV = "StdString";
+ EXPECT_EQ(to<std::string>(stringV), "StdString");
+
+ folly::fbstring fbStrV = "FBString";
+ EXPECT_EQ(to<folly::fbstring>(fbStrV), "FBString");
+
+ folly::StringPiece spV("StringPiece");
+ EXPECT_EQ(to<folly::StringPiece>(spV), "StringPiece");
+
+ // Rvalues
+ EXPECT_EQ(to<int>(42), 42);
+ EXPECT_EQ(to<float>(4.2f), 4.2f);
+ EXPECT_EQ(to<double>(.42), .42);
+ EXPECT_EQ(to<std::string>(std::string("Hello")), "Hello");
+ EXPECT_EQ(to<folly::fbstring>(folly::fbstring("hello")), "hello");
+ EXPECT_EQ(to<folly::StringPiece>(folly::StringPiece("Forty Two")),
+ "Forty Two");
+}
+
TEST(Conv, Integral2Integral) {
// Same size, different signs
s64 = numeric_limits<uint8_t>::max();