forked from catchorg/Catch2
		
	In the future, we will also want to introduce our own `uniform_int_distribution` and `uniform_real_distribution` to get repeatable test runs across different platforms.
		
			
				
	
	
		
			74 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			74 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/*
 | 
						|
 *  Created by Martin on 30/08/2017.
 | 
						|
 *
 | 
						|
 *  Distributed under the Boost Software License, Version 1.0. (See accompanying
 | 
						|
 *  file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 | 
						|
 */
 | 
						|
 | 
						|
#include "catch_random_number_generator.h"
 | 
						|
#include "catch_context.h"
 | 
						|
#include "catch_run_context.h"
 | 
						|
#include "catch_interfaces_config.h"
 | 
						|
 | 
						|
namespace Catch {
 | 
						|
 | 
						|
namespace {
 | 
						|
 | 
						|
#if defined(_MSC_VER)
 | 
						|
#pragma warning(push)
 | 
						|
#pragma warning(disable:4146) // we negate uint32 during the rotate
 | 
						|
#endif
 | 
						|
        // Safe rotr implementation thanks to John Regehr
 | 
						|
        uint32_t rotate_right(uint32_t val, uint32_t count) {
 | 
						|
            const uint32_t mask = 31;
 | 
						|
            count &= mask;
 | 
						|
            return (val >> count) | (val << (-count & mask));
 | 
						|
        }
 | 
						|
 | 
						|
#if defined(_MSC_VER)
 | 
						|
#pragma warning(pop)
 | 
						|
#endif
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
    SimplePcg32::SimplePcg32(result_type seed_) {
 | 
						|
        seed(seed_);
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    void SimplePcg32::seed(result_type seed_) {
 | 
						|
        m_state = 0;
 | 
						|
        (*this)();
 | 
						|
        m_state += seed_;
 | 
						|
        (*this)();
 | 
						|
    }
 | 
						|
 | 
						|
    void SimplePcg32::discard(uint64_t skip) {
 | 
						|
        // We could implement this to run in O(log n) steps, but this
 | 
						|
        // should suffice for our use case.
 | 
						|
        for (uint64_t s = 0; s < skip; ++s) {
 | 
						|
            static_cast<void>((*this)());
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    SimplePcg32::result_type SimplePcg32::operator()() {
 | 
						|
        // prepare the output value
 | 
						|
        const uint32_t xorshifted = static_cast<uint32_t>(((m_state >> 18u) ^ m_state) >> 27u);
 | 
						|
        const auto output = rotate_right(xorshifted, m_state >> 59u);
 | 
						|
 | 
						|
        // advance state
 | 
						|
        m_state = m_state * 6364136223846793005ULL + s_inc;
 | 
						|
 | 
						|
        return output;
 | 
						|
    }
 | 
						|
 | 
						|
    bool operator==(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
 | 
						|
        return lhs.m_state == rhs.m_state;
 | 
						|
    }
 | 
						|
 | 
						|
    bool operator!=(SimplePcg32 const& lhs, SimplePcg32 const& rhs) {
 | 
						|
        return lhs.m_state != rhs.m_state;
 | 
						|
    }
 | 
						|
}
 |