From 621adb9cdb959d778c17a1d309cf37e4b84d868d Mon Sep 17 00:00:00 2001 From: Yedidya Feldblum Date: Sun, 6 Nov 2016 13:09:44 -0800 Subject: [PATCH] Let folly::range be constexpr Summary: [Folly] Let `folly::range` be `constexpr`. It will be useful to have this helper function be `constexpr` to support further compile-time code. Reviewed By: juchem Differential Revision: D4135943 fbshipit-source-id: a62be93f9e492ca302130d1a3b190ed4b69f7a80 --- folly/Range.h | 13 ++++++------ folly/test/RangeTest.cpp | 45 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 50 insertions(+), 8 deletions(-) diff --git a/folly/Range.h b/folly/Range.h index 97a7f1d0..06123d34 100644 --- a/folly/Range.h +++ b/folly/Range.h @@ -864,7 +864,7 @@ void swap(Range& lhs, Range& rhs) { * Create a range from two iterators, with type deduction. */ template -Range range(Iter first, Iter last) { +constexpr Range range(Iter first, Iter last) { return Range(first, last); } @@ -872,15 +872,16 @@ Range range(Iter first, Iter 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) { +template < + class Collection, + class T = typename std::remove_pointer< + decltype(std::declval().data())>::type> +constexpr Range range(Collection&& v) { return Range(v.data(), v.data() + v.size()); } template -Range range(T (&array)[n]) { +constexpr Range range(T (&array)[n]) { return Range(array, array + n); } diff --git a/folly/test/RangeTest.cpp b/folly/test/RangeTest.cpp index ef4c1e1e..dc7e4ff0 100644 --- a/folly/test/RangeTest.cpp +++ b/folly/test/RangeTest.cpp @@ -293,9 +293,9 @@ TEST(StringPiece, InvalidRange) { EXPECT_THROW(a.subpiece(6), std::out_of_range); } -constexpr const char* helloArray = "hello"; - TEST(StringPiece, Constexpr) { + constexpr const char* helloArray = "hello"; + constexpr StringPiece hello1("hello"); EXPECT_EQ("hello", hello1); static_assert(hello1.size() == 5, "hello size should be 5 at compile time"); @@ -1098,6 +1098,47 @@ TEST(RangeFunc, CArray) { testRangeFunc(x, 4); } +TEST(RangeFunc, ConstexprCArray) { + static constexpr const int numArray[4] = {3, 17, 1, 9}; + constexpr const auto numArrayRange = range(numArray); + EXPECT_EQ(17, numArrayRange[1]); + constexpr const auto numArrayRangeSize = numArrayRange.size(); + EXPECT_EQ(4, numArrayRangeSize); +} + +TEST(RangeFunc, ConstexprIteratorPair) { + static constexpr const int numArray[4] = {3, 17, 1, 9}; + constexpr const auto numPtr = static_cast(numArray); + constexpr const auto numIterRange = range(numPtr + 1, numPtr + 3); + EXPECT_EQ(1, numIterRange[1]); + constexpr const auto numIterRangeSize = numIterRange.size(); + EXPECT_EQ(2, numIterRangeSize); +} + +TEST(RangeFunc, ConstexprCollection) { + class IntCollection { + public: + constexpr IntCollection(const int* d, size_t s) : data_(d), size_(s) {} + constexpr const int* data() const { + return data_; + } + constexpr size_t size() const { + return size_; + } + + private: + const int* data_; + size_t size_; + }; + static constexpr const int numArray[4] = {3, 17, 1, 9}; + constexpr const auto numPtr = static_cast(numArray); + constexpr const auto numColl = IntCollection(numPtr + 1, 2); + constexpr const auto numCollRange = range(numColl); + EXPECT_EQ(1, numCollRange[1]); + constexpr const auto numCollRangeSize = numCollRange.size(); + EXPECT_EQ(2, numCollRangeSize); +} + std::string get_rand_str(size_t size, std::uniform_int_distribution<>& dist, std::mt19937& gen) { -- 2.34.1