// Copyright (c) 2026 Progmasoft. // SPDX-License-Identifier: MPL-2.0 WITH AdditionRef-Progmasoft-Exception-2.0 #pragma once #include #include #include #include #include #include #include #include #include namespace Progmasoft::Catch3 { /// Picks uniformly from a fixed, non-empty list of values. /// /// The list order is the simplicity order: a value shrinks to the values /// listed before it, earliest first, so place the simplest case first. /// A value that is not in the list has no candidates. template, int> = 0> [[nodiscard]] Generator Element(std::vector values) { if (values.empty()) { Detail::RejectInvalidArgument( "Element requires at least one value"); } // Both callbacks share one immutable copy of the list. const auto shared = std::make_shared>(std::move(values)); return MakeGenerator( [shared](Random &random) { const std::size_t index = random.Between(std::size_t{ 0 }, shared->size() - 1); return static_cast((*shared)[index]); }, [shared](const ValueType &value) { const auto found = std::find(shared->begin(), shared->end(), value); if (found == shared->end()) { return std::vector{}; } return std::vector(shared->begin(), found); }); } /// Convenience overload for a literal list of values. template, int> = 0> [[nodiscard]] Generator Element(std::initializer_list values) { return Element(std::vector(values)); } } // namespace Progmasoft::Catch3