Commit f53901c9 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook Github Bot

Allow StringPiece construction from string with custom allocator

Summary: [Folly] Allow `StringPiece` construction from `string` with custom allocator.

Reviewed By: nbronson

Differential Revision: D9494207

fbshipit-source-id: 22b6beb7e5718f69aa283431ad49dd36295e0825
parent f2654daf
......@@ -59,8 +59,9 @@ namespace folly {
template <class T>
struct IsSomeString : std::false_type {};
template <>
struct IsSomeString<std::string> : std::true_type {};
template <typename Alloc>
struct IsSomeString<std::basic_string<char, std::char_traits<char>, Alloc>>
: std::true_type {};
template <class Iter>
class Range;
......@@ -170,6 +171,10 @@ struct IsCharPointer<const char*> {
*/
template <class Iter>
class Range {
private:
template <typename Alloc>
using string = std::basic_string<char, std::char_traits<char>, Alloc>;
public:
typedef std::size_t size_type;
typedef Iter iterator;
......@@ -220,12 +225,18 @@ class Range {
"This constructor is only available for character ranges");
}
template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
/* implicit */ Range(const std::string& str)
template <
class Alloc,
class T = Iter,
typename detail::IsCharPointer<T>::const_type = 0>
/* implicit */ Range(const string<Alloc>& str)
: b_(str.data()), e_(b_ + str.size()) {}
template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
Range(const std::string& str, std::string::size_type startFrom) {
template <
class Alloc,
class T = Iter,
typename detail::IsCharPointer<T>::const_type = 0>
Range(const string<Alloc>& str, typename string<Alloc>::size_type startFrom) {
if (UNLIKELY(startFrom > str.size())) {
throw_exception<std::out_of_range>("index out of range");
}
......@@ -233,11 +244,14 @@ class Range {
e_ = str.data() + str.size();
}
template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
template <
class Alloc,
class T = Iter,
typename detail::IsCharPointer<T>::const_type = 0>
Range(
const std::string& str,
std::string::size_type startFrom,
std::string::size_type size) {
const string<Alloc>& str,
typename string<Alloc>::size_type startFrom,
typename string<Alloc>::size_type size) {
if (UNLIKELY(startFrom > str.size())) {
throw_exception<std::out_of_range>("index out of range");
}
......@@ -405,8 +419,11 @@ class Range {
Range& operator=(const Range& rhs) & = default;
Range& operator=(Range&& rhs) & = default;
template <class T = Iter, typename detail::IsCharPointer<T>::const_type = 0>
Range& operator=(std::string&& rhs) = delete;
template <
class Alloc,
class T = Iter,
typename detail::IsCharPointer<T>::const_type = 0>
Range& operator=(string<Alloc>&& rhs) = delete;
void clear() {
b_ = Iter();
......@@ -424,7 +441,8 @@ class Range {
}
// Works only for Range<const char*>
void reset(const std::string& str) {
template <typename Alloc>
void reset(const string<Alloc>& str) {
reset(str.data(), str.size());
}
......
......@@ -223,6 +223,19 @@ TEST(StringPiece, All) {
EXPECT_EQ(s2, s);
}
TEST(StringPiece, CustomAllocator) {
using Alloc = AlignedSysAllocator<char>;
Alloc const alloc{32};
char const* const text = "foo bar baz";
std::basic_string<char, std::char_traits<char>, Alloc> str{text, alloc};
EXPECT_EQ("foo", StringPiece(str).subpiece(0, 3));
EXPECT_EQ("bar", StringPiece(str, 4).subpiece(0, 3));
EXPECT_EQ("baz", StringPiece(str, 8, 3));
StringPiece piece;
piece.reset(str);
EXPECT_EQ("foo", piece.subpiece(0, 3));
}
template <class T>
void expectLT(const T& a, const T& b) {
EXPECT_TRUE(a < b);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment