| 4008 | |
| 4009 | template<typename T> |
| 4010 | class Generators : public IGenerator<T> { |
| 4011 | std::vector<GeneratorWrapper<T>> m_generators; |
| 4012 | size_t m_current = 0; |
| 4013 | |
| 4014 | void populate(GeneratorWrapper<T>&& generator) { |
| 4015 | m_generators.emplace_back(std::move(generator)); |
| 4016 | } |
| 4017 | void populate(T&& val) { |
| 4018 | m_generators.emplace_back(value(std::forward<T>(val))); |
| 4019 | } |
| 4020 | template<typename U> |
| 4021 | void populate(U&& val) { |
| 4022 | populate(T(std::forward<U>(val))); |
| 4023 | } |
| 4024 | template<typename U, typename... Gs> |
| 4025 | void populate(U&& valueOrGenerator, Gs &&... moreGenerators) { |
| 4026 | populate(std::forward<U>(valueOrGenerator)); |
| 4027 | populate(std::forward<Gs>(moreGenerators)...); |
| 4028 | } |
| 4029 | |
| 4030 | public: |
| 4031 | template <typename... Gs> |
| 4032 | Generators(Gs &&... moreGenerators) { |
| 4033 | m_generators.reserve(sizeof...(Gs)); |
| 4034 | populate(std::forward<Gs>(moreGenerators)...); |
| 4035 | } |
| 4036 | |
| 4037 | T const& get() const override { |
| 4038 | return m_generators[m_current].get(); |
| 4039 | } |
| 4040 | |
| 4041 | bool next() override { |
| 4042 | if (m_current >= m_generators.size()) { |
| 4043 | return false; |
| 4044 | } |
| 4045 | const bool current_status = m_generators[m_current].next(); |
| 4046 | if (!current_status) { |
| 4047 | ++m_current; |
| 4048 | } |
| 4049 | return m_current < m_generators.size(); |
| 4050 | } |
| 4051 | }; |
| 4052 | |
| 4053 | template<typename... Ts> |
| 4054 | GeneratorWrapper<std::tuple<Ts...>> table( std::initializer_list<std::tuple<typename std::decay<Ts>::type...>> tuples ) { |