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