/*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2016 Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// @author Mark Rabkin (mrabkin@fb.com)
// @author Andrei Alexandrescu (andrei.alexandrescu@fb.com)
-#ifndef FOLLY_RANGE_H_
-#define FOLLY_RANGE_H_
+#pragma once
-#include <folly/Portability.h>
#include <folly/FBString.h>
+#include <folly/Portability.h>
#include <folly/SpookyHashV2.h>
+#include <folly/portability/Constexpr.h>
+#include <folly/portability/String.h>
#include <algorithm>
#include <boost/operators.hpp>
#include <climits>
+#include <cstddef>
#include <cstring>
#include <glog/logging.h>
#include <iosfwd>
constexpr Range(Iter start, size_t size)
: b_(start), e_(start + size) { }
+# if !__clang__ || __CLANG_PREREQ(3, 7) // Clang 3.6 crashes on this line
+ /* implicit */ Range(std::nullptr_t) = delete;
+# endif
+
template <class T = Iter, typename detail::IsCharPointer<T>::type = 0>
constexpr /* implicit */ Range(Iter str)
: b_(str), e_(str + constexpr_strlen(str)) {}
reset(str.data(), str.size());
}
- size_type size() const {
- assert(b_ <= e_);
+ constexpr size_type size() const {
+ // It would be nice to assert(b_ <= e_) here. This can be achieved even
+ // in a C++11 compatible constexpr function:
+ // http://ericniebler.com/2014/09/27/assert-and-constexpr-in-cxx11/
+ // Unfortunately current gcc versions have a bug causing it to reject
+ // this check in a constexpr function:
+ // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71448
return e_ - b_;
}
size_type walk_size() const {
- assert(b_ <= e_);
return std::distance(b_, e_);
}
bool empty() const { return b_ == e_; }
return !empty() && back() == c;
}
+ /**
+ * Remove the items in [b, e), as long as this subrange is at the beginning
+ * or end of the Range.
+ *
+ * Required for boost::algorithm::trim()
+ */
+ void erase(Iter b, Iter e) {
+ if (b == b_) {
+ b_ = e;
+ } else if (e == e_) {
+ e_ = b;
+ } else {
+ throw std::out_of_range("index out of range");
+ }
+ }
+
/**
* Remove the given prefix and return true if the range starts with the given
* prefix; return false otherwise.
return pos == nullptr ? std::string::npos : pos - haystack.data();
}
-#if FOLLY_HAVE_MEMRCHR
template <>
inline size_t rfind(const Range<const char*>& haystack, const char& needle) {
auto pos = static_cast<const char*>(
::memrchr(haystack.data(), needle, haystack.size()));
return pos == nullptr ? std::string::npos : pos - haystack.data();
}
-#endif
// specialization for ByteRange
template <>
return pos == nullptr ? std::string::npos : pos - haystack.data();
}
-#if FOLLY_HAVE_MEMRCHR
template <>
inline size_t rfind(const Range<const unsigned char*>& haystack,
const unsigned char& needle) {
::memrchr(haystack.data(), needle, haystack.size()));
return pos == nullptr ? std::string::npos : pos - haystack.data();
}
-#endif
template <class T>
size_t qfind_first_of(const Range<T>& haystack,
#pragma GCC diagnostic pop
FOLLY_ASSUME_FBVECTOR_COMPATIBLE_1(folly::Range);
-
-#endif // FOLLY_RANGE_H_