chromium/third_party/abseil-cpp/absl/random/internal/pcg_engine.h

// Copyright 2018 The Abseil Authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_
#define ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_

#include <type_traits>

#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
#include "absl/numeric/bits.h"
#include "absl/numeric/int128.h"
#include "absl/random/internal/fastmath.h"
#include "absl/random/internal/iostream_state_saver.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {

// pcg_engine is a simplified implementation of Melissa O'Neil's PCG engine in
// C++.  PCG combines a linear congruential generator (LCG) with output state
// mixing functions to generate each random variate.  pcg_engine supports only a
// single sequence (oneseq), and does not support streams.
//
// pcg_engine is parameterized by two types:
//   Params, which provides the multiplier and increment values;
//   Mix, which mixes the state into the result.
//
template <typename Params, typename Mix>
class pcg_engine {};

// Parameterized implementation of the PCG 128-bit oneseq state.
// This provides state_type, multiplier, and increment for pcg_engine.
template <uint64_t kMultA, uint64_t kMultB, uint64_t kIncA, uint64_t kIncB>
class pcg128_params {};

// Implementation of the PCG xsl_rr_128_64 128-bit mixing function, which
// accepts an input of state_type and mixes it into an output of result_type.
struct pcg_xsl_rr_128_64 {};

// Parameterized implementation of the PCG 64-bit oneseq state.
// This provides state_type, multiplier, and increment for pcg_engine.
template <uint64_t kMult, uint64_t kInc>
class pcg64_params {};

// Implementation of the PCG xsh_rr_64_32 64-bit mixing function, which accepts
// an input of state_type and mixes it into an output of result_type.
struct pcg_xsh_rr_64_32 {};

// Stable pcg_engine implementations:
// This is a 64-bit generator using 128-bits of state.
// The output sequence is equivalent to Melissa O'Neil's pcg64_oneseq.
pcg64_2018_engine;

// This is a 32-bit generator using 64-bits of state.
// This is equivalent to Melissa O'Neil's pcg32_oneseq.
pcg32_2018_engine;

}  // namespace random_internal
ABSL_NAMESPACE_END
}  // namespace absl

#endif  // ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_