1 /*
2     Copyright (C) 2020 Julian Rüth
3 
4     This file is part of e-antic
5 
6     e-antic is free software: you can redistribute it and/or modify it under
7     the terms of the GNU Lesser General Public License (LGPL) as published
8     by the Free Software Foundation; either version 3.0 of the License, or
9     (at your option) any later version.  See <http://www.gnu.org/licenses/>.
10 */
11 
12 #ifndef E_ANTIC_TEST_RENF_ELEM_CLASS_GENERATOR_HPP
13 #define E_ANTIC_TEST_RENF_ELEM_CLASS_GENERATOR_HPP
14 
15 #include <memory>
16 
17 #include <boost/optional.hpp>
18 
19 #include "../e-antic/renfxx.h"
20 
21 #include "renf_elem_generator.hpp"
22 
23 #include "external/catch2/single_include/catch2/catch.hpp"
24 
25 namespace {
26 
27 struct RenfElemClassGenerator : public Catch::Generators::IGenerator<eantic::renf_elem_class>
28 {
29     flint_rand_t& state;
30     std::shared_ptr<const eantic::renf_class>& nf;
31     ulong minbits, maxbits;
32 
33     mutable boost::optional<eantic::renf_elem_class> current;
34 
RenfElemClassGenerator__anonfd1ef4980111::RenfElemClassGenerator35     RenfElemClassGenerator(flint_rand_t& state, std::shared_ptr<const eantic::renf_class>& nf, ulong minbits, ulong maxbits) : state(state), nf(nf), minbits(minbits), maxbits(maxbits) {
36       assert(maxbits > minbits);
37       current = nf->zero();
38     }
39 
next__anonfd1ef4980111::RenfElemClassGenerator40     bool next() override
41     {
42         if (current)
43             current = {};
44         return true;
45     }
46 
get__anonfd1ef4980111::RenfElemClassGenerator47     eantic::renf_elem_class& get() const override
48     {
49         if (!current)
50         {
51             ulong bits = minbits + n_randint(state, maxbits - minbits);
52 
53             current = eantic::renf_elem_class(nf);
54 
55             renf_elem_randtest(current->renf_elem_t(), state, bits, nf->renf_t());
56         }
57         return *current;
58     }
59 };
60 
61 /*
62  * Wrap RenfElemClassGenerator for use as GENERATE(renf_elem_classs(...))
63  */
renf_elem_classs(flint_rand_t & state,std::shared_ptr<const eantic::renf_class> & nf,ulong minbits=10,ulong maxbits=40)64 Catch::Generators::GeneratorWrapper<eantic::renf_elem_class> renf_elem_classs(flint_rand_t& state, std::shared_ptr<const eantic::renf_class>& nf, ulong minbits = 10, ulong maxbits = 40)
65 {
66     return Catch::Generators::GeneratorWrapper<eantic::renf_elem_class>(std::unique_ptr<Catch::Generators::IGenerator<eantic::renf_elem_class>>(new RenfElemClassGenerator(state, nf, minbits, maxbits)));
67 }
68 
69 }
70 
71 #endif
72