← comparison · rnda.h
1#pragma once23#include "array.h"4#include "common.h"5#include "gcc_primes_list.h"6#include "math_jngen.h"78#include <algorithm>9#include <cstdlib>1011namespace jngen {1213enum class UnorderedSetCompiler {14    Gcc4,15    Gcc5or6,16    Clang17};1819class ArrayRandom {20public:21    ArrayRandom() {22        static bool created = false;23        ENSURE(!created, "jngen::ArrayRandom should be created only once");24        created = true;25    }2627    template<typename F, typename ...Args>28    static auto randomf(29            size_t size,30            F func,31            Args... args) -> GenericArray<decltype(func(args...))>32    {33        typedef decltype(func(args...)) T;34        return GenericArray<T>::randomf(size, func, args...);35    }3637    template<typename F, typename ...Args>38    static auto randomfUnique(39            size_t size,40            F func,41            Args... args) -> GenericArray<decltype(func(args...))>42    {43        typedef decltype(func(args...)) T;44        return GenericArray<T>::randomfUnique(size, func, args...);45    }4647    template<typename F, typename ...Args>48    static auto randomfAll(49            F func,50            Args... args) -> GenericArray<decltype(func(args...))>51    {52        typedef decltype(func(args...)) T;53        return GenericArray<T>::randomfAll(func, args...);54    }5556    static Array64 antiUnorderedSet(57        int n,58        double maxLoadFactor = 1.0,59        bool reserve = false,60        UnorderedSetCompiler compiler = UnorderedSetCompiler::Gcc4);6162private:63    static Array64 numbersDividingPrime(int n, long long p);6465    static long long nextPrime(66        unsigned long long x,67        UnorderedSetCompiler compiler);68};6970JNGEN_EXTERN ArrayRandom rnda;7172#ifndef JNGEN_DECLARE_ONLY7374Array64 ArrayRandom::antiUnorderedSet(75    int n,76    double maxLoadFactor,77    bool reserve,78    UnorderedSetCompiler compiler)79{80    ensure(81        compiler == UnorderedSetCompiler::Gcc4,82        "unordered set antitest supported only for gcc-4.x yet");8384    ensure(85        n <= 1000000,86        "unordered set antitest supported only for n <= 1e7");8788    int buckets;8990    if (reserve) {91        buckets = nextPrime(std::ceil(n / maxLoadFactor), compiler);92    } else {93        buckets = 2;94        for (int size = 1; size <= n; ++size) {95            if (size + 1 > buckets * maxLoadFactor) {96                buckets = nextPrime(buckets * 2, compiler);97            }98        }99    }100101    return numbersDividingPrime(n, buckets);102}103104Array64 ArrayRandom::numbersDividingPrime(int n, long long p) {105    auto a = Array64::id(n);106    for (auto& x: a) {107        x *= p;108    }109    return a;110}111112long long ArrayRandom::nextPrime(113    unsigned long long x,114    UnorderedSetCompiler compiler)115{116    ENSURE(compiler == UnorderedSetCompiler::Gcc4);117118    const static size_t SIZE =119        sizeof(impl::primeList) / sizeof(impl::primeList[0]);120    return *std::lower_bound(impl::primeList, impl::primeList + SIZE, x);121}122123#endif // JNGEN_DECLARE_ONLY124125} // namespace jngen126127using jngen::rnda;128using jngen::UnorderedSetCompiler;