#endif
#endif
+#include <atomic>
+#include <limits>
+#include <type_traits>
+
+// libc++ doesn't provide this header
+#ifndef _LIBCPP_VERSION
// This file appears in two locations: inside fbcode and in the
// libstdc++ source code (when embedding fbstring as std::string).
// To aid in this schizophrenic use, two macros are defined in
// _LIBSTDCXX_FBSTRING - Set inside libstdc++. This is useful to
// gate use inside fbcode v. libstdc++
#include <bits/c++config.h>
+#endif
#ifdef _LIBSTDCXX_FBSTRING
#define FBSTRING_LIKELY(x) (__builtin_expect((x), 1))
#define FBSTRING_UNLIKELY(x) (__builtin_expect((x), 0))
-#include <atomic>
-#include <limits>
-#include <type_traits>
-
// Ignore shadowing warnings within this file, so includers can use -Wshadow.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wshadow"
const size_type nsize) const {
if (!nsize) return pos;
auto const size = this->size();
- if (nsize + pos > size) return npos;
+ // nsize + pos can overflow (eg pos == npos), guard against that by checking
+ // that nsize + pos does not wrap around.
+ if (nsize + pos > size || nsize + pos < pos) return npos;
// Don't use std::search, use a Boyer-Moore-like trick by comparing
// the last characters first
auto const haystack = data();
std::basic_ostream<typename basic_fbstring<E, T, A, S>::value_type,
typename basic_fbstring<E, T, A, S>::traits_type>& os,
const basic_fbstring<E, T, A, S>& str) {
- os.write(str.data(), str.size());
+ std::__ostream_insert(os, str.data(), str.size());
return os;
}