feat(Core/Random): port random system from TrinityCore (#5454)

* feat(Core/Random): port random system from TrinityCore

* lic

* logic correct

* MultimapErasePair move

* whitespace

17:13:34 1. 'Containers.h'. Replace (1)
17:13:40 2. 'LootMgr.h'. Replace (1)
17:13:44 3. 'World.cpp'. Replace (1)
17:13:47 4. 'instance_scholomance.cpp'. Replace (1)

* correct debug build
This commit is contained in:
Kargatum
2021-05-17 02:53:21 +07:00
committed by GitHub
parent 0d699222de
commit 13f71c9c4d
33 changed files with 2933 additions and 651 deletions

69
deps/SFMT/CHANGE-LOG.txt vendored Normal file
View File

@@ -0,0 +1,69 @@
ver 1.5
-------
bug fix to_res53 reported by Akio Takahashi.
ver 1.4.1
-------
fix MSC compile error reported by Dirk Steenpass.
ver 1.4
-------
internal state of SFMT is kept in structure.
function and macro names are changed to have sfmt_ prefix.
ALTIVEC OR BIGENDIAN ARE NOT TESTED AT ALL.
ver 1.3.3
-------
change condition compile of do_recursion in SFMT.c
ver 1.3.2
-------
bug fix to_res53_mix and genrand_res53_mix.
ver 1.3.1
-------
gcc compile option changed from -O9 to -O3.
add functions genrand_res53_mix and to_res53_mix.
bug fix about definition of ALWAYS_INLINE.
add new definition PRE_ALWAYS for MSC.
ver 1.3
-------
bug fixed: -DONLY64 without -DBIG_ENIAN64 had been generating
wrong sequence.
bug fixed: There is no documentation about BIG_ENDIAN64.
add automatic endian check by __BIG_ENDIAN__ predefined macro.
bug fixed: change == in check.sh to =
add SFMT-params216091.h
add AltiVec parameter format for systems which are not osx.
change Makefile for systems which are not osx and support AltiVec.
change sample2 of howto-compile for Free BSD.
change source files for BORLANDC and Visual Studio.
change period certification code more smart.
add params directory.
ver 1.2.1
-------
Fix typo in SFMT-alti.c SFMT-sse2.c
marge SFMT-alti.c and SFMT-alti.h into SFMT-alti.h
marge SFMT-sse2.c and SFMT-sse2.h into SFMT-sse2.h
This version is not released.
ver 1.2
-------
Support many periods: 2^{607}, 2^{1279}, 2^{2281}, 2^{4253}, 2^{11213},
2^{19937}, 2^{44497}, 2^{86243}, 2^{132049}
Fix typo in LICENSE.txt.
Add cast to vec_perm for SFMT-alti.c, SFMT-alti64.c.
combine source codes.
ver 1.1
-------
The period certification method is changed from constant to function.
The convert functions from 32-bit and 64-bit integer to double are added.
The documentation is changed.
Sample programs are added.
ver 1.0
-------
The first version.

View File

@@ -1,3 +1,4 @@
#
# Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/> # Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
# Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 # Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
# #
@@ -8,12 +9,79 @@
# This program is distributed in the hope that it will be useful, but # This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the # WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
add_library(sfmt INTERFACE) set(SFMT_SOURCES
SFMT.c
SFMT.h
SFMT-alti.h
SFMT-common.h
SFMT-neon.h
SFMT-params.h
SFMT-params607.h
SFMT-params1279.h
SFMT-params2281.h
SFMT-params4253.h
SFMT-params11213.h
SFMT-params19937.h
SFMT-params44497.h
SFMT-params86243.h
SFMT-params132049.h
SFMT-params216091.h
SFMT-sse2.h
SFMT-sse2-msc.h)
# Group sources add_library(sfmt STATIC ${SFMT_SOURCES})
GroupSources(${CMAKE_CURRENT_SOURCE_DIR})
target_include_directories(sfmt target_include_directories(sfmt
INTERFACE INTERFACE
${CMAKE_CURRENT_SOURCE_DIR}) ${CMAKE_CURRENT_SOURCE_DIR})
# using the standard Mersenne exponent 19937
target_compile_definitions(sfmt PUBLIC -DSFMT_MEXP=19937)
# enable SIMD instructions if available
include(CheckCCompilerFlag)
if (CMAKE_SYSTEM_PROCESSOR MATCHES "(powerpc|ppc)64|(powerpc|ppc)64le")
check_c_compiler_flag("-maltivec" HAVE_ALTIVEC)
if (HAVE_ALTIVEC)
target_compile_options(sfmt PRIVATE -mabi=altivec -maltivec)
target_compile_definitions(sfmt PUBLIC -DHAVE_ALTIVEC)
else ()
message(WARNING "Altivec not available - performance will be poor!")
endif ()
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "arm|ARM")
check_c_compiler_flag(-mfpu=neon HAVE_NEON)
if (HAVE_NEON)
target_compile_options(sfmt PRIVATE -mfpu=neon -ftree-vectorize)
target_compile_definitions(sfmt PUBLIC -DHAVE_NEON)
else ()
message(WARNING "Neon not available - performance will be poor!")
endif ()
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "aarch64|AARCH64")
check_c_compiler_flag(-march=armv8-a+simd HAVE_NEON)
if (HAVE_NEON)
target_compile_options(sfmt PRIVATE -ftree-vectorize)
target_compile_definitions(sfmt PUBLIC -DHAVE_NEON)
else ()
message(WARNING "Neon not available - performance will be poor!")
endif ()
elseif (CMAKE_SYSTEM_PROCESSOR MATCHES "i686|amd64|x86_64|AMD64")
#SSE2 is always available
set(HAVE_SSE2 1)
if (NOT CMAKE_C_COMPILER_ID MATCHES "MSVC")
target_compile_options(sfmt PRIVATE -msse2)
endif ()
target_compile_definitions(sfmt PUBLIC -DHAVE_SSE2)
endif ()
set_target_properties(sfmt PROPERTIES LINKER_LANGUAGE CXX)
# inherit generic build options (e.g. fPIC)
target_link_libraries(sfmt PRIVATE acore-dependency-interface)
set_target_properties(sfmt
PROPERTIES
FOLDER
"deps")

32
deps/SFMT/LICENSE.txt vendored Normal file
View File

@@ -0,0 +1,32 @@
Copyright (c) 2006,2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
University.
Copyright (c) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima University
and The University of Tokyo.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
* Neither the names of Hiroshima University, The University of
Tokyo nor the names of its contributors may be used to endorse
or promote products derived from this software without specific
prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

27
deps/SFMT/README.txt vendored Normal file
View File

@@ -0,0 +1,27 @@
=================================================================
SFMT ver. 1.5
SIMD oriented Fast Mersenne Twister(SFMT)
Mutsuo Saito (Hiroshima University) and
Makoto Matsumoto (The University of Tokyo)
Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
University.
Copyright (c) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima University
and The University of Tokyo.
All rights reserved.
The (modified) BSD License is applied to this software, see LICENSE.txt
=================================================================
CAUTION:
BIGENDIAN OR ALTIVEC FEATURES ARE NOT TESTED AT ALL.
To see documents, see html/index.html.
To make test program, see html/howto-compile.html
If you want to redistribute and/or change source files, see LICENSE.txt.
When you change these files and redistribute them, PLEASE write your
e-mail address in redistribution and write to contact YOU first if
users of your changed source encounter troubles.

156
deps/SFMT/SFMT-alti.h vendored Normal file
View File

@@ -0,0 +1,156 @@
#pragma once
/**
* @file SFMT-alti.h
*
* @brief SIMD oriented Fast Mersenne Twister(SFMT)
* pseudorandom number generator
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* Copyright (C) 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University. All rights reserved.
*
* The new BSD License is applied to this software.
* see LICENSE.txt
*/
#ifndef SFMT_ALTI_H
#define SFMT_ALTI_H
inline static vector unsigned int vec_recursion(vector unsigned int a,
vector unsigned int b,
vector unsigned int c,
vector unsigned int d);
/**
* This function represents the recursion formula in AltiVec and BIG ENDIAN.
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
* @return output
*/
inline static vector unsigned int vec_recursion(vector unsigned int a,
vector unsigned int b,
vector unsigned int c,
vector unsigned int d) {
const vector unsigned int sl1 = SFMT_ALTI_SL1;
const vector unsigned int sr1 = SFMT_ALTI_SR1;
#ifdef ONLY64
const vector unsigned int mask = SFMT_ALTI_MSK64;
const vector unsigned char perm_sl = SFMT_ALTI_SL2_PERM64;
const vector unsigned char perm_sr = SFMT_ALTI_SR2_PERM64;
#else
const vector unsigned int mask = SFMT_ALTI_MSK;
const vector unsigned char perm_sl = SFMT_ALTI_SL2_PERM;
const vector unsigned char perm_sr = SFMT_ALTI_SR2_PERM;
#endif
vector unsigned int v, w, x, y, z;
x = vec_perm(a, (vector unsigned int)perm_sl, perm_sl);
v = a;
y = vec_sr(b, sr1);
z = vec_perm(c, (vector unsigned int)perm_sr, perm_sr);
w = vec_sl(d, sl1);
z = vec_xor(z, w);
y = vec_and(y, mask);
v = vec_xor(v, x);
z = vec_xor(z, y);
z = vec_xor(z, v);
return z;
}
/**
* This function fills the internal state array with pseudorandom
* integers.
*/
void sfmt_gen_rand_all(sfmt_t * sfmt) {
int i;
vector unsigned int r, r1, r2;
r1 = sfmt->state[N - 2].s;
r2 = sfmt->state[N - 1].s;
for (i = 0; i < N - POS1; i++) {
r = vec_recursion(sfmt->state[i].s, sfmt->state[i + POS1].s, r1, r2);
sfmt->state[i].s = r;
r1 = r2;
r2 = r;
}
for (; i < N; i++) {
r = vec_recursion(sfmt->state[i].s, sfmt->state[i + POS1 - N].s, r1, r2);
sfmt->state[i].s = r;
r1 = r2;
r2 = r;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
*
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pesudorandom numbers to be generated.
*/
inline static void gen_rand_array(sfmt_t * sfmt, w128_t *array, int size) {
int i, j;
vector unsigned int r, r1, r2;
r1 = sfmt->state[N - 2].s;
r2 = sfmt->state[N - 1].s;
for (i = 0; i < N - POS1; i++) {
r = vec_recursion(sfmt->state[i].s, sfmt->state[i + POS1].s, r1, r2);
array[i].s = r;
r1 = r2;
r2 = r;
}
for (; i < N; i++) {
r = vec_recursion(sfmt->state[i].s, array[i + POS1 - N].s, r1, r2);
array[i].s = r;
r1 = r2;
r2 = r;
}
/* main loop */
for (; i < size - N; i++) {
r = vec_recursion(array[i - N].s, array[i + POS1 - N].s, r1, r2);
array[i].s = r;
r1 = r2;
r2 = r;
}
for (j = 0; j < 2 * N - size; j++) {
sfmt->state[j].s = array[j + size - N].s;
}
for (; i < size; i++) {
r = vec_recursion(array[i - N].s, array[i + POS1 - N].s, r1, r2);
array[i].s = r;
sfmt->state[j++].s = r;
r1 = r2;
r2 = r;
}
}
#ifndef ONLY64
#if defined(__APPLE__)
#define SFMT_ALTI_SWAP (vector unsigned char) \
(4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11)
#else
#define SFMT_ALTI_SWAP {4, 5, 6, 7, 0, 1, 2, 3, 12, 13, 14, 15, 8, 9, 10, 11}
#endif
/**
* This function swaps high and low 32-bit of 64-bit integers in user
* specified array.
*
* @param array an 128-bit array to be swaped.
* @param size size of 128-bit array.
*/
inline static void swap(w128_t *array, int size) {
int i;
const vector unsigned char perm = SFMT_ALTI_SWAP;
for (i = 0; i < size; i++) {
array[i].s = vec_perm(array[i].s, (vector unsigned int)perm, perm);
}
}
#endif
#endif

164
deps/SFMT/SFMT-common.h vendored Normal file
View File

@@ -0,0 +1,164 @@
#pragma once
/**
* @file SFMT-common.h
*
* @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom
* number generator with jump function. This file includes common functions
* used in random number generation and jump.
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (The University of Tokyo)
*
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University.
* Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima
* University and The University of Tokyo.
* All rights reserved.
*
* The 3-clause BSD License is applied to this software, see
* LICENSE.txt
*/
#ifndef SFMT_COMMON_H
#define SFMT_COMMON_H
#if defined(__cplusplus)
extern "C" {
#endif
#include "SFMT.h"
inline static void do_recursion(w128_t * r, w128_t * a, w128_t * b,
w128_t * c, w128_t * d);
inline static void rshift128(w128_t *out, w128_t const *in, int shift);
inline static void lshift128(w128_t *out, w128_t const *in, int shift);
/**
* This function simulates SIMD 128-bit right shift by the standard C.
* The 128-bit integer given in in is shifted by (shift * 8) bits.
* This function simulates the LITTLE ENDIAN SIMD.
* @param out the output of this function
* @param in the 128-bit data to be shifted
* @param shift the shift value
*/
#ifdef ONLY64
inline static void rshift128(w128_t *out, w128_t const *in, int shift) {
uint64_t th, tl, oh, ol;
th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
oh = th >> (shift * 8);
ol = tl >> (shift * 8);
ol |= th << (64 - shift * 8);
out->u[0] = (uint32_t)(ol >> 32);
out->u[1] = (uint32_t)ol;
out->u[2] = (uint32_t)(oh >> 32);
out->u[3] = (uint32_t)oh;
}
#else
inline static void rshift128(w128_t *out, w128_t const *in, int shift)
{
uint64_t th, tl, oh, ol;
th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
oh = th >> (shift * 8);
ol = tl >> (shift * 8);
ol |= th << (64 - shift * 8);
out->u[1] = (uint32_t)(ol >> 32);
out->u[0] = (uint32_t)ol;
out->u[3] = (uint32_t)(oh >> 32);
out->u[2] = (uint32_t)oh;
}
#endif
/**
* This function simulates SIMD 128-bit left shift by the standard C.
* The 128-bit integer given in in is shifted by (shift * 8) bits.
* This function simulates the LITTLE ENDIAN SIMD.
* @param out the output of this function
* @param in the 128-bit data to be shifted
* @param shift the shift value
*/
#ifdef ONLY64
inline static void lshift128(w128_t *out, w128_t const *in, int shift) {
uint64_t th, tl, oh, ol;
th = ((uint64_t)in->u[2] << 32) | ((uint64_t)in->u[3]);
tl = ((uint64_t)in->u[0] << 32) | ((uint64_t)in->u[1]);
oh = th << (shift * 8);
ol = tl << (shift * 8);
oh |= tl >> (64 - shift * 8);
out->u[0] = (uint32_t)(ol >> 32);
out->u[1] = (uint32_t)ol;
out->u[2] = (uint32_t)(oh >> 32);
out->u[3] = (uint32_t)oh;
}
#else
inline static void lshift128(w128_t *out, w128_t const *in, int shift)
{
uint64_t th, tl, oh, ol;
th = ((uint64_t)in->u[3] << 32) | ((uint64_t)in->u[2]);
tl = ((uint64_t)in->u[1] << 32) | ((uint64_t)in->u[0]);
oh = th << (shift * 8);
ol = tl << (shift * 8);
oh |= tl >> (64 - shift * 8);
out->u[1] = (uint32_t)(ol >> 32);
out->u[0] = (uint32_t)ol;
out->u[3] = (uint32_t)(oh >> 32);
out->u[2] = (uint32_t)oh;
}
#endif
/**
* This function represents the recursion formula.
* @param r output
* @param a a 128-bit part of the internal state array
* @param b a 128-bit part of the internal state array
* @param c a 128-bit part of the internal state array
* @param d a 128-bit part of the internal state array
*/
#ifdef ONLY64
inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b, w128_t *c,
w128_t *d) {
w128_t x;
w128_t y;
lshift128(&x, a, SFMT_SL2);
rshift128(&y, c, SFMT_SR2);
r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SFMT_SR1) & SFMT_MSK2) ^ y.u[0]
^ (d->u[0] << SFMT_SL1);
r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SFMT_SR1) & SFMT_MSK1) ^ y.u[1]
^ (d->u[1] << SFMT_SL1);
r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SFMT_SR1) & SFMT_MSK4) ^ y.u[2]
^ (d->u[2] << SFMT_SL1);
r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SFMT_SR1) & SFMT_MSK3) ^ y.u[3]
^ (d->u[3] << SFMT_SL1);
}
#else
inline static void do_recursion(w128_t *r, w128_t *a, w128_t *b,
w128_t *c, w128_t *d)
{
w128_t x;
w128_t y;
lshift128(&x, a, SFMT_SL2);
rshift128(&y, c, SFMT_SR2);
r->u[0] = a->u[0] ^ x.u[0] ^ ((b->u[0] >> SFMT_SR1) & SFMT_MSK1)
^ y.u[0] ^ (d->u[0] << SFMT_SL1);
r->u[1] = a->u[1] ^ x.u[1] ^ ((b->u[1] >> SFMT_SR1) & SFMT_MSK2)
^ y.u[1] ^ (d->u[1] << SFMT_SL1);
r->u[2] = a->u[2] ^ x.u[2] ^ ((b->u[2] >> SFMT_SR1) & SFMT_MSK3)
^ y.u[2] ^ (d->u[2] << SFMT_SL1);
r->u[3] = a->u[3] ^ x.u[3] ^ ((b->u[3] >> SFMT_SR1) & SFMT_MSK4)
^ y.u[3] ^ (d->u[3] << SFMT_SL1);
}
#endif
#if defined(__cplusplus)
}
#endif
#endif // SFMT_COMMON_H

111
deps/SFMT/SFMT-neon.h vendored Normal file
View File

@@ -0,0 +1,111 @@
/**
* @file SFMT-neon.h
* @brief SIMD oriented Fast Mersenne Twister(SFMT) for ARM with 128b NEON
*
* @author Masaki Ota
*
* @note We assume LITTLE ENDIAN in this file
*/
#ifndef SFMT_NEON_H
#define SFMT_NEON_H
inline static void neon_recursion(uint32x4_t * r, uint32x4_t a, uint32x4_t b,
uint32x4_t c, uint32x4_t d);
/**
* This function represents the recursion formula.
* @param r an output
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
*/
inline static void neon_recursion(uint32x4_t * r, uint32x4_t a, uint32x4_t b,
uint32x4_t c, uint32x4_t d)
{
uint32x4_t v, x, y, z;
static const uint32x4_t vzero = {0,0,0,0};
static const uint32x4_t vmask = {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4};
#define rotate_bytes(A, B, C) vreinterpretq_u32_u8(vextq_u8(vreinterpretq_u8_u32(A),vreinterpretq_u8_u32(B),(C)))
y = vshrq_n_u32(b, SFMT_SR1);
z = rotate_bytes(c, vzero, SFMT_SR2);
v = vshlq_n_u32(d, SFMT_SL1);
z = veorq_u32(z, a);
z = veorq_u32(z, v);
x = rotate_bytes(vzero, a, 16-SFMT_SL2);
y = vandq_u32(y, vmask);
z = veorq_u32(z, x);
z = veorq_u32(z, y);
*r = z;
}
/**
* This function fills the internal state array with pseudorandom
* integers.
* @param sfmt SFMT internal state
*/
void sfmt_gen_rand_all(sfmt_t * sfmt) {
int i;
uint32x4_t r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
neon_recursion(&pstate[i].si, pstate[i].si, pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
for (; i < SFMT_N; i++) {
neon_recursion(&pstate[i].si, pstate[i].si, pstate[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
* @param sfmt SFMT internal state.
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pseudorandom numbers to be generated.
*/
static void gen_rand_array(sfmt_t * sfmt, w128_t * array, int size)
{
int i, j;
uint32x4_t r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
neon_recursion(&array[i].si, pstate[i].si, pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < SFMT_N; i++) {
neon_recursion(&array[i].si, pstate[i].si, array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < size - SFMT_N; i++) {
neon_recursion(&array[i].si, array[i - SFMT_N].si, array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (j = 0; j < 2 * SFMT_N - size; j++) {
pstate[j] = array[j + size - SFMT_N];
}
for (; i < size; i++, j++) {
neon_recursion(&array[i].si, array[i - SFMT_N].si, array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = pstate[j].si = array[i].si;
}
}
#endif

98
deps/SFMT/SFMT-params.h vendored Normal file
View File

@@ -0,0 +1,98 @@
#pragma once
#ifndef SFMT_PARAMS_H
#define SFMT_PARAMS_H
#if !defined(SFMT_MEXP)
#if defined(__GNUC__) && !defined(__ICC)
#warning "SFMT_MEXP is not defined. I assume MEXP is 19937."
#endif
#define SFMT_MEXP 19937
#endif
/*-----------------
BASIC DEFINITIONS
-----------------*/
/** Mersenne Exponent. The period of the sequence
* is a multiple of 2^MEXP-1.
* #define SFMT_MEXP 19937 */
/** SFMT generator has an internal state array of 128-bit integers,
* and N is its size. */
#define SFMT_N (SFMT_MEXP / 128 + 1)
/** N32 is the size of internal state array when regarded as an array
* of 32-bit integers.*/
#define SFMT_N32 (SFMT_N * 4)
/** N64 is the size of internal state array when regarded as an array
* of 64-bit integers.*/
#define SFMT_N64 (SFMT_N * 2)
/*----------------------
the parameters of SFMT
following definitions are in paramsXXXX.h file.
----------------------*/
/** the pick up position of the array.
#define SFMT_POS1 122
*/
/** the parameter of shift left as four 32-bit registers.
#define SFMT_SL1 18
*/
/** the parameter of shift left as one 128-bit register.
* The 128-bit integer is shifted by (SFMT_SL2 * 8) bits.
#define SFMT_SL2 1
*/
/** the parameter of shift right as four 32-bit registers.
#define SFMT_SR1 11
*/
/** the parameter of shift right as one 128-bit register.
* The 128-bit integer is shifted by (SFMT_SR2 * 8) bits.
#define SFMT_SR2 1
*/
/** A bitmask, used in the recursion. These parameters are introduced
* to break symmetry of SIMD.
#define SFMT_MSK1 0xdfffffefU
#define SFMT_MSK2 0xddfecb7fU
#define SFMT_MSK3 0xbffaffffU
#define SFMT_MSK4 0xbffffff6U
*/
/** These definitions are part of a 128-bit period certification vector.
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0x00000000U
#define SFMT_PARITY4 0xc98e126aU
*/
#if SFMT_MEXP == 607
#include "SFMT-params607.h"
#elif SFMT_MEXP == 1279
#include "SFMT-params1279.h"
#elif SFMT_MEXP == 2281
#include "SFMT-params2281.h"
#elif SFMT_MEXP == 4253
#include "SFMT-params4253.h"
#elif SFMT_MEXP == 11213
#include "SFMT-params11213.h"
#elif SFMT_MEXP == 19937
#include "SFMT-params19937.h"
#elif SFMT_MEXP == 44497
#include "SFMT-params44497.h"
#elif SFMT_MEXP == 86243
#include "SFMT-params86243.h"
#elif SFMT_MEXP == 132049
#include "SFMT-params132049.h"
#elif SFMT_MEXP == 216091
#include "SFMT-params216091.h"
#else
#if defined(__GNUC__) && !defined(__ICC)
#error "SFMT_MEXP is not valid."
#undef SFMT_MEXP
#else
#undef SFMT_MEXP
#endif
#endif
#endif /* SFMT_PARAMS_H */

50
deps/SFMT/SFMT-params11213.h vendored Normal file
View File

@@ -0,0 +1,50 @@
#pragma once
#ifndef SFMT_PARAMS11213_H
#define SFMT_PARAMS11213_H
#define SFMT_POS1 68
#define SFMT_SL1 14
#define SFMT_SL2 3
#define SFMT_SR1 7
#define SFMT_SR2 3
#define SFMT_MSK1 0xeffff7fbU
#define SFMT_MSK2 0xffffffefU
#define SFMT_MSK3 0xdfdfbfffU
#define SFMT_MSK4 0x7fffdbfdU
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0xe8148000U
#define SFMT_PARITY4 0xd0c7afa3U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define SFMT_ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define SFMT_ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
#define SFMT_ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-11213:68-14-3-7-3:effff7fb-ffffffef-dfdfbfff-7fffdbfd"
#endif /* SFMT_PARAMS11213_H */

50
deps/SFMT/SFMT-params1279.h vendored Normal file
View File

@@ -0,0 +1,50 @@
#pragma once
#ifndef SFMT_PARAMS1279_H
#define SFMT_PARAMS1279_H
#define SFMT_POS1 7
#define SFMT_SL1 14
#define SFMT_SL2 3
#define SFMT_SR1 5
#define SFMT_SR2 1
#define SFMT_MSK1 0xf7fefffdU
#define SFMT_MSK2 0x7fefcfffU
#define SFMT_MSK3 0xaff3ef3fU
#define SFMT_MSK4 0xb5ffff7fU
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0x00000000U
#define SFMT_PARITY4 0x20000000U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define SFMT_ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define SFMT_ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define SFMT_ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-1279:7-14-3-5-1:f7fefffd-7fefcfff-aff3ef3f-b5ffff7f"
#endif /* SFMT_PARAMS1279_H */

50
deps/SFMT/SFMT-params132049.h vendored Normal file
View File

@@ -0,0 +1,50 @@
#pragma once
#ifndef SFMT_PARAMS132049_H
#define SFMT_PARAMS132049_H
#define SFMT_POS1 110
#define SFMT_SL1 19
#define SFMT_SL2 1
#define SFMT_SR1 21
#define SFMT_SR2 1
#define SFMT_MSK1 0xffffbb5fU
#define SFMT_MSK2 0xfb6ebf95U
#define SFMT_MSK3 0xfffefffaU
#define SFMT_MSK4 0xcff77fffU
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0xcb520000U
#define SFMT_PARITY4 0xc7e91c7dU
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define SFMT_ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define SFMT_ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define SFMT_ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-132049:110-19-1-21-1:ffffbb5f-fb6ebf95-fffefffa-cff77fff"
#endif /* SFMT_PARAMS132049_H */

50
deps/SFMT/SFMT-params19937.h vendored Normal file
View File

@@ -0,0 +1,50 @@
#pragma once
#ifndef SFMT_PARAMS19937_H
#define SFMT_PARAMS19937_H
#define SFMT_POS1 122
#define SFMT_SL1 18
#define SFMT_SL2 1
#define SFMT_SR1 11
#define SFMT_SR2 1
#define SFMT_MSK1 0xdfffffefU
#define SFMT_MSK2 0xddfecb7fU
#define SFMT_MSK3 0xbffaffffU
#define SFMT_MSK4 0xbffffff6U
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0x00000000U
#define SFMT_PARITY4 0x13c9e684U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define SFMT_ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define SFMT_ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define SFMT_ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-19937:122-18-1-11-1:dfffffef-ddfecb7f-bffaffff-bffffff6"
#endif /* SFMT_PARAMS19937_H */

50
deps/SFMT/SFMT-params216091.h vendored Normal file
View File

@@ -0,0 +1,50 @@
#pragma once
#ifndef SFMT_PARAMS216091_H
#define SFMT_PARAMS216091_H
#define SFMT_POS1 627
#define SFMT_SL1 11
#define SFMT_SL2 3
#define SFMT_SR1 10
#define SFMT_SR2 1
#define SFMT_MSK1 0xbff7bff7U
#define SFMT_MSK2 0xbfffffffU
#define SFMT_MSK3 0xbffffa7fU
#define SFMT_MSK4 0xffddfbfbU
#define SFMT_PARITY1 0xf8000001U
#define SFMT_PARITY2 0x89e80709U
#define SFMT_PARITY3 0x3bd2b64bU
#define SFMT_PARITY4 0x0c64b1e4U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define SFMT_ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define SFMT_ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define SFMT_ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-216091:627-11-3-10-1:bff7bff7-bfffffff-bffffa7f-ffddfbfb"
#endif /* SFMT_PARAMS216091_H */

50
deps/SFMT/SFMT-params2281.h vendored Normal file
View File

@@ -0,0 +1,50 @@
#pragma once
#ifndef SFMT_PARAMS2281_H
#define SFMT_PARAMS2281_H
#define SFMT_POS1 12
#define SFMT_SL1 19
#define SFMT_SL2 1
#define SFMT_SR1 5
#define SFMT_SR2 1
#define SFMT_MSK1 0xbff7ffbfU
#define SFMT_MSK2 0xfdfffffeU
#define SFMT_MSK3 0xf7ffef7fU
#define SFMT_MSK4 0xf2f7cbbfU
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0x00000000U
#define SFMT_PARITY4 0x41dfa600U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define SFMT_ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define SFMT_ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define SFMT_ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-2281:12-19-1-5-1:bff7ffbf-fdfffffe-f7ffef7f-f2f7cbbf"
#endif /* SFMT_PARAMS2281_H */

50
deps/SFMT/SFMT-params4253.h vendored Normal file
View File

@@ -0,0 +1,50 @@
#pragma once
#ifndef SFMT_PARAMS4253_H
#define SFMT_PARAMS4253_H
#define SFMT_POS1 17
#define SFMT_SL1 20
#define SFMT_SL2 1
#define SFMT_SR1 7
#define SFMT_SR2 1
#define SFMT_MSK1 0x9f7bffffU
#define SFMT_MSK2 0x9fffff5fU
#define SFMT_MSK3 0x3efffffbU
#define SFMT_MSK4 0xfffff7bbU
#define SFMT_PARITY1 0xa8000001U
#define SFMT_PARITY2 0xaf5390a3U
#define SFMT_PARITY3 0xb740b3f8U
#define SFMT_PARITY4 0x6c11486dU
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {1,2,3,23,5,6,7,0,9,10,11,4,13,14,15,8}
#define SFMT_ALTI_SL2_PERM64 {1,2,3,4,5,6,7,31,9,10,11,12,13,14,15,0}
#define SFMT_ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define SFMT_ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-4253:17-20-1-7-1:9f7bffff-9fffff5f-3efffffb-fffff7bb"
#endif /* SFMT_PARAMS4253_H */

50
deps/SFMT/SFMT-params44497.h vendored Normal file
View File

@@ -0,0 +1,50 @@
#pragma once
#ifndef SFMT_PARAMS44497_H
#define SFMT_PARAMS44497_H
#define SFMT_POS1 330
#define SFMT_SL1 5
#define SFMT_SL2 3
#define SFMT_SR1 9
#define SFMT_SR2 3
#define SFMT_MSK1 0xeffffffbU
#define SFMT_MSK2 0xdfbebfffU
#define SFMT_MSK3 0xbfbf7befU
#define SFMT_MSK4 0x9ffd7bffU
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0xa3ac4000U
#define SFMT_PARITY4 0xecc1327aU
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define SFMT_ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define SFMT_ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
#define SFMT_ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-44497:330-5-3-9-3:effffffb-dfbebfff-bfbf7bef-9ffd7bff"
#endif /* SFMT_PARAMS44497_H */

50
deps/SFMT/SFMT-params607.h vendored Normal file
View File

@@ -0,0 +1,50 @@
#pragma once
#ifndef SFMT_PARAMS607_H
#define SFMT_PARAMS607_H
#define SFMT_POS1 2
#define SFMT_SL1 15
#define SFMT_SL2 3
#define SFMT_SR1 13
#define SFMT_SR2 3
#define SFMT_MSK1 0xfdff37ffU
#define SFMT_MSK2 0xef7f3f7dU
#define SFMT_MSK3 0xff777b7dU
#define SFMT_MSK4 0x7ff7fb2fU
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0x00000000U
#define SFMT_PARITY4 0x5986f054U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {3,21,21,21,7,0,1,2,11,4,5,6,15,8,9,10}
#define SFMT_ALTI_SL2_PERM64 {3,4,5,6,7,29,29,29,11,12,13,14,15,0,1,2}
#define SFMT_ALTI_SR2_PERM {5,6,7,0,9,10,11,4,13,14,15,8,19,19,19,12}
#define SFMT_ALTI_SR2_PERM64 {13,14,15,0,1,2,3,4,19,19,19,8,9,10,11,12}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-607:2-15-3-13-3:fdff37ff-ef7f3f7d-ff777b7d-7ff7fb2f"
#endif /* SFMT_PARAMS607_H */

50
deps/SFMT/SFMT-params86243.h vendored Normal file
View File

@@ -0,0 +1,50 @@
#pragma once
#ifndef SFMT_PARAMS86243_H
#define SFMT_PARAMS86243_H
#define SFMT_POS1 366
#define SFMT_SL1 6
#define SFMT_SL2 7
#define SFMT_SR1 19
#define SFMT_SR2 1
#define SFMT_MSK1 0xfdbffbffU
#define SFMT_MSK2 0xbff7ff3fU
#define SFMT_MSK3 0xfd77efffU
#define SFMT_MSK4 0xbf9ff3ffU
#define SFMT_PARITY1 0x00000001U
#define SFMT_PARITY2 0x00000000U
#define SFMT_PARITY3 0x00000000U
#define SFMT_PARITY4 0xe9528d85U
/* PARAMETERS FOR ALTIVEC */
#if defined(__APPLE__) /* For OSX */
#define SFMT_ALTI_SL1 \
(vector unsigned int)(SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1)
#define SFMT_ALTI_SR1 \
(vector unsigned int)(SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1)
#define SFMT_ALTI_MSK \
(vector unsigned int)(SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4)
#define SFMT_ALTI_MSK64 \
(vector unsigned int)(SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3)
#define SFMT_ALTI_SL2_PERM \
(vector unsigned char)(25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6)
#define SFMT_ALTI_SL2_PERM64 \
(vector unsigned char)(7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6)
#define SFMT_ALTI_SR2_PERM \
(vector unsigned char)(7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14)
#define SFMT_ALTI_SR2_PERM64 \
(vector unsigned char)(15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14)
#else /* For OTHER OSs(Linux?) */
#define SFMT_ALTI_SL1 {SFMT_SL1, SFMT_SL1, SFMT_SL1, SFMT_SL1}
#define SFMT_ALTI_SR1 {SFMT_SR1, SFMT_SR1, SFMT_SR1, SFMT_SR1}
#define SFMT_ALTI_MSK {SFMT_MSK1, SFMT_MSK2, SFMT_MSK3, SFMT_MSK4}
#define SFMT_ALTI_MSK64 {SFMT_MSK2, SFMT_MSK1, SFMT_MSK4, SFMT_MSK3}
#define SFMT_ALTI_SL2_PERM {25,25,25,25,3,25,25,25,7,0,1,2,11,4,5,6}
#define SFMT_ALTI_SL2_PERM64 {7,25,25,25,25,25,25,25,15,0,1,2,3,4,5,6}
#define SFMT_ALTI_SR2_PERM {7,0,1,2,11,4,5,6,15,8,9,10,17,12,13,14}
#define SFMT_ALTI_SR2_PERM64 {15,0,1,2,3,4,5,6,17,8,9,10,11,12,13,14}
#endif /* For OSX */
#define SFMT_IDSTR "SFMT-86243:366-6-7-19-1:fdbffbff-bff7ff3f-fd77efff-bf9ff3ff"
#endif /* SFMT_PARAMS86243_H */

321
deps/SFMT/SFMT-sse2-msc.h vendored Normal file
View File

@@ -0,0 +1,321 @@
#pragma once
/**
* @file SFMT-sse2-msc.h
* @brief SIMD oriented Fast Mersenne Twister(SFMT) for Intel SSE2 for MSC
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* @note We assume LITTLE ENDIAN in this file
*
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University. All rights reserved.
* Copyright (C) 2013 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University.
*
* The new BSD License is applied to this software, see LICENSE.txt
*/
#ifndef SFMT_SSE2_MSC_H
#define SFMT_SSE2_MSC_H
/* This header file is included only when _MSC_VER is defined. */
#if _MSC_VER > 1700
inline static __m128i __vectorcall mm_recursion(__m128i a, __m128i b,
__m128i c, __m128i d);
/**
* This function represents the recursion formula.
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
* @return new value
*/
inline static __m128i __vectorcall mm_recursion(__m128i a, __m128i b,
__m128i c, __m128i d)
{
__m128i v, x, y, z;
y = _mm_srli_epi32(b, SFMT_SR1);
z = _mm_srli_si128(c, SFMT_SR2);
v = _mm_slli_epi32(d, SFMT_SL1);
z = _mm_xor_si128(z, a);
z = _mm_xor_si128(z, v);
x = _mm_slli_si128(a, SFMT_SL2);
y = _mm_and_si128(y, sse2_param_mask.si);
z = _mm_xor_si128(z, x);
return _mm_xor_si128(z, y);
}
/**
* This function fills the internal state array with pseudorandom
* integers.
* @param sfmt SFMT internal state
*/
void sfmt_gen_rand_all(sfmt_t * sfmt) {
int i;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
pstate[i].si = mm_recursion(pstate[i].si,
pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
for (; i < SFMT_N; i++) {
pstate[i].si = mm_recursion(pstate[i].si,
pstate[i + SFMT_POS1 - SFMT_N].si,
r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
* @param sfmt SFMT internal state.
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pseudorandom numbers to be generated.
*/
static void gen_rand_array(sfmt_t * sfmt, w128_t * array, int size)
{
int i, j;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
array[i].si = mm_recursion(pstate[i].si,
pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < SFMT_N; i++) {
array[i].si = mm_recursion(pstate[i].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < size - SFMT_N; i++) {
array[i].si = mm_recursion(array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (j = 0; j < 2 * SFMT_N - size; j++) {
pstate[j] = array[j + size - SFMT_N];
}
for (; i < size; i++, j++) {
array[i].si = mm_recursion(array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
pstate[j] = array[i];
}
}
#elif defined(SFMT_USE_MACRO_FUNCTION_FOR_MSC)
/**
* This function represents the recursion formula.
* @param r an output
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
*/
#define mm_recursion(r, a, b, c, d) \
do { \
__m128i v, x, y, z; \
\
y = _mm_srli_epi32((b), SFMT_SR1); \
z = _mm_srli_si128((c), SFMT_SR2); \
v = _mm_slli_epi32((d), SFMT_SL1); \
z = _mm_xor_si128(z, (a)); \
z = _mm_xor_si128(z, v); \
x = _mm_slli_si128((a), SFMT_SL2); \
y = _mm_and_si128(y, sse2_param_mask.si); \
z = _mm_xor_si128(z, x); \
r = _mm_xor_si128(z, y); \
} while (0)
/**
* This function fills the internal state array with pseudorandom
* integers.
* @param sfmt SFMT internal state
*/
void sfmt_gen_rand_all(sfmt_t * sfmt) {
int i;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
mm_recursion(pstate[i].si, pstate[i].si,
pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
for (; i < SFMT_N; i++) {
mm_recursion(pstate[i].si, pstate[i].si,
pstate[i + SFMT_POS1 - SFMT_N].si,
r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
* @param sfmt SFMT internal state.
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pseudorandom numbers to be generated.
*/
static void gen_rand_array(sfmt_t * sfmt, w128_t * array, int size)
{
int i, j;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
mm_recursion(array[i].si, pstate[i].si,
pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < SFMT_N; i++) {
mm_recursion(array[i].si, pstate[i].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < size - SFMT_N; i++) {
mm_recursion(array[i].si, array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (j = 0; j < 2 * SFMT_N - size; j++) {
pstate[j] = array[j + size - SFMT_N];
}
for (; i < size; i++, j++) {
mm_recursion(array[i].si, array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
pstate[j] = array[i];
}
}
#else
inline static void mm_recursion(__m128i * r, __m128i a, __m128i b,
__m128i c, __m128i * d);
/**
* This function represents the recursion formula.
* @param r an output
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
*/
inline static void mm_recursion(__m128i * r, __m128i a, __m128i b,
__m128i c, __m128i * d)
{
__m128i v, x, y, z;
y = _mm_srli_epi32(b, SFMT_SR1);
z = _mm_srli_si128(c, SFMT_SR2);
v = _mm_slli_epi32(*d, SFMT_SL1);
z = _mm_xor_si128(z, a);
z = _mm_xor_si128(z, v);
x = _mm_slli_si128(a, SFMT_SL2);
y = _mm_and_si128(y, sse2_param_mask.si);
z = _mm_xor_si128(z, x);
z = _mm_xor_si128(z, y);
*r = z;
}
/**
* This function fills the internal state array with pseudorandom
* integers.
* @param sfmt SFMT internal state
*/
void sfmt_gen_rand_all(sfmt_t * sfmt) {
int i;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
mm_recursion(&pstate[i].si, pstate[i].si,
pstate[i + SFMT_POS1].si, r1, &r2);
r1 = r2;
r2 = pstate[i].si;
}
for (; i < SFMT_N; i++) {
mm_recursion(&pstate[i].si, pstate[i].si,
pstate[i + SFMT_POS1 - SFMT_N].si,
r1, &r2);
r1 = r2;
r2 = pstate[i].si;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
* @param sfmt SFMT internal state.
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pseudorandom numbers to be generated.
*/
static void gen_rand_array(sfmt_t * sfmt, w128_t * array, int size)
{
int i, j;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
mm_recursion(&array[i].si, pstate[i].si,
pstate[i + SFMT_POS1].si, r1, &r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < SFMT_N; i++) {
mm_recursion(&array[i].si, pstate[i].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, &r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < size - SFMT_N; i++) {
mm_recursion(&array[i].si, array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, &r2);
r1 = r2;
r2 = array[i].si;
}
for (j = 0; j < 2 * SFMT_N - size; j++) {
pstate[j] = array[j + size - SFMT_N];
}
for (; i < size; i++, j++) {
mm_recursion(&array[i].si, array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, &r2);
r1 = r2;
r2 = array[i].si;
pstate[j] = array[i];
}
}
#endif
#endif

121
deps/SFMT/SFMT-sse2.h vendored Normal file
View File

@@ -0,0 +1,121 @@
#pragma once
/**
* @file SFMT-sse2.h
* @brief SIMD oriented Fast Mersenne Twister(SFMT) for Intel SSE2
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* @note We assume LITTLE ENDIAN in this file
*
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University. All rights reserved.
*
* The new BSD License is applied to this software, see LICENSE.txt
*/
#ifndef SFMT_SSE2_H
#define SFMT_SSE2_H
inline static void mm_recursion(__m128i * r, __m128i a, __m128i b,
__m128i c, __m128i d);
/**
* This function represents the recursion formula.
* @param r an output
* @param a a 128-bit part of the interal state array
* @param b a 128-bit part of the interal state array
* @param c a 128-bit part of the interal state array
* @param d a 128-bit part of the interal state array
*/
inline static void mm_recursion(__m128i * r, __m128i a, __m128i b,
__m128i c, __m128i d)
{
__m128i v, x, y, z;
y = _mm_srli_epi32(b, SFMT_SR1);
z = _mm_srli_si128(c, SFMT_SR2);
v = _mm_slli_epi32(d, SFMT_SL1);
z = _mm_xor_si128(z, a);
z = _mm_xor_si128(z, v);
x = _mm_slli_si128(a, SFMT_SL2);
y = _mm_and_si128(y, sse2_param_mask.si);
z = _mm_xor_si128(z, x);
z = _mm_xor_si128(z, y);
*r = z;
}
/**
* This function fills the internal state array with pseudorandom
* integers.
* @param sfmt SFMT internal state
*/
void sfmt_gen_rand_all(sfmt_t * sfmt) {
int i;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
mm_recursion(&pstate[i].si, pstate[i].si,
pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
for (; i < SFMT_N; i++) {
mm_recursion(&pstate[i].si, pstate[i].si,
pstate[i + SFMT_POS1 - SFMT_N].si,
r1, r2);
r1 = r2;
r2 = pstate[i].si;
}
}
/**
* This function fills the user-specified array with pseudorandom
* integers.
* @param sfmt SFMT internal state.
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pseudorandom numbers to be generated.
*/
static void gen_rand_array(sfmt_t * sfmt, w128_t * array, int size)
{
int i, j;
__m128i r1, r2;
w128_t * pstate = sfmt->state;
r1 = pstate[SFMT_N - 2].si;
r2 = pstate[SFMT_N - 1].si;
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
mm_recursion(&array[i].si, pstate[i].si,
pstate[i + SFMT_POS1].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < SFMT_N; i++) {
mm_recursion(&array[i].si, pstate[i].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (; i < size - SFMT_N; i++) {
mm_recursion(&array[i].si, array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
}
for (j = 0; j < 2 * SFMT_N - size; j++) {
pstate[j] = array[j + size - SFMT_N];
}
for (; i < size; i++, j++) {
mm_recursion(&array[i].si, array[i - SFMT_N].si,
array[i + SFMT_POS1 - SFMT_N].si, r1, r2);
r1 = r2;
r2 = array[i].si;
pstate[j] = array[i];
}
}
#endif

437
deps/SFMT/SFMT.c vendored Normal file
View File

@@ -0,0 +1,437 @@
/**
* @file SFMT.c
* @brief SIMD oriented Fast Mersenne Twister(SFMT)
*
* @author Mutsuo Saito (Hiroshima University)
* @author Makoto Matsumoto (Hiroshima University)
*
* Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University.
* Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima
* University and The University of Tokyo.
* Copyright (C) 2013 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* University.
* All rights reserved.
*
* The 3-clause BSD License is applied to this software, see
* LICENSE.txt
*/
#if defined(__cplusplus)
extern "C" {
#endif
#include <string.h>
#include <assert.h>
#include "SFMT.h"
#include "SFMT-params.h"
#include "SFMT-common.h"
#if defined(__BIG_ENDIAN__) && !defined(__amd64) && !defined(BIG_ENDIAN64)
#define BIG_ENDIAN64 1
#endif
#if defined(HAVE_ALTIVEC) && !defined(BIG_ENDIAN64)
#define BIG_ENDIAN64 1
#endif
#if defined(ONLY64) && !defined(BIG_ENDIAN64)
#if defined(__GNUC__)
#error "-DONLY64 must be specified with -DBIG_ENDIAN64"
#endif
#undef ONLY64
#endif
/*----------------
STATIC FUNCTIONS
----------------*/
inline static int idxof(int i);
inline static void gen_rand_array(sfmt_t * sfmt, w128_t *array, int size);
inline static uint32_t func1(uint32_t x);
inline static uint32_t func2(uint32_t x);
static void period_certification(sfmt_t * sfmt);
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
inline static void swap(w128_t *array, int size);
#endif
#if defined(HAVE_ALTIVEC)
#include "SFMT-alti.h"
#elif defined(HAVE_SSE2)
/**
* parameters used by sse2.
*/
static const w128_t sse2_param_mask = {{SFMT_MSK1, SFMT_MSK2,
SFMT_MSK3, SFMT_MSK4}};
#if defined(_MSC_VER)
#include "SFMT-sse2-msc.h"
#else
#include "SFMT-sse2.h"
#endif
#elif defined(HAVE_NEON)
#include "SFMT-neon.h"
#endif
/**
* This function simulate a 64-bit index of LITTLE ENDIAN
* in BIG ENDIAN machine.
*/
#ifdef ONLY64
inline static int idxof(int i) {
return i ^ 1;
}
#else
inline static int idxof(int i) {
return i;
}
#endif
#if (!defined(HAVE_ALTIVEC)) && (!defined(HAVE_SSE2)) && (!defined(HAVE_NEON))
/**
* This function fills the user-specified array with pseudorandom
* integers.
*
* @param sfmt SFMT internal state
* @param array an 128-bit array to be filled by pseudorandom numbers.
* @param size number of 128-bit pseudorandom numbers to be generated.
*/
inline static void gen_rand_array(sfmt_t * sfmt, w128_t *array, int size) {
int i, j;
w128_t *r1, *r2;
r1 = &sfmt->state[SFMT_N - 2];
r2 = &sfmt->state[SFMT_N - 1];
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
do_recursion(&array[i], &sfmt->state[i], &sfmt->state[i + SFMT_POS1], r1, r2);
r1 = r2;
r2 = &array[i];
}
for (; i < SFMT_N; i++) {
do_recursion(&array[i], &sfmt->state[i],
&array[i + SFMT_POS1 - SFMT_N], r1, r2);
r1 = r2;
r2 = &array[i];
}
for (; i < size - SFMT_N; i++) {
do_recursion(&array[i], &array[i - SFMT_N],
&array[i + SFMT_POS1 - SFMT_N], r1, r2);
r1 = r2;
r2 = &array[i];
}
for (j = 0; j < 2 * SFMT_N - size; j++) {
sfmt->state[j] = array[j + size - SFMT_N];
}
for (; i < size; i++, j++) {
do_recursion(&array[i], &array[i - SFMT_N],
&array[i + SFMT_POS1 - SFMT_N], r1, r2);
r1 = r2;
r2 = &array[i];
sfmt->state[j] = array[i];
}
}
#endif
#if defined(BIG_ENDIAN64) && !defined(ONLY64) && !defined(HAVE_ALTIVEC)
inline static void swap(w128_t *array, int size) {
int i;
uint32_t x, y;
for (i = 0; i < size; i++) {
x = array[i].u[0];
y = array[i].u[2];
array[i].u[0] = array[i].u[1];
array[i].u[2] = array[i].u[3];
array[i].u[1] = x;
array[i].u[3] = y;
}
}
#endif
/**
* This function represents a function used in the initialization
* by init_by_array
* @param x 32-bit integer
* @return 32-bit integer
*/
static uint32_t func1(uint32_t x) {
return (x ^ (x >> 27)) * (uint32_t)1664525UL;
}
/**
* This function represents a function used in the initialization
* by init_by_array
* @param x 32-bit integer
* @return 32-bit integer
*/
static uint32_t func2(uint32_t x) {
return (x ^ (x >> 27)) * (uint32_t)1566083941UL;
}
/**
* This function certificate the period of 2^{MEXP}
* @param sfmt SFMT internal state
*/
static void period_certification(sfmt_t * sfmt) {
uint32_t inner = 0;
int i, j;
uint32_t work;
uint32_t *psfmt32 = &sfmt->state[0].u[0];
const uint32_t parity[4] = {SFMT_PARITY1, SFMT_PARITY2,
SFMT_PARITY3, SFMT_PARITY4};
for (i = 0; i < 4; i++) {
inner ^= psfmt32[idxof(i)] & parity[i];
}
for (i = 16; i > 0; i >>= 1) {
inner ^= inner >> i;
}
inner &= 1;
/* check OK */
if (inner == 1) {
return;
}
/* check NG, and modification */
for (i = 0; i < 4; i++) {
work = 1;
for (j = 0; j < 32; j++) {
if ((work & parity[i]) != 0) {
psfmt32[idxof(i)] ^= work;
return;
}
work = work << 1;
}
}
}
/*----------------
PUBLIC FUNCTIONS
----------------*/
#define UNUSED_VARIABLE(x) (void)(x)
/**
* This function returns the identification string.
* The string shows the word size, the Mersenne exponent,
* and all parameters of this generator.
* @param sfmt SFMT internal state
*/
const char *sfmt_get_idstring(sfmt_t * sfmt) {
UNUSED_VARIABLE(sfmt);
return SFMT_IDSTR;
}
/**
* This function returns the minimum size of array used for \b
* fill_array32() function.
* @param sfmt SFMT internal state
* @return minimum size of array used for fill_array32() function.
*/
int sfmt_get_min_array_size32(sfmt_t * sfmt) {
UNUSED_VARIABLE(sfmt);
return SFMT_N32;
}
/**
* This function returns the minimum size of array used for \b
* fill_array64() function.
* @param sfmt SFMT internal state
* @return minimum size of array used for fill_array64() function.
*/
int sfmt_get_min_array_size64(sfmt_t * sfmt) {
UNUSED_VARIABLE(sfmt);
return SFMT_N64;
}
#if !defined(HAVE_SSE2) && !defined(HAVE_ALTIVEC) && !defined(HAVE_NEON)
/**
* This function fills the internal state array with pseudorandom
* integers.
* @param sfmt SFMT internal state
*/
void sfmt_gen_rand_all(sfmt_t * sfmt) {
int i;
w128_t *r1, *r2;
r1 = &sfmt->state[SFMT_N - 2];
r2 = &sfmt->state[SFMT_N - 1];
for (i = 0; i < SFMT_N - SFMT_POS1; i++) {
do_recursion(&sfmt->state[i], &sfmt->state[i],
&sfmt->state[i + SFMT_POS1], r1, r2);
r1 = r2;
r2 = &sfmt->state[i];
}
for (; i < SFMT_N; i++) {
do_recursion(&sfmt->state[i], &sfmt->state[i],
&sfmt->state[i + SFMT_POS1 - SFMT_N], r1, r2);
r1 = r2;
r2 = &sfmt->state[i];
}
}
#endif
#ifndef ONLY64
/**
* This function generates pseudorandom 32-bit integers in the
* specified array[] by one call. The number of pseudorandom integers
* is specified by the argument size, which must be at least 624 and a
* multiple of four. The generation by this function is much faster
* than the following gen_rand function.
*
* For initialization, init_gen_rand or init_by_array must be called
* before the first call of this function. This function can not be
* used after calling gen_rand function, without initialization.
*
* @param sfmt SFMT internal state
* @param array an array where pseudorandom 32-bit integers are filled
* by this function. The pointer to the array must be \b "aligned"
* (namely, must be a multiple of 16) in the SIMD version, since it
* refers to the address of a 128-bit integer. In the standard C
* version, the pointer is arbitrary.
*
* @param size the number of 32-bit pseudorandom integers to be
* generated. size must be a multiple of 4, and greater than or equal
* to (MEXP / 128 + 1) * 4.
*
* @note \b memalign or \b posix_memalign is available to get aligned
* memory. Mac OSX doesn't have these functions, but \b malloc of OSX
* returns the pointer to the aligned memory block.
*/
void sfmt_fill_array32(sfmt_t * sfmt, uint32_t *array, int size) {
assert(sfmt->idx == SFMT_N32);
assert(size % 4 == 0);
assert(size >= SFMT_N32);
gen_rand_array(sfmt, (w128_t *)array, size / 4);
sfmt->idx = SFMT_N32;
}
#endif
/**
* This function generates pseudorandom 64-bit integers in the
* specified array[] by one call. The number of pseudorandom integers
* is specified by the argument size, which must be at least 312 and a
* multiple of two. The generation by this function is much faster
* than the following gen_rand function.
*
* @param sfmt SFMT internal state
* For initialization, init_gen_rand or init_by_array must be called
* before the first call of this function. This function can not be
* used after calling gen_rand function, without initialization.
*
* @param array an array where pseudorandom 64-bit integers are filled
* by this function. The pointer to the array must be "aligned"
* (namely, must be a multiple of 16) in the SIMD version, since it
* refers to the address of a 128-bit integer. In the standard C
* version, the pointer is arbitrary.
*
* @param size the number of 64-bit pseudorandom integers to be
* generated. size must be a multiple of 2, and greater than or equal
* to (MEXP / 128 + 1) * 2
*
* @note \b memalign or \b posix_memalign is available to get aligned
* memory. Mac OSX doesn't have these functions, but \b malloc of OSX
* returns the pointer to the aligned memory block.
*/
void sfmt_fill_array64(sfmt_t * sfmt, uint64_t *array, int size) {
assert(sfmt->idx == SFMT_N32);
assert(size % 2 == 0);
assert(size >= SFMT_N64);
gen_rand_array(sfmt, (w128_t *)array, size / 2);
sfmt->idx = SFMT_N32;
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
swap((w128_t *)array, size /2);
#endif
}
/**
* This function initializes the internal state array with a 32-bit
* integer seed.
*
* @param sfmt SFMT internal state
* @param seed a 32-bit integer used as the seed.
*/
void sfmt_init_gen_rand(sfmt_t * sfmt, uint32_t seed) {
int i;
uint32_t *psfmt32 = &sfmt->state[0].u[0];
psfmt32[idxof(0)] = seed;
for (i = 1; i < SFMT_N32; i++) {
psfmt32[idxof(i)] = 1812433253UL * (psfmt32[idxof(i - 1)]
^ (psfmt32[idxof(i - 1)] >> 30))
+ i;
}
sfmt->idx = SFMT_N32;
period_certification(sfmt);
}
/**
* This function initializes the internal state array,
* with an array of 32-bit integers used as the seeds
* @param sfmt SFMT internal state
* @param init_key the array of 32-bit integers, used as a seed.
* @param key_length the length of init_key.
*/
void sfmt_init_by_array(sfmt_t * sfmt, uint32_t *init_key, int key_length) {
int i, j, count;
uint32_t r;
int lag;
int mid;
int size = SFMT_N * 4;
uint32_t *psfmt32 = &sfmt->state[0].u[0];
if (size >= 623) {
lag = 11;
} else if (size >= 68) {
lag = 7;
} else if (size >= 39) {
lag = 5;
} else {
lag = 3;
}
mid = (size - lag) / 2;
memset(sfmt, 0x8b, sizeof(sfmt_t));
if (key_length + 1 > SFMT_N32) {
count = key_length + 1;
} else {
count = SFMT_N32;
}
r = func1(psfmt32[idxof(0)] ^ psfmt32[idxof(mid)]
^ psfmt32[idxof(SFMT_N32 - 1)]);
psfmt32[idxof(mid)] += r;
r += key_length;
psfmt32[idxof(mid + lag)] += r;
psfmt32[idxof(0)] = r;
count--;
for (i = 1, j = 0; (j < count) && (j < key_length); j++) {
r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % SFMT_N32)]
^ psfmt32[idxof((i + SFMT_N32 - 1) % SFMT_N32)]);
psfmt32[idxof((i + mid) % SFMT_N32)] += r;
r += init_key[j] + i;
psfmt32[idxof((i + mid + lag) % SFMT_N32)] += r;
psfmt32[idxof(i)] = r;
i = (i + 1) % SFMT_N32;
}
for (; j < count; j++) {
r = func1(psfmt32[idxof(i)] ^ psfmt32[idxof((i + mid) % SFMT_N32)]
^ psfmt32[idxof((i + SFMT_N32 - 1) % SFMT_N32)]);
psfmt32[idxof((i + mid) % SFMT_N32)] += r;
r += i;
psfmt32[idxof((i + mid + lag) % SFMT_N32)] += r;
psfmt32[idxof(i)] = r;
i = (i + 1) % SFMT_N32;
}
for (j = 0; j < SFMT_N32; j++) {
r = func2(psfmt32[idxof(i)] + psfmt32[idxof((i + mid) % SFMT_N32)]
+ psfmt32[idxof((i + SFMT_N32 - 1) % SFMT_N32)]);
psfmt32[idxof((i + mid) % SFMT_N32)] ^= r;
r -= i;
psfmt32[idxof((i + mid + lag) % SFMT_N32)] ^= r;
psfmt32[idxof(i)] = r;
i = (i + 1) % SFMT_N32;
}
sfmt->idx = SFMT_N32;
period_certification(sfmt);
}
#if defined(__cplusplus)
}
#endif

644
deps/SFMT/SFMT.h vendored
View File

@@ -1,358 +1,304 @@
/* #pragma once
* Copyright notice /**
* ================ * @file SFMT.h
* GNU General Public License http://www.gnu.org/licenses/gpl.html
* This C++ implementation of SFMT contains parts of the original C code
* which was published under the following BSD license, which is therefore
* in effect in addition to the GNU General Public License.
* Copyright (c) 2006, 2007 by Mutsuo Saito, Makoto Matsumoto and Hiroshima University.
* Copyright (c) 2008 by Agner Fog.
* Copyright (c) 2008-2013 Trinity Core
* *
* BSD License: * @brief SIMD oriented Fast Mersenne Twister(SFMT) pseudorandom
* Redistribution and use in source and binary forms, with or without * number generator using C structure.
* modification, are permitted provided that the following conditions are met: *
* > Redistributions of source code must retain the above copyright notice, * @author Mutsuo Saito (Hiroshima University)
* this list of conditions and the following disclaimer. * @author Makoto Matsumoto (The University of Tokyo)
* > Redistributions in binary form must reproduce the above copyright notice, *
* this list of conditions and the following disclaimer in the documentation * Copyright (C) 2006, 2007 Mutsuo Saito, Makoto Matsumoto and Hiroshima
* and/or other materials provided with the distribution. * University.
* > Neither the name of the Hiroshima University nor the names of its * Copyright (C) 2012 Mutsuo Saito, Makoto Matsumoto, Hiroshima
* contributors may be used to endorse or promote products derived from * University and The University of Tokyo.
* this software without specific prior written permission. * All rights reserved.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * The 3-clause BSD License is applied to this software, see
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * LICENSE.txt
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT *
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * @note We assume that your system has inttypes.h. If your system
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * doesn't have inttypes.h, you have to typedef uint32_t and uint64_t,
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * and you have to define PRIu64 and PRIx64 in this file as follows:
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * @verbatim
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT typedef unsigned int uint32_t
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE typedef unsigned long long uint64_t
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #define PRIu64 "llu"
#define PRIx64 "llx"
@endverbatim
* uint32_t must be exactly 32-bit unsigned integer type (no more, no
* less), and uint64_t must be exactly 64-bit unsigned integer type.
* PRIu64 and PRIx64 are used for printf function to print 64-bit
* unsigned int and 64-bit unsigned int in hexadecimal format.
*/ */
#ifndef SFMT_H #ifndef SFMTST_H
#define SFMT_H #define SFMTST_H
#if defined(__cplusplus)
#include <emmintrin.h> // Define SSE2 intrinsics extern "C" {
#include "randomc.h" // Define integer types etc
#include <time.h>
#include <new>
// Choose one of the possible Mersenne exponents.
// Higher values give longer cycle length and use more memory:
//#define MEXP 607
//#define MEXP 1279
//#define MEXP 2281
//#define MEXP 4253
#define MEXP 11213
//#define MEXP 19937
//#define MEXP 44497
// Define constants for the selected Mersenne exponent:
#if MEXP == 44497
#define SFMT_N 348 // Size of state vector
#define SFMT_M 330 // Position of intermediate feedback
#define SFMT_SL1 5 // Left shift of W[N-1], 32-bit words
#define SFMT_SL2 3 // Left shift of W[0], *8, 128-bit words
#define SFMT_SR1 9 // Right shift of W[M], 32-bit words
#define SFMT_SR2 3 // Right shift of W[N-2], *8, 128-bit words
#define SFMT_MASK 0xeffffffb,0xdfbebfff,0xbfbf7bef,0x9ffd7bff // AND mask
#define SFMT_PARITY 1,0,0xa3ac4000,0xecc1327a // Period certification vector
#elif MEXP == 19937
#define SFMT_N 156 // Size of state vector
#define SFMT_M 122 // Position of intermediate feedback
#define SFMT_SL1 18 // Left shift of W[N-1], 32-bit words
#define SFMT_SL2 1 // Left shift of W[0], *8, 128-bit words
#define SFMT_SR1 11 // Right shift of W[M], 32-bit words
#define SFMT_SR2 1 // Right shift of W[N-2], *8, 128-bit words
#define SFMT_MASK 0xdfffffef,0xddfecb7f,0xbffaffff,0xbffffff6 // AND mask
#define SFMT_PARITY 1,0,0,0x13c9e684 // Period certification vector
#elif MEXP == 11213
#define SFMT_N 88 // Size of state vector
#define SFMT_M 68 // Position of intermediate feedback
#define SFMT_SL1 14 // Left shift of W[N-1], 32-bit words
#define SFMT_SL2 3 // Left shift of W[0], *8, 128-bit words
#define SFMT_SR1 7 // Right shift of W[M], 32-bit words
#define SFMT_SR2 3 // Right shift of W[N-2], *8, 128-bit words
#define SFMT_MASK 0xeffff7fb,0xffffffef,0xdfdfbfff,0x7fffdbfd // AND mask
#define SFMT_PARITY 1,0,0xe8148000,0xd0c7afa3 // Period certification vector
#elif MEXP == 4253
#define SFMT_N 34 // Size of state vector
#define SFMT_M 17 // Position of intermediate feedback
#define SFMT_SL1 20 // Left shift of W[N-1], 32-bit words
#define SFMT_SL2 1 // Left shift of W[0], *8, 128-bit words
#define SFMT_SR1 7 // Right shift of W[M], 32-bit words
#define SFMT_SR2 1 // Right shift of W[N-2], *8, 128-bit words
#define SFMT_MASK 0x9f7bffff, 0x9fffff5f, 0x3efffffb, 0xfffff7bb // AND mask
#define SFMT_PARITY 0xa8000001, 0xaf5390a3, 0xb740b3f8, 0x6c11486d // Period certification vector
#elif MEXP == 2281
#define SFMT_N 18 // Size of state vector
#define SFMT_M 12 // Position of intermediate feedback
#define SFMT_SL1 19 // Left shift of W[N-1], 32-bit words
#define SFMT_SL2 1 // Left shift of W[0], *8, 128-bit words
#define SFMT_SR1 5 // Right shift of W[M], 32-bit words
#define SFMT_SR2 1 // Right shift of W[N-2], *8, 128-bit words
#define SFMT_MASK 0xbff7ffbf, 0xfdfffffe, 0xf7ffef7f, 0xf2f7cbbf // AND mask
#define SFMT_PARITY 0x00000001, 0x00000000, 0x00000000, 0x41dfa600 // Period certification vector
#elif MEXP == 1279
#define SFMT_N 10 // Size of state vector
#define SFMT_M 7 // Position of intermediate feedback
#define SFMT_SL1 14 // Left shift of W[N-1], 32-bit words
#define SFMT_SL2 3 // Left shift of W[0], *8, 128-bit words
#define SFMT_SR1 5 // Right shift of W[M], 32-bit words
#define SFMT_SR2 1 // Right shift of W[N-2], *8, 128-bit words
#define SFMT_MASK 0xf7fefffd, 0x7fefcfff, 0xaff3ef3f, 0xb5ffff7f // AND mask
#define SFMT_PARITY 0x00000001, 0x00000000, 0x00000000, 0x20000000 // Period certification vector
#elif MEXP == 607
#define SFMT_N 5 // Size of state vector
#define SFMT_M 2 // Position of intermediate feedback
#define SFMT_SL1 15 // Left shift of W[N-1], 32-bit words
#define SFMT_SL2 3 // Left shift of W[0], *8, 128-bit words
#define SFMT_SR1 13 // Right shift of W[M], 32-bit words
#define SFMT_SR2 3 // Right shift of W[N-2], *8, 128-bit words
#define SFMT_MASK 0xfdff37ff, 0xef7f3f7d, 0xff777b7d, 0x7ff7fb2f // AND mask
#define SFMT_PARITY 0x00000001, 0x00000000, 0x00000000, 0x5986f054 // Period certification vector
#endif #endif
// Functions used by SFMTRand::RandomInitByArray (UNUSED AND COMMENTED OUT) #include <stdio.h>
/* #include <assert.h>
static uint32_t func1(uint32_t x) {
return (x ^ (x >> 27)) * 1664525U;
}
static uint32_t func2(uint32_t x) { #if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
return (x ^ (x >> 27)) * 1566083941U; #include <inttypes.h>
} #elif defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned int uint32_t;
typedef unsigned __int64 uint64_t;
#define inline __inline
#else
#include <inttypes.h>
#if defined(__GNUC__)
#define inline __inline__
#endif
#endif
#ifndef PRIu64
#if defined(_MSC_VER) || defined(__BORLANDC__)
#define PRIu64 "I64u"
#define PRIx64 "I64x"
#else
#define PRIu64 "llu"
#define PRIx64 "llx"
#endif
#endif
#include "SFMT-params.h"
/*------------------------------------------
128-bit SIMD like data type for standard C
------------------------------------------*/
#if defined(HAVE_ALTIVEC)
#if !defined(__APPLE__)
#include <altivec.h>
#endif
/** 128-bit data structure */
union W128_T {
vector unsigned int s;
uint32_t u[4];
uint64_t u64[2];
};
#elif defined(HAVE_NEON)
#include <arm_neon.h>
/** 128-bit data structure */
union W128_T {
uint32_t u[4];
uint64_t u64[2];
uint32x4_t si;
};
#elif defined(HAVE_SSE2)
#include <emmintrin.h>
/** 128-bit data structure */
union W128_T {
uint32_t u[4];
uint64_t u64[2];
__m128i si;
};
#else
/** 128-bit data structure */
union W128_T {
uint32_t u[4];
uint64_t u64[2];
};
#endif
/** 128-bit data type */
typedef union W128_T w128_t;
/**
* SFMT internal state
*/ */
struct SFMT_T {
// Subfunction for the sfmt algorithm /** the 128-bit internal state array */
static inline __m128i sfmt_recursion(__m128i const &a, __m128i const &b, w128_t state[SFMT_N];
__m128i const &c, __m128i const &d, __m128i const &mask) { /** index counter to the 32-bit internal state array */
__m128i a1, b1, c1, d1, z1, z2; int idx;
b1 = _mm_srli_epi32(b, SFMT_SR1);
a1 = _mm_slli_si128(a, SFMT_SL2);
c1 = _mm_srli_si128(c, SFMT_SR2);
d1 = _mm_slli_epi32(d, SFMT_SL1);
b1 = _mm_and_si128(b1, mask);
z1 = _mm_xor_si128(a, a1);
z2 = _mm_xor_si128(b1, d1);
z1 = _mm_xor_si128(z1, c1);
z2 = _mm_xor_si128(z1, z2);
return z2;
}
// Class for SFMT generator
class SFMTRand { // Encapsulate random number generator
friend class ACE_TSS<SFMTRand>;
public:
SFMTRand()
{
LastInterval = 0;
RandomInit((int)(time(0)));
}
void RandomInit(int seed) // Re-seed
{
// Re-seed
uint32_t i; // Loop counter
uint32_t y = seed; // Temporary
uint32_t statesize = SFMT_N*4; // Size of state vector
// Fill state vector with random numbers from seed
uint32_t* s = (uint32_t*)&state;
s[0] = y;
const uint32_t factor = 1812433253U;// Multiplication factor
for (i = 1; i < statesize; i++) {
y = factor * (y ^ (y >> 30)) + i;
((uint32_t*)state)[i] = y;
}
// Further initialization and period certification
Init2();
}
int32_t IRandom(int32_t min, int32_t max) // Output random integer
{
// Output random integer in the interval min <= x <= max
// Slightly inaccurate if (max-min+1) is not a power of 2
if (max <= min) {
if (max == min) return min; else return 0x80000000;
}
// Assume 64 bit integers supported. Use multiply and shift method
uint32_t interval; // Length of interval
uint64_t longran; // Random bits * interval
uint32_t iran; // Longran / 2^32
interval = (uint32_t)(max - min + 1);
longran = (uint64_t)BRandom() * interval;
iran = (uint32_t)(longran >> 32);
// Convert back to signed and return result
return (int32_t)iran + min;
}
uint32_t URandom(uint32_t min, uint32_t max)
{
// Output random integer in the interval min <= x <= max
// Slightly inaccurate if (max-min+1) is not a power of 2
if (max <= min) {
if (max == min) return min; else return 0;
}
// Assume 64 bit integers supported. Use multiply and shift method
uint32_t interval; // Length of interval
uint64_t longran; // Random bits * interval
uint32_t iran; // Longran / 2^32
interval = (uint32_t)(max - min + 1);
longran = (uint64_t)BRandom() * interval;
iran = (uint32_t)(longran >> 32);
// Convert back to signed and return result
return iran + min;
}
double Random() // Output random floating point number
{
// Output random floating point number
if (ix >= SFMT_N*4-1) {
// Make sure we have at least two 32-bit numbers
Generate();
}
uint64_t r = *(uint64_t*)((uint32_t*)state+ix);
ix += 2;
// 52 bits resolution for compatibility with assembly version:
return (int64_t)(r >> 12) * (1./(67108864.0*67108864.0));
}
uint32_t BRandom() // Output random bits
{
// Output 32 random bits
uint32_t y;
if (ix >= SFMT_N*4) {
Generate();
}
y = ((uint32_t*)state)[ix++];
return y;
}
private:
void Init2() // Various initializations and period certification
{
// Various initializations and period certification
uint32_t i, j, temp;
// Initialize mask
static const uint32_t maskinit[4] = {SFMT_MASK};
mask = _mm_loadu_si128((__m128i*)maskinit);
// Period certification
// Define period certification vector
static const uint32_t parityvec[4] = {SFMT_PARITY};
// Check if parityvec & state[0] has odd parity
temp = 0;
for (i = 0; i < 4; i++)
temp ^= parityvec[i] & ((uint32_t*)state)[i];
for (i = 16; i > 0; i >>= 1) temp ^= temp >> i;
if (!(temp & 1)) {
// parity is even. Certification failed
// Find a nonzero bit in period certification vector
for (i = 0; i < 4; i++) {
if (parityvec[i]) {
for (j = 1; j; j <<= 1) {
if (parityvec[i] & j) {
// Flip the corresponding bit in state[0] to change parity
((uint32_t*)state)[i] ^= j;
// Done. Exit i and j loops
i = 5; break;
}
}
}
}
}
// Generate first random numbers and set ix = 0
Generate();
}
void Generate() // Fill state array with new random numbers
{
// Fill state array with new random numbers
int i;
__m128i r, r1, r2;
r1 = state[SFMT_N - 2];
r2 = state[SFMT_N - 1];
for (i = 0; i < SFMT_N - SFMT_M; i++) {
r = sfmt_recursion(state[i], state[i + SFMT_M], r1, r2, mask);
state[i] = r;
r1 = r2;
r2 = r;
}
for (; i < SFMT_N; i++) {
r = sfmt_recursion(state[i], state[i + SFMT_M - SFMT_N], r1, r2, mask);
state[i] = r;
r1 = r2;
r2 = r;
}
ix = 0;
}
void* operator new(size_t size, std::nothrow_t const&)
{
return _mm_malloc(size, 16);
}
void operator delete(void* ptr, std::nothrow_t const&)
{
_mm_free(ptr);
}
void* operator new(size_t size)
{
return _mm_malloc(size, 16);
}
void operator delete(void* ptr)
{
_mm_free(ptr);
}
void* operator new[](size_t size, std::nothrow_t const&)
{
return _mm_malloc(size, 16);
}
void operator delete[](void* ptr, std::nothrow_t const&)
{
_mm_free(ptr);
}
void* operator new[](size_t size)
{
return _mm_malloc(size, 16);
}
void operator delete[](void* ptr)
{
_mm_free(ptr);
}
__m128i mask; // AND mask
__m128i state[SFMT_N]; // State vector for SFMT generator
uint32_t ix; // Index into state array
uint32_t LastInterval; // Last interval length for IRandom
uint32_t RLimit; // Rejection limit used by IRandom
}; };
#endif // SFMT_H typedef struct SFMT_T sfmt_t;
void sfmt_fill_array32(sfmt_t * sfmt, uint32_t * array, int size);
void sfmt_fill_array64(sfmt_t * sfmt, uint64_t * array, int size);
void sfmt_init_gen_rand(sfmt_t * sfmt, uint32_t seed);
void sfmt_init_by_array(sfmt_t * sfmt, uint32_t * init_key, int key_length);
const char * sfmt_get_idstring(sfmt_t * sfmt);
int sfmt_get_min_array_size32(sfmt_t * sfmt);
int sfmt_get_min_array_size64(sfmt_t * sfmt);
void sfmt_gen_rand_all(sfmt_t * sfmt);
#ifndef ONLY64
/**
* This function generates and returns 32-bit pseudorandom number.
* init_gen_rand or init_by_array must be called before this function.
* @param sfmt SFMT internal state
* @return 32-bit pseudorandom number
*/
inline static uint32_t sfmt_genrand_uint32(sfmt_t * sfmt) {
uint32_t r;
uint32_t * psfmt32 = &sfmt->state[0].u[0];
if (sfmt->idx >= SFMT_N32) {
sfmt_gen_rand_all(sfmt);
sfmt->idx = 0;
}
r = psfmt32[sfmt->idx++];
return r;
}
#endif
/**
* This function generates and returns 64-bit pseudorandom number.
* init_gen_rand or init_by_array must be called before this function.
* The function gen_rand64 should not be called after gen_rand32,
* unless an initialization is again executed.
* @param sfmt SFMT internal state
* @return 64-bit pseudorandom number
*/
inline static uint64_t sfmt_genrand_uint64(sfmt_t * sfmt) {
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
uint32_t * psfmt32 = &sfmt->state[0].u[0];
uint32_t r1, r2;
#else
uint64_t r;
#endif
uint64_t * psfmt64 = &sfmt->state[0].u64[0];
assert(sfmt->idx % 2 == 0);
if (sfmt->idx >= SFMT_N32) {
sfmt_gen_rand_all(sfmt);
sfmt->idx = 0;
}
#if defined(BIG_ENDIAN64) && !defined(ONLY64)
r1 = psfmt32[sfmt->idx];
r2 = psfmt32[sfmt->idx + 1];
sfmt->idx += 2;
return ((uint64_t)r2 << 32) | r1;
#else
r = psfmt64[sfmt->idx / 2];
sfmt->idx += 2;
return r;
#endif
}
/* =================================================
The following real versions are due to Isaku Wada
================================================= */
/**
* converts an unsigned 32-bit number to a double on [0,1]-real-interval.
* @param v 32-bit unsigned integer
* @return double on [0,1]-real-interval
*/
inline static double sfmt_to_real1(uint32_t v)
{
return v * (1.0/4294967295.0);
/* divided by 2^32-1 */
}
/**
* generates a random number on [0,1]-real-interval
* @param sfmt SFMT internal state
* @return double on [0,1]-real-interval
*/
inline static double sfmt_genrand_real1(sfmt_t * sfmt)
{
return sfmt_to_real1(sfmt_genrand_uint32(sfmt));
}
/**
* converts an unsigned 32-bit integer to a double on [0,1)-real-interval.
* @param v 32-bit unsigned integer
* @return double on [0,1)-real-interval
*/
inline static double sfmt_to_real2(uint32_t v)
{
return v * (1.0/4294967296.0);
/* divided by 2^32 */
}
/**
* generates a random number on [0,1)-real-interval
* @param sfmt SFMT internal state
* @return double on [0,1)-real-interval
*/
inline static double sfmt_genrand_real2(sfmt_t * sfmt)
{
return sfmt_to_real2(sfmt_genrand_uint32(sfmt));
}
/**
* converts an unsigned 32-bit integer to a double on (0,1)-real-interval.
* @param v 32-bit unsigned integer
* @return double on (0,1)-real-interval
*/
inline static double sfmt_to_real3(uint32_t v)
{
return (((double)v) + 0.5)*(1.0/4294967296.0);
/* divided by 2^32 */
}
/**
* generates a random number on (0,1)-real-interval
* @param sfmt SFMT internal state
* @return double on (0,1)-real-interval
*/
inline static double sfmt_genrand_real3(sfmt_t * sfmt)
{
return sfmt_to_real3(sfmt_genrand_uint32(sfmt));
}
/**
* converts an unsigned 32-bit integer to double on [0,1)
* with 53-bit resolution.
* @param v 32-bit unsigned integer
* @return double on [0,1)-real-interval with 53-bit resolution.
*/
inline static double sfmt_to_res53(uint64_t v)
{
return (v >> 11) * (1.0/9007199254740992.0);
}
/**
* generates a random number on [0,1) with 53-bit resolution
* @param sfmt SFMT internal state
* @return double on [0,1) with 53-bit resolution
*/
inline static double sfmt_genrand_res53(sfmt_t * sfmt)
{
return sfmt_to_res53(sfmt_genrand_uint64(sfmt));
}
/* =================================================
The following function are added by Saito.
================================================= */
/**
* generates a random number on [0,1) with 53-bit resolution from two
* 32 bit integers
*/
inline static double sfmt_to_res53_mix(uint32_t x, uint32_t y)
{
return sfmt_to_res53(x | ((uint64_t)y << 32));
}
/**
* generates a random number on [0,1) with 53-bit resolution
* using two 32bit integers.
* @param sfmt SFMT internal state
* @return double on [0,1) with 53-bit resolution
*/
inline static double sfmt_genrand_res53_mix(sfmt_t * sfmt)
{
uint32_t x, y;
x = sfmt_genrand_uint32(sfmt);
y = sfmt_genrand_uint32(sfmt);
return sfmt_to_res53_mix(x, y);
}
#if defined(__cplusplus)
}
#endif
#endif

View File

@@ -1,193 +0,0 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*/
#ifndef ACORE_CONTAINERS_H
#define ACORE_CONTAINERS_H
#include "Define.h"
#include <algorithm>
#include <exception>
#include <iterator>
#include <utility>
#include <list>
#include <vector>
#include <type_traits>
//! Because circular includes are bad
extern uint32 urand(uint32 min, uint32 max);
extern uint32 urandweighted(size_t count, double const* chances);
namespace acore
{
template<class T>
constexpr inline T* AddressOrSelf(T* ptr)
{
return ptr;
}
template<class T>
constexpr inline T* AddressOrSelf(T& not_ptr)
{
return std::addressof(not_ptr);
}
template <class T>
class CheckedBufferOutputIterator
{
public:
using iterator_category = std::output_iterator_tag;
using value_type = void;
using pointer = T*;
using reference = T&;
using difference_type = std::ptrdiff_t;
CheckedBufferOutputIterator(T* buf, size_t n) : _buf(buf), _end(buf + n) {}
T& operator*() const { check(); return *_buf; }
CheckedBufferOutputIterator& operator++() { check(); ++_buf; return *this; }
CheckedBufferOutputIterator operator++(int) { CheckedBufferOutputIterator v = *this; operator++(); return v; }
[[nodiscard]] size_t remaining() const { return (_end - _buf); }
private:
T* _buf;
T* _end;
void check() const
{
if (!(_buf < _end))
throw std::out_of_range("index");
}
};
namespace Containers
{
// replace with std::size in C++17
template<class C>
constexpr inline std::size_t Size(C const& container)
{
return container.size();
}
template<class T, std::size_t size>
constexpr inline std::size_t Size(T const(&)[size]) noexcept
{
return size;
}
// resizes <container> to have at most <requestedSize> elements
// if it has more than <requestedSize> elements, the elements to keep are selected randomly
template<class C>
void RandomResize(C& container, std::size_t requestedSize)
{
static_assert(std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<typename C::iterator>::iterator_category>::value, "Invalid container passed to acore::Containers::RandomResize");
if (Size(container) <= requestedSize)
{
return;
}
auto keepIt = std::begin(container), curIt = std::begin(container);
uint32 elementsToKeep = requestedSize, elementsToProcess = Size(container);
while (elementsToProcess)
{
// this element has chance (elementsToKeep / elementsToProcess) of being kept
if (urand(1, elementsToProcess) <= elementsToKeep)
{
if (keepIt != curIt)
*keepIt = std::move(*curIt);
++keepIt;
--elementsToKeep;
}
++curIt;
--elementsToProcess;
}
container.erase(keepIt, std::end(container));
}
template<class C, class Predicate>
void RandomResize(C& container, Predicate&& predicate, std::size_t requestedSize)
{
//! First use predicate filter
C containerCopy;
std::copy_if(std::begin(container), std::end(container), std::inserter(containerCopy, std::end(containerCopy)), predicate);
if (requestedSize)
{
RandomResize(containerCopy, requestedSize);
}
container = std::move(containerCopy);
}
/* Select a random element from a container. Note: make sure you explicitly empty check the container */
template <class C> typename C::value_type const& SelectRandomContainerElement(C const& container)
{
typename C::const_iterator it = container.begin();
std::advance(it, urand(0, container.size() - 1));
return *it;
}
/* Select a random element from a container where each element has a different chance to be selected. */
template <class C> typename C::value_type const& SelectRandomWeightedContainerElement(C const& container, std::vector<double> const& weights)
{
typename C::const_iterator it = container.begin();
std::advance(it, urandweighted(weights.size(), weights.data()));
return *it;
}
template <typename Container, typename Predicate>
std::enable_if_t<std::is_move_assignable_v<decltype(*std::declval<Container>().begin())>, void> EraseIf(Container& c, Predicate p)
{
auto wpos = c.begin();
for (auto rpos = c.begin(), end = c.end(); rpos != end; ++rpos)
{
if (!p(*rpos))
{
if (rpos != wpos)
{
std::swap(*rpos, *wpos);
}
++wpos;
}
}
c.erase(wpos, c.end());
}
template <typename Container, typename Predicate>
std::enable_if_t<!std::is_move_assignable_v<decltype(*std::declval<Container>().begin())>, void> EraseIf(Container& c, Predicate p)
{
for (auto it = c.begin(); it != c.end();)
{
if (p(*it))
{
it = c.erase(it);
}
else
{
++it;
}
}
}
template<class K, class V, template<class, class, class...> class M, class... Rest>
void MultimapErasePair(M<K, V, Rest...>& multimap, K const& key, V const& value)
{
auto range = multimap.equal_range(key);
for (auto itr = range.first; itr != range.second;)
{
if (itr->second == value)
itr = multimap.erase(itr);
else
++itr;
}
}
}
//! namespace Containers
}
//! namespace acore
#endif //! #ifdef ACORE_CONTAINERS_H

View File

@@ -0,0 +1,229 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
* Copyright (C) 2008-2016 TrinityCore <http://www.trinitycore.org/>
* Copyright (C) 2005-2009 MaNGOS <http://getmangos.com/>
*/
#ifndef ACORE_CONTAINERS_H
#define ACORE_CONTAINERS_H
#include "Define.h"
#include "Random.h"
#include <algorithm>
#include <iterator>
#include <stdexcept>
#include <type_traits>
#include <utility>
#include <vector>
namespace acore
{
template<class T>
constexpr inline T* AddressOrSelf(T* ptr)
{
return ptr;
}
template<class T>
constexpr inline T* AddressOrSelf(T& not_ptr)
{
return std::addressof(not_ptr);
}
template <class T>
class CheckedBufferOutputIterator
{
public:
using iterator_category = std::output_iterator_tag;
using value_type = void;
using pointer = T*;
using reference = T&;
using difference_type = std::ptrdiff_t;
CheckedBufferOutputIterator(T* buf, size_t n) : _buf(buf), _end(buf + n) {}
T& operator*() const { check(); return *_buf; }
CheckedBufferOutputIterator& operator++() { check(); ++_buf; return *this; }
CheckedBufferOutputIterator operator++(int) { CheckedBufferOutputIterator v = *this; operator++(); return v; }
[[nodiscard]] size_t remaining() const { return (_end - _buf); }
private:
T* _buf;
T* _end;
void check() const
{
if (!(_buf < _end))
throw std::out_of_range("index");
}
};
}
namespace acore::Containers
{
// resizes <container> to have at most <requestedSize> elements
// if it has more than <requestedSize> elements, the elements to keep are selected randomly
template<class C>
void RandomResize(C& container, std::size_t requestedSize)
{
static_assert(std::is_base_of<std::forward_iterator_tag, typename std::iterator_traits<typename C::iterator>::iterator_category>::value, "Invalid container passed to acore::Containers::RandomResize");
if (std::size(container) <= requestedSize)
return;
auto keepIt = std::begin(container), curIt = std::begin(container);
uint32 elementsToKeep = requestedSize, elementsToProcess = std::size(container);
while (elementsToProcess)
{
// this element has chance (elementsToKeep / elementsToProcess) of being kept
if (urand(1, elementsToProcess) <= elementsToKeep)
{
if (keepIt != curIt)
*keepIt = std::move(*curIt);
++keepIt;
--elementsToKeep;
}
++curIt;
--elementsToProcess;
}
container.erase(keepIt, std::end(container));
}
template<class C, class Predicate>
void RandomResize(C& container, Predicate&& predicate, std::size_t requestedSize)
{
//! First use predicate filter
C containerCopy;
std::copy_if(std::begin(container), std::end(container), std::inserter(containerCopy, std::end(containerCopy)), predicate);
if (requestedSize)
RandomResize(containerCopy, requestedSize);
container = std::move(containerCopy);
}
/*
* Select a random element from a container.
*
* Note: container cannot be empty
*/
template<class C>
inline auto SelectRandomContainerElement(C const& container) -> typename std::add_const<decltype(*std::begin(container))>::type&
{
auto it = std::begin(container);
std::advance(it, urand(0, uint32(std::size(container)) - 1));
return *it;
}
/*
* Select a random element from a container where each element has a different chance to be selected.
*
* @param container Container to select an element from
* @param weights Chances of each element to be selected, must be in the same order as elements in container.
* Caller is responsible for checking that sum of all weights is greater than 0.
*
* Note: container cannot be empty
*/
template<class C>
inline auto SelectRandomWeightedContainerElement(C const& container, std::vector<double> weights) -> decltype(std::begin(container))
{
auto it = std::begin(container);
std::advance(it, urandweighted(weights.size(), weights.data()));
return it;
}
/*
* Select a random element from a container where each element has a different chance to be selected.
*
* @param container Container to select an element from
* @param weightExtractor Function retrieving chance of each element in container, expected to take an element of the container and returning a double
*
* Note: container cannot be empty
*/
template<class C, class Fn>
auto SelectRandomWeightedContainerElement(C const& container, Fn weightExtractor) -> decltype(std::begin(container))
{
std::vector<double> weights;
weights.reserve(std::size(container));
double weightSum = 0.0;
for (auto& val : container)
{
double weight = weightExtractor(val);
weights.push_back(weight);
weightSum += weight;
}
if (weightSum <= 0.0)
weights.assign(std::size(container), 1.0);
return SelectRandomWeightedContainerElement(container, weights);
}
/*
* @fn void acore::Containers::RandomShuffle(C& container)
*
* @brief Reorder the elements of the container randomly.
*
* @param container Container to reorder
*/
template<class C>
inline void RandomShuffle(C& container)
{
std::shuffle(std::begin(container), std::end(container), RandomEngine::Instance());
}
template<class K, class V, template<class, class, class...> class M, class... Rest>
void MultimapErasePair(M<K, V, Rest...>& multimap, K const& key, V const& value)
{
auto range = multimap.equal_range(key);
for (auto itr = range.first; itr != range.second;)
{
if (itr->second == value)
itr = multimap.erase(itr);
else
++itr;
}
}
template <typename Container, typename Predicate>
std::enable_if_t<std::is_move_assignable_v<decltype(*std::declval<Container>().begin())>, void> EraseIf(Container& c, Predicate p)
{
auto wpos = c.begin();
for (auto rpos = c.begin(), end = c.end(); rpos != end; ++rpos)
{
if (!p(*rpos))
{
if (rpos != wpos)
{
std::swap(*rpos, *wpos);
}
++wpos;
}
}
c.erase(wpos, c.end());
}
template <typename Container, typename Predicate>
std::enable_if_t<!std::is_move_assignable_v<decltype(*std::declval<Container>().begin())>, void> EraseIf(Container& c, Predicate p)
{
for (auto it = c.begin(); it != c.end();)
{
if (p(*it))
{
it = c.erase(it);
}
else
{
++it;
}
}
}
}
#endif //! #ifdef ACORE_CONTAINERS_H

View File

@@ -0,0 +1,84 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
* Copyright (C) 2008-2021 TrinityCore <http://www.trinitycore.org/>
*/
#include "Random.h"
#include "Errors.h"
#include "SFMTRand.h"
#include <memory>
#include <random>
static thread_local std::unique_ptr<SFMTRand> sfmtRand;
static RandomEngine engine;
static SFMTRand* GetRng()
{
if (!sfmtRand)
sfmtRand = std::make_unique<SFMTRand>();
return sfmtRand.get();
}
int32 irand(int32 min, int32 max)
{
ASSERT(max >= min);
std::uniform_int_distribution<int32> uid(min, max);
return uid(engine);
}
uint32 urand(uint32 min, uint32 max)
{
ASSERT(max >= min);
std::uniform_int_distribution<uint32> uid(min, max);
return uid(engine);
}
uint32 urandms(uint32 min, uint32 max)
{
ASSERT(std::numeric_limits<uint32>::max() / Milliseconds::period::den >= max);
return urand(min * Milliseconds::period::den, max * Milliseconds::period::den);
}
float frand(float min, float max)
{
ASSERT(max >= min);
std::uniform_real_distribution<float> urd(min, max);
return urd(engine);
}
Milliseconds randtime(Milliseconds min, Milliseconds max)
{
long long diff = max.count() - min.count();
ASSERT(diff >= 0);
ASSERT(diff <= (uint32)-1);
return min + Milliseconds(urand(0, diff));
}
uint32 rand32()
{
return GetRng()->RandomUInt32();
}
double rand_norm()
{
std::uniform_real_distribution<double> urd;
return urd(engine);
}
double rand_chance()
{
std::uniform_real_distribution<double> urd(0.0, 100.0);
return urd(engine);
}
uint32 urandweighted(size_t count, double const* chances)
{
std::discrete_distribution<uint32> dd(chances, chances + count);
return dd(engine);
}
RandomEngine& RandomEngine::Instance()
{
return engine;
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
* Copyright (C) 2008-2021 TrinityCore <http://www.trinitycore.org/>
*/
#ifndef Random_h__
#define Random_h__
#include "Define.h"
#include "Duration.h"
#include <limits>
/* Return a random number in the range min..max. */
AC_COMMON_API int32 irand(int32 min, int32 max);
/* Return a random number in the range min..max (inclusive). */
AC_COMMON_API uint32 urand(uint32 min, uint32 max);
/* Return a random millisecond value between min and max seconds. Functionally equivalent to urand(min*IN_MILLISECONDS, max*IN_MILLISECONDS). */
AC_COMMON_API uint32 urandms(uint32 min, uint32 max);
/* Return a random number in the range 0 .. UINT32_MAX. */
AC_COMMON_API uint32 rand32();
/* Return a random time in the range min..max (up to millisecond precision). Only works for values where millisecond difference is a valid uint32. */
AC_COMMON_API Milliseconds randtime(Milliseconds min, Milliseconds max);
/* Return a random number in the range min..max */
AC_COMMON_API float frand(float min, float max);
/* Return a random double from 0.0 to 1.0 (exclusive). */
AC_COMMON_API double rand_norm();
/* Return a random double from 0.0 to 100.0 (exclusive). */
AC_COMMON_API double rand_chance();
/* Return a random number in the range 0..count (exclusive) with each value having a different chance of happening */
AC_COMMON_API uint32 urandweighted(size_t count, double const* chances);
/* Return true if a random roll fits in the specified chance (range 0-100). */
inline bool roll_chance_f(float chance)
{
return chance > rand_chance();
}
/* Return true if a random roll fits in the specified chance (range 0-100). */
inline bool roll_chance_i(int chance)
{
return chance > irand(0, 99);
}
/*
* Wrapper satisfying UniformRandomNumberGenerator concept for use in <random> algorithms
*/
class AC_COMMON_API RandomEngine
{
public:
typedef uint32 result_type;
static constexpr result_type min() { return std::numeric_limits<result_type>::min(); }
static constexpr result_type max() { return std::numeric_limits<result_type>::max(); }
result_type operator()() const { return rand32(); }
static RandomEngine& Instance();
};
#endif // Random_h__

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
* Copyright (C) 2008-2021 TrinityCore <http://www.trinitycore.org/>
*/
#include "SFMTRand.h"
#include <algorithm>
#include <array>
#include <functional>
#include <random>
#include <ctime>
#if defined(__aarch64__)
#if defined(__clang__)
#include <mm_malloc.h>
#elif defined(__GNUC__)
static __inline__ void *__attribute__((__always_inline__, __nodebug__, __malloc__))
_mm_malloc(size_t __size, size_t __align)
{
if (__align == 1)
{
return malloc(__size);
}
if (!(__align & (__align - 1)) && __align < sizeof(void *))
__align = sizeof(void *);
void *__mallocedMemory;
if (posix_memalign(&__mallocedMemory, __align, __size))
return NULL;
return __mallocedMemory;
}
static __inline__ void __attribute__((__always_inline__, __nodebug__))
_mm_free(void *__p)
{
free(__p);
}
#else
#error aarch64 only on clang and gcc
#endif
#else
#include <emmintrin.h>
#endif
SFMTRand::SFMTRand()
{
std::random_device dev;
if (dev.entropy() > 0)
{
std::array<uint32, SFMT_N32> seed;
std::generate(seed.begin(), seed.end(), std::ref(dev));
sfmt_init_by_array(&_state, seed.data(), seed.size());
}
else
{
sfmt_init_gen_rand(&_state, uint32(time(nullptr)));
}
}
uint32 SFMTRand::RandomUInt32() // Output random bits
{
return sfmt_genrand_uint32(&_state);
}
void* SFMTRand::operator new(size_t size, std::nothrow_t const&)
{
return _mm_malloc(size, 16);
}
void SFMTRand::operator delete(void* ptr, std::nothrow_t const&)
{
_mm_free(ptr);
}
void* SFMTRand::operator new(size_t size)
{
return _mm_malloc(size, 16);
}
void SFMTRand::operator delete(void* ptr)
{
_mm_free(ptr);
}
void* SFMTRand::operator new[](size_t size, std::nothrow_t const&)
{
return _mm_malloc(size, 16);
}
void SFMTRand::operator delete[](void* ptr, std::nothrow_t const&)
{
_mm_free(ptr);
}
void* SFMTRand::operator new[](size_t size)
{
return _mm_malloc(size, 16);
}
void SFMTRand::operator delete[](void* ptr)
{
_mm_free(ptr);
}

View File

@@ -0,0 +1,33 @@
/*
* Copyright (C) 2016+ AzerothCore <www.azerothcore.org>, released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3
* Copyright (C) 2008-2021 TrinityCore <http://www.trinitycore.org/>
*/
#ifndef SFMTRand_h__
#define SFMTRand_h__
#include "Define.h"
#include <SFMT.h>
#include <new>
/*
* C++ Wrapper for SFMT
*/
class SFMTRand
{
public:
SFMTRand();
uint32 RandomUInt32(); // Output random bits
void* operator new(size_t size, std::nothrow_t const&);
void operator delete(void* ptr, std::nothrow_t const&);
void* operator new(size_t size);
void operator delete(void* ptr);
void* operator new[](size_t size, std::nothrow_t const&);
void operator delete[](void* ptr, std::nothrow_t const&);
void* operator new[](size_t size);
void operator delete[](void* ptr);
private:
sfmt_t _state;
};
#endif // SFMTRand_h__

View File

@@ -10,62 +10,11 @@
#include "Log.h" #include "Log.h"
#include "Errors.h" #include "Errors.h"
#include "TypeList.h" #include "TypeList.h"
#include <ace/Task.h>
#include "SFMT.h"
#include "Errors.h" // for ASSERT #include "Errors.h" // for ASSERT
#include <ace/TSS_T.h>
#include <array> #include <array>
#include <cwchar> #include <cwchar>
#include <string> #include <string>
#include <random> #include <ace/Default_Constants.h>
typedef ACE_TSS<SFMTRand> SFMTRandTSS;
static SFMTRandTSS sfmtRand;
static SFMTEngine engine;
int32 irand(int32 min, int32 max)
{
ASSERT(max >= min);
return int32(sfmtRand->IRandom(min, max));
}
uint32 urand(uint32 min, uint32 max)
{
ASSERT(max >= min);
return sfmtRand->URandom(min, max);
}
float frand(float min, float max)
{
ASSERT(max >= min);
return float(sfmtRand->Random() * (max - min) + min);
}
uint32 rand32()
{
return int32(sfmtRand->BRandom());
}
double rand_norm()
{
return sfmtRand->Random();
}
double rand_chance()
{
return sfmtRand->Random() * 100.0;
}
uint32 urandweighted(size_t count, double const* chances)
{
std::discrete_distribution<uint32> dd(chances, chances + count);
return dd(SFMTEngine::Instance());
}
SFMTEngine& SFMTEngine::Instance()
{
return engine;
}
Tokenizer::Tokenizer(const std::string& src, const char sep, uint32 vectorReserve) Tokenizer::Tokenizer(const std::string& src, const char sep, uint32 vectorReserve)
{ {

View File

@@ -71,38 +71,6 @@ uint32 TimeStringToSecs(const std::string& timestring);
std::string TimeToTimestampStr(time_t t); std::string TimeToTimestampStr(time_t t);
std::string TimeToHumanReadable(time_t t); std::string TimeToHumanReadable(time_t t);
/* Return a random number in the range min..max. */
int32 irand(int32 min, int32 max);
/* Return a random number in the range min..max (inclusive). */
uint32 urand(uint32 min, uint32 max);
/* Return a random number in the range 0 .. UINT32_MAX. */
uint32 rand32();
/* Return a random number in the range min..max */
float frand(float min, float max);
/* Return a random double from 0.0 to 1.0 (exclusive). */
double rand_norm();
/* Return a random double from 0.0 to 100.0 (exclusive). */
double rand_chance();
uint32 urandweighted(size_t count, double const* chances);
/* Return true if a random roll fits in the specified chance (range 0-100). */
inline bool roll_chance_f(float chance)
{
return chance > rand_chance();
}
/* Return true if a random roll fits in the specified chance (range 0-100). */
inline bool roll_chance_i(int32 chance)
{
return chance > irand(0, 99);
}
inline void ApplyPercentModFloatVar(float& var, float val, bool apply) inline void ApplyPercentModFloatVar(float& var, float val, bool apply)
{ {
if (val == -100.0f) // prevent set var to zero if (val == -100.0f) // prevent set var to zero
@@ -582,21 +550,6 @@ bool CompareValues(ComparisionType type, T val1, T val2)
} }
} }
/*
* SFMT wrapper satisfying UniformRandomNumberGenerator concept for use in <random> algorithms
*/
class SFMTEngine
{
public:
typedef uint32 result_type;
static constexpr result_type min() { return std::numeric_limits<result_type>::min(); }
static constexpr result_type max() { return std::numeric_limits<result_type>::max(); }
result_type operator()() const { return rand32(); }
static SFMTEngine& Instance();
};
class EventMap class EventMap
{ {
typedef std::multimap<uint32, uint32> EventStore; typedef std::multimap<uint32, uint32> EventStore;

View File

@@ -100,24 +100,26 @@ public:
} }
template <class Predicate> template <class Predicate>
void DoAction(int32 info, Predicate& predicate, uint16 max = 0) void DoAction(int32 info, Predicate&& predicate, uint16 max = 0)
{ {
if (max) if (max)
RemoveNotExisting(); // pussywizard: when max is set, non existing can be chosen and nothing will happen RemoveNotExisting(); // pussywizard: when max is set, non existing can be chosen and nothing will happen
// We need to use a copy of SummonList here, otherwise original SummonList would be modified // We need to use a copy of SummonList here, otherwise original SummonList would be modified
StorageType listCopy = storage_; StorageType listCopy = storage_;
acore::Containers::RandomResize(listCopy, predicate, max); acore::Containers::RandomResize<StorageType, Predicate>(listCopy, std::forward<Predicate>(predicate), max);
for (StorageType::iterator i = listCopy.begin(); i != listCopy.end(); ++i)
for (auto const& guid : listCopy)
{ {
Creature* summon = ObjectAccessor::GetCreature(*me, *i); Creature* summon = ObjectAccessor::GetCreature(*me, guid);
if (summon) if (summon && summon->IsAIEnabled)
{ {
if (summon->IsAIEnabled)
summon->AI()->DoAction(info); summon->AI()->DoAction(info);
} }
else else if (!summon)
storage_.remove(*i); {
storage_.remove(guid);
}
} }
} }

View File

@@ -971,7 +971,7 @@ BattlegroundTypeId BattlegroundMgr::GetRandomBG(BattlegroundTypeId bgTypeId)
} }
} }
return acore::Containers::SelectRandomWeightedContainerElement(ids, weights); return *acore::Containers::SelectRandomWeightedContainerElement(ids, weights);
} }
return BATTLEGROUND_TYPE_NONE; return BATTLEGROUND_TYPE_NONE;

View File

@@ -644,7 +644,7 @@ public:
me->RemoveAurasDueToSpell(SPELL_INVOCATION_OF_BLOOD_TALDARAM); me->RemoveAurasDueToSpell(SPELL_INVOCATION_OF_BLOOD_TALDARAM);
break; break;
case ACTION_FLAME_BALL_CHASE: case ACTION_FLAME_BALL_CHASE:
summons.DoAction(ACTION_FLAME_BALL_CHASE, 1); summons.DoAction(ACTION_FLAME_BALL_CHASE);
break; break;
default: default:
break; break;