// Copyright 2020 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package fuzz

import (
	
	
	
	
	
	
)

type mutatorRand interface {
	uint32() uint32
	intn(int) int
	uint32n(uint32) uint32
	exp2() int
	bool() bool

	save(randState, randInc *uint64)
	restore(randState, randInc uint64)
}

// The functions in pcg implement a 32 bit PRNG with a 64 bit period: pcg xsh rr
// 64 32. See https://www.pcg-random.org/ for more information. This
// implementation is geared specifically towards the needs of fuzzing: Simple
// creation and use, no reproducibility, no concurrency safety, just the
// necessary methods, optimized for speed.

var globalInc atomic.Uint64 // PCG stream

const multiplier uint64 = 6364136223846793005

// pcgRand is a PRNG. It should not be copied or shared. No Rand methods are
// concurrency safe.
type pcgRand struct {
	noCopy noCopy // help avoid mistakes: ask vet to ensure that we don't make a copy
	state  uint64
	inc    uint64
}

func godebugSeed() *int {
	 := strings.Split(os.Getenv("GODEBUG"), ",")
	for ,  := range  {
		if strings.HasPrefix(, "fuzzseed=") {
			,  := strconv.Atoi(strings.TrimPrefix(, "fuzzseed="))
			if  != nil {
				panic("malformed fuzzseed")
			}
			return &
		}
	}
	return nil
}

// newPcgRand generates a new, seeded Rand, ready for use.
func newPcgRand() *pcgRand {
	 := new(pcgRand)
	 := uint64(time.Now().UnixNano())
	if  := godebugSeed();  != nil {
		 = uint64(*)
	}
	 := globalInc.Add(1)
	.state = 
	.inc = ( << 1) | 1
	.step()
	.state += 
	.step()
	return 
}

func ( *pcgRand) () {
	.state *= multiplier
	.state += .inc
}

func ( *pcgRand) (,  *uint64) {
	* = .state
	* = .inc
}

func ( *pcgRand) (,  uint64) {
	.state = 
	.inc = 
}

// uint32 returns a pseudo-random uint32.
func ( *pcgRand) () uint32 {
	 := .state
	.step()
	return bits.RotateLeft32(uint32(((>>18)^)>>27), -int(>>59))
}

// intn returns a pseudo-random number in [0, n).
// n must fit in a uint32.
func ( *pcgRand) ( int) int {
	if int(uint32()) !=  {
		panic("large Intn")
	}
	return int(.uint32n(uint32()))
}

// uint32n returns a pseudo-random number in [0, n).
//
// For implementation details, see:
// https://lemire.me/blog/2016/06/27/a-fast-alternative-to-the-modulo-reduction
// https://lemire.me/blog/2016/06/30/fast-random-shuffling
func ( *pcgRand) ( uint32) uint32 {
	 := .uint32()
	 := uint64() * uint64()
	 := uint32()
	if  <  {
		 := uint32(-int32()) % 
		for  <  {
			 = .uint32()
			 = uint64() * uint64()
			 = uint32()
		}
	}
	return uint32( >> 32)
}

// exp2 generates n with probability 1/2^(n+1).
func ( *pcgRand) () int {
	return bits.TrailingZeros32(.uint32())
}

// bool generates a random bool.
func ( *pcgRand) () bool {
	return .uint32()&1 == 0
}

// noCopy may be embedded into structs which must not be copied
// after the first use.
//
// See https://golang.org/issues/8005#issuecomment-190753527
// for details.
type noCopy struct{}

// lock is a no-op used by -copylocks checker from `go vet`.
func (*noCopy) ()   {}
func (*noCopy) () {}