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;