From 5f92025ef5c641f44347a207d800023094ee56b5 Mon Sep 17 00:00:00 2001 From: Nick Terrell Date: Wed, 3 Aug 2016 17:53:52 -0700 Subject: [PATCH] Fix Enumerate C++17 Support Summary: `RangeEnumerator`s `begin()` and `end()` could return different values, but `Enumerator`s `operator ==` didn't support comparision with different types. Reviewed By: yfeldblum Differential Revision: D3662576 fbshipit-source-id: cfd10fffd220c70191ce0ac2ed78edd35daf5538 --- folly/Enumerate.h | 9 +++++++-- folly/test/EnumerateTest.cpp | 39 ++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/folly/Enumerate.h b/folly/Enumerate.h index 5733bfb6..f4fb12be 100644 --- a/folly/Enumerate.h +++ b/folly/Enumerate.h @@ -108,15 +108,20 @@ class Enumerator { return *this; } - bool operator==(const Enumerator& rhs) { + template + bool operator==(const Enumerator& rhs) { return it_ == rhs.it_; } - bool operator!=(const Enumerator& rhs) { + template + bool operator!=(const Enumerator& rhs) { return !(*this == rhs); } private: + template + friend class Enumerator; + Iterator it_; size_t idx_ = 0; }; diff --git a/folly/test/EnumerateTest.cpp b/folly/test/EnumerateTest.cpp index 5466ddcd..47ae5cd9 100644 --- a/folly/test/EnumerateTest.cpp +++ b/folly/test/EnumerateTest.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ +#include #include #include @@ -129,3 +130,41 @@ TEST(Enumerate, EmptyRange) { EXPECT_TRUE(false); } } + +class CStringRange { + const char* cstr; + + public: + struct Sentinel {}; + + explicit CStringRange(const char* cstr) : cstr(cstr) {} + + const char* begin() const { + return cstr; + } + Sentinel end() const { + return Sentinel{}; + } +}; + +bool operator==(const char* c, CStringRange::Sentinel) { + return *c == 0; +} + +TEST(Enumerate, Cpp17Support) { + std::array test = {"test"}; + // Can't use range based for loop until C++17, so test manually + // Equivalent to: + // for (const auto it : folly::enumerate(CStringRange{test.data()})) { ... } + { + auto&& enumerate = folly::enumerate(CStringRange{test.data()}); + auto begin = enumerate.begin(); + auto end = enumerate.end(); + for (; begin != end; ++begin) { + const auto it = *begin; + + ASSERT_LT(it.index, test.size()); + EXPECT_EQ(*it, test[it.index]); + } + } +} -- 2.34.1