// // common_test.cxx // stream-test // // Created by Sam Jaffe on 4/2/23. // #include "stream/view/common.h" #include #include #include "stream_test.h" using testing::StaticAssertTypeEq; struct SizedIterator : iterator::facade { private: // Default constructed SizedIterator should not be a vaguely valid state. size_t i_{~0ul}; size_t n_{~0ul}; public: SizedIterator() = default; SizedIterator(size_t i, size_t n) : i_(i), n_(n) {} size_t dereference() const { return i_; } void advance(std::ptrdiff_t off) { i_ += off; } // Bad detection requires us to provide this... // TODO: See if I can use one of these tests to why... bool equal_to(SizedIterator const & other) const { return other.i_ == i_; } std::ptrdiff_t distance_to(SizedIterator const & other) const { return other.i_ - i_; } bool at_end() const { return i_ >= n_; } }; MAKE_ITERATOR_FACADE_TYPEDEFS(SizedIterator); struct SentinelRange { private: size_t size_; public: SentinelRange(size_t size = 0) : size_(size) {} SizedIterator begin() const { return {0, size_}; } auto end() const { return iterator::sentinel; } bool empty() const { return size_ == 0; } size_t size() const { return size_; } }; TEST(CommonView, CoercesSentinelIntoCommon) { SentinelRange input(10); auto range = input | views::common(); StaticAssertTypeEq(); } TEST(CommonView, IteratesThroughSameValues) { SentinelRange input(10); auto range = input | views::common(); EXPECT_THAT(range, RangesEq(input)); } TEST(CommonView, PropagatesSize) { SentinelRange input(10); auto range = input | views::common(); static_assert(stream::detail::has_size_v); EXPECT_THAT(range.size(), input.size()); } TEST(CommonView, PropagatesEmpty) { SentinelRange input(10); auto range = input | views::common(); static_assert(stream::detail::has_empty_v); EXPECT_THAT(range.empty(), input.empty()); } TEST(CommonView, PassesNonSentinelTypes) { std::vector input(10); auto range = input | views::common(); StaticAssertTypeEq(); }