From: Peter Griess Date: Wed, 25 Sep 2013 23:49:10 +0000 (-0500) Subject: Handle lack of and X-Git-Tag: v0.22.0~793 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=758e4c7773f067231bec9739caac165dde9442f9;p=folly.git Handle lack of and Summary: - Clang's libc++ doesn't provide these header files. Detect libc++ via the _LIBCPP_VERSION symbol (pulling it in by sourcing some header files earlier if necessary) and avoid using these files. Test Plan: - fbconfig -r folly && fbmake runtests - ./configure && make check on Ubuntu/FC/Mac Reviewed By: andrewjcg@fb.com FB internal diff: D998595 --- diff --git a/folly/FBString.h b/folly/FBString.h index 6f5ea131..6912e0c7 100644 --- a/folly/FBString.h +++ b/folly/FBString.h @@ -58,6 +58,12 @@ #endif #endif +#include +#include +#include + +// 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 @@ -65,6 +71,7 @@ // _LIBSTDCXX_FBSTRING - Set inside libstdc++. This is useful to // gate use inside fbcode v. libstdc++ #include +#endif #ifdef _LIBSTDCXX_FBSTRING @@ -80,16 +87,28 @@ #undef FOLLY_MALLOC_H_ #endif +// FBString cannot use throw when replacing std::string, though it may still +// use std::__throw_* +#define throw FOLLY_FBSTRING_MAY_NOT_USE_THROW +#define THROW_LENGTH_ERROR std::__throw_length_error +#define THROW_LOGIC_ERROR std::__throw_logic_error +#define THROW_OUT_OF_RANGE std::__throw_out_of_range + #else // !_LIBSTDCXX_FBSTRING #include #include #include +#include #include "folly/Traits.h" #include "folly/Malloc.h" #include "folly/Hash.h" +#define THROW_LENGTH_ERROR ::folly::throw_length_error +#define THROW_LOGIC_ERROR ::folly::throw_logic_error +#define THROW_OUT_OF_RANGE ::folly::throw_out_of_range + #endif // We defined these here rather than including Likely.h to avoid @@ -97,23 +116,30 @@ #define FBSTRING_LIKELY(x) (__builtin_expect((x), 1)) #define FBSTRING_UNLIKELY(x) (__builtin_expect((x), 0)) -#include -#include -#include - // Ignore shadowing warnings within this file, so includers can use -Wshadow. #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wshadow" -// FBString cannot use throw when replacing std::string, though it may still -// use std::__throw_* -#define throw FOLLY_FBSTRING_MAY_NOT_USE_THROW - #ifdef _LIBSTDCXX_FBSTRING namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION #else namespace folly { +namespace { + +void throw_length_error(const char* msg) { + throw std::length_error(msg); +} + +void throw_logic_error(const char* msg) { + throw std::logic_error(msg); +} + +void throw_out_of_range(const char* msg) { + throw std::out_of_range(msg); +} + +} // namespace fbstring_detail #endif // Different versions of gcc/clang support different versions of @@ -1048,7 +1074,7 @@ public: : store_(s, s ? traits_type::length(s) : ({ basic_fbstring err = __PRETTY_FUNCTION__; err += ": null pointer initializer not valid"; - std::__throw_logic_error(err.c_str()); + THROW_LOGIC_ERROR(err.c_str()); 0; })) { } @@ -1261,7 +1287,7 @@ public: size_type capacity() const { return store_.capacity(); } void reserve(size_type res_arg = 0) { - enforce(res_arg <= max_size(), std::__throw_length_error, ""); + enforce(res_arg <= max_size(), THROW_LENGTH_ERROR, ""); store_.reserve(res_arg); } @@ -1291,12 +1317,12 @@ public: } const_reference at(size_type n) const { - enforce(n <= size(), std::__throw_out_of_range, ""); + enforce(n <= size(), THROW_OUT_OF_RANGE, ""); return (*this)[n]; } reference at(size_type n) { - enforce(n < size(), std::__throw_out_of_range, ""); + enforce(n < size(), THROW_OUT_OF_RANGE, ""); return (*this)[n]; } @@ -1331,7 +1357,7 @@ public: basic_fbstring& append(const basic_fbstring& str, const size_type pos, size_type n) { const size_type sz = str.size(); - enforce(pos <= sz, std::__throw_out_of_range, ""); + enforce(pos <= sz, THROW_OUT_OF_RANGE, ""); procrustes(n, sz - pos); return append(str.data() + pos, n); } @@ -1408,7 +1434,7 @@ public: basic_fbstring& assign(const basic_fbstring& str, const size_type pos, size_type n) { const size_type sz = str.size(); - enforce(pos <= sz, std::__throw_out_of_range, ""); + enforce(pos <= sz, THROW_OUT_OF_RANGE, ""); procrustes(n, sz - pos); return assign(str.data() + pos, n); } @@ -1450,13 +1476,13 @@ public: basic_fbstring& insert(size_type pos1, const basic_fbstring& str, size_type pos2, size_type n) { - enforce(pos2 <= str.length(), std::__throw_out_of_range, ""); + enforce(pos2 <= str.length(), THROW_OUT_OF_RANGE, ""); procrustes(n, str.length() - pos2); return insert(pos1, str.data() + pos2, n); } basic_fbstring& insert(size_type pos, const value_type* s, size_type n) { - enforce(pos <= length(), std::__throw_out_of_range, ""); + enforce(pos <= length(), THROW_OUT_OF_RANGE, ""); insert(begin() + pos, s, s + n); return *this; } @@ -1466,7 +1492,7 @@ public: } basic_fbstring& insert(size_type pos, size_type n, value_type c) { - enforce(pos <= length(), std::__throw_out_of_range, ""); + enforce(pos <= length(), THROW_OUT_OF_RANGE, ""); insert(begin() + pos, n, c); return *this; } @@ -1586,7 +1612,7 @@ public: basic_fbstring& erase(size_type pos = 0, size_type n = npos) { Invariant checker(*this); (void) checker; - enforce(pos <= length(), std::__throw_out_of_range, ""); + enforce(pos <= length(), THROW_OUT_OF_RANGE, ""); procrustes(n, length() - pos); std::copy(begin() + pos + n, end(), begin() + pos); resize(length() - n); @@ -1595,7 +1621,7 @@ public: iterator erase(iterator position) { const size_type pos(position - begin()); - enforce(pos <= size(), std::__throw_out_of_range, ""); + enforce(pos <= size(), THROW_OUT_OF_RANGE, ""); erase(pos, 1); return begin() + pos; } @@ -1618,7 +1644,7 @@ public: basic_fbstring& replace(size_type pos1, size_type n1, const basic_fbstring& str, size_type pos2, size_type n2) { - enforce(pos2 <= str.length(), std::__throw_out_of_range, ""); + enforce(pos2 <= str.length(), THROW_OUT_OF_RANGE, ""); return replace(pos1, n1, str.data() + pos2, std::min(n2, str.size() - pos2)); } @@ -1640,7 +1666,7 @@ public: StrOrLength s_or_n2, NumOrChar n_or_c) { Invariant checker(*this); (void) checker; - enforce(pos <= size(), std::__throw_out_of_range, ""); + enforce(pos <= size(), THROW_OUT_OF_RANGE, ""); procrustes(n1, length() - pos); const iterator b = begin() + pos; return replace(b, b + n1, s_or_n2, n_or_c); @@ -1762,7 +1788,7 @@ public: } size_type copy(value_type* s, size_type n, size_type pos = 0) const { - enforce(pos <= size(), std::__throw_out_of_range, ""); + enforce(pos <= size(), THROW_OUT_OF_RANGE, ""); procrustes(n, size() - pos); fbstring_detail::pod_copy( @@ -1994,7 +2020,7 @@ public: } basic_fbstring substr(size_type pos = 0, size_type n = npos) const { - enforce(pos <= size(), std::__throw_out_of_range, ""); + enforce(pos <= size(), THROW_OUT_OF_RANGE, ""); return basic_fbstring(data() + pos, std::min(n, size() - pos)); } @@ -2015,7 +2041,7 @@ public: int compare(size_type pos1, size_type n1, const value_type* s, size_type n2) const { - enforce(pos1 <= size(), std::__throw_out_of_range, ""); + enforce(pos1 <= size(), THROW_OUT_OF_RANGE, ""); procrustes(n1, size() - pos1); // The line below fixed by Jean-Francois Bastien, 04-23-2007. Thanks! const int r = traits_type::compare(pos1 + data(), s, std::min(n1, n2)); @@ -2025,7 +2051,7 @@ public: int compare(size_type pos1, size_type n1, const basic_fbstring& str, size_type pos2, size_type n2) const { - enforce(pos2 <= str.size(), std::__throw_out_of_range, ""); + enforce(pos2 <= str.size(), THROW_OUT_OF_RANGE, ""); return compare(pos1, n1, str.data() + pos2, std::min(n2, str.size() - pos2)); } diff --git a/folly/Malloc.h b/folly/Malloc.h index f7c94ca1..8310a9aa 100644 --- a/folly/Malloc.h +++ b/folly/Malloc.h @@ -41,9 +41,11 @@ namespace folly { #ifdef _LIBSTDCXX_FBSTRING #pragma GCC system_header +#include #define FOLLY_HAVE_MALLOC_H 1 #else #include "folly/Portability.h" +#include #endif // for malloc_usable_size @@ -62,8 +64,6 @@ namespace folly { #include -#include - /** * Define various ALLOCM_* macros normally provided by jemalloc. We define * them so that we don't have to include jemalloc.h, in case the program is @@ -157,19 +157,31 @@ static const size_t jemallocMinInPlaceExpandable = 4096; */ inline void* checkedMalloc(size_t size) { void* p = malloc(size); +#ifdef _LIBSTDCXX_FBSTRING if (!p) std::__throw_bad_alloc(); +#else + if (!p) throw std::bad_alloc(); +#endif return p; } inline void* checkedCalloc(size_t n, size_t size) { void* p = calloc(n, size); +#ifdef _LIBSTDCXX_FBSTRING if (!p) std::__throw_bad_alloc(); +#else + if (!p) throw std::bad_alloc(); +#endif return p; } inline void* checkedRealloc(void* ptr, size_t size) { void* p = realloc(ptr, size); +#ifdef _LIBSTDCXX_FBSTRING if (!p) std::__throw_bad_alloc(); +#else + if (!p) throw std::bad_alloc(); +#endif return p; } diff --git a/folly/Range.h b/folly/Range.h index 2041d29b..487bc4ed 100644 --- a/folly/Range.h +++ b/folly/Range.h @@ -30,7 +30,18 @@ #include #include #include + +// libc++ doesn't provide this header +#if !FOLLY_USE_LIBCPP +// 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 +// c++config.h: +// _LIBSTDCXX_FBSTRING - Set inside libstdc++. This is useful to +// gate use inside fbcode v. libstdc++ #include +#endif + #include "folly/CpuId.h" #include "folly/Traits.h" #include "folly/Likely.h" diff --git a/folly/Traits.h b/folly/Traits.h index f5fe5816..4d6deeb5 100644 --- a/folly/Traits.h +++ b/folly/Traits.h @@ -25,7 +25,16 @@ #include "folly/Portability.h" +// libc++ doesn't provide this header +#if !FOLLY_USE_LIBCPP +// 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 +// c++config.h: +// _LIBSTDCXX_FBSTRING - Set inside libstdc++. This is useful to +// gate use inside fbcode v. libstdc++ #include +#endif #include #include