diff --git a/llvm/include/llvm/ADT/Sequence.h b/llvm/include/llvm/ADT/Sequence.h --- a/llvm/include/llvm/ADT/Sequence.h +++ b/llvm/include/llvm/ADT/Sequence.h @@ -15,71 +15,69 @@ #ifndef LLVM_ADT_SEQUENCE_H #define LLVM_ADT_SEQUENCE_H -#include "llvm/ADT/iterator.h" -#include "llvm/ADT/iterator_range.h" -#include #include -#include namespace llvm { namespace detail { -template -class value_sequence_iterator - : public iterator_facade_base, - std::random_access_iterator_tag, - const ValueT> { - using BaseT = typename value_sequence_iterator::iterator_facade_base; - - ValueT Value; - -public: - using difference_type = typename BaseT::difference_type; - using reference = typename BaseT::reference; - - value_sequence_iterator() = default; - value_sequence_iterator(const value_sequence_iterator &) = default; - value_sequence_iterator(value_sequence_iterator &&Arg) - : Value(std::move(Arg.Value)) {} - value_sequence_iterator &operator=(const value_sequence_iterator &Arg) { - Value = Arg.Value; - return *this; - } +template +struct value_sequence_iterator + : public std::iterator { + value_sequence_iterator(const T Value) : Value(Value) {} - template ()))> - value_sequence_iterator(U &&Value) : Value(std::forward(Value)) {} + T operator*() const { return Value; } - value_sequence_iterator &operator+=(difference_type N) { - Value += N; - return *this; - } - value_sequence_iterator &operator-=(difference_type N) { - Value -= N; - return *this; - } - using BaseT::operator-; - difference_type operator-(const value_sequence_iterator &RHS) const { - return Value - RHS.Value; + bool operator!=(const value_sequence_iterator &RHS) const { + return Value != RHS.Value; } - bool operator==(const value_sequence_iterator &RHS) const { - return Value == RHS.Value; - } - bool operator<(const value_sequence_iterator &RHS) const { - return Value < RHS.Value; + value_sequence_iterator &operator++() { + if (IsForward) + ++Value; + else + --Value; + return *this; } - reference operator*() const { return Value; } +private: + T Value; }; -} // end namespace detail +} // namespace detail + +template struct value_sequence { + static_assert(std::is_same>::value, + "T must not be const nor volatile"); + using value_type = const T; + using reference = T &; + using const_reference = const T &; + using pointer = T *; + using const_pointer = const T *; + using difference_type = std::ptrdiff_t; + using size_type = std::size_t; + using iterator = detail::value_sequence_iterator; + using const_iterator = detail::value_sequence_iterator; + using reverse_iterator = detail::value_sequence_iterator; + using const_reverse_iterator = detail::value_sequence_iterator; + + value_type Begin; + value_type End; + + value_sequence(T Begin, T End) : Begin(Begin), End(End) {} + + size_t size() const { return End - Begin; } + bool empty() const { return Begin == End; } + + auto begin() const { return const_iterator(Begin); } + auto end() const { return const_iterator(End); } + + auto rbegin() const { return const_reverse_iterator(End - 1); } + auto rend() const { return const_reverse_iterator(Begin - 1); } +}; -template -iterator_range> seq(ValueT Begin, - ValueT End) { - return make_range(detail::value_sequence_iterator(Begin), - detail::value_sequence_iterator(End)); +template auto seq(ValueT Begin, ValueT End) { + return value_sequence(Begin, End); } } // end namespace llvm diff --git a/llvm/unittests/ADT/SequenceTest.cpp b/llvm/unittests/ADT/SequenceTest.cpp --- a/llvm/unittests/ADT/SequenceTest.cpp +++ b/llvm/unittests/ADT/SequenceTest.cpp @@ -15,26 +15,22 @@ namespace { -TEST(SequenceTest, Basic) { +TEST(SequenceTest, Forward) { int x = 0; for (int i : seq(0, 10)) { EXPECT_EQ(x, i); - x++; + ++x; } EXPECT_EQ(10, x); +} - auto my_seq = seq(0, 4); - EXPECT_EQ(4, my_seq.end() - my_seq.begin()); - for (int i : {0, 1, 2, 3}) - EXPECT_EQ(i, (int)my_seq.begin()[i]); - - EXPECT_TRUE(my_seq.begin() < my_seq.end()); - - auto adjusted_begin = my_seq.begin() + 2; - auto adjusted_end = my_seq.end() - 2; - EXPECT_TRUE(adjusted_begin == adjusted_end); - EXPECT_EQ(2, *adjusted_begin); - EXPECT_EQ(2, *adjusted_end); +TEST(SequenceTest, Backward) { + int x = 9; + for (int i : reverse(seq(0, 10))) { + EXPECT_EQ(x, i); + --x; + } + EXPECT_EQ(-1, x); } } // anonymous namespace