int main() { // Test for constant generator functions { int i = 0, j = 1; auto fib = view::generate_n([&]()->int{int tmp = i; i += j; std::swap(i, j); return tmp;}, 10); CONCEPT_ASSERT(ranges::InputRange<decltype(fib)>()); check_equal(fib, {0,1,1,2,3,5,8,13,21,34}); auto const &cfib = fib; auto it = fib.begin(); auto cit = cfib.begin(); CONCEPT_ASSERT(ranges::Same<decltype(it), decltype(cit)>()); } // Test for mutable-only generator functions { int i = 0, j = 1; auto fib = view::generate_n([=]()mutable->int{int tmp = i; i += j; std::swap(i, j); return tmp;}, 10); CONCEPT_ASSERT(ranges::InputRange<decltype(fib)>()); check_equal(fib, {0,1,1,2,3,5,8,13,21,34}); // The generator cannot be called when it's const-qualified, so "fib const" // does not model Range. CONCEPT_ASSERT(!ranges::Range<decltype(fib) const>()); } return test_result(); }
int main() { CONCEPT_ASSERT(Trivial,int{}); CONCEPT_ASSERT(Trivial,bool{}); CONCEPT_ASSERT(Trivial,std::vector<int>{}); //... Here's where I miss reflection, imagine a loop over C++ types //without having to write a typelist by hand }
iterator_t<Rng> get_begin_(std::false_type, detail::any) { CONCEPT_ASSERT(!RandomAccessRange<Rng>()); using cache_t = detail::non_propagating_cache< iterator_t<Rng>, drop_view<Rng>>; auto &begin_ = static_cast<cache_t&>(*this); if(!begin_) begin_ = next(ranges::begin(rng_), n_, ranges::end(rng_)); return *begin_; }
iterator_t<Rng> get_begin_(std::true_type, std::false_type) { CONCEPT_ASSERT(RandomAccessRange<Rng>()); return next(ranges::begin(rng_), n_, ranges::end(rng_)); }
constexpr unbounded_view<I> operator()(I it) const { CONCEPT_ASSERT(InputIterator<I>()); return unbounded_view<I>{detail::move(it)}; }
void models_not(Types &&...) { CONCEPT_ASSERT(!ranges::concepts::models<Concept, Types...>()); }
counted_view<I> operator()(I it, iterator_difference_t<I> n) const { // Nothing wrong with a weak counted output iterator! CONCEPT_ASSERT(WeakIterator<I>()); return {std::move(it), n}; }
static counted_view<I> invoke(counted_fn, I it, iterator_difference_t<I> n) { // Nothing wrong with a weak counted output iterator! CONCEPT_ASSERT(WeakIterator<I>()); return {std::move(it), n}; }