From: Tudor Bosman Date: Thu, 20 Feb 2014 21:20:00 +0000 (-0800) Subject: Better support for folly::Range with non-const iterators underneath X-Git-Tag: v0.22.0~689 X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=commitdiff_plain;h=c18d575d269443232bdfd116349d9fc450e17b9c Better support for folly::Range with non-const iterators underneath Summary: Implicitly construct Range from Range if From is implicitly convertible to To. Explicitly construct Range from Range if To is (explicitly) constructible from From. Add special-cases for Range, Range similar to the ones for Range, Range. Test Plan: test added Reviewed By: philipp@fb.com FB internal diff: D1182999 --- diff --git a/folly/Range.h b/folly/Range.h index f692b75a..e4d42a4d 100644 --- a/folly/Range.h +++ b/folly/Range.h @@ -240,20 +240,59 @@ public: // direction. template ::value && - std::is_same::value), int>::type = 0> + (std::is_same::value || + std::is_same::value)), int>::type = 0> /* implicit */ Range(const Range& other) : b_(reinterpret_cast(other.begin())), e_(reinterpret_cast(other.end())) { } + template ::value && + std::is_same::value), int>::type = 0> + /* implicit */ Range(const Range& other) + : b_(reinterpret_cast(other.begin())), + e_(reinterpret_cast(other.end())) { + } + template ::value && - std::is_same::value), int>::type = 0> + (std::is_same::value || + std::is_same::value)), int>::type = 0> explicit Range(const Range& other) : b_(reinterpret_cast(other.begin())), e_(reinterpret_cast(other.end())) { } + template ::value && + std::is_same::value), int>::type = 0> + explicit Range(const Range& other) + : b_(reinterpret_cast(other.begin())), + e_(reinterpret_cast(other.end())) { + } + + // Allow implicit conversion from Range to Range if From is + // implicitly convertible to To. + template ::value && + std::is_convertible::value), int>::type = 0> + /* implicit */ Range(const Range& other) + : b_(other.begin()), + e_(other.end()) { + } + + // Allow explicit conversion from Range to Range if From is + // explicitly convertible to To. + template ::value && + !std::is_convertible::value && + std::is_constructible::value), int>::type = 0> + explicit Range(const Range& other) + : b_(other.begin()), + e_(other.end()) { + } + void clear() { b_ = Iter(); e_ = Iter(); @@ -616,7 +655,9 @@ Range makeRange(Iter first, Iter last) { } typedef Range StringPiece; +typedef Range MutableStringPiece; typedef Range ByteRange; +typedef Range MutableByteRange; std::ostream& operator<<(std::ostream& os, const StringPiece& piece); diff --git a/folly/test/RangeTest.cpp b/folly/test/RangeTest.cpp index ee6a0e1b..faec8866 100644 --- a/folly/test/RangeTest.cpp +++ b/folly/test/RangeTest.cpp @@ -908,3 +908,17 @@ TYPED_TEST(NeedleFinderTest, NoSegFault) { } } +TEST(NonConstTest, StringPiece) { + std::string hello("hello"); + MutableStringPiece sp(&hello.front(), hello.size()); + sp[0] = 'x'; + EXPECT_EQ("xello", hello); + { + StringPiece s(sp); + EXPECT_EQ("xello", s); + } + { + ByteRange r1(sp); + MutableByteRange r2(sp); + } +}