/*
- * Copyright 2013 Facebook, Inc.
+ * Copyright 2014 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
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>
const T& getLastElement(const T & v) {
return v;
*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.
*/
template <class Tgt, class Src>
typename std::enable_if<
std::is_convertible<Src, const char*>::value
- && detail::IsSomeString<Tgt>::value>::type
+ && IsSomeString<Tgt>::value>::type
toAppend(Src value, Tgt * result) {
// Treat null pointers like an empty string, as in:
// operator<<(std::ostream&, const char*).
*/
template <class Tgt, class Src>
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) {
result->append(value);
}
*/
template <class Tgt>
typename std::enable_if<
- detail::IsSomeString<Tgt>::value>::type
+ IsSomeString<Tgt>::value>::type
toAppend(StringPiece value, Tgt * result) {
result->append(value.data(), value.size());
}
*/
template <class Tgt>
typename std::enable_if<
- detail::IsSomeString<Tgt>::value>::type
+ IsSomeString<Tgt>::value>::type
toAppend(const fbstring& value, Tgt * result) {
result->append(value.data(), value.size());
}
template <class Tgt, class Src>
typename std::enable_if<
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) {
char buffer[20];
if (value < 0) {
template <class Tgt, class Src>
typename std::enable_if<
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) {
char buffer[20];
result->append(buffer, buffer + uint64ToBufferUnsafe(value, buffer));
template <class Tgt, class Src>
typename std::enable_if<
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) {
typedef typename
std::conditional<std::is_signed<Src>::value, int64_t, uint64_t>::type
*/
template <class Tgt, class Src>
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(
static_cast<typename std::underlying_type<Src>::type>(value), result);
*/
template <class Tgt, class Src>
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) {
/* static */ if (Src(-1) < 0) {
/* static */ if (sizeof(Src) <= sizeof(int)) {
template <class Tgt, class Src>
typename std::enable_if<
std::is_floating_point<Src>::value
- && detail::IsSomeString<Tgt>::value>::type
+ && IsSomeString<Tgt>::value>::type
toAppend(
Src value,
Tgt * result,
template <class Tgt, class Src>
typename std::enable_if<
std::is_floating_point<Src>::value
- && detail::IsSomeString<Tgt>::value>::type
+ && IsSomeString<Tgt>::value>::type
toAppend(Src value, Tgt * result) {
toAppend(
value, result, double_conversion::DoubleToStringConverter::SHORTEST, 0);
*/
template <class T, class... Ts>
typename std::enable_if<sizeof...(Ts) >= 2
- && detail::IsSomeString<
+ && IsSomeString<
typename std::remove_pointer<
typename detail::last_element<Ts...>::type
>::type>::value>::type
* Variadic base case: do nothing.
*/
template <class Tgt>
-typename std::enable_if<detail::IsSomeString<Tgt>::value>::type
+typename std::enable_if<IsSomeString<Tgt>::value>::type
toAppend(Tgt* result) {
}
* Variadic base case: do nothing.
*/
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) {
}
* 1 element: same as toAppend.
*/
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) {
toAppend(v, tgt);
}
*/
template <class Delimiter, class T, class... Ts>
typename std::enable_if<sizeof...(Ts) >= 2
- && detail::IsSomeString<
+ && IsSomeString<
typename std::remove_pointer<
typename detail::last_element<Ts...>::type
>::type>::value>::type
* for all types.
*/
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) {
Tgt result;
toAppend(vs..., &result);
* back-end for all types.
*/
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) {
Tgt result;
toAppendDelim(delim, vs..., &result);
/*
- * Copyright 2013 Facebook, Inc.
+ * Copyright 2014 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* Append to a string.
*/
template <class Str>
- typename std::enable_if<detail::IsSomeString<Str>::value>::type
+ typename std::enable_if<IsSomeString<Str>::value>::type
appendTo(Str& str) const {
auto appender = [&str] (StringPiece s) { str.append(s.data(), s.size()); };
(*this)(appender);
* Shortcut for toAppend(format(...), &foo);
*/
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(fmt, std::forward<Args>(args)...).appendTo(*out);
}
* Append vformatted output to a string.
*/
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(fmt, std::forward<Container>(container)).appendTo(*out);
}