Commit 5a7d0d75 authored by Marc Horowitz's avatar Marc Horowitz Committed by Jordan DeLong

move folly::detail::IsSomeString outside of folly::detail

Summary:
It is useful when writing additional specializations of of
toAppend() and related functions to use IsSomeString, the same way the
ones in Conv.h do.  Move IsSomeString out of detail, so outside code
doesn't access a detail namespace inappropriately.

Test Plan: fbmake runtests; arc lint

Reviewed By: tudorb@fb.com

FB internal diff: D1130910
parent a247c8d3
/* /*
* Copyright 2013 Facebook, Inc. * Copyright 2014 Facebook, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -104,11 +104,6 @@ to(const Src & value) { ...@@ -104,11 +104,6 @@ to(const Src & value) {
namespace detail { namespace detail {
template <class T> struct IsSomeString {
enum { value = std::is_same<T, std::string>::value
|| std::is_same<T, fbstring>::value };
};
template <class T> template <class T>
const T& getLastElement(const T & v) { const T& getLastElement(const T & v) {
return v; return v;
...@@ -245,13 +240,21 @@ void toAppend(char value, Tgt * result) { ...@@ -245,13 +240,21 @@ void toAppend(char value, Tgt * result) {
*result += value; *result += value;
} }
/**
* Ubiquitous helper template for writing string appenders
*/
template <class T> struct IsSomeString {
enum { value = std::is_same<T, std::string>::value
|| std::is_same<T, fbstring>::value };
};
/** /**
* Everything implicitly convertible to const char* gets appended. * Everything implicitly convertible to const char* gets appended.
*/ */
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_convertible<Src, const char*>::value std::is_convertible<Src, const char*>::value
&& detail::IsSomeString<Tgt>::value>::type && IsSomeString<Tgt>::value>::type
toAppend(Src value, Tgt * result) { toAppend(Src value, Tgt * result) {
// Treat null pointers like an empty string, as in: // Treat null pointers like an empty string, as in:
// operator<<(std::ostream&, const char*). // operator<<(std::ostream&, const char*).
...@@ -266,7 +269,7 @@ toAppend(Src value, Tgt * result) { ...@@ -266,7 +269,7 @@ toAppend(Src value, Tgt * result) {
*/ */
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
detail::IsSomeString<Src>::value && detail::IsSomeString<Tgt>::value>::type IsSomeString<Src>::value && IsSomeString<Tgt>::value>::type
toAppend(const Src& value, Tgt * result) { toAppend(const Src& value, Tgt * result) {
result->append(value); result->append(value);
} }
...@@ -276,7 +279,7 @@ toAppend(const Src& value, Tgt * result) { ...@@ -276,7 +279,7 @@ toAppend(const Src& value, Tgt * result) {
*/ */
template <class Tgt> template <class Tgt>
typename std::enable_if< typename std::enable_if<
detail::IsSomeString<Tgt>::value>::type IsSomeString<Tgt>::value>::type
toAppend(StringPiece value, Tgt * result) { toAppend(StringPiece value, Tgt * result) {
result->append(value.data(), value.size()); result->append(value.data(), value.size());
} }
...@@ -287,7 +290,7 @@ toAppend(StringPiece value, Tgt * result) { ...@@ -287,7 +290,7 @@ toAppend(StringPiece value, Tgt * result) {
*/ */
template <class Tgt> template <class Tgt>
typename std::enable_if< typename std::enable_if<
detail::IsSomeString<Tgt>::value>::type IsSomeString<Tgt>::value>::type
toAppend(const fbstring& value, Tgt * result) { toAppend(const fbstring& value, Tgt * result) {
result->append(value.data(), value.size()); result->append(value.data(), value.size());
} }
...@@ -338,7 +341,7 @@ toAppend(unsigned __int128 value, Tgt * result) { ...@@ -338,7 +341,7 @@ toAppend(unsigned __int128 value, Tgt * result) {
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_integral<Src>::value && std::is_signed<Src>::value && std::is_integral<Src>::value && std::is_signed<Src>::value &&
detail::IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type
toAppend(Src value, Tgt * result) { toAppend(Src value, Tgt * result) {
char buffer[20]; char buffer[20];
if (value < 0) { if (value < 0) {
...@@ -355,7 +358,7 @@ toAppend(Src value, Tgt * result) { ...@@ -355,7 +358,7 @@ toAppend(Src value, Tgt * result) {
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_integral<Src>::value && !std::is_signed<Src>::value std::is_integral<Src>::value && !std::is_signed<Src>::value
&& detail::IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type && IsSomeString<Tgt>::value && sizeof(Src) >= 4>::type
toAppend(Src value, Tgt * result) { toAppend(Src value, Tgt * result) {
char buffer[20]; char buffer[20];
result->append(buffer, buffer + uint64ToBufferUnsafe(value, buffer)); result->append(buffer, buffer + uint64ToBufferUnsafe(value, buffer));
...@@ -368,7 +371,7 @@ toAppend(Src value, Tgt * result) { ...@@ -368,7 +371,7 @@ toAppend(Src value, Tgt * result) {
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_integral<Src>::value std::is_integral<Src>::value
&& detail::IsSomeString<Tgt>::value && sizeof(Src) < 4>::type && IsSomeString<Tgt>::value && sizeof(Src) < 4>::type
toAppend(Src value, Tgt * result) { toAppend(Src value, Tgt * result) {
typedef typename typedef typename
std::conditional<std::is_signed<Src>::value, int64_t, uint64_t>::type std::conditional<std::is_signed<Src>::value, int64_t, uint64_t>::type
...@@ -384,7 +387,7 @@ toAppend(Src value, Tgt * result) { ...@@ -384,7 +387,7 @@ toAppend(Src value, Tgt * result) {
*/ */
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_enum<Src>::value && detail::IsSomeString<Tgt>::value>::type std::is_enum<Src>::value && IsSomeString<Tgt>::value>::type
toAppend(Src value, Tgt * result) { toAppend(Src value, Tgt * result) {
toAppend( toAppend(
static_cast<typename std::underlying_type<Src>::type>(value), result); static_cast<typename std::underlying_type<Src>::type>(value), result);
...@@ -397,7 +400,7 @@ toAppend(Src value, Tgt * result) { ...@@ -397,7 +400,7 @@ toAppend(Src value, Tgt * result) {
*/ */
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_enum<Src>::value && detail::IsSomeString<Tgt>::value>::type std::is_enum<Src>::value && IsSomeString<Tgt>::value>::type
toAppend(Src value, Tgt * result) { toAppend(Src value, Tgt * result) {
/* static */ if (Src(-1) < 0) { /* static */ if (Src(-1) < 0) {
/* static */ if (sizeof(Src) <= sizeof(int)) { /* static */ if (sizeof(Src) <= sizeof(int)) {
...@@ -424,7 +427,7 @@ toAppend(Src value, Tgt * result) { ...@@ -424,7 +427,7 @@ toAppend(Src value, Tgt * result) {
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_floating_point<Src>::value std::is_floating_point<Src>::value
&& detail::IsSomeString<Tgt>::value>::type && IsSomeString<Tgt>::value>::type
toAppend( toAppend(
Src value, Src value,
Tgt * result, Tgt * result,
...@@ -463,7 +466,7 @@ toAppend( ...@@ -463,7 +466,7 @@ toAppend(
template <class Tgt, class Src> template <class Tgt, class Src>
typename std::enable_if< typename std::enable_if<
std::is_floating_point<Src>::value std::is_floating_point<Src>::value
&& detail::IsSomeString<Tgt>::value>::type && IsSomeString<Tgt>::value>::type
toAppend(Src value, Tgt * result) { toAppend(Src value, Tgt * result) {
toAppend( toAppend(
value, result, double_conversion::DoubleToStringConverter::SHORTEST, 0); value, result, double_conversion::DoubleToStringConverter::SHORTEST, 0);
...@@ -474,7 +477,7 @@ toAppend(Src value, Tgt * result) { ...@@ -474,7 +477,7 @@ toAppend(Src value, Tgt * result) {
*/ */
template <class T, class... Ts> template <class T, class... Ts>
typename std::enable_if<sizeof...(Ts) >= 2 typename std::enable_if<sizeof...(Ts) >= 2
&& detail::IsSomeString< && IsSomeString<
typename std::remove_pointer< typename std::remove_pointer<
typename detail::last_element<Ts...>::type typename detail::last_element<Ts...>::type
>::type>::value>::type >::type>::value>::type
...@@ -487,7 +490,7 @@ toAppend(const T& v, const Ts&... vs) { ...@@ -487,7 +490,7 @@ toAppend(const T& v, const Ts&... vs) {
* Variadic base case: do nothing. * Variadic base case: do nothing.
*/ */
template <class Tgt> template <class Tgt>
typename std::enable_if<detail::IsSomeString<Tgt>::value>::type typename std::enable_if<IsSomeString<Tgt>::value>::type
toAppend(Tgt* result) { toAppend(Tgt* result) {
} }
...@@ -495,7 +498,7 @@ toAppend(Tgt* result) { ...@@ -495,7 +498,7 @@ toAppend(Tgt* result) {
* Variadic base case: do nothing. * Variadic base case: do nothing.
*/ */
template <class Delimiter, class Tgt> template <class Delimiter, class Tgt>
typename std::enable_if<detail::IsSomeString<Tgt>::value>::type typename std::enable_if<IsSomeString<Tgt>::value>::type
toAppendDelim(const Delimiter& delim, Tgt* result) { toAppendDelim(const Delimiter& delim, Tgt* result) {
} }
...@@ -503,7 +506,7 @@ toAppendDelim(const Delimiter& delim, Tgt* result) { ...@@ -503,7 +506,7 @@ toAppendDelim(const Delimiter& delim, Tgt* result) {
* 1 element: same as toAppend. * 1 element: same as toAppend.
*/ */
template <class Delimiter, class T, class Tgt> template <class Delimiter, class T, class Tgt>
typename std::enable_if<detail::IsSomeString<Tgt>::value>::type typename std::enable_if<IsSomeString<Tgt>::value>::type
toAppendDelim(const Delimiter& delim, const T& v, Tgt* tgt) { toAppendDelim(const Delimiter& delim, const T& v, Tgt* tgt) {
toAppend(v, tgt); toAppend(v, tgt);
} }
...@@ -513,7 +516,7 @@ toAppendDelim(const Delimiter& delim, const T& v, Tgt* tgt) { ...@@ -513,7 +516,7 @@ toAppendDelim(const Delimiter& delim, const T& v, Tgt* tgt) {
*/ */
template <class Delimiter, class T, class... Ts> template <class Delimiter, class T, class... Ts>
typename std::enable_if<sizeof...(Ts) >= 2 typename std::enable_if<sizeof...(Ts) >= 2
&& detail::IsSomeString< && IsSomeString<
typename std::remove_pointer< typename std::remove_pointer<
typename detail::last_element<Ts...>::type typename detail::last_element<Ts...>::type
>::type>::value>::type >::type>::value>::type
...@@ -527,7 +530,7 @@ toAppendDelim(const Delimiter& delim, const T& v, const Ts&... vs) { ...@@ -527,7 +530,7 @@ toAppendDelim(const Delimiter& delim, const T& v, const Ts&... vs) {
* for all types. * for all types.
*/ */
template <class Tgt, class... Ts> template <class Tgt, class... Ts>
typename std::enable_if<detail::IsSomeString<Tgt>::value, Tgt>::type typename std::enable_if<IsSomeString<Tgt>::value, Tgt>::type
to(const Ts&... vs) { to(const Ts&... vs) {
Tgt result; Tgt result;
toAppend(vs..., &result); toAppend(vs..., &result);
...@@ -539,7 +542,7 @@ to(const Ts&... vs) { ...@@ -539,7 +542,7 @@ to(const Ts&... vs) {
* back-end for all types. * back-end for all types.
*/ */
template <class Tgt, class Delim, class... Ts> template <class Tgt, class Delim, class... Ts>
typename std::enable_if<detail::IsSomeString<Tgt>::value, Tgt>::type typename std::enable_if<IsSomeString<Tgt>::value, Tgt>::type
toDelim(const Delim& delim, const Ts&... vs) { toDelim(const Delim& delim, const Ts&... vs) {
Tgt result; Tgt result;
toAppendDelim(delim, vs..., &result); toAppendDelim(delim, vs..., &result);
......
/* /*
* Copyright 2013 Facebook, Inc. * Copyright 2014 Facebook, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -1112,7 +1112,7 @@ class FormatValue<Formatter<containerMode, Args...>, void> { ...@@ -1112,7 +1112,7 @@ class FormatValue<Formatter<containerMode, Args...>, void> {
*/ */
template <class Tgt, bool containerMode, class... Args> template <class Tgt, bool containerMode, class... Args>
typename std::enable_if< typename std::enable_if<
detail::IsSomeString<Tgt>::value>::type IsSomeString<Tgt>::value>::type
toAppend(const Formatter<containerMode, Args...>& value, Tgt * result) { toAppend(const Formatter<containerMode, Args...>& value, Tgt * result) {
value.appendTo(*result); value.appendTo(*result);
} }
......
/* /*
* Copyright 2013 Facebook, Inc. * Copyright 2014 Facebook, Inc.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
...@@ -76,7 +76,7 @@ class Formatter { ...@@ -76,7 +76,7 @@ class Formatter {
* Append to a string. * Append to a string.
*/ */
template <class Str> template <class Str>
typename std::enable_if<detail::IsSomeString<Str>::value>::type typename std::enable_if<IsSomeString<Str>::value>::type
appendTo(Str& str) const { appendTo(Str& str) const {
auto appender = [&str] (StringPiece s) { str.append(s.data(), s.size()); }; auto appender = [&str] (StringPiece s) { str.append(s.data(), s.size()); };
(*this)(appender); (*this)(appender);
...@@ -202,7 +202,7 @@ Formatter<true, Container> vformat(StringPiece fmt, Container&& container) { ...@@ -202,7 +202,7 @@ Formatter<true, Container> vformat(StringPiece fmt, Container&& container) {
* Shortcut for toAppend(format(...), &foo); * Shortcut for toAppend(format(...), &foo);
*/ */
template <class Str, class... Args> template <class Str, class... Args>
typename std::enable_if<detail::IsSomeString<Str>::value>::type typename std::enable_if<IsSomeString<Str>::value>::type
format(Str* out, StringPiece fmt, Args&&... args) { format(Str* out, StringPiece fmt, Args&&... args) {
format(fmt, std::forward<Args>(args)...).appendTo(*out); format(fmt, std::forward<Args>(args)...).appendTo(*out);
} }
...@@ -211,7 +211,7 @@ format(Str* out, StringPiece fmt, Args&&... args) { ...@@ -211,7 +211,7 @@ format(Str* out, StringPiece fmt, Args&&... args) {
* Append vformatted output to a string. * Append vformatted output to a string.
*/ */
template <class Str, class Container> template <class Str, class Container>
typename std::enable_if<detail::IsSomeString<Str>::value>::type typename std::enable_if<IsSomeString<Str>::value>::type
vformat(Str* out, StringPiece fmt, Container&& container) { vformat(Str* out, StringPiece fmt, Container&& container) {
vformat(fmt, std::forward<Container>(container)).appendTo(*out); vformat(fmt, std::forward<Container>(container)).appendTo(*out);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment