| 3911 | |
| 3912 | template<typename T> |
| 3913 | class Generators : public IGenerator<T> { |
| 3914 | std::vector<GeneratorWrapper<T>> m_generators; |
| 3915 | size_t m_current = 0; |
| 3916 | |
| 3917 | void populate(GeneratorWrapper<T>&& generator) { |
| 3918 | m_generators.emplace_back(std::move(generator)); |
| 3919 | } |
| 3920 | void populate(T&& val) { |
| 3921 | m_generators.emplace_back(value(std::move(val))); |
| 3922 | } |
| 3923 | template<typename U> |
| 3924 | void populate(U&& val) { |
| 3925 | populate(T(std::move(val))); |
| 3926 | } |
| 3927 | template<typename U, typename... Gs> |
| 3928 | void populate(U&& valueOrGenerator, Gs... moreGenerators) { |
| 3929 | populate(std::forward<U>(valueOrGenerator)); |
| 3930 | populate(std::forward<Gs>(moreGenerators)...); |
| 3931 | } |
| 3932 | |
| 3933 | public: |
| 3934 | template <typename... Gs> |
| 3935 | Generators(Gs... moreGenerators) { |
| 3936 | m_generators.reserve(sizeof...(Gs)); |
| 3937 | populate(std::forward<Gs>(moreGenerators)...); |
| 3938 | } |
| 3939 | |
| 3940 | T const& get() const override { |
| 3941 | return m_generators[m_current].get(); |
| 3942 | } |
| 3943 | |
| 3944 | bool next() override { |
| 3945 | if (m_current >= m_generators.size()) { |
| 3946 | return false; |
| 3947 | } |
| 3948 | const bool current_status = m_generators[m_current].next(); |
| 3949 | if (!current_status) { |
| 3950 | ++m_current; |
| 3951 | } |
| 3952 | return m_current < m_generators.size(); |
| 3953 | } |
| 3954 | }; |
| 3955 | |
| 3956 | template<typename... Ts> |
| 3957 | GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) { |