Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/src/catch2/generators
diff options
context:
space:
mode:
authorMartin Hořeňovský2026-02-09 19:05:39 +0100
committerMartin Hořeňovský2026-02-10 09:37:15 +0100
commitd079ee13ab137547ab26bd1ed5ca2858d7fbd847 (patch)
tree1e73da54d02eecbf095dd07bd4c0183d7a7f107b /src/catch2/generators
parent0056cd4efb01ab65f02af188e137fc65d79e18f8 (diff)
downloadcatch3-d079ee13ab137547ab26bd1ed5ca2858d7fbd847.tar.gz
Allow generators to declare themselves (infinite)
This will be useful later to implement warning on infinitely running `GENERATE` expressions.
Diffstat (limited to 'src/catch2/generators')
-rw-r--r--src/catch2/generators/catch_generators.hpp14
-rw-r--r--src/catch2/generators/catch_generators_adapters.hpp20
-rw-r--r--src/catch2/generators/catch_generators_random.cpp5
-rw-r--r--src/catch2/generators/catch_generators_random.hpp3
-rw-r--r--src/catch2/generators/catch_generators_range.hpp4
5 files changed, 46 insertions, 0 deletions
diff --git a/src/catch2/generators/catch_generators.hpp b/src/catch2/generators/catch_generators.hpp
index e64f9b5f..719775fb 100644
--- a/src/catch2/generators/catch_generators.hpp
+++ b/src/catch2/generators/catch_generators.hpp
@@ -64,6 +64,8 @@ namespace Detail {
bool next() {
return m_generator->countedNext();
}
+
+ bool isFinite() const { return m_generator->isFinite(); }
};
@@ -84,6 +86,8 @@ namespace Detail {
bool next() override {
return false;
}
+
+ bool isFinite() const override { return true; }
};
template<typename T>
@@ -112,6 +116,8 @@ namespace Detail {
++m_idx;
return m_idx < m_values.size();
}
+
+ bool isFinite() const override { return true; }
};
template <typename T, typename DecayedT = std::decay_t<T>>
@@ -176,6 +182,14 @@ namespace Detail {
}
return m_current < m_generators.size();
}
+
+ bool isFinite() const override {
+ for (auto const& gen : m_generators) {
+ if (!gen.isFinite()) { return false;
+ }
+ }
+ return true;
+ }
};
diff --git a/src/catch2/generators/catch_generators_adapters.hpp b/src/catch2/generators/catch_generators_adapters.hpp
index 35c103ce..2f6d8ed3 100644
--- a/src/catch2/generators/catch_generators_adapters.hpp
+++ b/src/catch2/generators/catch_generators_adapters.hpp
@@ -62,6 +62,8 @@ namespace Generators {
}
return success;
}
+
+ bool isFinite() const override { return true; }
};
template <typename T>
@@ -103,6 +105,8 @@ namespace Generators {
while (!m_predicate(m_generator.get()) && (success = m_generator.next()) == true);
return success;
}
+
+ bool isFinite() const override { return m_generator.isFinite(); }
};
@@ -127,6 +131,9 @@ namespace Generators {
m_target_repeats(repeats)
{
assert(m_target_repeats > 0 && "Repeat generator must repeat at least once");
+ if (!m_generator.isFinite()) {
+ Detail::throw_generator_exception( "Cannot repeat infinite generator" );
+ }
}
T const& get() const override {
@@ -160,6 +167,8 @@ namespace Generators {
}
return m_current_repeat < m_target_repeats;
}
+
+ bool isFinite() const override { return m_generator.isFinite(); }
};
template <typename T>
@@ -207,6 +216,8 @@ namespace Generators {
}
return success;
}
+
+ bool isFinite() const override { return m_generator.isFinite(); }
};
template <typename Func, typename U, typename T = FunctionReturnType<Func, U>>
@@ -256,6 +267,8 @@ namespace Generators {
}
return true;
}
+
+ bool isFinite() const override { return m_generator.isFinite(); }
};
template <typename T>
@@ -297,6 +310,13 @@ namespace Generators {
++m_current_generator;
return m_current_generator < m_generators.size();
}
+
+ bool isFinite() const override {
+ for ( auto const& gen : m_generators ) {
+ if ( !gen.isFinite() ) { return false; }
+ }
+ return true;
+ }
};
template <typename T, typename... Generators>
diff --git a/src/catch2/generators/catch_generators_random.cpp b/src/catch2/generators/catch_generators_random.cpp
index 00a8e634..d5163c16 100644
--- a/src/catch2/generators/catch_generators_random.cpp
+++ b/src/catch2/generators/catch_generators_random.cpp
@@ -37,5 +37,10 @@ namespace Catch {
m_current_number = m_pimpl->dist( m_pimpl->rng );
return true;
}
+
+ bool RandomFloatingGenerator<long double>::isFinite() const {
+ return false;
+ }
+
} // namespace Generators
} // namespace Catch
diff --git a/src/catch2/generators/catch_generators_random.hpp b/src/catch2/generators/catch_generators_random.hpp
index 71283561..e0287360 100644
--- a/src/catch2/generators/catch_generators_random.hpp
+++ b/src/catch2/generators/catch_generators_random.hpp
@@ -42,6 +42,7 @@ public:
m_current_number = m_dist(m_rng);
return true;
}
+ bool isFinite() const override { return false; }
};
template <>
@@ -59,6 +60,7 @@ public:
bool next() override;
~RandomFloatingGenerator() override; // = default
+ bool isFinite() const override;
};
template <typename Integer>
@@ -80,6 +82,7 @@ public:
m_current_number = m_dist(m_rng);
return true;
}
+ bool isFinite() const override { return false; }
};
template <typename T>
diff --git a/src/catch2/generators/catch_generators_range.hpp b/src/catch2/generators/catch_generators_range.hpp
index 55d673c2..62739b23 100644
--- a/src/catch2/generators/catch_generators_range.hpp
+++ b/src/catch2/generators/catch_generators_range.hpp
@@ -48,6 +48,8 @@ public:
m_current += m_step;
return (m_positive) ? (m_current < m_end) : (m_current > m_end);
}
+
+ bool isFinite() const override { return true; }
};
template <typename T>
@@ -87,6 +89,8 @@ public:
++m_current;
return m_current != m_elems.size();
}
+
+ bool isFinite() const override { return true; }
};
template <typename InputIterator,