X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FFBString.h;h=e492e8f560f04eb317c340f6965528f298d13c50;hp=e80eba5914434885ffb28a82f37ca0d8baa339ff;hb=275ca94d04e44f28cfa411668eb1c1dd8db90b80;hpb=df377ed2a89f02d266468ef2a2d4ea109f741138 diff --git a/folly/FBString.h b/folly/FBString.h index e80eba59..e492e8f5 100644 --- a/folly/FBString.h +++ b/folly/FBString.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. @@ -36,9 +36,9 @@ // either before or after this inclusion. #ifdef FOLLY_MALLOC_H_ #undef FOLLY_MALLOC_H_ -#include "basic_fbstring_malloc.h" +#include "basic_fbstring_malloc.h" // nolint #else -#include "basic_fbstring_malloc.h" +#include "basic_fbstring_malloc.h" // nolint #undef FOLLY_MALLOC_H_ #endif @@ -86,6 +86,7 @@ // FBString cannot use throw when replacing std::string, though it may still // use std::__throw_* +// nolint #define throw FOLLY_FBSTRING_MAY_NOT_USE_THROW #ifdef _LIBSTDCXX_FBSTRING @@ -1968,11 +1969,18 @@ public: return find_last_not_of(&c, pos, 1); } - basic_fbstring substr(size_type pos = 0, size_type n = npos) const { + basic_fbstring substr(size_type pos = 0, size_type n = npos) const& { enforce(pos <= size(), std::__throw_out_of_range, ""); return basic_fbstring(data() + pos, std::min(n, size() - pos)); } + basic_fbstring substr(size_type pos = 0, size_type n = npos) && { + enforce(pos <= size(), std::__throw_out_of_range, ""); + erase(0, pos); + if (n < size()) resize(n); + return std::move(*this); + } + int compare(const basic_fbstring& str) const { // FIX due to Goncalo N M de Carvalho July 18, 2005 return compare(0, size(), str); @@ -2020,7 +2028,7 @@ private: }; // non-member functions -// C++11 21.4.8.1/2 +// C++11 21.4.8.1/1 template inline basic_fbstring operator+(const basic_fbstring& lhs, @@ -2062,24 +2070,44 @@ basic_fbstring operator+(basic_fbstring&& lhs, return std::move(lhs.append(rhs)); } +// C++11 21.4.8.1/5 template inline basic_fbstring operator+( - const typename basic_fbstring::value_type* lhs, + const E* lhs, const basic_fbstring& rhs) { // basic_fbstring result; - const typename basic_fbstring::size_type len = - basic_fbstring::traits_type::length(lhs); + const auto len = basic_fbstring::traits_type::length(lhs); + result.reserve(len + rhs.size()); + result.append(lhs, len).append(rhs); + return result; +} + +// C++11 21.4.8.1/6 +template +inline +basic_fbstring operator+( + const E* lhs, + basic_fbstring&& rhs) { + // + const auto len = basic_fbstring::traits_type::length(lhs); + if (rhs.capacity() >= len + rhs.size()) { + // Good, at least we don't need to reallocate + return std::move(rhs.insert(rhs.begin(), lhs, lhs + len)); + } + // Meh, no go. Do it by hand since we have len already. + basic_fbstring result; result.reserve(len + rhs.size()); result.append(lhs, len).append(rhs); return result; } +// C++11 21.4.8.1/7 template inline basic_fbstring operator+( - typename basic_fbstring::value_type lhs, + E lhs, const basic_fbstring& rhs) { basic_fbstring result; @@ -2089,11 +2117,28 @@ basic_fbstring operator+( return result; } +// C++11 21.4.8.1/8 +template +inline +basic_fbstring operator+( + E lhs, + basic_fbstring&& rhs) { + // + if (rhs.capacity() > rhs.size()) { + // Good, at least we don't need to reallocate + return std::move(rhs.insert(rhs.begin(), lhs)); + } + // Meh, no go. Forward to operator+(E, const&). + auto const& rhsC = rhs; + return lhs + rhsC; +} + +// C++11 21.4.8.1/9 template inline basic_fbstring operator+( const basic_fbstring& lhs, - const typename basic_fbstring::value_type* rhs) { + const E* rhs) { typedef typename basic_fbstring::size_type size_type; typedef typename basic_fbstring::traits_type traits_type; @@ -2105,11 +2150,22 @@ basic_fbstring operator+( return result; } +// C++11 21.4.8.1/10 +template +inline +basic_fbstring operator+( + basic_fbstring&& lhs, + const E* rhs) { + // + return std::move(lhs += rhs); +} + +// C++11 21.4.8.1/11 template inline basic_fbstring operator+( const basic_fbstring& lhs, - typename basic_fbstring::value_type rhs) { + E rhs) { basic_fbstring result; result.reserve(lhs.size() + 1); @@ -2118,6 +2174,16 @@ basic_fbstring operator+( return result; } +// C++11 21.4.8.1/12 +template +inline +basic_fbstring operator+( + basic_fbstring&& lhs, + E rhs) { + // + return std::move(lhs += rhs); +} + template inline bool operator==(const basic_fbstring& lhs, @@ -2252,20 +2318,20 @@ std::basic_istream< auto err = __ios_base::goodbit; if (sentry) { auto n = is.width(); - if (n == 0) { + if (n <= 0) { n = str.max_size(); } str.erase(); - auto got = is.rdbuf()->sgetc(); - for (; extracted != n && got != T::eof() && !isspace(got); ++extracted) { - // Whew. We get to store this guy + for (auto got = is.rdbuf()->sgetc(); extracted != size_t(n); ++extracted) { + if (got == T::eof()) { + err |= __ios_base::eofbit; + is.width(0); + break; + } + if (isspace(got)) break; str.push_back(got); got = is.rdbuf()->snextc(); } - if (got == T::eof()) { - err |= __ios_base::eofbit; - is.width(0); - } } if (!extracted) { err |= __ios_base::failbit;