Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cycle_generator.h
Go to the documentation of this file.
1// Copyright (C) 2022 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#pragma once
5
6#include "../../namespaces.h"
7#include "../../utilities/semantics/generator_handler.h"
8
9#include <catch/catch.hpp>
10
11#include <vector>
12
15
16 template<typename T>
18 public:
19 CycleGenerator(Catch::Generators::GeneratorWrapper<T>&& generator)
20 : generator{std::move(generator)},
21 cache{},
22 cache_index{0}
23 {
24 // REMARK: We generally handle extracting the first
25 // value by using an handler, to avoid code
26 // duplication and the possibility of an error.
27 // In this specific case, we turn to a more "manual"
28 // approach as it better models the cache-based
29 // implementation, removing the need to not increment
30 // cache_index the first time that next is called.
31 cache.emplace_back(this->generator.get());
32 }
33
34 T const& get() const override { return cache[cache_index]; }
35
36 bool next() override {
37 if (generator.next()) {
38 cache.emplace_back(generator.get());
39 ++cache_index;
40 } else {
41 cache_index = (cache_index + 1) % cache.size();
42 }
43
44 return true;
45 }
46
47 private:
48 Catch::Generators::GeneratorWrapper<T> generator;
49
50 std::vector<T> cache;
51 std::size_t cache_index;
52 };
53
54 } // end QDOC_CATCH_GENERATORS_PRIVATE_NAMESPACE
55
56 /*!
57 * Returns a generator that behaves like \a generator until \a
58 * generator is exhausted, repeating the same generation that \a
59 * generator produced, infinitely, afterwards.
60 *
61 * This is generally intended to produce infinite generators from
62 * finite ones.
63 *
64 * For example, consider a generator that produces values based on
65 * another generator that it owns.
66 * If the owning generator needs to produce more values that the
67 * owned generator can support, it might fail at some point.
68 * By cycling over the owned generator, we can extend the sequence
69 * of produced values so that enough are generated, in a controlled
70 * way.
71 *
72 * The type T should generally be copyable for this generator to
73 * work.
74 */
75 template<typename T>
76 inline Catch::Generators::GeneratorWrapper<T> cycle(Catch::Generators::GeneratorWrapper<T>&& generator) {
77 return Catch::Generators::GeneratorWrapper<T>(std::unique_ptr<Catch::Generators::IGenerator<T>>(new QDOC_CATCH_GENERATORS_PRIVATE_NAMESPACE::CycleGenerator(std::move(generator))));
78 }
79
80} // end QDOC_CATCH_GENERATORS_ROOT_NAMESPACE
Catch::Generators::GeneratorWrapper< T > cycle(Catch::Generators::GeneratorWrapper< T > &&generator)
Returns a generator that behaves like generator until generator is exhausted, repeating the same gene...
#define QDOC_CATCH_GENERATORS_PRIVATE_NAMESPACE
Definition namespaces.h:8
#define QDOC_CATCH_GENERATORS_ROOT_NAMESPACE
Definition namespaces.h:6