inline vec<u8, N> random_bits(random_bit_generator& gen) { constexpr size_t N2 = prev_poweroftwo(N - 1); const vec<u8, N2> bits1 = random_bits<N2>(gen); const vec<u8, N - N2> bits2 = random_bits<N - N2>(gen); return concat(bits1, bits2); }
void test_expression(const E& expr, size_t size, Fn&& fn, const char* expression = nullptr) { using T = value_type_of<E>; ::testo::test_case* test = ::testo::active_test(); auto&& c = ::testo::make_comparison(); test->check(c <= expr.size() == size, expression); if (expr.size() != size) return; size = size_min(size, 200); constexpr size_t maxsize = 2 + ilog2(vector_width<T> * 2); for (size_t i = 0; i < size;) { const size_t next_size = std::min(prev_poweroftwo(size - i), static_cast<size_t>(1) << (std::rand() % maxsize)); cswitch(csize<1> << csizeseq<maxsize>, next_size, [&](auto x) { constexpr size_t nsize = val_of(decltype(x)()); ::testo::scope s(as_string("i = ", i)); test->check(c <= get_elements(expr, cinput, i, vec_shape<T, nsize>()) == internal::get_fn_value<T, nsize>(i, fn), expression); }); i += next_size; } }