diff --git a/folly/Range.h b/folly/Range.h index e4d42a4dc6b..b4e76deeaef 100644 --- a/folly/Range.h +++ b/folly/Range.h @@ -22,14 +22,14 @@ #include "folly/Portability.h" #include "folly/FBString.h" -#include #include +#include #include +#include #include -#include #include +#include #include -#include // libc++ doesn't provide this header #if !FOLLY_USE_LIBCPP @@ -174,6 +174,7 @@ class Range : private boost::totally_ordered > { // Works only for Range /* implicit */ Range(const std::string& str) : b_(str.data()), e_(b_ + str.size()) {} + // Works only for Range Range(const std::string& str, std::string::size_type startFrom) { if (UNLIKELY(startFrom > str.size())) { @@ -650,10 +651,26 @@ void swap(Range& lhs, Range& rhs) { * Create a range from two iterators, with type deduction. */ template -Range makeRange(Iter first, Iter last) { +Range range(Iter first, Iter last) { return Range(first, last); } +/* + * Creates a range to reference the contents of a contiguous-storage container. + */ +// Use pointers for types with '.data()' member +template ().data())>::type> +Range range(Collection&& v) { + return Range(v.data(), v.data() + v.size()); +} + +template +Range range(T (&array)[n]) { + return Range(array, array + n); +} + typedef Range StringPiece; typedef Range MutableStringPiece; typedef Range ByteRange; diff --git a/folly/gen/test/BaseBenchmark.cpp b/folly/gen/test/BaseBenchmark.cpp index 26009743fce..a7b095af880 100644 --- a/folly/gen/test/BaseBenchmark.cpp +++ b/folly/gen/test/BaseBenchmark.cpp @@ -19,8 +19,8 @@ #include "folly/Benchmark.h" #include "folly/gen/Base.h" -using namespace folly; using namespace folly::gen; +using folly::fbstring; using std::pair; using std::set; using std::vector; @@ -339,6 +339,6 @@ BENCHMARK(Sample, iters) { int main(int argc, char *argv[]) { google::ParseCommandLineFlags(&argc, &argv, true); - runBenchmarks(); + folly::runBenchmarks(); return 0; } diff --git a/folly/gen/test/BaseTest.cpp b/folly/gen/test/BaseTest.cpp index 3a0b500ca93..6f58e732a49 100644 --- a/folly/gen/test/BaseTest.cpp +++ b/folly/gen/test/BaseTest.cpp @@ -189,13 +189,13 @@ TEST(Gen, Seq) { TEST(Gen, Range) { // cover the fenceposts of the loop unrolling for (int n = 1; n < 100; ++n) { - EXPECT_EQ(range(0, n) | count, n); + EXPECT_EQ(gen::range(0, n) | count, n); } } TEST(Gen, FromIterators) { vector source {2, 3, 5, 7, 11}; - auto gen = from(makeRange(source.begin() + 1, source.end() - 1)); + auto gen = from(folly::range(source.begin() + 1, source.end() - 1)); EXPECT_EQ(3 * 5 * 7, gen | product); } @@ -618,7 +618,7 @@ TEST(Gen, Any) { EXPECT_FALSE(seq(0, 10) | any([](int i) { return i == 11; })); EXPECT_TRUE(from({1}) | any); - EXPECT_FALSE(range(0, 0) | any); + EXPECT_FALSE(gen::range(0, 0) | any); EXPECT_FALSE(from({1}) | take(0) | any); } diff --git a/folly/json.cpp b/folly/json.cpp index 24ce2b298f9..5ca57d475b3 100644 --- a/folly/json.cpp +++ b/folly/json.cpp @@ -216,7 +216,7 @@ struct Printer { indent(); newline(); (*this)(a[0]); - for (auto& val : makeRange(boost::next(a.begin()), a.end())) { + for (auto& val : range(boost::next(a.begin()), a.end())) { out_ += ','; newline(); (*this)(val); @@ -509,7 +509,7 @@ dynamic parseNumber(Input& in) { auto expPart = in.skipDigits(); end = expPart.end(); } - auto fullNum = makeRange(integral.begin(), end); + auto fullNum = range(integral.begin(), end); auto val = to(fullNum); return val; diff --git a/folly/test/DynamicConverterTest.cpp b/folly/test/DynamicConverterTest.cpp index 59d9006c7d1..4a8648aa707 100644 --- a/folly/test/DynamicConverterTest.cpp +++ b/folly/test/DynamicConverterTest.cpp @@ -341,8 +341,8 @@ TEST(DynamicConverter, construct) { { vector vi { 2, 3, 4, 5 }; - auto c = std::make_pair(makeRange(vi.begin(), vi.begin() + 3), - makeRange(vi.begin() + 1, vi.begin() + 4)); + auto c = std::make_pair(range(vi.begin(), vi.begin() + 3), + range(vi.begin() + 1, vi.begin() + 4)); dynamic d = { { 2, 3, 4 }, { 3, 4, 5 } }; EXPECT_EQ(d, toDynamic(c)); } diff --git a/folly/test/RangeTest.cpp b/folly/test/RangeTest.cpp index faec886660d..e9a56b2c07c 100644 --- a/folly/test/RangeTest.cpp +++ b/folly/test/RangeTest.cpp @@ -19,13 +19,15 @@ #include "folly/Range.h" -#include +#include +#include #include -#include +#include #include +#include +#include #include -#include -#include +#include namespace folly { namespace detail { @@ -922,3 +924,37 @@ TEST(NonConstTest, StringPiece) { MutableByteRange r2(sp); } } + +template +void testRangeFunc(C&& x, size_t n) { + const auto& cx = x; + // type, conversion checks + Range r1 = range(std::forward(x)); + Range r2 = range(std::forward(x)); + Range r3 = range(cx); + Range r5 = range(std::move(cx)); + EXPECT_EQ(r1.begin(), &x[0]); + EXPECT_EQ(r1.end(), &x[n]); + EXPECT_EQ(n, r1.size()); + EXPECT_EQ(n, r2.size()); + EXPECT_EQ(n, r3.size()); + EXPECT_EQ(n, r5.size()); +} + +TEST(RangeFunc, Vector) { + std::vector x; + testRangeFunc(x, 0); + x.push_back(2); + testRangeFunc(x, 1); + testRangeFunc(std::vector{1, 2}, 2); +} + +TEST(RangeFunc, Array) { + std::array x; + testRangeFunc(x, 3); +} + +TEST(RangeFunc, CArray) { + int x[] {1, 2, 3, 4}; + testRangeFunc(x, 4); +}