IAP GITLAB

Skip to content
Snippets Groups Projects
Commit 88e7f28d authored by Antonio Augusto Alves Junior's avatar Antonio Augusto Alves Junior
Browse files

solving issue #1

parent de0934e7
No related branches found
No related tags found
No related merge requests found
/*----------------------------------------------------------------------------
*
* Copyright (C) 2021 Antonio Augusto Alves Junior
*
* This file is part of RandomIterator.
*
* RandomIterator is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RandomIterator is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RandomIterator. If not, see <http://www.gnu.org/licenses/>.
*
*---------------------------------------------------------------------------*/
/*
* Engine.hpp
*
* Created on: 22 de fev. de 2021
* Author: Antonio Augusto Alves Junior
*/
#pragma once
#include <limits>
#include <random_iterator/detail/EngineTraits.hpp>
#include <random_iterator/detail/SplitMix.hpp>
#include <random_iterator/detail/Squares3_128.hpp>
#include <random_iterator/detail/Squares4_128.hpp>
#include <random_iterator/detail/Squares3_64.hpp>
#include <random_iterator/detail/Squares4_64.hpp>
namespace random_iterator {
namespace detail {
template<typename Engine123>
class Engine{
typedef unsigned trigger_type;
public:
typedef Engine123 engine_type;
typedef typename detail::random_traits<engine_type>::state_type state_type;
typedef typename detail::random_traits<engine_type>::seed_type seed_type;
typedef typename detail::random_traits<engine_type>::advance_type advance_type;
typedef typename detail::random_traits<engine_type>::init_type init_type;
typedef typename detail::random_traits<engine_type>::result_type result_type;
static const unsigned arity = detail::random_traits<engine_type>::arity;
Engine()=delete;
Engine(result_type seed):
engine_(engine_type{}),
cache_(state_type{}),
state_(state_type{}),
seed_(seed_type{}),
trigger_(arity)
{
init_type temp{{}};
for(unsigned i=0; i< temp.size(); ++i){
temp[i]=detail::splitmix<result_type>(seed);
}
seed_ = temp;
}
Engine(result_type seed, uint32_t stream ):
engine_(engine_type{}),
cache_(state_type{}),
state_(state_type{}),
seed_(seed_type{}),
trigger_(arity)
{
init_type temp{{}};
for(unsigned i=0; i< temp.size(); ++i){
temp[i]=detail::splitmix<result_type>(seed);
}
state_[arity-1] = stream;
state_[arity-1] << 32;
seed_ = temp;
}
Engine(init_type seed):
engine_(engine_type{}),
cache_(state_type{}),
state_(state_type{}),
seed_(seed),
trigger_(arity)
{}
Engine(init_type seed , uint32_t stream):
engine_(engine_type{}),
cache_(state_type{}),
state_(state_type{}),
seed_(seed),
trigger_(arity)
{
state_[arity-1] = stream;
state_[arity-1] << 32;
}
Engine( Engine<Engine123> const& other):
engine_(engine_type{} ),
cache_(other.getCache()),
state_(other.getState()),
seed_(other.getSeed() ),
trigger_(other.getTrigger())
{}
inline Engine<Engine123>&
operator=( Engine<Engine123> const& other)
{
if(this==&other) return *this;
engine_ = engine_type{};
cache_ = other.getCache();
state_ = other.getState();
seed_ = other.getSeed();
trigger_ = other.getTrigger();
return *this;
}
inline result_type operator()(void)
{
result_type result = 0;
if(trigger_==arity){
trigger_=0;
cache_ = engine_(state_.incr(), seed_);
result = cache_[trigger_];
++trigger_;
}
else {
result = cache_[trigger_];
++trigger_;
}
return result;
}
inline void discard( advance_type n){
state_.incr(n);
trigger_=arity;
}
inline void reset(void) {
trigger_ = arity;
state_ = state_type{};
cache_ = state_type{};
}
inline const seed_type& getSeed() const {
return seed_;
}
inline void setSeed(seed_type seed) {
seed_ = seed;
}
inline void setSeed(result_type seed) {
init_type temp{{}};
for(unsigned i=0; i< temp.size(); ++i){
temp[i]=detail::splitmix<result_type>(seed);
}
seed_ = temp;
}
inline const state_type& getState() const {
return state_;
}
inline void setState(const state_type& state) {
state_ = state;
}
static constexpr result_type min() { return 0;}
static constexpr result_type max() { return std::numeric_limits<result_type>::max(); }
private:
inline state_type getCache() const {
return cache_;
}
inline trigger_type getTrigger() const {
return trigger_;
}
engine_type engine_;
state_type cache_;
state_type state_;
seed_type seed_;
trigger_type trigger_;
};
typedef Engine<random_iterator_r123::Philox2x64> philox;
typedef Engine<random_iterator_r123::Threefry2x64> threefry;
typedef detail::Squares3_64 squares3_64;
typedef detail::Squares4_64 squares4_64;
typedef detail::Squares3_128 squares3_128;
typedef detail::Squares4_128 squares4_128;
#if RANDOM_ITERATOR_R123_USE_AES_NI
typedef Engine<random_iterator_r123::ARS2x64> ars;
#endif
} // namespace detail
} // namespace random_iterator
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment