/*
- * 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.
// 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
// 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
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);
};
// non-member functions
-// C++11 21.4.8.1/2
+// C++11 21.4.8.1/1
template <typename E, class T, class A, class S>
inline
basic_fbstring<E, T, A, S> operator+(const basic_fbstring<E, T, A, S>& lhs,
return std::move(lhs.append(rhs));
}
+// C++11 21.4.8.1/5
template <typename E, class T, class A, class S>
inline
basic_fbstring<E, T, A, S> operator+(
- const typename basic_fbstring<E, T, A, S>::value_type* lhs,
+ const E* lhs,
const basic_fbstring<E, T, A, S>& rhs) {
//
basic_fbstring<E, T, A, S> result;
- const typename basic_fbstring<E, T, A, S>::size_type len =
- basic_fbstring<E, T, A, S>::traits_type::length(lhs);
+ const auto len = basic_fbstring<E, T, A, S>::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 <typename E, class T, class A, class S>
+inline
+basic_fbstring<E, T, A, S> operator+(
+ const E* lhs,
+ basic_fbstring<E, T, A, S>&& rhs) {
+ //
+ const auto len = basic_fbstring<E, T, A, S>::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<E, T, A, S> result;
result.reserve(len + rhs.size());
result.append(lhs, len).append(rhs);
return result;
}
+// C++11 21.4.8.1/7
template <typename E, class T, class A, class S>
inline
basic_fbstring<E, T, A, S> operator+(
- typename basic_fbstring<E, T, A, S>::value_type lhs,
+ E lhs,
const basic_fbstring<E, T, A, S>& rhs) {
basic_fbstring<E, T, A, S> result;
return result;
}
+// C++11 21.4.8.1/8
+template <typename E, class T, class A, class S>
+inline
+basic_fbstring<E, T, A, S> operator+(
+ E lhs,
+ basic_fbstring<E, T, A, S>&& 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 <typename E, class T, class A, class S>
inline
basic_fbstring<E, T, A, S> operator+(
const basic_fbstring<E, T, A, S>& lhs,
- const typename basic_fbstring<E, T, A, S>::value_type* rhs) {
+ const E* rhs) {
typedef typename basic_fbstring<E, T, A, S>::size_type size_type;
typedef typename basic_fbstring<E, T, A, S>::traits_type traits_type;
return result;
}
+// C++11 21.4.8.1/10
+template <typename E, class T, class A, class S>
+inline
+basic_fbstring<E, T, A, S> operator+(
+ basic_fbstring<E, T, A, S>&& lhs,
+ const E* rhs) {
+ //
+ return std::move(lhs += rhs);
+}
+
+// C++11 21.4.8.1/11
template <typename E, class T, class A, class S>
inline
basic_fbstring<E, T, A, S> operator+(
const basic_fbstring<E, T, A, S>& lhs,
- typename basic_fbstring<E, T, A, S>::value_type rhs) {
+ E rhs) {
basic_fbstring<E, T, A, S> result;
result.reserve(lhs.size() + 1);
return result;
}
+// C++11 21.4.8.1/12
+template <typename E, class T, class A, class S>
+inline
+basic_fbstring<E, T, A, S> operator+(
+ basic_fbstring<E, T, A, S>&& lhs,
+ E rhs) {
+ //
+ return std::move(lhs += rhs);
+}
+
template <typename E, class T, class A, class S>
inline
bool operator==(const basic_fbstring<E, T, A, S>& lhs,
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;