X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FString.h;h=9ce4be650861b941096b2af70373079931a8d64d;hb=bc34a5a774095b639bef86ca3b9383b8082c8b87;hp=241d4dbf6aac26479d88853cf3514a4f99eac137;hpb=e3225b60a767f9bae67a475997e2b5ac426e29ea;p=folly.git diff --git a/folly/String.h b/folly/String.h index 241d4dbf..9ce4be65 100644 --- a/folly/String.h +++ b/folly/String.h @@ -1,5 +1,5 @@ /* - * Copyright 2014 Facebook, Inc. + * Copyright 2015 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,24 +18,27 @@ #define FOLLY_BASE_STRING_H_ #include +#include #include #include +#ifdef FOLLY_HAVE_DEPRECATED_ASSOC #ifdef _GLIBCXX_SYMVER #include #include #endif +#endif #include #include -#include "folly/Conv.h" -#include "folly/Demangle.h" -#include "folly/FBString.h" -#include "folly/FBVector.h" -#include "folly/Portability.h" -#include "folly/Range.h" -#include "folly/ScopeGuard.h" +#include +#include +#include +#include +#include +#include +#include // Compatibility function, to make sure toStdString(s) can be called // to convert a std::string or fbstring variable s into type std::string @@ -173,16 +176,26 @@ String uriUnescape(StringPiece str, UriEscapeMode mode = UriEscapeMode::ALL) { * resulting string, and the second appends the produced characters to * the specified string and returns a reference to it. */ -std::string stringPrintf(const char* format, ...) - __attribute__ ((format (printf, 1, 2))); +std::string stringPrintf(FOLLY_PRINTF_FORMAT const char* format, ...) + FOLLY_PRINTF_FORMAT_ATTR(1, 2); + +/* Similar to stringPrintf, with different signature. */ +void stringPrintf(std::string* out, FOLLY_PRINTF_FORMAT const char* fmt, ...) + FOLLY_PRINTF_FORMAT_ATTR(2, 3); -/** Similar to stringPrintf, with different signiture. - */ -void stringPrintf(std::string* out, const char* fmt, ...) - __attribute__ ((format (printf, 2, 3))); +std::string& stringAppendf(std::string* output, + FOLLY_PRINTF_FORMAT const char* format, ...) + FOLLY_PRINTF_FORMAT_ATTR(2, 3); -std::string& stringAppendf(std::string* output, const char* format, ...) - __attribute__ ((format (printf, 2, 3))); +/** + * Similar to stringPrintf, but accepts a va_list argument. + * + * As with vsnprintf() itself, the value of ap is undefined after the call. + * These functions do not call va_end() on ap. + */ +std::string stringVPrintf(const char* format, va_list ap); +void stringVPrintf(std::string* out, const char* format, va_list ap); +std::string& stringVAppendf(std::string* out, const char* format, va_list ap); /** * Backslashify a string, that is, replace non-printable characters @@ -268,7 +281,8 @@ bool unhexlify(const InputString& input, OutputString& output); * PRETTY_UNITS_METRIC - k, M, G, etc (goes up by 10^3 = 1000 each time) * PRETTY_UNITS_BINARY - k, M, G, etc (goes up by 2^10 = 1024 each time) * PRETTY_UNITS_BINARY_IEC - Ki, Mi, Gi, etc - * + * PRETTY_SI - full SI metric prefixes from yocto to Yotta + * http://en.wikipedia.org/wiki/Metric_prefix * @author Mark Rabkin */ enum PrettyType { @@ -284,11 +298,38 @@ enum PrettyType { PRETTY_UNITS_BINARY, PRETTY_UNITS_BINARY_IEC, - PRETTY_NUM_TYPES + PRETTY_SI, + PRETTY_NUM_TYPES, }; std::string prettyPrint(double val, PrettyType, bool addSpace = true); +/** + * This utility converts StringPiece in pretty format (look above) to double, + * with progress information. Alters the StringPiece parameter + * to get rid of the already-parsed characters. + * Expects string in form {space}* [] + * If string is not in correct format, utility finds longest valid prefix and + * if there at least one, returns double value based on that prefix and + * modifies string to what is left after parsing. Throws and std::range_error + * exception if there is no correct parse. + * Examples(for PRETTY_UNITS_METRIC): + * '10M' => 10 000 000 + * '10 M' => 10 000 000 + * '10' => 10 + * '10 Mx' => 10 000 000, prettyString == "x" + * 'abc' => throws std::range_error + */ +double prettyToDouble(folly::StringPiece *const prettyString, + const PrettyType type); + +/* + * Same as prettyToDouble(folly::StringPiece*, PrettyType), but + * expects whole string to be correctly parseable. Throws std::range_error + * otherwise + */ +double prettyToDouble(folly::StringPiece prettyString, const PrettyType type); + /** * Write a hex dump of size bytes starting at ptr to out. * @@ -319,12 +360,21 @@ std::string hexDump(const void* ptr, size_t size); fbstring errnoStr(int err); /** - * Debug string for an exception: include type and what(). + * Debug string for an exception: include type and what(), if + * defined. */ inline fbstring exceptionStr(const std::exception& e) { +#ifdef FOLLY_HAS_RTTI return folly::to(demangle(typeid(e)), ": ", e.what()); +#else + return folly::to("Exception (no RTTI available): ", e.what()); +#endif } +// Empirically, this indicates if the runtime supports +// std::exception_ptr, as not all (arm, for instance) do. +#if defined(__GNUC__) && defined(__GCC_ATOMIC_INT_LOCK_FREE) && \ + __GCC_ATOMIC_INT_LOCK_FREE > 1 inline fbstring exceptionStr(std::exception_ptr ep) { try { std::rethrow_exception(ep); @@ -334,6 +384,19 @@ inline fbstring exceptionStr(std::exception_ptr ep) { return ""; } } +#endif + +template +auto exceptionStr(const E& e) + -> typename std::enable_if::value, + fbstring>::type +{ +#ifdef FOLLY_HAS_RTTI + return folly::to(demangle(typeid(e))); +#else + return "Exception (no RTTI available)"; +#endif +} /* * Split a string into a list of tokens by delimiter. @@ -384,16 +447,26 @@ void splitTo(const Delim& delimiter, bool ignoreEmpty = false); /* - * Split a string into a fixed number of pieces by delimiter. Returns 'true' if - * the fields were all successfully populated. + * Split a string into a fixed number of string pieces and/or numeric types + * by delimiter. Any numeric type that folly::to<> can convert to from a + * string piece is supported as a target. Returns 'true' if the fields were + * all successfully populated. Returns 'false' if there were too few fields + * in the input, or too many fields if exact=true. Casting exceptions will + * not be caught. * - * Example: + * Examples: * * folly::StringPiece name, key, value; * if (folly::split('\t', line, name, key, value)) * ... * - * The 'exact' template paremeter specifies how the function behaves when too + * folly::StringPiece name; + * double value; + * int id; + * if (folly::split('\t', line, name, value, id)) + * ... + * + * The 'exact' template parameter specifies how the function behaves when too * many fields are present in the input string. When 'exact' is set to its * default value of 'true', a call to split will fail if the number of fields in * the input string does not exactly match the number of output parameters @@ -403,14 +476,25 @@ void splitTo(const Delim& delimiter, * folly::StringPiece x, y. * if (folly::split(':', "a:b:c", x, y)) * assert(x == "a" && y == "b:c"); + * + * Note that this will likely not work if the last field's target is of numeric + * type, in which case folly::to<> will throw an exception. */ +template +using IsSplitTargetType = std::integral_constant::value || + std::is_same::value || + IsSomeString::value>; + template -bool split(const Delim& delimiter, - StringPiece input, - StringPiece& outHead, - StringPieces&... outTail); + class OutputType, + class... OutputTypes> +typename std::enable_if::value, bool>::type +split(const Delim& delimiter, + StringPiece input, + OutputType& outHead, + OutputTypes&... outTail); /* * Join list of tokens. @@ -455,35 +539,40 @@ std::string join(const Delim& delimiter, return output; } -} // namespace folly +template ::iterator_category, + std::random_access_iterator_tag>::value>::type* = nullptr> +std::string join(const Delim& delimiter, Iterator begin, Iterator end) { + std::string output; + join(delimiter, begin, end, output); + return output; +} -// Hash functions to make std::string usable with e.g. hash_map -// -// Handle interaction with different C++ standard libraries, which -// expect these types to be in different namespaces. -namespace std { +/** + * Returns a subpiece with all whitespace removed from the front of @sp. + * Whitespace means any of [' ', '\n', '\r', '\t']. + */ +StringPiece skipWhitespace(StringPiece sp); -template -struct hash > : private hash { - size_t operator()(const std::basic_string & s) const { - return hash::operator()(s.c_str()); - } -}; +/** + * Fast, in-place lowercasing of ASCII alphabetic characters in strings. + * Leaves all other characters unchanged, including those with the 0x80 + * bit set. + * @param str String to convert + * @param len Length of str, in bytes + */ +void toLowerAscii(char* str, size_t length); +inline void toLowerAscii(MutableStringPiece str) { + toLowerAscii(str.begin(), str.size()); } -#if defined(_GLIBCXX_SYMVER) && !defined(__BIONIC__) -namespace __gnu_cxx { +// glibc doesn't have strlcpy +size_t strlcpy(char* dest, const char* const src, size_t size); -template -struct hash > : private hash { - size_t operator()(const std::basic_string & s) const { - return hash::operator()(s.c_str()); - } -}; - -} -#endif +} // namespace folly // Hook into boost's type traits namespace boost { @@ -493,6 +582,6 @@ struct has_nothrow_constructor > : true_type { }; } // namespace boost -#include "folly/String-inl.h" +#include #endif