#include <folly/FBString.h>
#include <folly/Portability.h>
#include <folly/SpookyHashV2.h>
+#include <folly/portability/BitsFunctexcept.h>
#include <folly/portability/Constexpr.h>
#include <folly/portability/String.h>
template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
Range(const std::string& str, std::string::size_type startFrom) {
if (UNLIKELY(startFrom > str.size())) {
- throw std::out_of_range("index out of range");
+ std::__throw_out_of_range("index out of range");
}
b_ = str.data() + startFrom;
e_ = str.data() + str.size();
std::string::size_type startFrom,
std::string::size_type size) {
if (UNLIKELY(startFrom > str.size())) {
- throw std::out_of_range("index out of range");
+ std::__throw_out_of_range("index out of range");
}
b_ = str.data() + startFrom;
if (str.size() - startFrom < size) {
template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
Range(const fbstring& str, fbstring::size_type startFrom) {
if (UNLIKELY(startFrom > str.size())) {
- throw std::out_of_range("index out of range");
+ std::__throw_out_of_range("index out of range");
}
b_ = str.data() + startFrom;
e_ = str.data() + str.size();
Range(const fbstring& str, fbstring::size_type startFrom,
fbstring::size_type size) {
if (UNLIKELY(startFrom > str.size())) {
- throw std::out_of_range("index out of range");
+ std::__throw_out_of_range("index out of range");
}
b_ = str.data() + startFrom;
if (str.size() - startFrom < size) {
}
value_type& at(size_t i) {
- if (i >= size()) throw std::out_of_range("index out of range");
+ if (i >= size()) std::__throw_out_of_range("index out of range");
return b_[i];
}
const value_type& at(size_t i) const {
- if (i >= size()) throw std::out_of_range("index out of range");
+ if (i >= size()) std::__throw_out_of_range("index out of range");
return b_[i];
}
// (The above advice does not apply if you are targeting a 32-bit system.)
//
// Works only for Range<const char*> and Range<char*>
+ //
+ //
+ // ** WANT TO GET RID OF THIS LINT? **
+ //
+ // A) Use a better hash function (*cough*folly::Hash*cough*), but
+ // only if you don't serialize data in a format that depends on
+ // this formula (ie the writer and reader assume this exact hash
+ // function is used).
+ //
+ // B) If you have to use this exact function then make your own hasher
+ // object and copy the body over (see thrift example: D3972362).
+ // https://github.com/facebook/fbthrift/commit/f8ed502e24ab4a32a9d5f266580
+ FOLLY_DEPRECATED("Replace with folly::Hash if the hash is not serialized")
uint32_t hash() const {
// Taken from fbi/nstring.h:
// Quick and dirty bernstein hash...fine for short ascii strings
void advance(size_type n) {
if (UNLIKELY(n > size())) {
- throw std::out_of_range("index out of range");
+ std::__throw_out_of_range("index out of range");
}
b_ += n;
}
void subtract(size_type n) {
if (UNLIKELY(n > size())) {
- throw std::out_of_range("index out of range");
+ std::__throw_out_of_range("index out of range");
}
e_ -= n;
}
+ Range subpiece(size_type first, size_type length = npos) const {
+ if (UNLIKELY(first > size())) {
+ std::__throw_out_of_range("index out of range");
+ }
+
+ return Range(b_ + first, std::min(length, size() - first));
+ }
+
+ // unchecked versions
+ void uncheckedAdvance(size_type n) {
+ DCHECK_LE(n, size());
+ b_ += n;
+ }
+
+ void uncheckedSubtract(size_type n) {
+ DCHECK_LE(n, size());
+ e_ -= n;
+ }
+
+ Range uncheckedSubpiece(size_type first, size_type length = npos) const {
+ DCHECK_LE(first, size());
+ return Range(b_ + first, std::min(length, size() - first));
+ }
+
void pop_front() {
assert(b_ < e_);
++b_;
--e_;
}
- Range subpiece(size_type first, size_type length = npos) const {
- if (UNLIKELY(first > size())) {
- throw std::out_of_range("index out of range");
- }
-
- return Range(b_ + first, std::min(length, size() - first));
- }
-
// string work-alike functions
size_type find(const_range_type str) const {
return qfind(castToConst(), str);
} else if (e == e_) {
e_ = b;
} else {
- throw std::out_of_range("index out of range");
+ std::__throw_out_of_range("index out of range");
}
}
return StringPiece(lhs) >= StringPiece(rhs);
}
-// Do NOT use this, use SpookyHashV2 instead, see commment on hash() above.
-struct StringPieceHash {
- std::size_t operator()(const StringPiece str) const {
- return static_cast<std::size_t>(str.hash());
- }
-};
-
/**
* Finds substrings faster than brute force by borrowing from Boyer-Moore
*/
// specialization for StringPiece
template <>
inline size_t qfind(const Range<const char*>& haystack, const char& needle) {
+ // memchr expects a not-null pointer, early return if the range is empty.
+ if (haystack.empty()) {
+ return std::string::npos;
+ }
auto pos = static_cast<const char*>(
::memchr(haystack.data(), needle, haystack.size()));
return pos == nullptr ? std::string::npos : pos - haystack.data();
template <>
inline size_t rfind(const Range<const char*>& haystack, const char& needle) {
+ // memchr expects a not-null pointer, early return if the range is empty.
+ if (haystack.empty()) {
+ return std::string::npos;
+ }
auto pos = static_cast<const char*>(
::memrchr(haystack.data(), needle, haystack.size()));
return pos == nullptr ? std::string::npos : pos - haystack.data();
template <>
inline size_t qfind(const Range<const unsigned char*>& haystack,
const unsigned char& needle) {
+ // memchr expects a not-null pointer, early return if the range is empty.
+ if (haystack.empty()) {
+ return std::string::npos;
+ }
auto pos = static_cast<const unsigned char*>(
::memchr(haystack.data(), needle, haystack.size()));
return pos == nullptr ? std::string::npos : pos - haystack.data();
template <>
inline size_t rfind(const Range<const unsigned char*>& haystack,
const unsigned char& needle) {
+ // memchr expects a not-null pointer, early return if the range is empty.
+ if (haystack.empty()) {
+ return std::string::npos;
+ }
auto pos = static_cast<const unsigned char*>(
::memrchr(haystack.data(), needle, haystack.size()));
return pos == nullptr ? std::string::npos : pos - haystack.data();
}
};
+/**
+ * Ubiquitous helper template for knowing what's a string
+ */
+template <class T> struct IsSomeString {
+ enum { value = std::is_same<T, std::string>::value
+ || std::is_same<T, fbstring>::value };
+};
+
} // !namespace folly
#pragma GCC diagnostic pop