/* * Copyright (c) 2016 The WebM project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #ifndef TEST_RANDOMISE_H_ #define TEST_RANDOMISE_H_ #include #include #include "third_party/googletest/src/include/gtest/gtest.h" #include "test/acm_random.h" namespace libvpx_test { // TODO(any): Replace this when built with C++11 #define STATIC_ASSERT_INTEGER_TYPE_(T) \ GTEST_COMPILE_ASSERT_(std::numeric_limits::is_integer, \ integer_type_required); /** * Deterministic random number generator with various convenience methods. */ class Randomise { public: Randomise() { rnd_.Reset(ACMRandom::DeterministicSeed()); } virtual ~Randomise() { } // Uniformly distributed random number from the range // [std::numeric_limits::min(), and std::numeric_limits::max()] template R uniform() { STATIC_ASSERT_INTEGER_TYPE_(R); } // Uniformly distributed random number from the range // [0, hi) template R uniform(H hi) { assert(hi > 0); R v = uniform(); if (std::numeric_limits::is_signed && v < 0) return -v % hi; else return v % hi; } // Uniformly distributed random number from the range // [lo, hi) template R uniform(L lo, H hi) { assert(hi > lo); return uniform(hi - lo) + lo; } // Randomly pick and return one of the arguments template T choice(T v0, T v1) { switch (uniform(2)) { case 0: return v0; default: return v1; } } // Randomly pick and return one of the arguments template T choice(T v0, T v1, T v2) { switch (uniform(3)) { case 0: return v0; case 1: return v1; default: return v2; } } template void operator()(T &e) { // NOLINT STATIC_ASSERT_INTEGER_TYPE_(T); e = uniform(); } template void operator()(T &e, H hi) { // NOLINT STATIC_ASSERT_INTEGER_TYPE_(T); e = uniform(hi); } template void operator()(T &e, L lo, H hi) { // NOLINT STATIC_ASSERT_INTEGER_TYPE_(T); e = uniform(lo, hi); } template void operator()(T (&arr)[n]) { STATIC_ASSERT_INTEGER_TYPE_(T); for (size_t i = 0; i < n ; i++) { arr[i] = uniform(); } } template void operator()(T (&arr)[n], H hi) { STATIC_ASSERT_INTEGER_TYPE_(T); for (size_t i = 0; i < n ; i++) { arr[i] = uniform(hi); } } template void operator()(T (&arr)[n], L lo, H hi) { STATIC_ASSERT_INTEGER_TYPE_(T); for (size_t i = 0; i < n ; i++) { arr[i] = uniform(lo, hi); } } template void operator()(T (&arr)[n][m]) { STATIC_ASSERT_INTEGER_TYPE_(T); for (size_t i = 0; i < n ; i++) { for (size_t j = 0; j < m ; j++) { arr[i][j] = uniform(); } } } template void operator()(T (&arr)[n][m], H hi) { STATIC_ASSERT_INTEGER_TYPE_(T); for (size_t i = 0; i < n ; i++) { for (size_t j = 0; j < m ; j++) { arr[i][j] = uniform(hi); } } } template void operator()(T (&arr)[n][m], L lo, H hi) { STATIC_ASSERT_INTEGER_TYPE_(T); for (size_t i = 0; i < n ; i++) { for (size_t j = 0; j < m ; j++) { arr[i][j] = uniform(lo, hi); } } } private: libvpx_test::ACMRandom rnd_; }; // Add further specialisations as necessary template<> bool Randomise::uniform(); template<> uint8_t Randomise::uniform(); template<> uint16_t Randomise::uniform(); template<> uint32_t Randomise::uniform(); template<> uint64_t Randomise::uniform(); template<> int8_t Randomise::uniform(); template<> int16_t Randomise::uniform(); template<> int32_t Randomise::uniform(); template<> int64_t Randomise::uniform(); } // namespace libvpx_test #endif // TEST_RANDOMISE_H_