X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=folly%2FString.h;h=39dc11e314a8d51f9d97019b33d1ec44bf022dc1;hb=c8aadaad37770dc4d1caf2bff239c604b51a6132;hp=19a2c3b23727a93d32a3ab312ca7483740af9e3a;hpb=b0a7bdf6b2ad6255b4ea843703b77aed040718d3;p=folly.git diff --git a/folly/String.h b/folly/String.h index 19a2c3b2..39dc11e3 100644 --- a/folly/String.h +++ b/folly/String.h @@ -1,5 +1,5 @@ /* - * Copyright 2016 Facebook, Inc. + * Copyright 2017 Facebook, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,12 +14,13 @@ * limitations under the License. */ -#ifndef FOLLY_BASE_STRING_H_ -#define FOLLY_BASE_STRING_H_ +#pragma once +#define FOLLY_STRING_H_ #include #include #include +#include #include #include @@ -34,7 +35,7 @@ #include #include -#include +#include #include #include #include @@ -259,6 +260,21 @@ template bool hexlify(const InputString& input, OutputString& output, bool append=false); +template +OutputString hexlify(ByteRange input) { + OutputString output; + if (!hexlify(input, output)) { + // hexlify() currently always returns true, so this can't really happen + throw std::runtime_error("hexlify failed"); + } + return output; +} + +template +OutputString hexlify(StringPiece input) { + return hexlify(ByteRange{input}); +} + /** * Same functionality as Python's binascii.unhexlify. Returns true * on successful conversion. @@ -266,6 +282,17 @@ bool hexlify(const InputString& input, OutputString& output, template bool unhexlify(const InputString& input, OutputString& output); +template +OutputString unhexlify(StringPiece input) { + OutputString output; + if (!unhexlify(input, output)) { + // unhexlify() fails if the input has non-hexidecimal characters, + // or if it doesn't consist of a whole number of bytes + throw std::domain_error("unhexlify() called with non-hex input"); + } + return output; +} + /* * A pretty-printer for numbers that appends suffixes of units of the * given type. It prints 4 sig-figs of value with the most @@ -360,45 +387,6 @@ std::string hexDump(const void* ptr, size_t size); */ fbstring errnoStr(int err); -/** - * 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); - } catch (const std::exception& e) { - return exceptionStr(e); - } catch (...) { - 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. * @@ -432,28 +420,28 @@ template void split(const Delim& delimiter, const String& input, std::vector& out, - bool ignoreEmpty = false); + const bool ignoreEmpty = false); template void split(const Delim& delimiter, const String& input, folly::fbvector& out, - bool ignoreEmpty = false); + const bool ignoreEmpty = false); template void splitTo(const Delim& delimiter, const String& input, OutputIterator out, - bool ignoreEmpty = false); + const bool ignoreEmpty = false); /* * 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. + * by delimiter. Conversions are supported for any type which folly:to<> can + * target, including all overloads of parseTo(). 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. * * Examples: * @@ -481,21 +469,58 @@ void splitTo(const Delim& delimiter, * 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 +struct IsSomeVector { + enum { value = false }; +}; + +template +struct IsSomeVector, void> { + enum { value = true }; +}; + template -using IsSplitTargetType = std::integral_constant::value || - std::is_same::value || - IsSomeString::value>; - -template -typename std::enable_if::value, bool>::type -split(const Delim& delimiter, - StringPiece input, - OutputType& outHead, - OutputTypes&... outTail); +struct IsSomeVector, void> { + enum { value = true }; +}; + +template +struct IsConvertible { + enum { value = false }; +}; + +template +struct IsConvertible< + T, + decltype(static_cast( + parseTo(std::declval(), std::declval())))> { + enum { value = true }; +}; + +template +struct AllConvertible; + +template +struct AllConvertible { + enum { value = IsConvertible::value && AllConvertible::value }; +}; + +template <> +struct AllConvertible<> { + enum { value = true }; +}; + +static_assert(AllConvertible::value, ""); +static_assert(AllConvertible::value, ""); +static_assert(AllConvertible::value, ""); +static_assert(AllConvertible::value, ""); +static_assert(!AllConvertible>::value, ""); + +template +typename std::enable_if< + AllConvertible::value && sizeof...(OutputTypes) >= 1, + bool>::type +split(const Delim& delimiter, StringPiece input, OutputTypes&... outputs); /* * Join list of tokens. @@ -613,20 +638,12 @@ class UTF8Range : public Base { baseRange.begin(), baseRange.begin(), baseRange.end()), boost::u8_to_u32_iterator( baseRange.end(), baseRange.begin(), baseRange.end())) {} + /* implicit */ UTF8Range(const std::string& baseString) + : Base(folly::Range(baseString)) {} }; using UTF8StringPiece = UTF8Range; } // namespace folly -// Hook into boost's type traits -namespace boost { -template -struct has_nothrow_constructor > : true_type { - enum { value = true }; -}; -} // namespace boost - #include - -#endif