#pragma GCC system_header
+// When used as std::string replacement always disable assertions.
+#ifndef NDEBUG
+#define NDEBUG
+#define FOLLY_DEFINED_NDEBUG_FOR_FBSTRING
+#endif // NDEBUG
+
// Handle the cases where the fbcode version (folly/Malloc.h) is included
// either before or after this inclusion.
#ifdef FOLLY_MALLOC_H_
// has issues when inlining is used, so disable that as well.
#if defined(__clang__)
# if __has_feature(address_sanitizer)
-# if __has_attribute(__no_address_safety_analysis__)
+# if __has_attribute(__no_sanitize__)
+# define FBSTRING_DISABLE_ADDRESS_SANITIZER \
+ __attribute__((__no_sanitize__("address"), __noinline__))
+# elif __has_attribute(__no_address_safety_analysis__)
# define FBSTRING_DISABLE_ADDRESS_SANITIZER \
__attribute__((__no_address_safety_analysis__, __noinline__))
# elif __has_attribute(__no_sanitize_address__)
# endif
# endif
#elif defined (__GNUC__) && \
- (__GNUC__ == 4) && \
- (__GNUC_MINOR__ >= 8) && \
__SANITIZE_ADDRESS__
# define FBSTRING_DISABLE_ADDRESS_SANITIZER \
__attribute__((__no_address_safety_analysis__, __noinline__))
public:
// C++11 21.4.2 construct/copy/destroy
- explicit basic_fbstring(const A& /*a*/ = A()) noexcept {
+
+ // Note: while the following two constructors can be (and previously were)
+ // collapsed into one constructor written this way:
+ //
+ // explicit basic_fbstring(const A& a = A()) noexcept { }
+ //
+ // This can cause Clang (at least version 3.7) to fail with the error:
+ // "chosen constructor is explicit in copy-initialization ...
+ // in implicit initialization of field '(x)' with omitted initializer"
+ //
+ // if used in a struct which is default-initialized. Hence the split into
+ // these two separate constructors.
+
+ basic_fbstring() noexcept : basic_fbstring(A()) {
+ }
+
+ explicit basic_fbstring(const A&) noexcept {
}
basic_fbstring(const basic_fbstring& str)
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));
+ rhs.insert(rhs.begin(), lhs, lhs + len);
+ return rhs;
}
// Meh, no go. Do it by hand since we have len already.
basic_fbstring<E, T, A, S> result;
//
if (rhs.capacity() > rhs.size()) {
// Good, at least we don't need to reallocate
- return std::move(rhs.insert(rhs.begin(), lhs));
+ rhs.insert(rhs.begin(), lhs);
+ return rhs;
}
// Meh, no go. Forward to operator+(E, const&).
auto const& rhsC = rhs;
#undef FBSTRING_LIKELY
#undef FBSTRING_UNLIKELY
+#ifdef FOLLY_DEFINED_NDEBUG_FOR_FBSTRING
+#undef NDEBUG
+#undef FOLLY_DEFINED_NDEBUG_FOR_FBSTRING
+#endif // FOLLY_DEFINED_NDEBUG_FOR_FBSTRING
+
#endif // FOLLY_BASE_FBSTRING_H_