xref: /freebsd/contrib/llvm-project/libcxx/include/random (revision e8d8bef961a50d4dc22501cde4fb9fb0be1b2532)
10b57cec5SDimitry Andric// -*- C++ -*-
20b57cec5SDimitry Andric//===--------------------------- random -----------------------------------===//
30b57cec5SDimitry Andric//
40b57cec5SDimitry Andric// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
50b57cec5SDimitry Andric// See https://llvm.org/LICENSE.txt for license information.
60b57cec5SDimitry Andric// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
70b57cec5SDimitry Andric//
80b57cec5SDimitry Andric//===----------------------------------------------------------------------===//
90b57cec5SDimitry Andric
100b57cec5SDimitry Andric#ifndef _LIBCPP_RANDOM
110b57cec5SDimitry Andric#define _LIBCPP_RANDOM
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric/*
140b57cec5SDimitry Andric    random synopsis
150b57cec5SDimitry Andric
160b57cec5SDimitry Andric#include <initializer_list>
170b57cec5SDimitry Andric
180b57cec5SDimitry Andricnamespace std
190b57cec5SDimitry Andric{
200b57cec5SDimitry Andric
210b57cec5SDimitry Andric// Engines
220b57cec5SDimitry Andric
230b57cec5SDimitry Andrictemplate <class UIntType, UIntType a, UIntType c, UIntType m>
240b57cec5SDimitry Andricclass linear_congruential_engine
250b57cec5SDimitry Andric{
260b57cec5SDimitry Andricpublic:
270b57cec5SDimitry Andric    // types
280b57cec5SDimitry Andric    typedef UIntType result_type;
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric    // engine characteristics
310b57cec5SDimitry Andric    static constexpr result_type multiplier = a;
320b57cec5SDimitry Andric    static constexpr result_type increment = c;
330b57cec5SDimitry Andric    static constexpr result_type modulus = m;
340b57cec5SDimitry Andric    static constexpr result_type min() { return c == 0u ? 1u: 0u;}
350b57cec5SDimitry Andric    static constexpr result_type max() { return m - 1u;}
360b57cec5SDimitry Andric    static constexpr result_type default_seed = 1u;
370b57cec5SDimitry Andric
380b57cec5SDimitry Andric    // constructors and seeding functions
39*e8d8bef9SDimitry Andric    explicit linear_congruential_engine(result_type s = default_seed);         // before C++20
40*e8d8bef9SDimitry Andric    linear_congruential_engine() : linear_congruential_engine(default_seed) {} // C++20
41*e8d8bef9SDimitry Andric    explicit linear_congruential_engine(result_type s);                        // C++20
420b57cec5SDimitry Andric    template<class Sseq> explicit linear_congruential_engine(Sseq& q);
430b57cec5SDimitry Andric    void seed(result_type s = default_seed);
440b57cec5SDimitry Andric    template<class Sseq> void seed(Sseq& q);
450b57cec5SDimitry Andric
460b57cec5SDimitry Andric    // generating functions
470b57cec5SDimitry Andric    result_type operator()();
480b57cec5SDimitry Andric    void discard(unsigned long long z);
490b57cec5SDimitry Andric};
500b57cec5SDimitry Andric
510b57cec5SDimitry Andrictemplate <class UIntType, UIntType a, UIntType c, UIntType m>
520b57cec5SDimitry Andricbool
530b57cec5SDimitry Andricoperator==(const linear_congruential_engine<UIntType, a, c, m>& x,
540b57cec5SDimitry Andric           const linear_congruential_engine<UIntType, a, c, m>& y);
550b57cec5SDimitry Andric
560b57cec5SDimitry Andrictemplate <class UIntType, UIntType a, UIntType c, UIntType m>
570b57cec5SDimitry Andricbool
580b57cec5SDimitry Andricoperator!=(const linear_congruential_engine<UIntType, a, c, m>& x,
590b57cec5SDimitry Andric           const linear_congruential_engine<UIntType, a, c, m>& y);
600b57cec5SDimitry Andric
610b57cec5SDimitry Andrictemplate <class charT, class traits,
620b57cec5SDimitry Andric          class UIntType, UIntType a, UIntType c, UIntType m>
630b57cec5SDimitry Andricbasic_ostream<charT, traits>&
640b57cec5SDimitry Andricoperator<<(basic_ostream<charT, traits>& os,
650b57cec5SDimitry Andric           const linear_congruential_engine<UIntType, a, c, m>& x);
660b57cec5SDimitry Andric
670b57cec5SDimitry Andrictemplate <class charT, class traits,
680b57cec5SDimitry Andric          class UIntType, UIntType a, UIntType c, UIntType m>
690b57cec5SDimitry Andricbasic_istream<charT, traits>&
700b57cec5SDimitry Andricoperator>>(basic_istream<charT, traits>& is,
710b57cec5SDimitry Andric           linear_congruential_engine<UIntType, a, c, m>& x);
720b57cec5SDimitry Andric
730b57cec5SDimitry Andrictemplate <class UIntType, size_t w, size_t n, size_t m, size_t r,
740b57cec5SDimitry Andric          UIntType a, size_t u, UIntType d, size_t s,
750b57cec5SDimitry Andric          UIntType b, size_t t, UIntType c, size_t l, UIntType f>
760b57cec5SDimitry Andricclass mersenne_twister_engine
770b57cec5SDimitry Andric{
780b57cec5SDimitry Andricpublic:
790b57cec5SDimitry Andric    // types
800b57cec5SDimitry Andric    typedef UIntType result_type;
810b57cec5SDimitry Andric
820b57cec5SDimitry Andric    // engine characteristics
830b57cec5SDimitry Andric    static constexpr size_t word_size = w;
840b57cec5SDimitry Andric    static constexpr size_t state_size = n;
850b57cec5SDimitry Andric    static constexpr size_t shift_size = m;
860b57cec5SDimitry Andric    static constexpr size_t mask_bits = r;
870b57cec5SDimitry Andric    static constexpr result_type xor_mask = a;
880b57cec5SDimitry Andric    static constexpr size_t tempering_u = u;
890b57cec5SDimitry Andric    static constexpr result_type tempering_d = d;
900b57cec5SDimitry Andric    static constexpr size_t tempering_s = s;
910b57cec5SDimitry Andric    static constexpr result_type tempering_b = b;
920b57cec5SDimitry Andric    static constexpr size_t tempering_t = t;
930b57cec5SDimitry Andric    static constexpr result_type tempering_c = c;
940b57cec5SDimitry Andric    static constexpr size_t tempering_l = l;
950b57cec5SDimitry Andric    static constexpr result_type initialization_multiplier = f;
960b57cec5SDimitry Andric    static constexpr result_type min () { return 0; }
970b57cec5SDimitry Andric    static constexpr result_type max() { return 2^w - 1; }
980b57cec5SDimitry Andric    static constexpr result_type default_seed = 5489u;
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric    // constructors and seeding functions
101*e8d8bef9SDimitry Andric    explicit mersenne_twister_engine(result_type s = default_seed);      // before C++20
102*e8d8bef9SDimitry Andric    mersenne_twister_engine() : mersenne_twister_engine(default_seed) {} // C++20
103*e8d8bef9SDimitry Andric    explicit mersenne_twister_engine(result_type s);                     // C++20
1040b57cec5SDimitry Andric    template<class Sseq> explicit mersenne_twister_engine(Sseq& q);
1050b57cec5SDimitry Andric    void seed(result_type value = default_seed);
1060b57cec5SDimitry Andric    template<class Sseq> void seed(Sseq& q);
1070b57cec5SDimitry Andric
1080b57cec5SDimitry Andric    // generating functions
1090b57cec5SDimitry Andric    result_type operator()();
1100b57cec5SDimitry Andric    void discard(unsigned long long z);
1110b57cec5SDimitry Andric};
1120b57cec5SDimitry Andric
1130b57cec5SDimitry Andrictemplate <class UIntType, size_t w, size_t n, size_t m, size_t r,
1140b57cec5SDimitry Andric          UIntType a, size_t u, UIntType d, size_t s,
1150b57cec5SDimitry Andric          UIntType b, size_t t, UIntType c, size_t l, UIntType f>
1160b57cec5SDimitry Andricbool
1170b57cec5SDimitry Andricoperator==(
1180b57cec5SDimitry Andric    const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& x,
1190b57cec5SDimitry Andric    const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& y);
1200b57cec5SDimitry Andric
1210b57cec5SDimitry Andrictemplate <class UIntType, size_t w, size_t n, size_t m, size_t r,
1220b57cec5SDimitry Andric          UIntType a, size_t u, UIntType d, size_t s,
1230b57cec5SDimitry Andric          UIntType b, size_t t, UIntType c, size_t l, UIntType f>
1240b57cec5SDimitry Andricbool
1250b57cec5SDimitry Andricoperator!=(
1260b57cec5SDimitry Andric    const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& x,
1270b57cec5SDimitry Andric    const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& y);
1280b57cec5SDimitry Andric
1290b57cec5SDimitry Andrictemplate <class charT, class traits,
1300b57cec5SDimitry Andric          class UIntType, size_t w, size_t n, size_t m, size_t r,
1310b57cec5SDimitry Andric          UIntType a, size_t u, UIntType d, size_t s,
1320b57cec5SDimitry Andric          UIntType b, size_t t, UIntType c, size_t l, UIntType f>
1330b57cec5SDimitry Andricbasic_ostream<charT, traits>&
1340b57cec5SDimitry Andricoperator<<(basic_ostream<charT, traits>& os,
1350b57cec5SDimitry Andric           const mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& x);
1360b57cec5SDimitry Andric
1370b57cec5SDimitry Andrictemplate <class charT, class traits,
1380b57cec5SDimitry Andric          class UIntType, size_t w, size_t n, size_t m, size_t r,
1390b57cec5SDimitry Andric          UIntType a, size_t u, UIntType d, size_t s,
1400b57cec5SDimitry Andric          UIntType b, size_t t, UIntType c, size_t l, UIntType f>
1410b57cec5SDimitry Andricbasic_istream<charT, traits>&
1420b57cec5SDimitry Andricoperator>>(basic_istream<charT, traits>& is,
1430b57cec5SDimitry Andric           mersenne_twister_engine<UIntType, w, n, m, r, a, u, d, s, b, t, c, l, f>& x);
1440b57cec5SDimitry Andric
1450b57cec5SDimitry Andrictemplate<class UIntType, size_t w, size_t s, size_t r>
1460b57cec5SDimitry Andricclass subtract_with_carry_engine
1470b57cec5SDimitry Andric{
1480b57cec5SDimitry Andricpublic:
1490b57cec5SDimitry Andric    // types
1500b57cec5SDimitry Andric    typedef UIntType result_type;
1510b57cec5SDimitry Andric
1520b57cec5SDimitry Andric    // engine characteristics
1530b57cec5SDimitry Andric    static constexpr size_t word_size = w;
1540b57cec5SDimitry Andric    static constexpr size_t short_lag = s;
1550b57cec5SDimitry Andric    static constexpr size_t long_lag = r;
1560b57cec5SDimitry Andric    static constexpr result_type min() { return 0; }
1570b57cec5SDimitry Andric    static constexpr result_type max() { return m-1; }
1580b57cec5SDimitry Andric    static constexpr result_type default_seed = 19780503u;
1590b57cec5SDimitry Andric
1600b57cec5SDimitry Andric    // constructors and seeding functions
161*e8d8bef9SDimitry Andric    explicit subtract_with_carry_engine(result_type value = default_seed);     // before C++20
162*e8d8bef9SDimitry Andric    subtract_with_carry_engine() : subtract_with_carry_engine(default_seed) {} // C++20
163*e8d8bef9SDimitry Andric    explicit subtract_with_carry_engine(result_type value);                    // C++20
1640b57cec5SDimitry Andric    template<class Sseq> explicit subtract_with_carry_engine(Sseq& q);
1650b57cec5SDimitry Andric    void seed(result_type value = default_seed);
1660b57cec5SDimitry Andric    template<class Sseq> void seed(Sseq& q);
1670b57cec5SDimitry Andric
1680b57cec5SDimitry Andric    // generating functions
1690b57cec5SDimitry Andric    result_type operator()();
1700b57cec5SDimitry Andric    void discard(unsigned long long z);
1710b57cec5SDimitry Andric};
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andrictemplate<class UIntType, size_t w, size_t s, size_t r>
1740b57cec5SDimitry Andricbool
1750b57cec5SDimitry Andricoperator==(
1760b57cec5SDimitry Andric    const subtract_with_carry_engine<UIntType, w, s, r>& x,
1770b57cec5SDimitry Andric    const subtract_with_carry_engine<UIntType, w, s, r>& y);
1780b57cec5SDimitry Andric
1790b57cec5SDimitry Andrictemplate<class UIntType, size_t w, size_t s, size_t r>
1800b57cec5SDimitry Andricbool
1810b57cec5SDimitry Andricoperator!=(
1820b57cec5SDimitry Andric    const subtract_with_carry_engine<UIntType, w, s, r>& x,
1830b57cec5SDimitry Andric    const subtract_with_carry_engine<UIntType, w, s, r>& y);
1840b57cec5SDimitry Andric
1850b57cec5SDimitry Andrictemplate <class charT, class traits,
1860b57cec5SDimitry Andric          class UIntType, size_t w, size_t s, size_t r>
1870b57cec5SDimitry Andricbasic_ostream<charT, traits>&
1880b57cec5SDimitry Andricoperator<<(basic_ostream<charT, traits>& os,
1890b57cec5SDimitry Andric           const subtract_with_carry_engine<UIntType, w, s, r>& x);
1900b57cec5SDimitry Andric
1910b57cec5SDimitry Andrictemplate <class charT, class traits,
1920b57cec5SDimitry Andric          class UIntType, size_t w, size_t s, size_t r>
1930b57cec5SDimitry Andricbasic_istream<charT, traits>&
1940b57cec5SDimitry Andricoperator>>(basic_istream<charT, traits>& is,
1950b57cec5SDimitry Andric           subtract_with_carry_engine<UIntType, w, s, r>& x);
1960b57cec5SDimitry Andric
1970b57cec5SDimitry Andrictemplate<class Engine, size_t p, size_t r>
1980b57cec5SDimitry Andricclass discard_block_engine
1990b57cec5SDimitry Andric{
2000b57cec5SDimitry Andricpublic:
2010b57cec5SDimitry Andric    // types
2020b57cec5SDimitry Andric    typedef typename Engine::result_type result_type;
2030b57cec5SDimitry Andric
2040b57cec5SDimitry Andric    // engine characteristics
2050b57cec5SDimitry Andric    static constexpr size_t block_size = p;
2060b57cec5SDimitry Andric    static constexpr size_t used_block = r;
2070b57cec5SDimitry Andric    static constexpr result_type min() { return Engine::min(); }
2080b57cec5SDimitry Andric    static constexpr result_type max() { return Engine::max(); }
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andric    // constructors and seeding functions
2110b57cec5SDimitry Andric    discard_block_engine();
2120b57cec5SDimitry Andric    explicit discard_block_engine(const Engine& e);
2130b57cec5SDimitry Andric    explicit discard_block_engine(Engine&& e);
2140b57cec5SDimitry Andric    explicit discard_block_engine(result_type s);
2150b57cec5SDimitry Andric    template<class Sseq> explicit discard_block_engine(Sseq& q);
2160b57cec5SDimitry Andric    void seed();
2170b57cec5SDimitry Andric    void seed(result_type s);
2180b57cec5SDimitry Andric    template<class Sseq> void seed(Sseq& q);
2190b57cec5SDimitry Andric
2200b57cec5SDimitry Andric    // generating functions
2210b57cec5SDimitry Andric    result_type operator()();
2220b57cec5SDimitry Andric    void discard(unsigned long long z);
2230b57cec5SDimitry Andric
2240b57cec5SDimitry Andric    // property functions
2250b57cec5SDimitry Andric    const Engine& base() const noexcept;
2260b57cec5SDimitry Andric};
2270b57cec5SDimitry Andric
2280b57cec5SDimitry Andrictemplate<class Engine, size_t p, size_t r>
2290b57cec5SDimitry Andricbool
2300b57cec5SDimitry Andricoperator==(
2310b57cec5SDimitry Andric    const discard_block_engine<Engine, p, r>& x,
2320b57cec5SDimitry Andric    const discard_block_engine<Engine, p, r>& y);
2330b57cec5SDimitry Andric
2340b57cec5SDimitry Andrictemplate<class Engine, size_t p, size_t r>
2350b57cec5SDimitry Andricbool
2360b57cec5SDimitry Andricoperator!=(
2370b57cec5SDimitry Andric    const discard_block_engine<Engine, p, r>& x,
2380b57cec5SDimitry Andric    const discard_block_engine<Engine, p, r>& y);
2390b57cec5SDimitry Andric
2400b57cec5SDimitry Andrictemplate <class charT, class traits,
2410b57cec5SDimitry Andric          class Engine, size_t p, size_t r>
2420b57cec5SDimitry Andricbasic_ostream<charT, traits>&
2430b57cec5SDimitry Andricoperator<<(basic_ostream<charT, traits>& os,
2440b57cec5SDimitry Andric           const discard_block_engine<Engine, p, r>& x);
2450b57cec5SDimitry Andric
2460b57cec5SDimitry Andrictemplate <class charT, class traits,
2470b57cec5SDimitry Andric          class Engine, size_t p, size_t r>
2480b57cec5SDimitry Andricbasic_istream<charT, traits>&
2490b57cec5SDimitry Andricoperator>>(basic_istream<charT, traits>& is,
2500b57cec5SDimitry Andric           discard_block_engine<Engine, p, r>& x);
2510b57cec5SDimitry Andric
2520b57cec5SDimitry Andrictemplate<class Engine, size_t w, class UIntType>
2530b57cec5SDimitry Andricclass independent_bits_engine
2540b57cec5SDimitry Andric{
2550b57cec5SDimitry Andricpublic:
2560b57cec5SDimitry Andric    // types
2570b57cec5SDimitry Andric    typedef UIntType result_type;
2580b57cec5SDimitry Andric
2590b57cec5SDimitry Andric    // engine characteristics
2600b57cec5SDimitry Andric    static constexpr result_type min() { return 0; }
2610b57cec5SDimitry Andric    static constexpr result_type max() { return 2^w - 1; }
2620b57cec5SDimitry Andric
2630b57cec5SDimitry Andric    // constructors and seeding functions
2640b57cec5SDimitry Andric    independent_bits_engine();
2650b57cec5SDimitry Andric    explicit independent_bits_engine(const Engine& e);
2660b57cec5SDimitry Andric    explicit independent_bits_engine(Engine&& e);
2670b57cec5SDimitry Andric    explicit independent_bits_engine(result_type s);
2680b57cec5SDimitry Andric    template<class Sseq> explicit independent_bits_engine(Sseq& q);
2690b57cec5SDimitry Andric    void seed();
2700b57cec5SDimitry Andric    void seed(result_type s);
2710b57cec5SDimitry Andric    template<class Sseq> void seed(Sseq& q);
2720b57cec5SDimitry Andric
2730b57cec5SDimitry Andric    // generating functions
2740b57cec5SDimitry Andric    result_type operator()(); void discard(unsigned long long z);
2750b57cec5SDimitry Andric
2760b57cec5SDimitry Andric    // property functions
2770b57cec5SDimitry Andric    const Engine& base() const noexcept;
2780b57cec5SDimitry Andric};
2790b57cec5SDimitry Andric
2800b57cec5SDimitry Andrictemplate<class Engine, size_t w, class UIntType>
2810b57cec5SDimitry Andricbool
2820b57cec5SDimitry Andricoperator==(
2830b57cec5SDimitry Andric    const independent_bits_engine<Engine, w, UIntType>& x,
2840b57cec5SDimitry Andric    const independent_bits_engine<Engine, w, UIntType>& y);
2850b57cec5SDimitry Andric
2860b57cec5SDimitry Andrictemplate<class Engine, size_t w, class UIntType>
2870b57cec5SDimitry Andricbool
2880b57cec5SDimitry Andricoperator!=(
2890b57cec5SDimitry Andric    const independent_bits_engine<Engine, w, UIntType>& x,
2900b57cec5SDimitry Andric    const independent_bits_engine<Engine, w, UIntType>& y);
2910b57cec5SDimitry Andric
2920b57cec5SDimitry Andrictemplate <class charT, class traits,
2930b57cec5SDimitry Andric          class Engine, size_t w, class UIntType>
2940b57cec5SDimitry Andricbasic_ostream<charT, traits>&
2950b57cec5SDimitry Andricoperator<<(basic_ostream<charT, traits>& os,
2960b57cec5SDimitry Andric           const independent_bits_engine<Engine, w, UIntType>& x);
2970b57cec5SDimitry Andric
2980b57cec5SDimitry Andrictemplate <class charT, class traits,
2990b57cec5SDimitry Andric          class Engine, size_t w, class UIntType>
3000b57cec5SDimitry Andricbasic_istream<charT, traits>&
3010b57cec5SDimitry Andricoperator>>(basic_istream<charT, traits>& is,
3020b57cec5SDimitry Andric           independent_bits_engine<Engine, w, UIntType>& x);
3030b57cec5SDimitry Andric
3040b57cec5SDimitry Andrictemplate<class Engine, size_t k>
3050b57cec5SDimitry Andricclass shuffle_order_engine
3060b57cec5SDimitry Andric{
3070b57cec5SDimitry Andricpublic:
3080b57cec5SDimitry Andric    // types
3090b57cec5SDimitry Andric    typedef typename Engine::result_type result_type;
3100b57cec5SDimitry Andric
3110b57cec5SDimitry Andric    // engine characteristics
3120b57cec5SDimitry Andric    static constexpr size_t table_size = k;
3130b57cec5SDimitry Andric    static constexpr result_type min() { return Engine::min; }
3140b57cec5SDimitry Andric    static constexpr result_type max() { return Engine::max; }
3150b57cec5SDimitry Andric
3160b57cec5SDimitry Andric    // constructors and seeding functions
3170b57cec5SDimitry Andric    shuffle_order_engine();
3180b57cec5SDimitry Andric    explicit shuffle_order_engine(const Engine& e);
3190b57cec5SDimitry Andric    explicit shuffle_order_engine(Engine&& e);
3200b57cec5SDimitry Andric    explicit shuffle_order_engine(result_type s);
3210b57cec5SDimitry Andric    template<class Sseq> explicit shuffle_order_engine(Sseq& q);
3220b57cec5SDimitry Andric    void seed();
3230b57cec5SDimitry Andric    void seed(result_type s);
3240b57cec5SDimitry Andric    template<class Sseq> void seed(Sseq& q);
3250b57cec5SDimitry Andric
3260b57cec5SDimitry Andric    // generating functions
3270b57cec5SDimitry Andric    result_type operator()();
3280b57cec5SDimitry Andric    void discard(unsigned long long z);
3290b57cec5SDimitry Andric
3300b57cec5SDimitry Andric    // property functions
3310b57cec5SDimitry Andric    const Engine& base() const noexcept;
3320b57cec5SDimitry Andric};
3330b57cec5SDimitry Andric
3340b57cec5SDimitry Andrictemplate<class Engine, size_t k>
3350b57cec5SDimitry Andricbool
3360b57cec5SDimitry Andricoperator==(
3370b57cec5SDimitry Andric    const shuffle_order_engine<Engine, k>& x,
3380b57cec5SDimitry Andric    const shuffle_order_engine<Engine, k>& y);
3390b57cec5SDimitry Andric
3400b57cec5SDimitry Andrictemplate<class Engine, size_t k>
3410b57cec5SDimitry Andricbool
3420b57cec5SDimitry Andricoperator!=(
3430b57cec5SDimitry Andric    const shuffle_order_engine<Engine, k>& x,
3440b57cec5SDimitry Andric    const shuffle_order_engine<Engine, k>& y);
3450b57cec5SDimitry Andric
3460b57cec5SDimitry Andrictemplate <class charT, class traits,
3470b57cec5SDimitry Andric          class Engine, size_t k>
3480b57cec5SDimitry Andricbasic_ostream<charT, traits>&
3490b57cec5SDimitry Andricoperator<<(basic_ostream<charT, traits>& os,
3500b57cec5SDimitry Andric           const shuffle_order_engine<Engine, k>& x);
3510b57cec5SDimitry Andric
3520b57cec5SDimitry Andrictemplate <class charT, class traits,
3530b57cec5SDimitry Andric          class Engine, size_t k>
3540b57cec5SDimitry Andricbasic_istream<charT, traits>&
3550b57cec5SDimitry Andricoperator>>(basic_istream<charT, traits>& is,
3560b57cec5SDimitry Andric           shuffle_order_engine<Engine, k>& x);
3570b57cec5SDimitry Andric
3580b57cec5SDimitry Andrictypedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>
3590b57cec5SDimitry Andric                                                                   minstd_rand0;
3600b57cec5SDimitry Andrictypedef linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647>
3610b57cec5SDimitry Andric                                                                    minstd_rand;
3620b57cec5SDimitry Andrictypedef mersenne_twister_engine<uint_fast32_t, 32, 624, 397, 31,
3630b57cec5SDimitry Andric                                0x9908b0df,
3640b57cec5SDimitry Andric                                11, 0xffffffff,
3650b57cec5SDimitry Andric                                7,  0x9d2c5680,
3660b57cec5SDimitry Andric                                15, 0xefc60000,
3670b57cec5SDimitry Andric                                18, 1812433253>                         mt19937;
3680b57cec5SDimitry Andrictypedef mersenne_twister_engine<uint_fast64_t, 64, 312, 156, 31,
3690b57cec5SDimitry Andric                                0xb5026f5aa96619e9,
3700b57cec5SDimitry Andric                                29, 0x5555555555555555,
3710b57cec5SDimitry Andric                                17, 0x71d67fffeda60000,
3720b57cec5SDimitry Andric                                37, 0xfff7eee000000000,
3730b57cec5SDimitry Andric                                43, 6364136223846793005>             mt19937_64;
3740b57cec5SDimitry Andrictypedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>     ranlux24_base;
3750b57cec5SDimitry Andrictypedef subtract_with_carry_engine<uint_fast64_t, 48,  5, 12>     ranlux48_base;
3760b57cec5SDimitry Andrictypedef discard_block_engine<ranlux24_base, 223, 23>                   ranlux24;
3770b57cec5SDimitry Andrictypedef discard_block_engine<ranlux48_base, 389, 11>                   ranlux48;
3780b57cec5SDimitry Andrictypedef shuffle_order_engine<minstd_rand0, 256>                         knuth_b;
3790b57cec5SDimitry Andrictypedef minstd_rand                                       default_random_engine;
3800b57cec5SDimitry Andric
3810b57cec5SDimitry Andric// Generators
3820b57cec5SDimitry Andric
3830b57cec5SDimitry Andricclass random_device
3840b57cec5SDimitry Andric{
3850b57cec5SDimitry Andricpublic:
3860b57cec5SDimitry Andric    // types
3870b57cec5SDimitry Andric    typedef unsigned int result_type;
3880b57cec5SDimitry Andric
3890b57cec5SDimitry Andric    // generator characteristics
3900b57cec5SDimitry Andric    static constexpr result_type min() { return numeric_limits<result_type>::min(); }
3910b57cec5SDimitry Andric    static constexpr result_type max() { return numeric_limits<result_type>::max(); }
3920b57cec5SDimitry Andric
3930b57cec5SDimitry Andric    // constructors
394*e8d8bef9SDimitry Andric    explicit random_device(const string& token = implementation-defined); // before C++20
395*e8d8bef9SDimitry Andric    random_device() : random_device(implementation-defined) {}            // C++20
396*e8d8bef9SDimitry Andric    explicit random_device(const string& token);                          // C++20
3970b57cec5SDimitry Andric
3980b57cec5SDimitry Andric    // generating functions
3990b57cec5SDimitry Andric    result_type operator()();
4000b57cec5SDimitry Andric
4010b57cec5SDimitry Andric    // property functions
4020b57cec5SDimitry Andric    double entropy() const noexcept;
4030b57cec5SDimitry Andric
4040b57cec5SDimitry Andric    // no copy functions
4050b57cec5SDimitry Andric    random_device(const random_device& ) = delete;
4060b57cec5SDimitry Andric    void operator=(const random_device& ) = delete;
4070b57cec5SDimitry Andric};
4080b57cec5SDimitry Andric
4090b57cec5SDimitry Andric// Utilities
4100b57cec5SDimitry Andric
4110b57cec5SDimitry Andricclass seed_seq
4120b57cec5SDimitry Andric{
4130b57cec5SDimitry Andricpublic:
4140b57cec5SDimitry Andric    // types
4150b57cec5SDimitry Andric    typedef uint_least32_t result_type;
4160b57cec5SDimitry Andric
4170b57cec5SDimitry Andric    // constructors
4180b57cec5SDimitry Andric    seed_seq();
4190b57cec5SDimitry Andric    template<class T>
4200b57cec5SDimitry Andric        seed_seq(initializer_list<T> il);
4210b57cec5SDimitry Andric    template<class InputIterator>
4220b57cec5SDimitry Andric        seed_seq(InputIterator begin, InputIterator end);
4230b57cec5SDimitry Andric
4240b57cec5SDimitry Andric    // generating functions
4250b57cec5SDimitry Andric    template<class RandomAccessIterator>
4260b57cec5SDimitry Andric        void generate(RandomAccessIterator begin, RandomAccessIterator end);
4270b57cec5SDimitry Andric
4280b57cec5SDimitry Andric    // property functions
4290b57cec5SDimitry Andric    size_t size() const;
4300b57cec5SDimitry Andric    template<class OutputIterator>
4310b57cec5SDimitry Andric        void param(OutputIterator dest) const;
4320b57cec5SDimitry Andric
4330b57cec5SDimitry Andric    // no copy functions
4340b57cec5SDimitry Andric    seed_seq(const seed_seq&) = delete;
4350b57cec5SDimitry Andric    void operator=(const seed_seq& ) = delete;
4360b57cec5SDimitry Andric};
4370b57cec5SDimitry Andric
4380b57cec5SDimitry Andrictemplate<class RealType, size_t bits, class URNG>
4390b57cec5SDimitry Andric    RealType generate_canonical(URNG& g);
4400b57cec5SDimitry Andric
4410b57cec5SDimitry Andric// Distributions
4420b57cec5SDimitry Andric
4430b57cec5SDimitry Andrictemplate<class IntType = int>
4440b57cec5SDimitry Andricclass uniform_int_distribution
4450b57cec5SDimitry Andric{
4460b57cec5SDimitry Andricpublic:
4470b57cec5SDimitry Andric    // types
4480b57cec5SDimitry Andric    typedef IntType result_type;
4490b57cec5SDimitry Andric
4500b57cec5SDimitry Andric    class param_type
4510b57cec5SDimitry Andric    {
4520b57cec5SDimitry Andric    public:
4530b57cec5SDimitry Andric        typedef uniform_int_distribution distribution_type;
4540b57cec5SDimitry Andric
4550b57cec5SDimitry Andric        explicit param_type(IntType a = 0,
4560b57cec5SDimitry Andric                                    IntType b = numeric_limits<IntType>::max());
4570b57cec5SDimitry Andric
4580b57cec5SDimitry Andric        result_type a() const;
4590b57cec5SDimitry Andric        result_type b() const;
4600b57cec5SDimitry Andric
4610b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
4620b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
4630b57cec5SDimitry Andric    };
4640b57cec5SDimitry Andric
4650b57cec5SDimitry Andric    // constructors and reset functions
4660b57cec5SDimitry Andric    explicit uniform_int_distribution(IntType a = 0,
467*e8d8bef9SDimitry Andric                                      IntType b = numeric_limits<IntType>::max()); // before C++20
468*e8d8bef9SDimitry Andric    uniform_int_distribution() : uniform_int_distribution(0) {}                    // C++20
469*e8d8bef9SDimitry Andric    explicit uniform_int_distribution(IntType a,
470*e8d8bef9SDimitry Andric                                      IntType b = numeric_limits<IntType>::max()); // C++20
4710b57cec5SDimitry Andric    explicit uniform_int_distribution(const param_type& parm);
4720b57cec5SDimitry Andric    void reset();
4730b57cec5SDimitry Andric
4740b57cec5SDimitry Andric    // generating functions
4750b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
4760b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
4770b57cec5SDimitry Andric
4780b57cec5SDimitry Andric    // property functions
4790b57cec5SDimitry Andric    result_type a() const;
4800b57cec5SDimitry Andric    result_type b() const;
4810b57cec5SDimitry Andric
4820b57cec5SDimitry Andric    param_type param() const;
4830b57cec5SDimitry Andric    void param(const param_type& parm);
4840b57cec5SDimitry Andric
4850b57cec5SDimitry Andric    result_type min() const;
4860b57cec5SDimitry Andric    result_type max() const;
4870b57cec5SDimitry Andric
4880b57cec5SDimitry Andric    friend bool operator==(const uniform_int_distribution& x,
4890b57cec5SDimitry Andric                           const uniform_int_distribution& y);
4900b57cec5SDimitry Andric    friend bool operator!=(const uniform_int_distribution& x,
4910b57cec5SDimitry Andric                           const uniform_int_distribution& y);
4920b57cec5SDimitry Andric
4930b57cec5SDimitry Andric    template <class charT, class traits>
4940b57cec5SDimitry Andric    friend
4950b57cec5SDimitry Andric    basic_ostream<charT, traits>&
4960b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
4970b57cec5SDimitry Andric               const uniform_int_distribution& x);
4980b57cec5SDimitry Andric
4990b57cec5SDimitry Andric    template <class charT, class traits>
5000b57cec5SDimitry Andric    friend
5010b57cec5SDimitry Andric    basic_istream<charT, traits>&
5020b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
5030b57cec5SDimitry Andric               uniform_int_distribution& x);
5040b57cec5SDimitry Andric};
5050b57cec5SDimitry Andric
5060b57cec5SDimitry Andrictemplate<class RealType = double>
5070b57cec5SDimitry Andricclass uniform_real_distribution
5080b57cec5SDimitry Andric{
5090b57cec5SDimitry Andricpublic:
5100b57cec5SDimitry Andric    // types
5110b57cec5SDimitry Andric    typedef RealType result_type;
5120b57cec5SDimitry Andric
5130b57cec5SDimitry Andric    class param_type
5140b57cec5SDimitry Andric    {
5150b57cec5SDimitry Andric    public:
5160b57cec5SDimitry Andric        typedef uniform_real_distribution distribution_type;
5170b57cec5SDimitry Andric
5180b57cec5SDimitry Andric        explicit param_type(RealType a = 0,
5190b57cec5SDimitry Andric                            RealType b = 1);
5200b57cec5SDimitry Andric
5210b57cec5SDimitry Andric        result_type a() const;
5220b57cec5SDimitry Andric        result_type b() const;
5230b57cec5SDimitry Andric
5240b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
5250b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
5260b57cec5SDimitry Andric    };
5270b57cec5SDimitry Andric
5280b57cec5SDimitry Andric    // constructors and reset functions
529*e8d8bef9SDimitry Andric    explicit uniform_real_distribution(RealType a = 0.0, RealType b = 1.0); // before C++20
530*e8d8bef9SDimitry Andric    uniform_real_distribution() : uniform_real_distribution(0.0) {}         // C++20
531*e8d8bef9SDimitry Andric    explicit uniform_real_distribution(RealType a, RealType b = 1.0);       // C++20
5320b57cec5SDimitry Andric    explicit uniform_real_distribution(const param_type& parm);
5330b57cec5SDimitry Andric    void reset();
5340b57cec5SDimitry Andric
5350b57cec5SDimitry Andric    // generating functions
5360b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
5370b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
5380b57cec5SDimitry Andric
5390b57cec5SDimitry Andric    // property functions
5400b57cec5SDimitry Andric    result_type a() const;
5410b57cec5SDimitry Andric    result_type b() const;
5420b57cec5SDimitry Andric
5430b57cec5SDimitry Andric    param_type param() const;
5440b57cec5SDimitry Andric    void param(const param_type& parm);
5450b57cec5SDimitry Andric
5460b57cec5SDimitry Andric    result_type min() const;
5470b57cec5SDimitry Andric    result_type max() const;
5480b57cec5SDimitry Andric
5490b57cec5SDimitry Andric    friend bool operator==(const uniform_real_distribution& x,
5500b57cec5SDimitry Andric                           const uniform_real_distribution& y);
5510b57cec5SDimitry Andric    friend bool operator!=(const uniform_real_distribution& x,
5520b57cec5SDimitry Andric                           const uniform_real_distribution& y);
5530b57cec5SDimitry Andric
5540b57cec5SDimitry Andric    template <class charT, class traits>
5550b57cec5SDimitry Andric    friend
5560b57cec5SDimitry Andric    basic_ostream<charT, traits>&
5570b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
5580b57cec5SDimitry Andric               const uniform_real_distribution& x);
5590b57cec5SDimitry Andric
5600b57cec5SDimitry Andric    template <class charT, class traits>
5610b57cec5SDimitry Andric    friend
5620b57cec5SDimitry Andric    basic_istream<charT, traits>&
5630b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
5640b57cec5SDimitry Andric               uniform_real_distribution& x);
5650b57cec5SDimitry Andric};
5660b57cec5SDimitry Andric
5670b57cec5SDimitry Andricclass bernoulli_distribution
5680b57cec5SDimitry Andric{
5690b57cec5SDimitry Andricpublic:
5700b57cec5SDimitry Andric    // types
5710b57cec5SDimitry Andric    typedef bool result_type;
5720b57cec5SDimitry Andric
5730b57cec5SDimitry Andric    class param_type
5740b57cec5SDimitry Andric    {
5750b57cec5SDimitry Andric    public:
5760b57cec5SDimitry Andric        typedef bernoulli_distribution distribution_type;
5770b57cec5SDimitry Andric
5780b57cec5SDimitry Andric        explicit param_type(double p = 0.5);
5790b57cec5SDimitry Andric
5800b57cec5SDimitry Andric        double p() const;
5810b57cec5SDimitry Andric
5820b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
5830b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
5840b57cec5SDimitry Andric    };
5850b57cec5SDimitry Andric
5860b57cec5SDimitry Andric    // constructors and reset functions
587*e8d8bef9SDimitry Andric    explicit bernoulli_distribution(double p = 0.5);          // before C++20
588*e8d8bef9SDimitry Andric    bernoulli_distribution() : bernoulli_distribution(0.5) {} // C++20
589*e8d8bef9SDimitry Andric    explicit bernoulli_distribution(double p);                // C++20
5900b57cec5SDimitry Andric    explicit bernoulli_distribution(const param_type& parm);
5910b57cec5SDimitry Andric    void reset();
5920b57cec5SDimitry Andric
5930b57cec5SDimitry Andric    // generating functions
5940b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
5950b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
5960b57cec5SDimitry Andric
5970b57cec5SDimitry Andric    // property functions
5980b57cec5SDimitry Andric    double p() const;
5990b57cec5SDimitry Andric
6000b57cec5SDimitry Andric    param_type param() const;
6010b57cec5SDimitry Andric    void param(const param_type& parm);
6020b57cec5SDimitry Andric
6030b57cec5SDimitry Andric    result_type min() const;
6040b57cec5SDimitry Andric    result_type max() const;
6050b57cec5SDimitry Andric
6060b57cec5SDimitry Andric    friend bool operator==(const bernoulli_distribution& x,
6070b57cec5SDimitry Andric                           const bernoulli_distribution& y);
6080b57cec5SDimitry Andric    friend bool operator!=(const bernoulli_distribution& x,
6090b57cec5SDimitry Andric                           const bernoulli_distribution& y);
6100b57cec5SDimitry Andric
6110b57cec5SDimitry Andric    template <class charT, class traits>
6120b57cec5SDimitry Andric    friend
6130b57cec5SDimitry Andric    basic_ostream<charT, traits>&
6140b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
6150b57cec5SDimitry Andric               const bernoulli_distribution& x);
6160b57cec5SDimitry Andric
6170b57cec5SDimitry Andric    template <class charT, class traits>
6180b57cec5SDimitry Andric    friend
6190b57cec5SDimitry Andric    basic_istream<charT, traits>&
6200b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
6210b57cec5SDimitry Andric               bernoulli_distribution& x);
6220b57cec5SDimitry Andric};
6230b57cec5SDimitry Andric
6240b57cec5SDimitry Andrictemplate<class IntType = int>
6250b57cec5SDimitry Andricclass binomial_distribution
6260b57cec5SDimitry Andric{
6270b57cec5SDimitry Andricpublic:
6280b57cec5SDimitry Andric    // types
6290b57cec5SDimitry Andric    typedef IntType result_type;
6300b57cec5SDimitry Andric
6310b57cec5SDimitry Andric    class param_type
6320b57cec5SDimitry Andric    {
6330b57cec5SDimitry Andric    public:
6340b57cec5SDimitry Andric        typedef binomial_distribution distribution_type;
6350b57cec5SDimitry Andric
6360b57cec5SDimitry Andric        explicit param_type(IntType t = 1, double p = 0.5);
6370b57cec5SDimitry Andric
6380b57cec5SDimitry Andric        IntType t() const;
6390b57cec5SDimitry Andric        double p() const;
6400b57cec5SDimitry Andric
6410b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
6420b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
6430b57cec5SDimitry Andric    };
6440b57cec5SDimitry Andric
6450b57cec5SDimitry Andric    // constructors and reset functions
646*e8d8bef9SDimitry Andric    explicit binomial_distribution(IntType t = 1, double p = 0.5); // before C++20
647*e8d8bef9SDimitry Andric    binomial_distribution() : binomial_distribution(1) {}          // C++20
648*e8d8bef9SDimitry Andric    explicit binomial_distribution(IntType t, double p = 0.5);     // C++20
6490b57cec5SDimitry Andric    explicit binomial_distribution(const param_type& parm);
6500b57cec5SDimitry Andric    void reset();
6510b57cec5SDimitry Andric
6520b57cec5SDimitry Andric    // generating functions
6530b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
6540b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
6550b57cec5SDimitry Andric
6560b57cec5SDimitry Andric    // property functions
6570b57cec5SDimitry Andric    IntType t() const;
6580b57cec5SDimitry Andric    double p() const;
6590b57cec5SDimitry Andric
6600b57cec5SDimitry Andric    param_type param() const;
6610b57cec5SDimitry Andric    void param(const param_type& parm);
6620b57cec5SDimitry Andric
6630b57cec5SDimitry Andric    result_type min() const;
6640b57cec5SDimitry Andric    result_type max() const;
6650b57cec5SDimitry Andric
6660b57cec5SDimitry Andric    friend bool operator==(const binomial_distribution& x,
6670b57cec5SDimitry Andric                           const binomial_distribution& y);
6680b57cec5SDimitry Andric    friend bool operator!=(const binomial_distribution& x,
6690b57cec5SDimitry Andric                           const binomial_distribution& y);
6700b57cec5SDimitry Andric
6710b57cec5SDimitry Andric    template <class charT, class traits>
6720b57cec5SDimitry Andric    friend
6730b57cec5SDimitry Andric    basic_ostream<charT, traits>&
6740b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
6750b57cec5SDimitry Andric               const binomial_distribution& x);
6760b57cec5SDimitry Andric
6770b57cec5SDimitry Andric    template <class charT, class traits>
6780b57cec5SDimitry Andric    friend
6790b57cec5SDimitry Andric    basic_istream<charT, traits>&
6800b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
6810b57cec5SDimitry Andric               binomial_distribution& x);
6820b57cec5SDimitry Andric};
6830b57cec5SDimitry Andric
6840b57cec5SDimitry Andrictemplate<class IntType = int>
6850b57cec5SDimitry Andricclass geometric_distribution
6860b57cec5SDimitry Andric{
6870b57cec5SDimitry Andricpublic:
6880b57cec5SDimitry Andric    // types
6890b57cec5SDimitry Andric    typedef IntType result_type;
6900b57cec5SDimitry Andric
6910b57cec5SDimitry Andric    class param_type
6920b57cec5SDimitry Andric    {
6930b57cec5SDimitry Andric    public:
6940b57cec5SDimitry Andric        typedef geometric_distribution distribution_type;
6950b57cec5SDimitry Andric
6960b57cec5SDimitry Andric        explicit param_type(double p = 0.5);
6970b57cec5SDimitry Andric
6980b57cec5SDimitry Andric        double p() const;
6990b57cec5SDimitry Andric
7000b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
7010b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
7020b57cec5SDimitry Andric    };
7030b57cec5SDimitry Andric
7040b57cec5SDimitry Andric    // constructors and reset functions
705*e8d8bef9SDimitry Andric    explicit geometric_distribution(double p = 0.5);          // before C++20
706*e8d8bef9SDimitry Andric    geometric_distribution() : geometric_distribution(0.5) {} // C++20
707*e8d8bef9SDimitry Andric    explicit geometric_distribution(double p);                // C++20
7080b57cec5SDimitry Andric    explicit geometric_distribution(const param_type& parm);
7090b57cec5SDimitry Andric    void reset();
7100b57cec5SDimitry Andric
7110b57cec5SDimitry Andric    // generating functions
7120b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
7130b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
7140b57cec5SDimitry Andric
7150b57cec5SDimitry Andric    // property functions
7160b57cec5SDimitry Andric    double p() const;
7170b57cec5SDimitry Andric
7180b57cec5SDimitry Andric    param_type param() const;
7190b57cec5SDimitry Andric    void param(const param_type& parm);
7200b57cec5SDimitry Andric
7210b57cec5SDimitry Andric    result_type min() const;
7220b57cec5SDimitry Andric    result_type max() const;
7230b57cec5SDimitry Andric
7240b57cec5SDimitry Andric    friend bool operator==(const geometric_distribution& x,
7250b57cec5SDimitry Andric                           const geometric_distribution& y);
7260b57cec5SDimitry Andric    friend bool operator!=(const geometric_distribution& x,
7270b57cec5SDimitry Andric                           const geometric_distribution& y);
7280b57cec5SDimitry Andric
7290b57cec5SDimitry Andric    template <class charT, class traits>
7300b57cec5SDimitry Andric    friend
7310b57cec5SDimitry Andric    basic_ostream<charT, traits>&
7320b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
7330b57cec5SDimitry Andric               const geometric_distribution& x);
7340b57cec5SDimitry Andric
7350b57cec5SDimitry Andric    template <class charT, class traits>
7360b57cec5SDimitry Andric    friend
7370b57cec5SDimitry Andric    basic_istream<charT, traits>&
7380b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
7390b57cec5SDimitry Andric               geometric_distribution& x);
7400b57cec5SDimitry Andric};
7410b57cec5SDimitry Andric
7420b57cec5SDimitry Andrictemplate<class IntType = int>
7430b57cec5SDimitry Andricclass negative_binomial_distribution
7440b57cec5SDimitry Andric{
7450b57cec5SDimitry Andricpublic:
7460b57cec5SDimitry Andric    // types
7470b57cec5SDimitry Andric    typedef IntType result_type;
7480b57cec5SDimitry Andric
7490b57cec5SDimitry Andric    class param_type
7500b57cec5SDimitry Andric    {
7510b57cec5SDimitry Andric    public:
7520b57cec5SDimitry Andric        typedef negative_binomial_distribution distribution_type;
7530b57cec5SDimitry Andric
7540b57cec5SDimitry Andric        explicit param_type(result_type k = 1, double p = 0.5);
7550b57cec5SDimitry Andric
7560b57cec5SDimitry Andric        result_type k() const;
7570b57cec5SDimitry Andric        double p() const;
7580b57cec5SDimitry Andric
7590b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
7600b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
7610b57cec5SDimitry Andric    };
7620b57cec5SDimitry Andric
7630b57cec5SDimitry Andric    // constructor and reset functions
764*e8d8bef9SDimitry Andric    explicit negative_binomial_distribution(IntType k = 1, double p = 0.5); // before C++20
765*e8d8bef9SDimitry Andric    negative_binomial_distribution() : negative_binomial_distribution(1) {} // C++20
766*e8d8bef9SDimitry Andric    explicit negative_binomial_distribution(IntType k, double p = 0.5);     // C++20
7670b57cec5SDimitry Andric    explicit negative_binomial_distribution(const param_type& parm);
7680b57cec5SDimitry Andric    void reset();
7690b57cec5SDimitry Andric
7700b57cec5SDimitry Andric    // generating functions
7710b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
7720b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
7730b57cec5SDimitry Andric
7740b57cec5SDimitry Andric    // property functions
7750b57cec5SDimitry Andric    result_type k() const;
7760b57cec5SDimitry Andric    double p() const;
7770b57cec5SDimitry Andric
7780b57cec5SDimitry Andric    param_type param() const;
7790b57cec5SDimitry Andric    void param(const param_type& parm);
7800b57cec5SDimitry Andric
7810b57cec5SDimitry Andric    result_type min() const;
7820b57cec5SDimitry Andric    result_type max() const;
7830b57cec5SDimitry Andric
7840b57cec5SDimitry Andric    friend bool operator==(const negative_binomial_distribution& x,
7850b57cec5SDimitry Andric                           const negative_binomial_distribution& y);
7860b57cec5SDimitry Andric    friend bool operator!=(const negative_binomial_distribution& x,
7870b57cec5SDimitry Andric                           const negative_binomial_distribution& y);
7880b57cec5SDimitry Andric
7890b57cec5SDimitry Andric    template <class charT, class traits>
7900b57cec5SDimitry Andric    friend
7910b57cec5SDimitry Andric    basic_ostream<charT, traits>&
7920b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
7930b57cec5SDimitry Andric               const negative_binomial_distribution& x);
7940b57cec5SDimitry Andric
7950b57cec5SDimitry Andric    template <class charT, class traits>
7960b57cec5SDimitry Andric    friend
7970b57cec5SDimitry Andric    basic_istream<charT, traits>&
7980b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
7990b57cec5SDimitry Andric               negative_binomial_distribution& x);
8000b57cec5SDimitry Andric};
8010b57cec5SDimitry Andric
8020b57cec5SDimitry Andrictemplate<class IntType = int>
8030b57cec5SDimitry Andricclass poisson_distribution
8040b57cec5SDimitry Andric{
8050b57cec5SDimitry Andricpublic:
8060b57cec5SDimitry Andric    // types
8070b57cec5SDimitry Andric    typedef IntType result_type;
8080b57cec5SDimitry Andric
8090b57cec5SDimitry Andric    class param_type
8100b57cec5SDimitry Andric    {
8110b57cec5SDimitry Andric    public:
8120b57cec5SDimitry Andric        typedef poisson_distribution distribution_type;
8130b57cec5SDimitry Andric
8140b57cec5SDimitry Andric        explicit param_type(double mean = 1.0);
8150b57cec5SDimitry Andric
8160b57cec5SDimitry Andric        double mean() const;
8170b57cec5SDimitry Andric
8180b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
8190b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
8200b57cec5SDimitry Andric    };
8210b57cec5SDimitry Andric
8220b57cec5SDimitry Andric    // constructors and reset functions
823*e8d8bef9SDimitry Andric    explicit poisson_distribution(double mean = 1.0);     // before C++20
824*e8d8bef9SDimitry Andric    poisson_distribution() : poisson_distribution(1.0) {} // C++20
825*e8d8bef9SDimitry Andric    explicit poisson_distribution(double mean);           // C++20
8260b57cec5SDimitry Andric    explicit poisson_distribution(const param_type& parm);
8270b57cec5SDimitry Andric    void reset();
8280b57cec5SDimitry Andric
8290b57cec5SDimitry Andric    // generating functions
8300b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
8310b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
8320b57cec5SDimitry Andric
8330b57cec5SDimitry Andric    // property functions
8340b57cec5SDimitry Andric    double mean() const;
8350b57cec5SDimitry Andric
8360b57cec5SDimitry Andric    param_type param() const;
8370b57cec5SDimitry Andric    void param(const param_type& parm);
8380b57cec5SDimitry Andric
8390b57cec5SDimitry Andric    result_type min() const;
8400b57cec5SDimitry Andric    result_type max() const;
8410b57cec5SDimitry Andric
8420b57cec5SDimitry Andric    friend bool operator==(const poisson_distribution& x,
8430b57cec5SDimitry Andric                           const poisson_distribution& y);
8440b57cec5SDimitry Andric    friend bool operator!=(const poisson_distribution& x,
8450b57cec5SDimitry Andric                           const poisson_distribution& y);
8460b57cec5SDimitry Andric
8470b57cec5SDimitry Andric    template <class charT, class traits>
8480b57cec5SDimitry Andric    friend
8490b57cec5SDimitry Andric    basic_ostream<charT, traits>&
8500b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
8510b57cec5SDimitry Andric               const poisson_distribution& x);
8520b57cec5SDimitry Andric
8530b57cec5SDimitry Andric    template <class charT, class traits>
8540b57cec5SDimitry Andric    friend
8550b57cec5SDimitry Andric    basic_istream<charT, traits>&
8560b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
8570b57cec5SDimitry Andric               poisson_distribution& x);
8580b57cec5SDimitry Andric};
8590b57cec5SDimitry Andric
8600b57cec5SDimitry Andrictemplate<class RealType = double>
8610b57cec5SDimitry Andricclass exponential_distribution
8620b57cec5SDimitry Andric{
8630b57cec5SDimitry Andricpublic:
8640b57cec5SDimitry Andric    // types
8650b57cec5SDimitry Andric    typedef RealType result_type;
8660b57cec5SDimitry Andric
8670b57cec5SDimitry Andric    class param_type
8680b57cec5SDimitry Andric    {
8690b57cec5SDimitry Andric    public:
8700b57cec5SDimitry Andric        typedef exponential_distribution distribution_type;
8710b57cec5SDimitry Andric
8720b57cec5SDimitry Andric        explicit param_type(result_type lambda = 1.0);
8730b57cec5SDimitry Andric
8740b57cec5SDimitry Andric        result_type lambda() const;
8750b57cec5SDimitry Andric
8760b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
8770b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
8780b57cec5SDimitry Andric    };
8790b57cec5SDimitry Andric
8800b57cec5SDimitry Andric    // constructors and reset functions
881*e8d8bef9SDimitry Andric    explicit exponential_distribution(RealType lambda = 1.0);     // before C++20
882*e8d8bef9SDimitry Andric    exponential_distribution() : exponential_distribution(1.0) {} // C++20
883*e8d8bef9SDimitry Andric    explicit exponential_distribution(RealType lambda);           // C++20
8840b57cec5SDimitry Andric    explicit exponential_distribution(const param_type& parm);
8850b57cec5SDimitry Andric    void reset();
8860b57cec5SDimitry Andric
8870b57cec5SDimitry Andric    // generating functions
8880b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
8890b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
8900b57cec5SDimitry Andric
8910b57cec5SDimitry Andric    // property functions
8920b57cec5SDimitry Andric    result_type lambda() const;
8930b57cec5SDimitry Andric
8940b57cec5SDimitry Andric    param_type param() const;
8950b57cec5SDimitry Andric    void param(const param_type& parm);
8960b57cec5SDimitry Andric
8970b57cec5SDimitry Andric    result_type min() const;
8980b57cec5SDimitry Andric    result_type max() const;
8990b57cec5SDimitry Andric
9000b57cec5SDimitry Andric    friend bool operator==(const exponential_distribution& x,
9010b57cec5SDimitry Andric                           const exponential_distribution& y);
9020b57cec5SDimitry Andric    friend bool operator!=(const exponential_distribution& x,
9030b57cec5SDimitry Andric                           const exponential_distribution& y);
9040b57cec5SDimitry Andric
9050b57cec5SDimitry Andric    template <class charT, class traits>
9060b57cec5SDimitry Andric    friend
9070b57cec5SDimitry Andric    basic_ostream<charT, traits>&
9080b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
9090b57cec5SDimitry Andric               const exponential_distribution& x);
9100b57cec5SDimitry Andric
9110b57cec5SDimitry Andric    template <class charT, class traits>
9120b57cec5SDimitry Andric    friend
9130b57cec5SDimitry Andric    basic_istream<charT, traits>&
9140b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
9150b57cec5SDimitry Andric               exponential_distribution& x);
9160b57cec5SDimitry Andric};
9170b57cec5SDimitry Andric
9180b57cec5SDimitry Andrictemplate<class RealType = double>
9190b57cec5SDimitry Andricclass gamma_distribution
9200b57cec5SDimitry Andric{
9210b57cec5SDimitry Andricpublic:
9220b57cec5SDimitry Andric    // types
9230b57cec5SDimitry Andric    typedef RealType result_type;
9240b57cec5SDimitry Andric
9250b57cec5SDimitry Andric    class param_type
9260b57cec5SDimitry Andric    {
9270b57cec5SDimitry Andric    public:
9280b57cec5SDimitry Andric        typedef gamma_distribution distribution_type;
9290b57cec5SDimitry Andric
9300b57cec5SDimitry Andric        explicit param_type(result_type alpha = 1, result_type beta = 1);
9310b57cec5SDimitry Andric
9320b57cec5SDimitry Andric        result_type alpha() const;
9330b57cec5SDimitry Andric        result_type beta() const;
9340b57cec5SDimitry Andric
9350b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
9360b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
9370b57cec5SDimitry Andric    };
9380b57cec5SDimitry Andric
9390b57cec5SDimitry Andric    // constructors and reset functions
940*e8d8bef9SDimitry Andric    explicit gamma_distribution(RealType alpha = 0.0, RealType beta = 1.0); // before C++20
941*e8d8bef9SDimitry Andric    gamma_distribution() : gamma_distribution(0.0) {}                       // C++20
942*e8d8bef9SDimitry Andric    explicit gamma_distribution(RealType alpha, RealType beta = 1.0);       // C++20
9430b57cec5SDimitry Andric    explicit gamma_distribution(const param_type& parm);
9440b57cec5SDimitry Andric    void reset();
9450b57cec5SDimitry Andric
9460b57cec5SDimitry Andric    // generating functions
9470b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
9480b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
9490b57cec5SDimitry Andric
9500b57cec5SDimitry Andric    // property functions
9510b57cec5SDimitry Andric    result_type alpha() const;
9520b57cec5SDimitry Andric    result_type beta() const;
9530b57cec5SDimitry Andric
9540b57cec5SDimitry Andric    param_type param() const;
9550b57cec5SDimitry Andric    void param(const param_type& parm);
9560b57cec5SDimitry Andric
9570b57cec5SDimitry Andric    result_type min() const;
9580b57cec5SDimitry Andric    result_type max() const;
9590b57cec5SDimitry Andric
9600b57cec5SDimitry Andric    friend bool operator==(const gamma_distribution& x,
9610b57cec5SDimitry Andric                           const gamma_distribution& y);
9620b57cec5SDimitry Andric    friend bool operator!=(const gamma_distribution& x,
9630b57cec5SDimitry Andric                           const gamma_distribution& y);
9640b57cec5SDimitry Andric
9650b57cec5SDimitry Andric    template <class charT, class traits>
9660b57cec5SDimitry Andric    friend
9670b57cec5SDimitry Andric    basic_ostream<charT, traits>&
9680b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
9690b57cec5SDimitry Andric               const gamma_distribution& x);
9700b57cec5SDimitry Andric
9710b57cec5SDimitry Andric    template <class charT, class traits>
9720b57cec5SDimitry Andric    friend
9730b57cec5SDimitry Andric    basic_istream<charT, traits>&
9740b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
9750b57cec5SDimitry Andric               gamma_distribution& x);
9760b57cec5SDimitry Andric};
9770b57cec5SDimitry Andric
9780b57cec5SDimitry Andrictemplate<class RealType = double>
9790b57cec5SDimitry Andricclass weibull_distribution
9800b57cec5SDimitry Andric{
9810b57cec5SDimitry Andricpublic:
9820b57cec5SDimitry Andric    // types
9830b57cec5SDimitry Andric    typedef RealType result_type;
9840b57cec5SDimitry Andric
9850b57cec5SDimitry Andric    class param_type
9860b57cec5SDimitry Andric    {
9870b57cec5SDimitry Andric    public:
9880b57cec5SDimitry Andric        typedef weibull_distribution distribution_type;
9890b57cec5SDimitry Andric
9900b57cec5SDimitry Andric        explicit param_type(result_type alpha = 1, result_type beta = 1);
9910b57cec5SDimitry Andric
9920b57cec5SDimitry Andric        result_type a() const;
9930b57cec5SDimitry Andric        result_type b() const;
9940b57cec5SDimitry Andric
9950b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
9960b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
9970b57cec5SDimitry Andric    };
9980b57cec5SDimitry Andric
9990b57cec5SDimitry Andric    // constructor and reset functions
1000*e8d8bef9SDimitry Andric    explicit weibull_distribution(RealType a = 1.0, RealType b = 1.0); // before C++20
1001*e8d8bef9SDimitry Andric    weibull_distribution() : weibull_distribution(1.0) {}              // C++20
1002*e8d8bef9SDimitry Andric    explicit weibull_distribution(RealType a, RealType b = 1.0);       // C++20
10030b57cec5SDimitry Andric    explicit weibull_distribution(const param_type& parm);
10040b57cec5SDimitry Andric    void reset();
10050b57cec5SDimitry Andric
10060b57cec5SDimitry Andric    // generating functions
10070b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
10080b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
10090b57cec5SDimitry Andric
10100b57cec5SDimitry Andric    // property functions
10110b57cec5SDimitry Andric    result_type a() const;
10120b57cec5SDimitry Andric    result_type b() const;
10130b57cec5SDimitry Andric
10140b57cec5SDimitry Andric    param_type param() const;
10150b57cec5SDimitry Andric    void param(const param_type& parm);
10160b57cec5SDimitry Andric
10170b57cec5SDimitry Andric    result_type min() const;
10180b57cec5SDimitry Andric    result_type max() const;
10190b57cec5SDimitry Andric
10200b57cec5SDimitry Andric    friend bool operator==(const weibull_distribution& x,
10210b57cec5SDimitry Andric                           const weibull_distribution& y);
10220b57cec5SDimitry Andric    friend bool operator!=(const weibull_distribution& x,
10230b57cec5SDimitry Andric                           const weibull_distribution& y);
10240b57cec5SDimitry Andric
10250b57cec5SDimitry Andric    template <class charT, class traits>
10260b57cec5SDimitry Andric    friend
10270b57cec5SDimitry Andric    basic_ostream<charT, traits>&
10280b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
10290b57cec5SDimitry Andric               const weibull_distribution& x);
10300b57cec5SDimitry Andric
10310b57cec5SDimitry Andric    template <class charT, class traits>
10320b57cec5SDimitry Andric    friend
10330b57cec5SDimitry Andric    basic_istream<charT, traits>&
10340b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
10350b57cec5SDimitry Andric               weibull_distribution& x);
10360b57cec5SDimitry Andric};
10370b57cec5SDimitry Andric
10380b57cec5SDimitry Andrictemplate<class RealType = double>
10390b57cec5SDimitry Andricclass extreme_value_distribution
10400b57cec5SDimitry Andric{
10410b57cec5SDimitry Andricpublic:
10420b57cec5SDimitry Andric    // types
10430b57cec5SDimitry Andric    typedef RealType result_type;
10440b57cec5SDimitry Andric
10450b57cec5SDimitry Andric    class param_type
10460b57cec5SDimitry Andric    {
10470b57cec5SDimitry Andric    public:
10480b57cec5SDimitry Andric        typedef extreme_value_distribution distribution_type;
10490b57cec5SDimitry Andric
10500b57cec5SDimitry Andric        explicit param_type(result_type a = 0, result_type b = 1);
10510b57cec5SDimitry Andric
10520b57cec5SDimitry Andric        result_type a() const;
10530b57cec5SDimitry Andric        result_type b() const;
10540b57cec5SDimitry Andric
10550b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
10560b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
10570b57cec5SDimitry Andric    };
10580b57cec5SDimitry Andric
10590b57cec5SDimitry Andric    // constructor and reset functions
1060*e8d8bef9SDimitry Andric    explicit extreme_value_distribution(RealType a = 0.0, RealType b = 1.0); // before C++20
1061*e8d8bef9SDimitry Andric    extreme_value_distribution() : extreme_value_distribution(0.0) {}        // C++20
1062*e8d8bef9SDimitry Andric    explicit extreme_value_distribution(RealType a, RealType b = 1.0);       // C++20
10630b57cec5SDimitry Andric    explicit extreme_value_distribution(const param_type& parm);
10640b57cec5SDimitry Andric    void reset();
10650b57cec5SDimitry Andric
10660b57cec5SDimitry Andric    // generating functions
10670b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
10680b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
10690b57cec5SDimitry Andric
10700b57cec5SDimitry Andric    // property functions
10710b57cec5SDimitry Andric    result_type a() const;
10720b57cec5SDimitry Andric    result_type b() const;
10730b57cec5SDimitry Andric
10740b57cec5SDimitry Andric    param_type param() const;
10750b57cec5SDimitry Andric    void param(const param_type& parm);
10760b57cec5SDimitry Andric
10770b57cec5SDimitry Andric    result_type min() const;
10780b57cec5SDimitry Andric    result_type max() const;
10790b57cec5SDimitry Andric
10800b57cec5SDimitry Andric    friend bool operator==(const extreme_value_distribution& x,
10810b57cec5SDimitry Andric                           const extreme_value_distribution& y);
10820b57cec5SDimitry Andric    friend bool operator!=(const extreme_value_distribution& x,
10830b57cec5SDimitry Andric                           const extreme_value_distribution& y);
10840b57cec5SDimitry Andric
10850b57cec5SDimitry Andric    template <class charT, class traits>
10860b57cec5SDimitry Andric    friend
10870b57cec5SDimitry Andric    basic_ostream<charT, traits>&
10880b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
10890b57cec5SDimitry Andric               const extreme_value_distribution& x);
10900b57cec5SDimitry Andric
10910b57cec5SDimitry Andric    template <class charT, class traits>
10920b57cec5SDimitry Andric    friend
10930b57cec5SDimitry Andric    basic_istream<charT, traits>&
10940b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
10950b57cec5SDimitry Andric               extreme_value_distribution& x);
10960b57cec5SDimitry Andric};
10970b57cec5SDimitry Andric
10980b57cec5SDimitry Andrictemplate<class RealType = double>
10990b57cec5SDimitry Andricclass normal_distribution
11000b57cec5SDimitry Andric{
11010b57cec5SDimitry Andricpublic:
11020b57cec5SDimitry Andric    // types
11030b57cec5SDimitry Andric    typedef RealType result_type;
11040b57cec5SDimitry Andric
11050b57cec5SDimitry Andric    class param_type
11060b57cec5SDimitry Andric    {
11070b57cec5SDimitry Andric    public:
11080b57cec5SDimitry Andric        typedef normal_distribution distribution_type;
11090b57cec5SDimitry Andric
11100b57cec5SDimitry Andric        explicit param_type(result_type mean = 0, result_type stddev = 1);
11110b57cec5SDimitry Andric
11120b57cec5SDimitry Andric        result_type mean() const;
11130b57cec5SDimitry Andric        result_type stddev() const;
11140b57cec5SDimitry Andric
11150b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
11160b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
11170b57cec5SDimitry Andric    };
11180b57cec5SDimitry Andric
11190b57cec5SDimitry Andric    // constructors and reset functions
1120*e8d8bef9SDimitry Andric    explicit normal_distribution(RealType mean = 0.0, RealType stddev = 1.0); // before C++20
1121*e8d8bef9SDimitry Andric    normal_distribution() : normal_distribution(0.0) {}                       // C++20
1122*e8d8bef9SDimitry Andric    explicit normal_distribution(RealType mean, RealType stddev = 1.0);       // C++20
11230b57cec5SDimitry Andric    explicit normal_distribution(const param_type& parm);
11240b57cec5SDimitry Andric    void reset();
11250b57cec5SDimitry Andric
11260b57cec5SDimitry Andric    // generating functions
11270b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
11280b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
11290b57cec5SDimitry Andric
11300b57cec5SDimitry Andric    // property functions
11310b57cec5SDimitry Andric    result_type mean() const;
11320b57cec5SDimitry Andric    result_type stddev() const;
11330b57cec5SDimitry Andric
11340b57cec5SDimitry Andric    param_type param() const;
11350b57cec5SDimitry Andric    void param(const param_type& parm);
11360b57cec5SDimitry Andric
11370b57cec5SDimitry Andric    result_type min() const;
11380b57cec5SDimitry Andric    result_type max() const;
11390b57cec5SDimitry Andric
11400b57cec5SDimitry Andric    friend bool operator==(const normal_distribution& x,
11410b57cec5SDimitry Andric                           const normal_distribution& y);
11420b57cec5SDimitry Andric    friend bool operator!=(const normal_distribution& x,
11430b57cec5SDimitry Andric                           const normal_distribution& y);
11440b57cec5SDimitry Andric
11450b57cec5SDimitry Andric    template <class charT, class traits>
11460b57cec5SDimitry Andric    friend
11470b57cec5SDimitry Andric    basic_ostream<charT, traits>&
11480b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
11490b57cec5SDimitry Andric               const normal_distribution& x);
11500b57cec5SDimitry Andric
11510b57cec5SDimitry Andric    template <class charT, class traits>
11520b57cec5SDimitry Andric    friend
11530b57cec5SDimitry Andric    basic_istream<charT, traits>&
11540b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
11550b57cec5SDimitry Andric               normal_distribution& x);
11560b57cec5SDimitry Andric};
11570b57cec5SDimitry Andric
11580b57cec5SDimitry Andrictemplate<class RealType = double>
11590b57cec5SDimitry Andricclass lognormal_distribution
11600b57cec5SDimitry Andric{
11610b57cec5SDimitry Andricpublic:
11620b57cec5SDimitry Andric    // types
11630b57cec5SDimitry Andric    typedef RealType result_type;
11640b57cec5SDimitry Andric
11650b57cec5SDimitry Andric    class param_type
11660b57cec5SDimitry Andric    {
11670b57cec5SDimitry Andric    public:
11680b57cec5SDimitry Andric        typedef lognormal_distribution distribution_type;
11690b57cec5SDimitry Andric
11700b57cec5SDimitry Andric        explicit param_type(result_type m = 0, result_type s = 1);
11710b57cec5SDimitry Andric
11720b57cec5SDimitry Andric        result_type m() const;
11730b57cec5SDimitry Andric        result_type s() const;
11740b57cec5SDimitry Andric
11750b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
11760b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
11770b57cec5SDimitry Andric    };
11780b57cec5SDimitry Andric
11790b57cec5SDimitry Andric    // constructor and reset functions
1180*e8d8bef9SDimitry Andric    explicit lognormal_distribution(RealType mean = 0.0, RealType stddev = 1.0); // before C++20
1181*e8d8bef9SDimitry Andric    lognormal_distribution() : lognormal_distribution(0.0) {}                    // C++20
1182*e8d8bef9SDimitry Andric    explicit lognormal_distribution(RealType mean, RealType stddev = 1.0);       // C++20
11830b57cec5SDimitry Andric    explicit lognormal_distribution(const param_type& parm);
11840b57cec5SDimitry Andric    void reset();
11850b57cec5SDimitry Andric
11860b57cec5SDimitry Andric    // generating functions
11870b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
11880b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
11890b57cec5SDimitry Andric
11900b57cec5SDimitry Andric    // property functions
11910b57cec5SDimitry Andric    result_type m() const;
11920b57cec5SDimitry Andric    result_type s() const;
11930b57cec5SDimitry Andric
11940b57cec5SDimitry Andric    param_type param() const;
11950b57cec5SDimitry Andric    void param(const param_type& parm);
11960b57cec5SDimitry Andric
11970b57cec5SDimitry Andric    result_type min() const;
11980b57cec5SDimitry Andric    result_type max() const;
11990b57cec5SDimitry Andric
12000b57cec5SDimitry Andric    friend bool operator==(const lognormal_distribution& x,
12010b57cec5SDimitry Andric                           const lognormal_distribution& y);
12020b57cec5SDimitry Andric    friend bool operator!=(const lognormal_distribution& x,
12030b57cec5SDimitry Andric                           const lognormal_distribution& y);
12040b57cec5SDimitry Andric
12050b57cec5SDimitry Andric    template <class charT, class traits>
12060b57cec5SDimitry Andric    friend
12070b57cec5SDimitry Andric    basic_ostream<charT, traits>&
12080b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
12090b57cec5SDimitry Andric               const lognormal_distribution& x);
12100b57cec5SDimitry Andric
12110b57cec5SDimitry Andric    template <class charT, class traits>
12120b57cec5SDimitry Andric    friend
12130b57cec5SDimitry Andric    basic_istream<charT, traits>&
12140b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
12150b57cec5SDimitry Andric               lognormal_distribution& x);
12160b57cec5SDimitry Andric};
12170b57cec5SDimitry Andric
12180b57cec5SDimitry Andrictemplate<class RealType = double>
12190b57cec5SDimitry Andricclass chi_squared_distribution
12200b57cec5SDimitry Andric{
12210b57cec5SDimitry Andricpublic:
12220b57cec5SDimitry Andric    // types
12230b57cec5SDimitry Andric    typedef RealType result_type;
12240b57cec5SDimitry Andric
12250b57cec5SDimitry Andric    class param_type
12260b57cec5SDimitry Andric    {
12270b57cec5SDimitry Andric    public:
12280b57cec5SDimitry Andric        typedef chi_squared_distribution distribution_type;
12290b57cec5SDimitry Andric
12300b57cec5SDimitry Andric        explicit param_type(result_type n = 1);
12310b57cec5SDimitry Andric
12320b57cec5SDimitry Andric        result_type n() const;
12330b57cec5SDimitry Andric
12340b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
12350b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
12360b57cec5SDimitry Andric    };
12370b57cec5SDimitry Andric
12380b57cec5SDimitry Andric    // constructor and reset functions
1239*e8d8bef9SDimitry Andric    explicit chi_squared_distribution(RealType n = 1.0);          // before C++20
1240*e8d8bef9SDimitry Andric    chi_squared_distribution() : chi_squared_distribution(1.0) {} // C++20
1241*e8d8bef9SDimitry Andric    explicit chi_squared_distribution(RealType n);                // C++20
12420b57cec5SDimitry Andric    explicit chi_squared_distribution(const param_type& parm);
12430b57cec5SDimitry Andric    void reset();
12440b57cec5SDimitry Andric
12450b57cec5SDimitry Andric    // generating functions
12460b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
12470b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
12480b57cec5SDimitry Andric
12490b57cec5SDimitry Andric    // property functions
12500b57cec5SDimitry Andric    result_type n() const;
12510b57cec5SDimitry Andric
12520b57cec5SDimitry Andric    param_type param() const;
12530b57cec5SDimitry Andric    void param(const param_type& parm);
12540b57cec5SDimitry Andric
12550b57cec5SDimitry Andric    result_type min() const;
12560b57cec5SDimitry Andric    result_type max() const;
12570b57cec5SDimitry Andric
12580b57cec5SDimitry Andric    friend bool operator==(const chi_squared_distribution& x,
12590b57cec5SDimitry Andric                           const chi_squared_distribution& y);
12600b57cec5SDimitry Andric    friend bool operator!=(const chi_squared_distribution& x,
12610b57cec5SDimitry Andric                           const chi_squared_distribution& y);
12620b57cec5SDimitry Andric
12630b57cec5SDimitry Andric    template <class charT, class traits>
12640b57cec5SDimitry Andric    friend
12650b57cec5SDimitry Andric    basic_ostream<charT, traits>&
12660b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
12670b57cec5SDimitry Andric               const chi_squared_distribution& x);
12680b57cec5SDimitry Andric
12690b57cec5SDimitry Andric    template <class charT, class traits>
12700b57cec5SDimitry Andric    friend
12710b57cec5SDimitry Andric    basic_istream<charT, traits>&
12720b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
12730b57cec5SDimitry Andric               chi_squared_distribution& x);
12740b57cec5SDimitry Andric};
12750b57cec5SDimitry Andric
12760b57cec5SDimitry Andrictemplate<class RealType = double>
12770b57cec5SDimitry Andricclass cauchy_distribution
12780b57cec5SDimitry Andric{
12790b57cec5SDimitry Andricpublic:
12800b57cec5SDimitry Andric    // types
12810b57cec5SDimitry Andric    typedef RealType result_type;
12820b57cec5SDimitry Andric
12830b57cec5SDimitry Andric    class param_type
12840b57cec5SDimitry Andric    {
12850b57cec5SDimitry Andric    public:
12860b57cec5SDimitry Andric        typedef cauchy_distribution distribution_type;
12870b57cec5SDimitry Andric
12880b57cec5SDimitry Andric        explicit param_type(result_type a = 0, result_type b = 1);
12890b57cec5SDimitry Andric
12900b57cec5SDimitry Andric        result_type a() const;
12910b57cec5SDimitry Andric        result_type b() const;
12920b57cec5SDimitry Andric
12930b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
12940b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
12950b57cec5SDimitry Andric    };
12960b57cec5SDimitry Andric
12970b57cec5SDimitry Andric    // constructor and reset functions
1298*e8d8bef9SDimitry Andric    explicit cauchy_distribution(RealType a = 0.0, RealType b = 1.0); // before C++20
1299*e8d8bef9SDimitry Andric    cauchy_distribution() : cauchy_distribution(0.0) {}               // C++20
1300*e8d8bef9SDimitry Andric    explicit cauchy_distribution(RealType a, RealType b = 1.0);       // C++20
13010b57cec5SDimitry Andric    explicit cauchy_distribution(const param_type& parm);
13020b57cec5SDimitry Andric    void reset();
13030b57cec5SDimitry Andric
13040b57cec5SDimitry Andric    // generating functions
13050b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
13060b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
13070b57cec5SDimitry Andric
13080b57cec5SDimitry Andric    // property functions
13090b57cec5SDimitry Andric    result_type a() const;
13100b57cec5SDimitry Andric    result_type b() const;
13110b57cec5SDimitry Andric
13120b57cec5SDimitry Andric    param_type param() const;
13130b57cec5SDimitry Andric    void param(const param_type& parm);
13140b57cec5SDimitry Andric
13150b57cec5SDimitry Andric    result_type min() const;
13160b57cec5SDimitry Andric    result_type max() const;
13170b57cec5SDimitry Andric
13180b57cec5SDimitry Andric    friend bool operator==(const cauchy_distribution& x,
13190b57cec5SDimitry Andric                           const cauchy_distribution& y);
13200b57cec5SDimitry Andric    friend bool operator!=(const cauchy_distribution& x,
13210b57cec5SDimitry Andric                           const cauchy_distribution& y);
13220b57cec5SDimitry Andric
13230b57cec5SDimitry Andric    template <class charT, class traits>
13240b57cec5SDimitry Andric    friend
13250b57cec5SDimitry Andric    basic_ostream<charT, traits>&
13260b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
13270b57cec5SDimitry Andric               const cauchy_distribution& x);
13280b57cec5SDimitry Andric
13290b57cec5SDimitry Andric    template <class charT, class traits>
13300b57cec5SDimitry Andric    friend
13310b57cec5SDimitry Andric    basic_istream<charT, traits>&
13320b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
13330b57cec5SDimitry Andric               cauchy_distribution& x);
13340b57cec5SDimitry Andric};
13350b57cec5SDimitry Andric
13360b57cec5SDimitry Andrictemplate<class RealType = double>
13370b57cec5SDimitry Andricclass fisher_f_distribution
13380b57cec5SDimitry Andric{
13390b57cec5SDimitry Andricpublic:
13400b57cec5SDimitry Andric    // types
13410b57cec5SDimitry Andric    typedef RealType result_type;
13420b57cec5SDimitry Andric
13430b57cec5SDimitry Andric    class param_type
13440b57cec5SDimitry Andric    {
13450b57cec5SDimitry Andric    public:
13460b57cec5SDimitry Andric        typedef fisher_f_distribution distribution_type;
13470b57cec5SDimitry Andric
13480b57cec5SDimitry Andric        explicit param_type(result_type m = 1, result_type n = 1);
13490b57cec5SDimitry Andric
13500b57cec5SDimitry Andric        result_type m() const;
13510b57cec5SDimitry Andric        result_type n() const;
13520b57cec5SDimitry Andric
13530b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
13540b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
13550b57cec5SDimitry Andric    };
13560b57cec5SDimitry Andric
13570b57cec5SDimitry Andric    // constructor and reset functions
1358*e8d8bef9SDimitry Andric    explicit fisher_f_distribution(RealType m = 1.0, RealType n = 1.0); // before C++20
1359*e8d8bef9SDimitry Andric    fisher_f_distribution() : fisher_f_distribution(1.0) {}             // C++20
1360*e8d8bef9SDimitry Andric    explicit fisher_f_distribution(RealType m, RealType n = 1.0);       // C++20
13610b57cec5SDimitry Andric    explicit fisher_f_distribution(const param_type& parm);
13620b57cec5SDimitry Andric    void reset();
13630b57cec5SDimitry Andric
13640b57cec5SDimitry Andric    // generating functions
13650b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
13660b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
13670b57cec5SDimitry Andric
13680b57cec5SDimitry Andric    // property functions
13690b57cec5SDimitry Andric    result_type m() const;
13700b57cec5SDimitry Andric    result_type n() const;
13710b57cec5SDimitry Andric
13720b57cec5SDimitry Andric    param_type param() const;
13730b57cec5SDimitry Andric    void param(const param_type& parm);
13740b57cec5SDimitry Andric
13750b57cec5SDimitry Andric    result_type min() const;
13760b57cec5SDimitry Andric    result_type max() const;
13770b57cec5SDimitry Andric
13780b57cec5SDimitry Andric    friend bool operator==(const fisher_f_distribution& x,
13790b57cec5SDimitry Andric                           const fisher_f_distribution& y);
13800b57cec5SDimitry Andric    friend bool operator!=(const fisher_f_distribution& x,
13810b57cec5SDimitry Andric                           const fisher_f_distribution& y);
13820b57cec5SDimitry Andric
13830b57cec5SDimitry Andric    template <class charT, class traits>
13840b57cec5SDimitry Andric    friend
13850b57cec5SDimitry Andric    basic_ostream<charT, traits>&
13860b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
13870b57cec5SDimitry Andric               const fisher_f_distribution& x);
13880b57cec5SDimitry Andric
13890b57cec5SDimitry Andric    template <class charT, class traits>
13900b57cec5SDimitry Andric    friend
13910b57cec5SDimitry Andric    basic_istream<charT, traits>&
13920b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
13930b57cec5SDimitry Andric               fisher_f_distribution& x);
13940b57cec5SDimitry Andric};
13950b57cec5SDimitry Andric
13960b57cec5SDimitry Andrictemplate<class RealType = double>
13970b57cec5SDimitry Andricclass student_t_distribution
13980b57cec5SDimitry Andric{
13990b57cec5SDimitry Andricpublic:
14000b57cec5SDimitry Andric    // types
14010b57cec5SDimitry Andric    typedef RealType result_type;
14020b57cec5SDimitry Andric
14030b57cec5SDimitry Andric    class param_type
14040b57cec5SDimitry Andric    {
14050b57cec5SDimitry Andric    public:
14060b57cec5SDimitry Andric        typedef student_t_distribution distribution_type;
14070b57cec5SDimitry Andric
14080b57cec5SDimitry Andric        explicit param_type(result_type n = 1);
14090b57cec5SDimitry Andric
14100b57cec5SDimitry Andric        result_type n() const;
14110b57cec5SDimitry Andric
14120b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
14130b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
14140b57cec5SDimitry Andric    };
14150b57cec5SDimitry Andric
14160b57cec5SDimitry Andric    // constructor and reset functions
1417*e8d8bef9SDimitry Andric    explicit student_t_distribution(RealType n = 1.0);        // before C++20
1418*e8d8bef9SDimitry Andric    student_t_distribution() : student_t_distribution(1.0) {} // C++20
1419*e8d8bef9SDimitry Andric    explicit student_t_distribution(RealType n);              // C++20
14200b57cec5SDimitry Andric    explicit student_t_distribution(const param_type& parm);
14210b57cec5SDimitry Andric    void reset();
14220b57cec5SDimitry Andric
14230b57cec5SDimitry Andric    // generating functions
14240b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
14250b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
14260b57cec5SDimitry Andric
14270b57cec5SDimitry Andric    // property functions
14280b57cec5SDimitry Andric    result_type n() const;
14290b57cec5SDimitry Andric
14300b57cec5SDimitry Andric    param_type param() const;
14310b57cec5SDimitry Andric    void param(const param_type& parm);
14320b57cec5SDimitry Andric
14330b57cec5SDimitry Andric    result_type min() const;
14340b57cec5SDimitry Andric    result_type max() const;
14350b57cec5SDimitry Andric
14360b57cec5SDimitry Andric    friend bool operator==(const student_t_distribution& x,
14370b57cec5SDimitry Andric                           const student_t_distribution& y);
14380b57cec5SDimitry Andric    friend bool operator!=(const student_t_distribution& x,
14390b57cec5SDimitry Andric                           const student_t_distribution& y);
14400b57cec5SDimitry Andric
14410b57cec5SDimitry Andric    template <class charT, class traits>
14420b57cec5SDimitry Andric    friend
14430b57cec5SDimitry Andric    basic_ostream<charT, traits>&
14440b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
14450b57cec5SDimitry Andric               const student_t_distribution& x);
14460b57cec5SDimitry Andric
14470b57cec5SDimitry Andric    template <class charT, class traits>
14480b57cec5SDimitry Andric    friend
14490b57cec5SDimitry Andric    basic_istream<charT, traits>&
14500b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
14510b57cec5SDimitry Andric               student_t_distribution& x);
14520b57cec5SDimitry Andric};
14530b57cec5SDimitry Andric
14540b57cec5SDimitry Andrictemplate<class IntType = int>
14550b57cec5SDimitry Andricclass discrete_distribution
14560b57cec5SDimitry Andric{
14570b57cec5SDimitry Andricpublic:
14580b57cec5SDimitry Andric    // types
14590b57cec5SDimitry Andric    typedef IntType result_type;
14600b57cec5SDimitry Andric
14610b57cec5SDimitry Andric    class param_type
14620b57cec5SDimitry Andric    {
14630b57cec5SDimitry Andric    public:
14640b57cec5SDimitry Andric        typedef discrete_distribution distribution_type;
14650b57cec5SDimitry Andric
14660b57cec5SDimitry Andric        param_type();
14670b57cec5SDimitry Andric        template<class InputIterator>
14680b57cec5SDimitry Andric            param_type(InputIterator firstW, InputIterator lastW);
14690b57cec5SDimitry Andric        param_type(initializer_list<double> wl);
14700b57cec5SDimitry Andric        template<class UnaryOperation>
14710b57cec5SDimitry Andric            param_type(size_t nw, double xmin, double xmax, UnaryOperation fw);
14720b57cec5SDimitry Andric
14730b57cec5SDimitry Andric        vector<double> probabilities() const;
14740b57cec5SDimitry Andric
14750b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
14760b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
14770b57cec5SDimitry Andric    };
14780b57cec5SDimitry Andric
14790b57cec5SDimitry Andric    // constructor and reset functions
14800b57cec5SDimitry Andric    discrete_distribution();
14810b57cec5SDimitry Andric    template<class InputIterator>
14820b57cec5SDimitry Andric        discrete_distribution(InputIterator firstW, InputIterator lastW);
14830b57cec5SDimitry Andric    discrete_distribution(initializer_list<double> wl);
14840b57cec5SDimitry Andric    template<class UnaryOperation>
14850b57cec5SDimitry Andric        discrete_distribution(size_t nw, double xmin, double xmax,
14860b57cec5SDimitry Andric                              UnaryOperation fw);
14870b57cec5SDimitry Andric    explicit discrete_distribution(const param_type& parm);
14880b57cec5SDimitry Andric    void reset();
14890b57cec5SDimitry Andric
14900b57cec5SDimitry Andric    // generating functions
14910b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
14920b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
14930b57cec5SDimitry Andric
14940b57cec5SDimitry Andric    // property functions
14950b57cec5SDimitry Andric    vector<double> probabilities() const;
14960b57cec5SDimitry Andric
14970b57cec5SDimitry Andric    param_type param() const;
14980b57cec5SDimitry Andric    void param(const param_type& parm);
14990b57cec5SDimitry Andric
15000b57cec5SDimitry Andric    result_type min() const;
15010b57cec5SDimitry Andric    result_type max() const;
15020b57cec5SDimitry Andric
15030b57cec5SDimitry Andric    friend bool operator==(const discrete_distribution& x,
15040b57cec5SDimitry Andric                           const discrete_distribution& y);
15050b57cec5SDimitry Andric    friend bool operator!=(const discrete_distribution& x,
15060b57cec5SDimitry Andric                           const discrete_distribution& y);
15070b57cec5SDimitry Andric
15080b57cec5SDimitry Andric    template <class charT, class traits>
15090b57cec5SDimitry Andric    friend
15100b57cec5SDimitry Andric    basic_ostream<charT, traits>&
15110b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
15120b57cec5SDimitry Andric               const discrete_distribution& x);
15130b57cec5SDimitry Andric
15140b57cec5SDimitry Andric    template <class charT, class traits>
15150b57cec5SDimitry Andric    friend
15160b57cec5SDimitry Andric    basic_istream<charT, traits>&
15170b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
15180b57cec5SDimitry Andric               discrete_distribution& x);
15190b57cec5SDimitry Andric};
15200b57cec5SDimitry Andric
15210b57cec5SDimitry Andrictemplate<class RealType = double>
15220b57cec5SDimitry Andricclass piecewise_constant_distribution
15230b57cec5SDimitry Andric{
15240b57cec5SDimitry Andric    // types
15250b57cec5SDimitry Andric    typedef RealType result_type;
15260b57cec5SDimitry Andric
15270b57cec5SDimitry Andric    class param_type
15280b57cec5SDimitry Andric    {
15290b57cec5SDimitry Andric    public:
15300b57cec5SDimitry Andric        typedef piecewise_constant_distribution distribution_type;
15310b57cec5SDimitry Andric
15320b57cec5SDimitry Andric        param_type();
15330b57cec5SDimitry Andric        template<class InputIteratorB, class InputIteratorW>
15340b57cec5SDimitry Andric            param_type(InputIteratorB firstB, InputIteratorB lastB,
15350b57cec5SDimitry Andric                       InputIteratorW firstW);
15360b57cec5SDimitry Andric        template<class UnaryOperation>
15370b57cec5SDimitry Andric            param_type(initializer_list<result_type> bl, UnaryOperation fw);
15380b57cec5SDimitry Andric        template<class UnaryOperation>
15390b57cec5SDimitry Andric            param_type(size_t nw, result_type xmin, result_type xmax,
15400b57cec5SDimitry Andric                       UnaryOperation fw);
15410b57cec5SDimitry Andric
15420b57cec5SDimitry Andric        vector<result_type> intervals() const;
15430b57cec5SDimitry Andric        vector<result_type> densities() const;
15440b57cec5SDimitry Andric
15450b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
15460b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
15470b57cec5SDimitry Andric    };
15480b57cec5SDimitry Andric
15490b57cec5SDimitry Andric    // constructor and reset functions
15500b57cec5SDimitry Andric    piecewise_constant_distribution();
15510b57cec5SDimitry Andric    template<class InputIteratorB, class InputIteratorW>
15520b57cec5SDimitry Andric        piecewise_constant_distribution(InputIteratorB firstB,
15530b57cec5SDimitry Andric                                        InputIteratorB lastB,
15540b57cec5SDimitry Andric                                        InputIteratorW firstW);
15550b57cec5SDimitry Andric    template<class UnaryOperation>
15560b57cec5SDimitry Andric        piecewise_constant_distribution(initializer_list<result_type> bl,
15570b57cec5SDimitry Andric                                        UnaryOperation fw);
15580b57cec5SDimitry Andric    template<class UnaryOperation>
15590b57cec5SDimitry Andric        piecewise_constant_distribution(size_t nw, result_type xmin,
15600b57cec5SDimitry Andric                                        result_type xmax, UnaryOperation fw);
15610b57cec5SDimitry Andric    explicit piecewise_constant_distribution(const param_type& parm);
15620b57cec5SDimitry Andric    void reset();
15630b57cec5SDimitry Andric
15640b57cec5SDimitry Andric    // generating functions
15650b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
15660b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
15670b57cec5SDimitry Andric
15680b57cec5SDimitry Andric    // property functions
15690b57cec5SDimitry Andric    vector<result_type> intervals() const;
15700b57cec5SDimitry Andric    vector<result_type> densities() const;
15710b57cec5SDimitry Andric
15720b57cec5SDimitry Andric    param_type param() const;
15730b57cec5SDimitry Andric    void param(const param_type& parm);
15740b57cec5SDimitry Andric
15750b57cec5SDimitry Andric    result_type min() const;
15760b57cec5SDimitry Andric    result_type max() const;
15770b57cec5SDimitry Andric
15780b57cec5SDimitry Andric    friend bool operator==(const piecewise_constant_distribution& x,
15790b57cec5SDimitry Andric                           const piecewise_constant_distribution& y);
15800b57cec5SDimitry Andric    friend bool operator!=(const piecewise_constant_distribution& x,
15810b57cec5SDimitry Andric                           const piecewise_constant_distribution& y);
15820b57cec5SDimitry Andric
15830b57cec5SDimitry Andric    template <class charT, class traits>
15840b57cec5SDimitry Andric    friend
15850b57cec5SDimitry Andric    basic_ostream<charT, traits>&
15860b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
15870b57cec5SDimitry Andric               const piecewise_constant_distribution& x);
15880b57cec5SDimitry Andric
15890b57cec5SDimitry Andric    template <class charT, class traits>
15900b57cec5SDimitry Andric    friend
15910b57cec5SDimitry Andric    basic_istream<charT, traits>&
15920b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
15930b57cec5SDimitry Andric               piecewise_constant_distribution& x);
15940b57cec5SDimitry Andric};
15950b57cec5SDimitry Andric
15960b57cec5SDimitry Andrictemplate<class RealType = double>
15970b57cec5SDimitry Andricclass piecewise_linear_distribution
15980b57cec5SDimitry Andric{
15990b57cec5SDimitry Andric    // types
16000b57cec5SDimitry Andric    typedef RealType result_type;
16010b57cec5SDimitry Andric
16020b57cec5SDimitry Andric    class param_type
16030b57cec5SDimitry Andric    {
16040b57cec5SDimitry Andric    public:
16050b57cec5SDimitry Andric        typedef piecewise_linear_distribution distribution_type;
16060b57cec5SDimitry Andric
16070b57cec5SDimitry Andric        param_type();
16080b57cec5SDimitry Andric        template<class InputIteratorB, class InputIteratorW>
16090b57cec5SDimitry Andric            param_type(InputIteratorB firstB, InputIteratorB lastB,
16100b57cec5SDimitry Andric                       InputIteratorW firstW);
16110b57cec5SDimitry Andric        template<class UnaryOperation>
16120b57cec5SDimitry Andric            param_type(initializer_list<result_type> bl, UnaryOperation fw);
16130b57cec5SDimitry Andric        template<class UnaryOperation>
16140b57cec5SDimitry Andric            param_type(size_t nw, result_type xmin, result_type xmax,
16150b57cec5SDimitry Andric                       UnaryOperation fw);
16160b57cec5SDimitry Andric
16170b57cec5SDimitry Andric        vector<result_type> intervals() const;
16180b57cec5SDimitry Andric        vector<result_type> densities() const;
16190b57cec5SDimitry Andric
16200b57cec5SDimitry Andric        friend bool operator==(const param_type& x, const param_type& y);
16210b57cec5SDimitry Andric        friend bool operator!=(const param_type& x, const param_type& y);
16220b57cec5SDimitry Andric    };
16230b57cec5SDimitry Andric
16240b57cec5SDimitry Andric    // constructor and reset functions
16250b57cec5SDimitry Andric    piecewise_linear_distribution();
16260b57cec5SDimitry Andric    template<class InputIteratorB, class InputIteratorW>
16270b57cec5SDimitry Andric        piecewise_linear_distribution(InputIteratorB firstB,
16280b57cec5SDimitry Andric                                      InputIteratorB lastB,
16290b57cec5SDimitry Andric                                      InputIteratorW firstW);
16300b57cec5SDimitry Andric
16310b57cec5SDimitry Andric    template<class UnaryOperation>
16320b57cec5SDimitry Andric        piecewise_linear_distribution(initializer_list<result_type> bl,
16330b57cec5SDimitry Andric                                      UnaryOperation fw);
16340b57cec5SDimitry Andric
16350b57cec5SDimitry Andric    template<class UnaryOperation>
16360b57cec5SDimitry Andric        piecewise_linear_distribution(size_t nw, result_type xmin,
16370b57cec5SDimitry Andric                                      result_type xmax, UnaryOperation fw);
16380b57cec5SDimitry Andric
16390b57cec5SDimitry Andric    explicit piecewise_linear_distribution(const param_type& parm);
16400b57cec5SDimitry Andric    void reset();
16410b57cec5SDimitry Andric
16420b57cec5SDimitry Andric    // generating functions
16430b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g);
16440b57cec5SDimitry Andric    template<class URNG> result_type operator()(URNG& g, const param_type& parm);
16450b57cec5SDimitry Andric
16460b57cec5SDimitry Andric    // property functions
16470b57cec5SDimitry Andric    vector<result_type> intervals() const;
16480b57cec5SDimitry Andric    vector<result_type> densities() const;
16490b57cec5SDimitry Andric
16500b57cec5SDimitry Andric    param_type param() const;
16510b57cec5SDimitry Andric    void param(const param_type& parm);
16520b57cec5SDimitry Andric
16530b57cec5SDimitry Andric    result_type min() const;
16540b57cec5SDimitry Andric    result_type max() const;
16550b57cec5SDimitry Andric
16560b57cec5SDimitry Andric    friend bool operator==(const piecewise_linear_distribution& x,
16570b57cec5SDimitry Andric                           const piecewise_linear_distribution& y);
16580b57cec5SDimitry Andric    friend bool operator!=(const piecewise_linear_distribution& x,
16590b57cec5SDimitry Andric                           const piecewise_linear_distribution& y);
16600b57cec5SDimitry Andric
16610b57cec5SDimitry Andric    template <class charT, class traits>
16620b57cec5SDimitry Andric    friend
16630b57cec5SDimitry Andric    basic_ostream<charT, traits>&
16640b57cec5SDimitry Andric    operator<<(basic_ostream<charT, traits>& os,
16650b57cec5SDimitry Andric               const piecewise_linear_distribution& x);
16660b57cec5SDimitry Andric
16670b57cec5SDimitry Andric    template <class charT, class traits>
16680b57cec5SDimitry Andric    friend
16690b57cec5SDimitry Andric    basic_istream<charT, traits>&
16700b57cec5SDimitry Andric    operator>>(basic_istream<charT, traits>& is,
16710b57cec5SDimitry Andric               piecewise_linear_distribution& x);
16720b57cec5SDimitry Andric};
16730b57cec5SDimitry Andric
16740b57cec5SDimitry Andric} // std
16750b57cec5SDimitry Andric*/
16760b57cec5SDimitry Andric
16770b57cec5SDimitry Andric#include <__config>
16780b57cec5SDimitry Andric#include <cstddef>
16790b57cec5SDimitry Andric#include <cstdint>
16800b57cec5SDimitry Andric#include <cmath>
16810b57cec5SDimitry Andric#include <type_traits>
16820b57cec5SDimitry Andric#include <initializer_list>
16830b57cec5SDimitry Andric#include <limits>
16840b57cec5SDimitry Andric#include <algorithm>
16850b57cec5SDimitry Andric#include <numeric>
16860b57cec5SDimitry Andric#include <vector>
16870b57cec5SDimitry Andric#include <string>
1688*e8d8bef9SDimitry Andric#include <iosfwd>
16890b57cec5SDimitry Andric
16900b57cec5SDimitry Andric#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
16910b57cec5SDimitry Andric#pragma GCC system_header
16920b57cec5SDimitry Andric#endif
16930b57cec5SDimitry Andric
16940b57cec5SDimitry Andric_LIBCPP_PUSH_MACROS
16950b57cec5SDimitry Andric#include <__undef_macros>
16960b57cec5SDimitry Andric
16970b57cec5SDimitry Andric
16980b57cec5SDimitry Andric_LIBCPP_BEGIN_NAMESPACE_STD
16990b57cec5SDimitry Andric
17000b57cec5SDimitry Andric// __is_seed_sequence
17010b57cec5SDimitry Andric
17020b57cec5SDimitry Andrictemplate <class _Sseq, class _Engine>
17030b57cec5SDimitry Andricstruct __is_seed_sequence
17040b57cec5SDimitry Andric{
17050b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const bool value =
17060b57cec5SDimitry Andric              !is_convertible<_Sseq, typename _Engine::result_type>::value &&
17070b57cec5SDimitry Andric              !is_same<typename remove_cv<_Sseq>::type, _Engine>::value;
17080b57cec5SDimitry Andric};
17090b57cec5SDimitry Andric
17100b57cec5SDimitry Andric// linear_congruential_engine
17110b57cec5SDimitry Andric
17120b57cec5SDimitry Andrictemplate <unsigned long long __a, unsigned long long __c,
17130b57cec5SDimitry Andric          unsigned long long __m, unsigned long long _Mp,
1714*e8d8bef9SDimitry Andric          bool _MightOverflow = (__a != 0 && __m != 0 && __m-1 > (_Mp-__c)/__a),
1715*e8d8bef9SDimitry Andric          bool _OverflowOK = ((__m|__m-1) > __m), // m = 2^n
1716*e8d8bef9SDimitry Andric          bool _SchrageOK = (__a != 0 && __m != 0 && __m % __a <= __m / __a)> // r <= q
1717*e8d8bef9SDimitry Andricstruct __lce_alg_picker
1718*e8d8bef9SDimitry Andric{
1719*e8d8bef9SDimitry Andric    static_assert(__a != 0 || __m != 0 || !_MightOverflow || _OverflowOK || _SchrageOK,
1720*e8d8bef9SDimitry Andric                  "The current values of a, c, and m cannot generate a number "
1721*e8d8bef9SDimitry Andric                  "within bounds of linear_congruential_engine.");
1722*e8d8bef9SDimitry Andric
1723*e8d8bef9SDimitry Andric    static _LIBCPP_CONSTEXPR const bool __use_schrage = _MightOverflow &&
1724*e8d8bef9SDimitry Andric                                                        !_OverflowOK &&
1725*e8d8bef9SDimitry Andric                                                        _SchrageOK;
1726*e8d8bef9SDimitry Andric};
1727*e8d8bef9SDimitry Andric
1728*e8d8bef9SDimitry Andrictemplate <unsigned long long __a, unsigned long long __c,
1729*e8d8bef9SDimitry Andric          unsigned long long __m, unsigned long long _Mp,
1730*e8d8bef9SDimitry Andric          bool _UseSchrage = __lce_alg_picker<__a, __c, __m, _Mp>::__use_schrage>
17310b57cec5SDimitry Andricstruct __lce_ta;
17320b57cec5SDimitry Andric
17330b57cec5SDimitry Andric// 64
17340b57cec5SDimitry Andric
17350b57cec5SDimitry Andrictemplate <unsigned long long __a, unsigned long long __c, unsigned long long __m>
17360b57cec5SDimitry Andricstruct __lce_ta<__a, __c, __m, (unsigned long long)(~0), true>
17370b57cec5SDimitry Andric{
17380b57cec5SDimitry Andric    typedef unsigned long long result_type;
17390b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17400b57cec5SDimitry Andric    static result_type next(result_type __x)
17410b57cec5SDimitry Andric    {
17420b57cec5SDimitry Andric        // Schrage's algorithm
17430b57cec5SDimitry Andric        const result_type __q = __m / __a;
17440b57cec5SDimitry Andric        const result_type __r = __m % __a;
17450b57cec5SDimitry Andric        const result_type __t0 = __a * (__x % __q);
17460b57cec5SDimitry Andric        const result_type __t1 = __r * (__x / __q);
17470b57cec5SDimitry Andric        __x = __t0 + (__t0 < __t1) * __m - __t1;
17480b57cec5SDimitry Andric        __x += __c - (__x >= __m - __c) * __m;
17490b57cec5SDimitry Andric        return __x;
17500b57cec5SDimitry Andric    }
17510b57cec5SDimitry Andric};
17520b57cec5SDimitry Andric
17530b57cec5SDimitry Andrictemplate <unsigned long long __a, unsigned long long __m>
17540b57cec5SDimitry Andricstruct __lce_ta<__a, 0, __m, (unsigned long long)(~0), true>
17550b57cec5SDimitry Andric{
17560b57cec5SDimitry Andric    typedef unsigned long long result_type;
17570b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17580b57cec5SDimitry Andric    static result_type next(result_type __x)
17590b57cec5SDimitry Andric    {
17600b57cec5SDimitry Andric        // Schrage's algorithm
17610b57cec5SDimitry Andric        const result_type __q = __m / __a;
17620b57cec5SDimitry Andric        const result_type __r = __m % __a;
17630b57cec5SDimitry Andric        const result_type __t0 = __a * (__x % __q);
17640b57cec5SDimitry Andric        const result_type __t1 = __r * (__x / __q);
17650b57cec5SDimitry Andric        __x = __t0 + (__t0 < __t1) * __m - __t1;
17660b57cec5SDimitry Andric        return __x;
17670b57cec5SDimitry Andric    }
17680b57cec5SDimitry Andric};
17690b57cec5SDimitry Andric
17700b57cec5SDimitry Andrictemplate <unsigned long long __a, unsigned long long __c, unsigned long long __m>
17710b57cec5SDimitry Andricstruct __lce_ta<__a, __c, __m, (unsigned long long)(~0), false>
17720b57cec5SDimitry Andric{
17730b57cec5SDimitry Andric    typedef unsigned long long result_type;
17740b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17750b57cec5SDimitry Andric    static result_type next(result_type __x)
17760b57cec5SDimitry Andric    {
17770b57cec5SDimitry Andric        return (__a * __x + __c) % __m;
17780b57cec5SDimitry Andric    }
17790b57cec5SDimitry Andric};
17800b57cec5SDimitry Andric
17810b57cec5SDimitry Andrictemplate <unsigned long long __a, unsigned long long __c>
17820b57cec5SDimitry Andricstruct __lce_ta<__a, __c, 0, (unsigned long long)(~0), false>
17830b57cec5SDimitry Andric{
17840b57cec5SDimitry Andric    typedef unsigned long long result_type;
17850b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17860b57cec5SDimitry Andric    static result_type next(result_type __x)
17870b57cec5SDimitry Andric    {
17880b57cec5SDimitry Andric        return __a * __x + __c;
17890b57cec5SDimitry Andric    }
17900b57cec5SDimitry Andric};
17910b57cec5SDimitry Andric
17920b57cec5SDimitry Andric// 32
17930b57cec5SDimitry Andric
17940b57cec5SDimitry Andrictemplate <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp>
17950b57cec5SDimitry Andricstruct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), true>
17960b57cec5SDimitry Andric{
17970b57cec5SDimitry Andric    typedef unsigned result_type;
17980b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
17990b57cec5SDimitry Andric    static result_type next(result_type __x)
18000b57cec5SDimitry Andric    {
18010b57cec5SDimitry Andric        const result_type __a = static_cast<result_type>(_Ap);
18020b57cec5SDimitry Andric        const result_type __c = static_cast<result_type>(_Cp);
18030b57cec5SDimitry Andric        const result_type __m = static_cast<result_type>(_Mp);
18040b57cec5SDimitry Andric        // Schrage's algorithm
18050b57cec5SDimitry Andric        const result_type __q = __m / __a;
18060b57cec5SDimitry Andric        const result_type __r = __m % __a;
18070b57cec5SDimitry Andric        const result_type __t0 = __a * (__x % __q);
18080b57cec5SDimitry Andric        const result_type __t1 = __r * (__x / __q);
18090b57cec5SDimitry Andric        __x = __t0 + (__t0 < __t1) * __m - __t1;
18100b57cec5SDimitry Andric        __x += __c - (__x >= __m - __c) * __m;
18110b57cec5SDimitry Andric        return __x;
18120b57cec5SDimitry Andric    }
18130b57cec5SDimitry Andric};
18140b57cec5SDimitry Andric
18150b57cec5SDimitry Andrictemplate <unsigned long long _Ap, unsigned long long _Mp>
18160b57cec5SDimitry Andricstruct __lce_ta<_Ap, 0, _Mp, unsigned(~0), true>
18170b57cec5SDimitry Andric{
18180b57cec5SDimitry Andric    typedef unsigned result_type;
18190b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18200b57cec5SDimitry Andric    static result_type next(result_type __x)
18210b57cec5SDimitry Andric    {
18220b57cec5SDimitry Andric        const result_type __a = static_cast<result_type>(_Ap);
18230b57cec5SDimitry Andric        const result_type __m = static_cast<result_type>(_Mp);
18240b57cec5SDimitry Andric        // Schrage's algorithm
18250b57cec5SDimitry Andric        const result_type __q = __m / __a;
18260b57cec5SDimitry Andric        const result_type __r = __m % __a;
18270b57cec5SDimitry Andric        const result_type __t0 = __a * (__x % __q);
18280b57cec5SDimitry Andric        const result_type __t1 = __r * (__x / __q);
18290b57cec5SDimitry Andric        __x = __t0 + (__t0 < __t1) * __m - __t1;
18300b57cec5SDimitry Andric        return __x;
18310b57cec5SDimitry Andric    }
18320b57cec5SDimitry Andric};
18330b57cec5SDimitry Andric
18340b57cec5SDimitry Andrictemplate <unsigned long long _Ap, unsigned long long _Cp, unsigned long long _Mp>
18350b57cec5SDimitry Andricstruct __lce_ta<_Ap, _Cp, _Mp, unsigned(~0), false>
18360b57cec5SDimitry Andric{
18370b57cec5SDimitry Andric    typedef unsigned result_type;
18380b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18390b57cec5SDimitry Andric    static result_type next(result_type __x)
18400b57cec5SDimitry Andric    {
18410b57cec5SDimitry Andric        const result_type __a = static_cast<result_type>(_Ap);
18420b57cec5SDimitry Andric        const result_type __c = static_cast<result_type>(_Cp);
18430b57cec5SDimitry Andric        const result_type __m = static_cast<result_type>(_Mp);
18440b57cec5SDimitry Andric        return (__a * __x + __c) % __m;
18450b57cec5SDimitry Andric    }
18460b57cec5SDimitry Andric};
18470b57cec5SDimitry Andric
18480b57cec5SDimitry Andrictemplate <unsigned long long _Ap, unsigned long long _Cp>
18490b57cec5SDimitry Andricstruct __lce_ta<_Ap, _Cp, 0, unsigned(~0), false>
18500b57cec5SDimitry Andric{
18510b57cec5SDimitry Andric    typedef unsigned result_type;
18520b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18530b57cec5SDimitry Andric    static result_type next(result_type __x)
18540b57cec5SDimitry Andric    {
18550b57cec5SDimitry Andric        const result_type __a = static_cast<result_type>(_Ap);
18560b57cec5SDimitry Andric        const result_type __c = static_cast<result_type>(_Cp);
18570b57cec5SDimitry Andric        return __a * __x + __c;
18580b57cec5SDimitry Andric    }
18590b57cec5SDimitry Andric};
18600b57cec5SDimitry Andric
18610b57cec5SDimitry Andric// 16
18620b57cec5SDimitry Andric
18630b57cec5SDimitry Andrictemplate <unsigned long long __a, unsigned long long __c, unsigned long long __m, bool __b>
18640b57cec5SDimitry Andricstruct __lce_ta<__a, __c, __m, (unsigned short)(~0), __b>
18650b57cec5SDimitry Andric{
18660b57cec5SDimitry Andric    typedef unsigned short result_type;
18670b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
18680b57cec5SDimitry Andric    static result_type next(result_type __x)
18690b57cec5SDimitry Andric    {
18700b57cec5SDimitry Andric        return static_cast<result_type>(__lce_ta<__a, __c, __m, unsigned(~0)>::next(__x));
18710b57cec5SDimitry Andric    }
18720b57cec5SDimitry Andric};
18730b57cec5SDimitry Andric
18740b57cec5SDimitry Andrictemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
18750b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS linear_congruential_engine;
18760b57cec5SDimitry Andric
18770b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
18780b57cec5SDimitry Andric          class _Up, _Up _Ap, _Up _Cp, _Up _Np>
18790b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
18800b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
18810b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
18820b57cec5SDimitry Andric           const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&);
18830b57cec5SDimitry Andric
18840b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
18850b57cec5SDimitry Andric          class _Up, _Up _Ap, _Up _Cp, _Up _Np>
18860b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
18870b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
18880b57cec5SDimitry Andric           linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x);
18890b57cec5SDimitry Andric
18900b57cec5SDimitry Andrictemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
18910b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS linear_congruential_engine
18920b57cec5SDimitry Andric{
18930b57cec5SDimitry Andricpublic:
18940b57cec5SDimitry Andric    // types
18950b57cec5SDimitry Andric    typedef _UIntType result_type;
18960b57cec5SDimitry Andric
18970b57cec5SDimitry Andricprivate:
18980b57cec5SDimitry Andric    result_type __x_;
18990b57cec5SDimitry Andric
19000b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Mp = result_type(~0);
19010b57cec5SDimitry Andric
19020b57cec5SDimitry Andric    static_assert(__m == 0 || __a < __m, "linear_congruential_engine invalid parameters");
19030b57cec5SDimitry Andric    static_assert(__m == 0 || __c < __m, "linear_congruential_engine invalid parameters");
1904*e8d8bef9SDimitry Andric    static_assert(_VSTD::is_unsigned<_UIntType>::value, "_UIntType must be unsigned type");
19050b57cec5SDimitry Andricpublic:
19060b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Min = __c == 0u ? 1u: 0u;
19070b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Max = __m - 1u;
19080b57cec5SDimitry Andric    static_assert(_Min < _Max,           "linear_congruential_engine invalid parameters");
19090b57cec5SDimitry Andric
19100b57cec5SDimitry Andric    // engine characteristics
19110b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type multiplier = __a;
19120b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type increment = __c;
19130b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type modulus = __m;
19140b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
19150b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR result_type min() {return _Min;}
19160b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
19170b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR result_type max() {return _Max;}
19180b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type default_seed = 1u;
19190b57cec5SDimitry Andric
19200b57cec5SDimitry Andric    // constructors and seeding functions
1921*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
19220b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1923*e8d8bef9SDimitry Andric    linear_congruential_engine() : linear_congruential_engine(default_seed) {}
1924*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1925*e8d8bef9SDimitry Andric    explicit linear_congruential_engine(result_type __s) { seed(__s); }
1926*e8d8bef9SDimitry Andric#else
1927*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
1928*e8d8bef9SDimitry Andric    explicit linear_congruential_engine(result_type __s = default_seed) {
1929*e8d8bef9SDimitry Andric      seed(__s);
1930*e8d8bef9SDimitry Andric    }
1931*e8d8bef9SDimitry Andric#endif
19320b57cec5SDimitry Andric    template<class _Sseq>
19330b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
19340b57cec5SDimitry Andric        explicit linear_congruential_engine(_Sseq& __q,
19350b57cec5SDimitry Andric        typename enable_if<__is_seed_sequence<_Sseq, linear_congruential_engine>::value>::type* = 0)
19360b57cec5SDimitry Andric        {seed(__q);}
19370b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
19380b57cec5SDimitry Andric    void seed(result_type __s = default_seed)
19390b57cec5SDimitry Andric        {seed(integral_constant<bool, __m == 0>(),
19400b57cec5SDimitry Andric              integral_constant<bool, __c == 0>(), __s);}
19410b57cec5SDimitry Andric    template<class _Sseq>
19420b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
19430b57cec5SDimitry Andric        typename enable_if
19440b57cec5SDimitry Andric        <
19450b57cec5SDimitry Andric            __is_seed_sequence<_Sseq, linear_congruential_engine>::value,
19460b57cec5SDimitry Andric            void
19470b57cec5SDimitry Andric        >::type
19480b57cec5SDimitry Andric        seed(_Sseq& __q)
19490b57cec5SDimitry Andric            {__seed(__q, integral_constant<unsigned,
19500b57cec5SDimitry Andric                1 + (__m == 0 ? (sizeof(result_type) * __CHAR_BIT__ - 1)/32
19510b57cec5SDimitry Andric                             :  (__m > 0x100000000ull))>());}
19520b57cec5SDimitry Andric
19530b57cec5SDimitry Andric    // generating functions
19540b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
19550b57cec5SDimitry Andric    result_type operator()()
19560b57cec5SDimitry Andric        {return __x_ = static_cast<result_type>(__lce_ta<__a, __c, __m, _Mp>::next(__x_));}
19570b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
19580b57cec5SDimitry Andric    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
19590b57cec5SDimitry Andric
19600b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
19610b57cec5SDimitry Andric    bool operator==(const linear_congruential_engine& __x,
19620b57cec5SDimitry Andric                    const linear_congruential_engine& __y)
19630b57cec5SDimitry Andric        {return __x.__x_ == __y.__x_;}
19640b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
19650b57cec5SDimitry Andric    bool operator!=(const linear_congruential_engine& __x,
19660b57cec5SDimitry Andric                    const linear_congruential_engine& __y)
19670b57cec5SDimitry Andric        {return !(__x == __y);}
19680b57cec5SDimitry Andric
19690b57cec5SDimitry Andricprivate:
19700b57cec5SDimitry Andric
19710b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
19720b57cec5SDimitry Andric    void seed(true_type, true_type, result_type __s) {__x_ = __s == 0 ? 1 : __s;}
19730b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
19740b57cec5SDimitry Andric    void seed(true_type, false_type, result_type __s) {__x_ = __s;}
19750b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
19760b57cec5SDimitry Andric    void seed(false_type, true_type, result_type __s) {__x_ = __s % __m == 0 ?
19770b57cec5SDimitry Andric                                                                 1 : __s % __m;}
19780b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
19790b57cec5SDimitry Andric    void seed(false_type, false_type, result_type __s) {__x_ = __s % __m;}
19800b57cec5SDimitry Andric
19810b57cec5SDimitry Andric    template<class _Sseq>
19820b57cec5SDimitry Andric        void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
19830b57cec5SDimitry Andric    template<class _Sseq>
19840b57cec5SDimitry Andric        void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
19850b57cec5SDimitry Andric
19860b57cec5SDimitry Andric    template <class _CharT, class _Traits,
19870b57cec5SDimitry Andric              class _Up, _Up _Ap, _Up _Cp, _Up _Np>
19880b57cec5SDimitry Andric    friend
19890b57cec5SDimitry Andric    basic_ostream<_CharT, _Traits>&
19900b57cec5SDimitry Andric    operator<<(basic_ostream<_CharT, _Traits>& __os,
19910b57cec5SDimitry Andric               const linear_congruential_engine<_Up, _Ap, _Cp, _Np>&);
19920b57cec5SDimitry Andric
19930b57cec5SDimitry Andric    template <class _CharT, class _Traits,
19940b57cec5SDimitry Andric              class _Up, _Up _Ap, _Up _Cp, _Up _Np>
19950b57cec5SDimitry Andric    friend
19960b57cec5SDimitry Andric    basic_istream<_CharT, _Traits>&
19970b57cec5SDimitry Andric    operator>>(basic_istream<_CharT, _Traits>& __is,
19980b57cec5SDimitry Andric               linear_congruential_engine<_Up, _Ap, _Cp, _Np>& __x);
19990b57cec5SDimitry Andric};
20000b57cec5SDimitry Andric
20010b57cec5SDimitry Andrictemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
20020b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
20030b57cec5SDimitry Andric    linear_congruential_engine<_UIntType, __a, __c, __m>::multiplier;
20040b57cec5SDimitry Andric
20050b57cec5SDimitry Andrictemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
20060b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
20070b57cec5SDimitry Andric    linear_congruential_engine<_UIntType, __a, __c, __m>::increment;
20080b57cec5SDimitry Andric
20090b57cec5SDimitry Andrictemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
20100b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
20110b57cec5SDimitry Andric    linear_congruential_engine<_UIntType, __a, __c, __m>::modulus;
20120b57cec5SDimitry Andric
20130b57cec5SDimitry Andrictemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
20140b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const typename linear_congruential_engine<_UIntType, __a, __c, __m>::result_type
20150b57cec5SDimitry Andric    linear_congruential_engine<_UIntType, __a, __c, __m>::default_seed;
20160b57cec5SDimitry Andric
20170b57cec5SDimitry Andrictemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
20180b57cec5SDimitry Andrictemplate<class _Sseq>
20190b57cec5SDimitry Andricvoid
20200b57cec5SDimitry Andriclinear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q,
20210b57cec5SDimitry Andric                                                 integral_constant<unsigned, 1>)
20220b57cec5SDimitry Andric{
20230b57cec5SDimitry Andric    const unsigned __k = 1;
20240b57cec5SDimitry Andric    uint32_t __ar[__k+3];
20250b57cec5SDimitry Andric    __q.generate(__ar, __ar + __k + 3);
20260b57cec5SDimitry Andric    result_type __s = static_cast<result_type>(__ar[3] % __m);
20270b57cec5SDimitry Andric    __x_ = __c == 0 && __s == 0 ? result_type(1) : __s;
20280b57cec5SDimitry Andric}
20290b57cec5SDimitry Andric
20300b57cec5SDimitry Andrictemplate <class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
20310b57cec5SDimitry Andrictemplate<class _Sseq>
20320b57cec5SDimitry Andricvoid
20330b57cec5SDimitry Andriclinear_congruential_engine<_UIntType, __a, __c, __m>::__seed(_Sseq& __q,
20340b57cec5SDimitry Andric                                                 integral_constant<unsigned, 2>)
20350b57cec5SDimitry Andric{
20360b57cec5SDimitry Andric    const unsigned __k = 2;
20370b57cec5SDimitry Andric    uint32_t __ar[__k+3];
20380b57cec5SDimitry Andric    __q.generate(__ar, __ar + __k + 3);
20390b57cec5SDimitry Andric    result_type __s = static_cast<result_type>((__ar[3] +
20400b57cec5SDimitry Andric                                              ((uint64_t)__ar[4] << 32)) % __m);
20410b57cec5SDimitry Andric    __x_ = __c == 0 && __s == 0 ? result_type(1) : __s;
20420b57cec5SDimitry Andric}
20430b57cec5SDimitry Andric
20440b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
20450b57cec5SDimitry Andric          class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
20460b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
20470b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
20480b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
20490b57cec5SDimitry Andric           const linear_congruential_engine<_UIntType, __a, __c, __m>& __x)
20500b57cec5SDimitry Andric{
20510b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
2052*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _Ostream;
2053*e8d8bef9SDimitry Andric    __os.flags(_Ostream::dec | _Ostream::left);
20540b57cec5SDimitry Andric    __os.fill(__os.widen(' '));
20550b57cec5SDimitry Andric    return __os << __x.__x_;
20560b57cec5SDimitry Andric}
20570b57cec5SDimitry Andric
20580b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
20590b57cec5SDimitry Andric          class _UIntType, _UIntType __a, _UIntType __c, _UIntType __m>
20600b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
20610b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
20620b57cec5SDimitry Andric           linear_congruential_engine<_UIntType, __a, __c, __m>& __x)
20630b57cec5SDimitry Andric{
20640b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
2065*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
2066*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
20670b57cec5SDimitry Andric    _UIntType __t;
20680b57cec5SDimitry Andric    __is >> __t;
20690b57cec5SDimitry Andric    if (!__is.fail())
20700b57cec5SDimitry Andric        __x.__x_ = __t;
20710b57cec5SDimitry Andric    return __is;
20720b57cec5SDimitry Andric}
20730b57cec5SDimitry Andric
20740b57cec5SDimitry Andrictypedef linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>
20750b57cec5SDimitry Andric                                                                   minstd_rand0;
20760b57cec5SDimitry Andrictypedef linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647>
20770b57cec5SDimitry Andric                                                                    minstd_rand;
20780b57cec5SDimitry Andrictypedef minstd_rand                                       default_random_engine;
20790b57cec5SDimitry Andric// mersenne_twister_engine
20800b57cec5SDimitry Andric
20810b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
20820b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
20830b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
20840b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS mersenne_twister_engine;
20850b57cec5SDimitry Andric
20860b57cec5SDimitry Andrictemplate <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
20870b57cec5SDimitry Andric          _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
20880b57cec5SDimitry Andric          _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
20890b57cec5SDimitry Andricbool
20900b57cec5SDimitry Andricoperator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
20910b57cec5SDimitry Andric                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
20920b57cec5SDimitry Andric           const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
20930b57cec5SDimitry Andric                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
20940b57cec5SDimitry Andric
20950b57cec5SDimitry Andrictemplate <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
20960b57cec5SDimitry Andric          _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
20970b57cec5SDimitry Andric          _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
20980b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
20990b57cec5SDimitry Andricbool
21000b57cec5SDimitry Andricoperator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
21010b57cec5SDimitry Andric                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
21020b57cec5SDimitry Andric           const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
21030b57cec5SDimitry Andric                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
21040b57cec5SDimitry Andric
21050b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
21060b57cec5SDimitry Andric          class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
21070b57cec5SDimitry Andric          _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
21080b57cec5SDimitry Andric          _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
21090b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
21100b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
21110b57cec5SDimitry Andric           const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
21120b57cec5SDimitry Andric                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
21130b57cec5SDimitry Andric
21140b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
21150b57cec5SDimitry Andric          class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
21160b57cec5SDimitry Andric          _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
21170b57cec5SDimitry Andric          _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
21180b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
21190b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
21200b57cec5SDimitry Andric           mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
21210b57cec5SDimitry Andric                                   _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
21220b57cec5SDimitry Andric
21230b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
21240b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
21250b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
21260b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS mersenne_twister_engine
21270b57cec5SDimitry Andric{
21280b57cec5SDimitry Andricpublic:
21290b57cec5SDimitry Andric    // types
21300b57cec5SDimitry Andric    typedef _UIntType result_type;
21310b57cec5SDimitry Andric
21320b57cec5SDimitry Andricprivate:
21330b57cec5SDimitry Andric    result_type __x_[__n];
21340b57cec5SDimitry Andric    size_t      __i_;
21350b57cec5SDimitry Andric
21360b57cec5SDimitry Andric    static_assert(  0 <  __m, "mersenne_twister_engine invalid parameters");
21370b57cec5SDimitry Andric    static_assert(__m <= __n, "mersenne_twister_engine invalid parameters");
21380b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits<result_type>::digits;
21390b57cec5SDimitry Andric    static_assert(__w <= _Dt, "mersenne_twister_engine invalid parameters");
21400b57cec5SDimitry Andric    static_assert(  2 <= __w, "mersenne_twister_engine invalid parameters");
21410b57cec5SDimitry Andric    static_assert(__r <= __w, "mersenne_twister_engine invalid parameters");
21420b57cec5SDimitry Andric    static_assert(__u <= __w, "mersenne_twister_engine invalid parameters");
21430b57cec5SDimitry Andric    static_assert(__s <= __w, "mersenne_twister_engine invalid parameters");
21440b57cec5SDimitry Andric    static_assert(__t <= __w, "mersenne_twister_engine invalid parameters");
21450b57cec5SDimitry Andric    static_assert(__l <= __w, "mersenne_twister_engine invalid parameters");
21460b57cec5SDimitry Andricpublic:
21470b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Min = 0;
21480b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) :
21490b57cec5SDimitry Andric                                                      (result_type(1) << __w) - result_type(1);
21500b57cec5SDimitry Andric    static_assert(_Min < _Max, "mersenne_twister_engine invalid parameters");
21510b57cec5SDimitry Andric    static_assert(__a <= _Max, "mersenne_twister_engine invalid parameters");
21520b57cec5SDimitry Andric    static_assert(__b <= _Max, "mersenne_twister_engine invalid parameters");
21530b57cec5SDimitry Andric    static_assert(__c <= _Max, "mersenne_twister_engine invalid parameters");
21540b57cec5SDimitry Andric    static_assert(__d <= _Max, "mersenne_twister_engine invalid parameters");
21550b57cec5SDimitry Andric    static_assert(__f <= _Max, "mersenne_twister_engine invalid parameters");
21560b57cec5SDimitry Andric
21570b57cec5SDimitry Andric    // engine characteristics
21580b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t word_size = __w;
21590b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t state_size = __n;
21600b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t shift_size = __m;
21610b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t mask_bits = __r;
21620b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type xor_mask = __a;
21630b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t tempering_u = __u;
21640b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type tempering_d = __d;
21650b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t tempering_s = __s;
21660b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type tempering_b = __b;
21670b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t tempering_t = __t;
21680b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type tempering_c = __c;
21690b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t tempering_l = __l;
21700b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type initialization_multiplier = __f;
21710b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
21720b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR result_type min() { return _Min; }
21730b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
21740b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR result_type max() { return _Max; }
21750b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type default_seed = 5489u;
21760b57cec5SDimitry Andric
21770b57cec5SDimitry Andric    // constructors and seeding functions
2178*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
21790b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2180*e8d8bef9SDimitry Andric    mersenne_twister_engine() : mersenne_twister_engine(default_seed) {}
2181*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2182*e8d8bef9SDimitry Andric    explicit mersenne_twister_engine(result_type __sd) { seed(__sd); }
2183*e8d8bef9SDimitry Andric#else
2184*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2185*e8d8bef9SDimitry Andric    explicit mersenne_twister_engine(result_type __sd = default_seed) {
2186*e8d8bef9SDimitry Andric      seed(__sd);
2187*e8d8bef9SDimitry Andric    }
2188*e8d8bef9SDimitry Andric#endif
21890b57cec5SDimitry Andric    template<class _Sseq>
21900b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
21910b57cec5SDimitry Andric        explicit mersenne_twister_engine(_Sseq& __q,
21920b57cec5SDimitry Andric        typename enable_if<__is_seed_sequence<_Sseq, mersenne_twister_engine>::value>::type* = 0)
21930b57cec5SDimitry Andric        {seed(__q);}
21940b57cec5SDimitry Andric    void seed(result_type __sd = default_seed);
21950b57cec5SDimitry Andric    template<class _Sseq>
21960b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
21970b57cec5SDimitry Andric        typename enable_if
21980b57cec5SDimitry Andric        <
21990b57cec5SDimitry Andric            __is_seed_sequence<_Sseq, mersenne_twister_engine>::value,
22000b57cec5SDimitry Andric            void
22010b57cec5SDimitry Andric        >::type
22020b57cec5SDimitry Andric        seed(_Sseq& __q)
22030b57cec5SDimitry Andric            {__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());}
22040b57cec5SDimitry Andric
22050b57cec5SDimitry Andric    // generating functions
22060b57cec5SDimitry Andric    result_type operator()();
22070b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
22080b57cec5SDimitry Andric    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
22090b57cec5SDimitry Andric
22100b57cec5SDimitry Andric    template <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
22110b57cec5SDimitry Andric              _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
22120b57cec5SDimitry Andric              _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
22130b57cec5SDimitry Andric    friend
22140b57cec5SDimitry Andric    bool
22150b57cec5SDimitry Andric    operator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
22160b57cec5SDimitry Andric                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
22170b57cec5SDimitry Andric               const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
22180b57cec5SDimitry Andric                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
22190b57cec5SDimitry Andric
22200b57cec5SDimitry Andric    template <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
22210b57cec5SDimitry Andric              _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
22220b57cec5SDimitry Andric              _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
22230b57cec5SDimitry Andric    friend
22240b57cec5SDimitry Andric    bool
22250b57cec5SDimitry Andric    operator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
22260b57cec5SDimitry Andric                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
22270b57cec5SDimitry Andric               const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
22280b57cec5SDimitry Andric                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __y);
22290b57cec5SDimitry Andric
22300b57cec5SDimitry Andric    template <class _CharT, class _Traits,
22310b57cec5SDimitry Andric              class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
22320b57cec5SDimitry Andric              _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
22330b57cec5SDimitry Andric              _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
22340b57cec5SDimitry Andric    friend
22350b57cec5SDimitry Andric    basic_ostream<_CharT, _Traits>&
22360b57cec5SDimitry Andric    operator<<(basic_ostream<_CharT, _Traits>& __os,
22370b57cec5SDimitry Andric               const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
22380b57cec5SDimitry Andric                                             _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
22390b57cec5SDimitry Andric
22400b57cec5SDimitry Andric    template <class _CharT, class _Traits,
22410b57cec5SDimitry Andric              class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
22420b57cec5SDimitry Andric              _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
22430b57cec5SDimitry Andric              _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
22440b57cec5SDimitry Andric    friend
22450b57cec5SDimitry Andric    basic_istream<_CharT, _Traits>&
22460b57cec5SDimitry Andric    operator>>(basic_istream<_CharT, _Traits>& __is,
22470b57cec5SDimitry Andric               mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
22480b57cec5SDimitry Andric                                       _Bp, _Tp, _Cp, _Lp, _Fp>& __x);
22490b57cec5SDimitry Andricprivate:
22500b57cec5SDimitry Andric
22510b57cec5SDimitry Andric    template<class _Sseq>
22520b57cec5SDimitry Andric        void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
22530b57cec5SDimitry Andric    template<class _Sseq>
22540b57cec5SDimitry Andric        void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
22550b57cec5SDimitry Andric
22560b57cec5SDimitry Andric    template <size_t __count>
22570b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
22580b57cec5SDimitry Andric        static
22590b57cec5SDimitry Andric        typename enable_if
22600b57cec5SDimitry Andric        <
22610b57cec5SDimitry Andric            __count < __w,
22620b57cec5SDimitry Andric            result_type
22630b57cec5SDimitry Andric        >::type
22640b57cec5SDimitry Andric        __lshift(result_type __x) {return (__x << __count) & _Max;}
22650b57cec5SDimitry Andric
22660b57cec5SDimitry Andric    template <size_t __count>
22670b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
22680b57cec5SDimitry Andric        static
22690b57cec5SDimitry Andric        typename enable_if
22700b57cec5SDimitry Andric        <
22710b57cec5SDimitry Andric            (__count >= __w),
22720b57cec5SDimitry Andric            result_type
22730b57cec5SDimitry Andric        >::type
22740b57cec5SDimitry Andric        __lshift(result_type) {return result_type(0);}
22750b57cec5SDimitry Andric
22760b57cec5SDimitry Andric    template <size_t __count>
22770b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
22780b57cec5SDimitry Andric        static
22790b57cec5SDimitry Andric        typename enable_if
22800b57cec5SDimitry Andric        <
22810b57cec5SDimitry Andric            __count < _Dt,
22820b57cec5SDimitry Andric            result_type
22830b57cec5SDimitry Andric        >::type
22840b57cec5SDimitry Andric        __rshift(result_type __x) {return __x >> __count;}
22850b57cec5SDimitry Andric
22860b57cec5SDimitry Andric    template <size_t __count>
22870b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
22880b57cec5SDimitry Andric        static
22890b57cec5SDimitry Andric        typename enable_if
22900b57cec5SDimitry Andric        <
22910b57cec5SDimitry Andric            (__count >= _Dt),
22920b57cec5SDimitry Andric            result_type
22930b57cec5SDimitry Andric        >::type
22940b57cec5SDimitry Andric        __rshift(result_type) {return result_type(0);}
22950b57cec5SDimitry Andric};
22960b57cec5SDimitry Andric
22970b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
22980b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
22990b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23000b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const size_t
23010b57cec5SDimitry Andric    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::word_size;
23020b57cec5SDimitry Andric
23030b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23040b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23050b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23060b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const size_t
23070b57cec5SDimitry Andric    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::state_size;
23080b57cec5SDimitry Andric
23090b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23100b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23110b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23120b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const size_t
23130b57cec5SDimitry Andric    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::shift_size;
23140b57cec5SDimitry Andric
23150b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23160b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23170b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23180b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const size_t
23190b57cec5SDimitry Andric    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::mask_bits;
23200b57cec5SDimitry Andric
23210b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23220b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23230b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23240b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
23250b57cec5SDimitry Andric    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::xor_mask;
23260b57cec5SDimitry Andric
23270b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23280b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23290b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23300b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const size_t
23310b57cec5SDimitry Andric    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_u;
23320b57cec5SDimitry Andric
23330b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23340b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23350b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23360b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
23370b57cec5SDimitry Andric    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_d;
23380b57cec5SDimitry Andric
23390b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23400b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23410b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23420b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const size_t
23430b57cec5SDimitry Andric    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_s;
23440b57cec5SDimitry Andric
23450b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23460b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23470b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23480b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
23490b57cec5SDimitry Andric    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_b;
23500b57cec5SDimitry Andric
23510b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23520b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23530b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23540b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const size_t
23550b57cec5SDimitry Andric    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_t;
23560b57cec5SDimitry Andric
23570b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23580b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23590b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23600b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
23610b57cec5SDimitry Andric    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_c;
23620b57cec5SDimitry Andric
23630b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23640b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23650b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23660b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const size_t
23670b57cec5SDimitry Andric    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::tempering_l;
23680b57cec5SDimitry Andric
23690b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23700b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23710b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23720b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
23730b57cec5SDimitry Andric    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::initialization_multiplier;
23740b57cec5SDimitry Andric
23750b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23760b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23770b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23780b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const typename mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::result_type
23790b57cec5SDimitry Andric    mersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b, __t, __c, __l, __f>::default_seed;
23800b57cec5SDimitry Andric
23810b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23820b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23830b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23840b57cec5SDimitry Andricvoid
23850b57cec5SDimitry Andricmersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
23860b57cec5SDimitry Andric    __t, __c, __l, __f>::seed(result_type __sd)
23870b57cec5SDimitry Andric    _LIBCPP_DISABLE_UBSAN_UNSIGNED_INTEGER_CHECK
23880b57cec5SDimitry Andric{   // __w >= 2
23890b57cec5SDimitry Andric    __x_[0] = __sd & _Max;
23900b57cec5SDimitry Andric    for (size_t __i = 1; __i < __n; ++__i)
23910b57cec5SDimitry Andric        __x_[__i] = (__f * (__x_[__i-1] ^ __rshift<__w - 2>(__x_[__i-1])) + __i) & _Max;
23920b57cec5SDimitry Andric    __i_ = 0;
23930b57cec5SDimitry Andric}
23940b57cec5SDimitry Andric
23950b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
23960b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
23970b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
23980b57cec5SDimitry Andrictemplate<class _Sseq>
23990b57cec5SDimitry Andricvoid
24000b57cec5SDimitry Andricmersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
24010b57cec5SDimitry Andric    __t, __c, __l, __f>::__seed(_Sseq& __q, integral_constant<unsigned, 1>)
24020b57cec5SDimitry Andric{
24030b57cec5SDimitry Andric    const unsigned __k = 1;
24040b57cec5SDimitry Andric    uint32_t __ar[__n * __k];
24050b57cec5SDimitry Andric    __q.generate(__ar, __ar + __n * __k);
24060b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
24070b57cec5SDimitry Andric        __x_[__i] = static_cast<result_type>(__ar[__i] & _Max);
24080b57cec5SDimitry Andric    const result_type __mask = __r == _Dt ? result_type(~0) :
24090b57cec5SDimitry Andric                                       (result_type(1) << __r) - result_type(1);
24100b57cec5SDimitry Andric    __i_ = 0;
24110b57cec5SDimitry Andric    if ((__x_[0] & ~__mask) == 0)
24120b57cec5SDimitry Andric    {
24130b57cec5SDimitry Andric        for (size_t __i = 1; __i < __n; ++__i)
24140b57cec5SDimitry Andric            if (__x_[__i] != 0)
24150b57cec5SDimitry Andric                return;
24160b57cec5SDimitry Andric        __x_[0] = result_type(1) << (__w - 1);
24170b57cec5SDimitry Andric    }
24180b57cec5SDimitry Andric}
24190b57cec5SDimitry Andric
24200b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
24210b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
24220b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
24230b57cec5SDimitry Andrictemplate<class _Sseq>
24240b57cec5SDimitry Andricvoid
24250b57cec5SDimitry Andricmersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
24260b57cec5SDimitry Andric    __t, __c, __l, __f>::__seed(_Sseq& __q, integral_constant<unsigned, 2>)
24270b57cec5SDimitry Andric{
24280b57cec5SDimitry Andric    const unsigned __k = 2;
24290b57cec5SDimitry Andric    uint32_t __ar[__n * __k];
24300b57cec5SDimitry Andric    __q.generate(__ar, __ar + __n * __k);
24310b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
24320b57cec5SDimitry Andric        __x_[__i] = static_cast<result_type>(
24330b57cec5SDimitry Andric            (__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max);
24340b57cec5SDimitry Andric    const result_type __mask = __r == _Dt ? result_type(~0) :
24350b57cec5SDimitry Andric                                       (result_type(1) << __r) - result_type(1);
24360b57cec5SDimitry Andric    __i_ = 0;
24370b57cec5SDimitry Andric    if ((__x_[0] & ~__mask) == 0)
24380b57cec5SDimitry Andric    {
24390b57cec5SDimitry Andric        for (size_t __i = 1; __i < __n; ++__i)
24400b57cec5SDimitry Andric            if (__x_[__i] != 0)
24410b57cec5SDimitry Andric                return;
24420b57cec5SDimitry Andric        __x_[0] = result_type(1) << (__w - 1);
24430b57cec5SDimitry Andric    }
24440b57cec5SDimitry Andric}
24450b57cec5SDimitry Andric
24460b57cec5SDimitry Andrictemplate <class _UIntType, size_t __w, size_t __n, size_t __m, size_t __r,
24470b57cec5SDimitry Andric          _UIntType __a, size_t __u, _UIntType __d, size_t __s,
24480b57cec5SDimitry Andric          _UIntType __b, size_t __t, _UIntType __c, size_t __l, _UIntType __f>
24490b57cec5SDimitry Andric_UIntType
24500b57cec5SDimitry Andricmersenne_twister_engine<_UIntType, __w, __n, __m, __r, __a, __u, __d, __s, __b,
24510b57cec5SDimitry Andric    __t, __c, __l, __f>::operator()()
24520b57cec5SDimitry Andric{
24530b57cec5SDimitry Andric    const size_t __j = (__i_ + 1) % __n;
24540b57cec5SDimitry Andric    const result_type __mask = __r == _Dt ? result_type(~0) :
24550b57cec5SDimitry Andric                                       (result_type(1) << __r) - result_type(1);
24560b57cec5SDimitry Andric    const result_type _Yp = (__x_[__i_] & ~__mask) | (__x_[__j] & __mask);
24570b57cec5SDimitry Andric    const size_t __k = (__i_ + __m) % __n;
24580b57cec5SDimitry Andric    __x_[__i_] = __x_[__k] ^ __rshift<1>(_Yp) ^ (__a * (_Yp & 1));
24590b57cec5SDimitry Andric    result_type __z = __x_[__i_] ^ (__rshift<__u>(__x_[__i_]) & __d);
24600b57cec5SDimitry Andric    __i_ = __j;
24610b57cec5SDimitry Andric    __z ^= __lshift<__s>(__z) & __b;
24620b57cec5SDimitry Andric    __z ^= __lshift<__t>(__z) & __c;
24630b57cec5SDimitry Andric    return __z ^ __rshift<__l>(__z);
24640b57cec5SDimitry Andric}
24650b57cec5SDimitry Andric
24660b57cec5SDimitry Andrictemplate <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
24670b57cec5SDimitry Andric          _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
24680b57cec5SDimitry Andric          _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
24690b57cec5SDimitry Andricbool
24700b57cec5SDimitry Andricoperator==(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
24710b57cec5SDimitry Andric                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
24720b57cec5SDimitry Andric           const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
24730b57cec5SDimitry Andric                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __y)
24740b57cec5SDimitry Andric{
24750b57cec5SDimitry Andric    if (__x.__i_ == __y.__i_)
24760b57cec5SDimitry Andric        return _VSTD::equal(__x.__x_, __x.__x_ + _Np, __y.__x_);
24770b57cec5SDimitry Andric    if (__x.__i_ == 0 || __y.__i_ == 0)
24780b57cec5SDimitry Andric    {
24790b57cec5SDimitry Andric        size_t __j = _VSTD::min(_Np - __x.__i_, _Np - __y.__i_);
24800b57cec5SDimitry Andric        if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + __x.__i_ + __j,
24810b57cec5SDimitry Andric                         __y.__x_ + __y.__i_))
24820b57cec5SDimitry Andric            return false;
24830b57cec5SDimitry Andric        if (__x.__i_ == 0)
24840b57cec5SDimitry Andric            return _VSTD::equal(__x.__x_ + __j, __x.__x_ + _Np, __y.__x_);
24850b57cec5SDimitry Andric        return _VSTD::equal(__x.__x_, __x.__x_ + (_Np - __j), __y.__x_ + __j);
24860b57cec5SDimitry Andric    }
24870b57cec5SDimitry Andric    if (__x.__i_ < __y.__i_)
24880b57cec5SDimitry Andric    {
24890b57cec5SDimitry Andric        size_t __j = _Np - __y.__i_;
24900b57cec5SDimitry Andric        if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + (__x.__i_ + __j),
24910b57cec5SDimitry Andric                         __y.__x_ + __y.__i_))
24920b57cec5SDimitry Andric            return false;
24930b57cec5SDimitry Andric        if (!_VSTD::equal(__x.__x_ + (__x.__i_ + __j), __x.__x_ + _Np,
24940b57cec5SDimitry Andric                         __y.__x_))
24950b57cec5SDimitry Andric            return false;
24960b57cec5SDimitry Andric        return _VSTD::equal(__x.__x_, __x.__x_ + __x.__i_,
24970b57cec5SDimitry Andric                           __y.__x_ + (_Np - (__x.__i_ + __j)));
24980b57cec5SDimitry Andric    }
24990b57cec5SDimitry Andric    size_t __j = _Np - __x.__i_;
25000b57cec5SDimitry Andric    if (!_VSTD::equal(__y.__x_ + __y.__i_, __y.__x_ + (__y.__i_ + __j),
25010b57cec5SDimitry Andric                     __x.__x_ + __x.__i_))
25020b57cec5SDimitry Andric        return false;
25030b57cec5SDimitry Andric    if (!_VSTD::equal(__y.__x_ + (__y.__i_ + __j), __y.__x_ + _Np,
25040b57cec5SDimitry Andric                     __x.__x_))
25050b57cec5SDimitry Andric        return false;
25060b57cec5SDimitry Andric    return _VSTD::equal(__y.__x_, __y.__x_ + __y.__i_,
25070b57cec5SDimitry Andric                       __x.__x_ + (_Np - (__y.__i_ + __j)));
25080b57cec5SDimitry Andric}
25090b57cec5SDimitry Andric
25100b57cec5SDimitry Andrictemplate <class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
25110b57cec5SDimitry Andric          _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
25120b57cec5SDimitry Andric          _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
25130b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
25140b57cec5SDimitry Andricbool
25150b57cec5SDimitry Andricoperator!=(const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
25160b57cec5SDimitry Andric                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x,
25170b57cec5SDimitry Andric           const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
25180b57cec5SDimitry Andric                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __y)
25190b57cec5SDimitry Andric{
25200b57cec5SDimitry Andric    return !(__x == __y);
25210b57cec5SDimitry Andric}
25220b57cec5SDimitry Andric
25230b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
25240b57cec5SDimitry Andric          class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
25250b57cec5SDimitry Andric          _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
25260b57cec5SDimitry Andric          _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
25270b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
25280b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
25290b57cec5SDimitry Andric           const mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
25300b57cec5SDimitry Andric                                         _Bp, _Tp, _Cp, _Lp, _Fp>& __x)
25310b57cec5SDimitry Andric{
25320b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
2533*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _Ostream;
2534*e8d8bef9SDimitry Andric    __os.flags(_Ostream::dec | _Ostream::left);
25350b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
25360b57cec5SDimitry Andric    __os.fill(__sp);
25370b57cec5SDimitry Andric    __os << __x.__x_[__x.__i_];
25380b57cec5SDimitry Andric    for (size_t __j = __x.__i_ + 1; __j < _Np; ++__j)
25390b57cec5SDimitry Andric        __os << __sp << __x.__x_[__j];
25400b57cec5SDimitry Andric    for (size_t __j = 0; __j < __x.__i_; ++__j)
25410b57cec5SDimitry Andric        __os << __sp << __x.__x_[__j];
25420b57cec5SDimitry Andric    return __os;
25430b57cec5SDimitry Andric}
25440b57cec5SDimitry Andric
25450b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
25460b57cec5SDimitry Andric          class _UInt, size_t _Wp, size_t _Np, size_t _Mp, size_t _Rp,
25470b57cec5SDimitry Andric          _UInt _Ap, size_t _Up, _UInt _Dp, size_t _Sp,
25480b57cec5SDimitry Andric          _UInt _Bp, size_t _Tp, _UInt _Cp, size_t _Lp, _UInt _Fp>
25490b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
25500b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
25510b57cec5SDimitry Andric           mersenne_twister_engine<_UInt, _Wp, _Np, _Mp, _Rp, _Ap, _Up, _Dp, _Sp,
25520b57cec5SDimitry Andric                                   _Bp, _Tp, _Cp, _Lp, _Fp>& __x)
25530b57cec5SDimitry Andric{
25540b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
2555*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
2556*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
25570b57cec5SDimitry Andric    _UInt __t[_Np];
25580b57cec5SDimitry Andric    for (size_t __i = 0; __i < _Np; ++__i)
25590b57cec5SDimitry Andric        __is >> __t[__i];
25600b57cec5SDimitry Andric    if (!__is.fail())
25610b57cec5SDimitry Andric    {
25620b57cec5SDimitry Andric        for (size_t __i = 0; __i < _Np; ++__i)
25630b57cec5SDimitry Andric            __x.__x_[__i] = __t[__i];
25640b57cec5SDimitry Andric        __x.__i_ = 0;
25650b57cec5SDimitry Andric    }
25660b57cec5SDimitry Andric    return __is;
25670b57cec5SDimitry Andric}
25680b57cec5SDimitry Andric
25690b57cec5SDimitry Andrictypedef mersenne_twister_engine<uint_fast32_t, 32, 624, 397, 31,
25700b57cec5SDimitry Andric                                0x9908b0df, 11, 0xffffffff,
25710b57cec5SDimitry Andric                                7,  0x9d2c5680,
25720b57cec5SDimitry Andric                                15, 0xefc60000,
25730b57cec5SDimitry Andric                                18, 1812433253>                         mt19937;
25740b57cec5SDimitry Andrictypedef mersenne_twister_engine<uint_fast64_t, 64, 312, 156, 31,
25750b57cec5SDimitry Andric                                0xb5026f5aa96619e9ULL, 29, 0x5555555555555555ULL,
25760b57cec5SDimitry Andric                                17, 0x71d67fffeda60000ULL,
25770b57cec5SDimitry Andric                                37, 0xfff7eee000000000ULL,
25780b57cec5SDimitry Andric                                43, 6364136223846793005ULL>          mt19937_64;
25790b57cec5SDimitry Andric
25800b57cec5SDimitry Andric// subtract_with_carry_engine
25810b57cec5SDimitry Andric
25820b57cec5SDimitry Andrictemplate<class _UIntType, size_t __w, size_t __s, size_t __r>
25830b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS subtract_with_carry_engine;
25840b57cec5SDimitry Andric
25850b57cec5SDimitry Andrictemplate<class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
25860b57cec5SDimitry Andricbool
25870b57cec5SDimitry Andricoperator==(
25880b57cec5SDimitry Andric    const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x,
25890b57cec5SDimitry Andric    const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y);
25900b57cec5SDimitry Andric
25910b57cec5SDimitry Andrictemplate<class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
25920b57cec5SDimitry Andric_LIBCPP_INLINE_VISIBILITY
25930b57cec5SDimitry Andricbool
25940b57cec5SDimitry Andricoperator!=(
25950b57cec5SDimitry Andric    const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x,
25960b57cec5SDimitry Andric    const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y);
25970b57cec5SDimitry Andric
25980b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
25990b57cec5SDimitry Andric          class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
26000b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
26010b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
26020b57cec5SDimitry Andric           const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x);
26030b57cec5SDimitry Andric
26040b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
26050b57cec5SDimitry Andric          class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
26060b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
26070b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
26080b57cec5SDimitry Andric           subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x);
26090b57cec5SDimitry Andric
26100b57cec5SDimitry Andrictemplate<class _UIntType, size_t __w, size_t __s, size_t __r>
26110b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS subtract_with_carry_engine
26120b57cec5SDimitry Andric{
26130b57cec5SDimitry Andricpublic:
26140b57cec5SDimitry Andric    // types
26150b57cec5SDimitry Andric    typedef _UIntType result_type;
26160b57cec5SDimitry Andric
26170b57cec5SDimitry Andricprivate:
26180b57cec5SDimitry Andric    result_type __x_[__r];
26190b57cec5SDimitry Andric    result_type  __c_;
26200b57cec5SDimitry Andric    size_t      __i_;
26210b57cec5SDimitry Andric
26220b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits<result_type>::digits;
26230b57cec5SDimitry Andric    static_assert(  0 <  __w, "subtract_with_carry_engine invalid parameters");
26240b57cec5SDimitry Andric    static_assert(__w <= _Dt, "subtract_with_carry_engine invalid parameters");
26250b57cec5SDimitry Andric    static_assert(  0 <  __s, "subtract_with_carry_engine invalid parameters");
26260b57cec5SDimitry Andric    static_assert(__s <  __r, "subtract_with_carry_engine invalid parameters");
26270b57cec5SDimitry Andricpublic:
26280b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Min = 0;
26290b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) :
26300b57cec5SDimitry Andric                                                      (result_type(1) << __w) - result_type(1);
26310b57cec5SDimitry Andric    static_assert(_Min < _Max, "subtract_with_carry_engine invalid parameters");
26320b57cec5SDimitry Andric
26330b57cec5SDimitry Andric    // engine characteristics
26340b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t word_size = __w;
26350b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t short_lag = __s;
26360b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t long_lag = __r;
26370b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
26380b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR result_type min() { return _Min; }
26390b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
26400b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR result_type max() { return _Max; }
26410b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type default_seed = 19780503u;
26420b57cec5SDimitry Andric
26430b57cec5SDimitry Andric    // constructors and seeding functions
2644*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
26450b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2646*e8d8bef9SDimitry Andric    subtract_with_carry_engine() : subtract_with_carry_engine(default_seed) {}
2647*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2648*e8d8bef9SDimitry Andric    explicit subtract_with_carry_engine(result_type __sd) { seed(__sd); }
2649*e8d8bef9SDimitry Andric#else
2650*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
2651*e8d8bef9SDimitry Andric    explicit subtract_with_carry_engine(result_type __sd = default_seed) {
2652*e8d8bef9SDimitry Andric      seed(__sd);
2653*e8d8bef9SDimitry Andric    }
2654*e8d8bef9SDimitry Andric#endif
26550b57cec5SDimitry Andric    template<class _Sseq>
26560b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
26570b57cec5SDimitry Andric        explicit subtract_with_carry_engine(_Sseq& __q,
26580b57cec5SDimitry Andric        typename enable_if<__is_seed_sequence<_Sseq, subtract_with_carry_engine>::value>::type* = 0)
26590b57cec5SDimitry Andric        {seed(__q);}
26600b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
26610b57cec5SDimitry Andric    void seed(result_type __sd = default_seed)
26620b57cec5SDimitry Andric        {seed(__sd, integral_constant<unsigned, 1 + (__w - 1) / 32>());}
26630b57cec5SDimitry Andric    template<class _Sseq>
26640b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
26650b57cec5SDimitry Andric        typename enable_if
26660b57cec5SDimitry Andric        <
26670b57cec5SDimitry Andric            __is_seed_sequence<_Sseq, subtract_with_carry_engine>::value,
26680b57cec5SDimitry Andric            void
26690b57cec5SDimitry Andric        >::type
26700b57cec5SDimitry Andric        seed(_Sseq& __q)
26710b57cec5SDimitry Andric            {__seed(__q, integral_constant<unsigned, 1 + (__w - 1) / 32>());}
26720b57cec5SDimitry Andric
26730b57cec5SDimitry Andric    // generating functions
26740b57cec5SDimitry Andric    result_type operator()();
26750b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
26760b57cec5SDimitry Andric    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
26770b57cec5SDimitry Andric
26780b57cec5SDimitry Andric    template<class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
26790b57cec5SDimitry Andric    friend
26800b57cec5SDimitry Andric    bool
26810b57cec5SDimitry Andric    operator==(
26820b57cec5SDimitry Andric        const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x,
26830b57cec5SDimitry Andric        const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y);
26840b57cec5SDimitry Andric
26850b57cec5SDimitry Andric    template<class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
26860b57cec5SDimitry Andric    friend
26870b57cec5SDimitry Andric    bool
26880b57cec5SDimitry Andric    operator!=(
26890b57cec5SDimitry Andric        const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x,
26900b57cec5SDimitry Andric        const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y);
26910b57cec5SDimitry Andric
26920b57cec5SDimitry Andric    template <class _CharT, class _Traits,
26930b57cec5SDimitry Andric              class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
26940b57cec5SDimitry Andric    friend
26950b57cec5SDimitry Andric    basic_ostream<_CharT, _Traits>&
26960b57cec5SDimitry Andric    operator<<(basic_ostream<_CharT, _Traits>& __os,
26970b57cec5SDimitry Andric               const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x);
26980b57cec5SDimitry Andric
26990b57cec5SDimitry Andric    template <class _CharT, class _Traits,
27000b57cec5SDimitry Andric              class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
27010b57cec5SDimitry Andric    friend
27020b57cec5SDimitry Andric    basic_istream<_CharT, _Traits>&
27030b57cec5SDimitry Andric    operator>>(basic_istream<_CharT, _Traits>& __is,
27040b57cec5SDimitry Andric               subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x);
27050b57cec5SDimitry Andric
27060b57cec5SDimitry Andricprivate:
27070b57cec5SDimitry Andric
27080b57cec5SDimitry Andric    void seed(result_type __sd, integral_constant<unsigned, 1>);
27090b57cec5SDimitry Andric    void seed(result_type __sd, integral_constant<unsigned, 2>);
27100b57cec5SDimitry Andric    template<class _Sseq>
27110b57cec5SDimitry Andric        void __seed(_Sseq& __q, integral_constant<unsigned, 1>);
27120b57cec5SDimitry Andric    template<class _Sseq>
27130b57cec5SDimitry Andric        void __seed(_Sseq& __q, integral_constant<unsigned, 2>);
27140b57cec5SDimitry Andric};
27150b57cec5SDimitry Andric
27160b57cec5SDimitry Andrictemplate<class _UIntType, size_t __w, size_t __s, size_t __r>
27170b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::word_size;
27180b57cec5SDimitry Andric
27190b57cec5SDimitry Andrictemplate<class _UIntType, size_t __w, size_t __s, size_t __r>
27200b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::short_lag;
27210b57cec5SDimitry Andric
27220b57cec5SDimitry Andrictemplate<class _UIntType, size_t __w, size_t __s, size_t __r>
27230b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const size_t subtract_with_carry_engine<_UIntType, __w, __s, __r>::long_lag;
27240b57cec5SDimitry Andric
27250b57cec5SDimitry Andrictemplate<class _UIntType, size_t __w, size_t __s, size_t __r>
27260b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const typename subtract_with_carry_engine<_UIntType, __w, __s, __r>::result_type
27270b57cec5SDimitry Andric    subtract_with_carry_engine<_UIntType, __w, __s, __r>::default_seed;
27280b57cec5SDimitry Andric
27290b57cec5SDimitry Andrictemplate<class _UIntType, size_t __w, size_t __s, size_t __r>
27300b57cec5SDimitry Andricvoid
27310b57cec5SDimitry Andricsubtract_with_carry_engine<_UIntType, __w, __s, __r>::seed(result_type __sd,
27320b57cec5SDimitry Andric        integral_constant<unsigned, 1>)
27330b57cec5SDimitry Andric{
27340b57cec5SDimitry Andric    linear_congruential_engine<result_type, 40014u, 0u, 2147483563u>
27350b57cec5SDimitry Andric        __e(__sd == 0u ? default_seed : __sd);
27360b57cec5SDimitry Andric    for (size_t __i = 0; __i < __r; ++__i)
27370b57cec5SDimitry Andric        __x_[__i] = static_cast<result_type>(__e() & _Max);
27380b57cec5SDimitry Andric    __c_ = __x_[__r-1] == 0;
27390b57cec5SDimitry Andric    __i_ = 0;
27400b57cec5SDimitry Andric}
27410b57cec5SDimitry Andric
27420b57cec5SDimitry Andrictemplate<class _UIntType, size_t __w, size_t __s, size_t __r>
27430b57cec5SDimitry Andricvoid
27440b57cec5SDimitry Andricsubtract_with_carry_engine<_UIntType, __w, __s, __r>::seed(result_type __sd,
27450b57cec5SDimitry Andric        integral_constant<unsigned, 2>)
27460b57cec5SDimitry Andric{
27470b57cec5SDimitry Andric    linear_congruential_engine<result_type, 40014u, 0u, 2147483563u>
27480b57cec5SDimitry Andric        __e(__sd == 0u ? default_seed : __sd);
27490b57cec5SDimitry Andric    for (size_t __i = 0; __i < __r; ++__i)
27500b57cec5SDimitry Andric    {
27510b57cec5SDimitry Andric        result_type __e0 = __e();
27520b57cec5SDimitry Andric        __x_[__i] = static_cast<result_type>(
27530b57cec5SDimitry Andric                                    (__e0 + ((uint64_t)__e() << 32)) & _Max);
27540b57cec5SDimitry Andric    }
27550b57cec5SDimitry Andric    __c_ = __x_[__r-1] == 0;
27560b57cec5SDimitry Andric    __i_ = 0;
27570b57cec5SDimitry Andric}
27580b57cec5SDimitry Andric
27590b57cec5SDimitry Andrictemplate<class _UIntType, size_t __w, size_t __s, size_t __r>
27600b57cec5SDimitry Andrictemplate<class _Sseq>
27610b57cec5SDimitry Andricvoid
27620b57cec5SDimitry Andricsubtract_with_carry_engine<_UIntType, __w, __s, __r>::__seed(_Sseq& __q,
27630b57cec5SDimitry Andric        integral_constant<unsigned, 1>)
27640b57cec5SDimitry Andric{
27650b57cec5SDimitry Andric    const unsigned __k = 1;
27660b57cec5SDimitry Andric    uint32_t __ar[__r * __k];
27670b57cec5SDimitry Andric    __q.generate(__ar, __ar + __r * __k);
27680b57cec5SDimitry Andric    for (size_t __i = 0; __i < __r; ++__i)
27690b57cec5SDimitry Andric        __x_[__i] = static_cast<result_type>(__ar[__i] & _Max);
27700b57cec5SDimitry Andric    __c_ = __x_[__r-1] == 0;
27710b57cec5SDimitry Andric    __i_ = 0;
27720b57cec5SDimitry Andric}
27730b57cec5SDimitry Andric
27740b57cec5SDimitry Andrictemplate<class _UIntType, size_t __w, size_t __s, size_t __r>
27750b57cec5SDimitry Andrictemplate<class _Sseq>
27760b57cec5SDimitry Andricvoid
27770b57cec5SDimitry Andricsubtract_with_carry_engine<_UIntType, __w, __s, __r>::__seed(_Sseq& __q,
27780b57cec5SDimitry Andric        integral_constant<unsigned, 2>)
27790b57cec5SDimitry Andric{
27800b57cec5SDimitry Andric    const unsigned __k = 2;
27810b57cec5SDimitry Andric    uint32_t __ar[__r * __k];
27820b57cec5SDimitry Andric    __q.generate(__ar, __ar + __r * __k);
27830b57cec5SDimitry Andric    for (size_t __i = 0; __i < __r; ++__i)
27840b57cec5SDimitry Andric        __x_[__i] = static_cast<result_type>(
27850b57cec5SDimitry Andric                  (__ar[2 * __i] + ((uint64_t)__ar[2 * __i + 1] << 32)) & _Max);
27860b57cec5SDimitry Andric    __c_ = __x_[__r-1] == 0;
27870b57cec5SDimitry Andric    __i_ = 0;
27880b57cec5SDimitry Andric}
27890b57cec5SDimitry Andric
27900b57cec5SDimitry Andrictemplate<class _UIntType, size_t __w, size_t __s, size_t __r>
27910b57cec5SDimitry Andric_UIntType
27920b57cec5SDimitry Andricsubtract_with_carry_engine<_UIntType, __w, __s, __r>::operator()()
27930b57cec5SDimitry Andric{
27940b57cec5SDimitry Andric    const result_type& __xs = __x_[(__i_ + (__r - __s)) % __r];
27950b57cec5SDimitry Andric    result_type& __xr = __x_[__i_];
27960b57cec5SDimitry Andric    result_type __new_c = __c_ == 0 ? __xs < __xr : __xs != 0 ? __xs <= __xr : 1;
27970b57cec5SDimitry Andric    __xr = (__xs - __xr - __c_) & _Max;
27980b57cec5SDimitry Andric    __c_ = __new_c;
27990b57cec5SDimitry Andric    __i_ = (__i_ + 1) % __r;
28000b57cec5SDimitry Andric    return __xr;
28010b57cec5SDimitry Andric}
28020b57cec5SDimitry Andric
28030b57cec5SDimitry Andrictemplate<class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
28040b57cec5SDimitry Andricbool
28050b57cec5SDimitry Andricoperator==(
28060b57cec5SDimitry Andric    const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x,
28070b57cec5SDimitry Andric    const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y)
28080b57cec5SDimitry Andric{
28090b57cec5SDimitry Andric    if (__x.__c_ != __y.__c_)
28100b57cec5SDimitry Andric        return false;
28110b57cec5SDimitry Andric    if (__x.__i_ == __y.__i_)
28120b57cec5SDimitry Andric        return _VSTD::equal(__x.__x_, __x.__x_ + _Rp, __y.__x_);
28130b57cec5SDimitry Andric    if (__x.__i_ == 0 || __y.__i_ == 0)
28140b57cec5SDimitry Andric    {
28150b57cec5SDimitry Andric        size_t __j = _VSTD::min(_Rp - __x.__i_, _Rp - __y.__i_);
28160b57cec5SDimitry Andric        if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + __x.__i_ + __j,
28170b57cec5SDimitry Andric                         __y.__x_ + __y.__i_))
28180b57cec5SDimitry Andric            return false;
28190b57cec5SDimitry Andric        if (__x.__i_ == 0)
28200b57cec5SDimitry Andric            return _VSTD::equal(__x.__x_ + __j, __x.__x_ + _Rp, __y.__x_);
28210b57cec5SDimitry Andric        return _VSTD::equal(__x.__x_, __x.__x_ + (_Rp - __j), __y.__x_ + __j);
28220b57cec5SDimitry Andric    }
28230b57cec5SDimitry Andric    if (__x.__i_ < __y.__i_)
28240b57cec5SDimitry Andric    {
28250b57cec5SDimitry Andric        size_t __j = _Rp - __y.__i_;
28260b57cec5SDimitry Andric        if (!_VSTD::equal(__x.__x_ + __x.__i_, __x.__x_ + (__x.__i_ + __j),
28270b57cec5SDimitry Andric                         __y.__x_ + __y.__i_))
28280b57cec5SDimitry Andric            return false;
28290b57cec5SDimitry Andric        if (!_VSTD::equal(__x.__x_ + (__x.__i_ + __j), __x.__x_ + _Rp,
28300b57cec5SDimitry Andric                         __y.__x_))
28310b57cec5SDimitry Andric            return false;
28320b57cec5SDimitry Andric        return _VSTD::equal(__x.__x_, __x.__x_ + __x.__i_,
28330b57cec5SDimitry Andric                           __y.__x_ + (_Rp - (__x.__i_ + __j)));
28340b57cec5SDimitry Andric    }
28350b57cec5SDimitry Andric    size_t __j = _Rp - __x.__i_;
28360b57cec5SDimitry Andric    if (!_VSTD::equal(__y.__x_ + __y.__i_, __y.__x_ + (__y.__i_ + __j),
28370b57cec5SDimitry Andric                     __x.__x_ + __x.__i_))
28380b57cec5SDimitry Andric        return false;
28390b57cec5SDimitry Andric    if (!_VSTD::equal(__y.__x_ + (__y.__i_ + __j), __y.__x_ + _Rp,
28400b57cec5SDimitry Andric                     __x.__x_))
28410b57cec5SDimitry Andric        return false;
28420b57cec5SDimitry Andric    return _VSTD::equal(__y.__x_, __y.__x_ + __y.__i_,
28430b57cec5SDimitry Andric                       __x.__x_ + (_Rp - (__y.__i_ + __j)));
28440b57cec5SDimitry Andric}
28450b57cec5SDimitry Andric
28460b57cec5SDimitry Andrictemplate<class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
28470b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
28480b57cec5SDimitry Andricbool
28490b57cec5SDimitry Andricoperator!=(
28500b57cec5SDimitry Andric    const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x,
28510b57cec5SDimitry Andric    const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __y)
28520b57cec5SDimitry Andric{
28530b57cec5SDimitry Andric    return !(__x == __y);
28540b57cec5SDimitry Andric}
28550b57cec5SDimitry Andric
28560b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
28570b57cec5SDimitry Andric          class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
28580b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
28590b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
28600b57cec5SDimitry Andric           const subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x)
28610b57cec5SDimitry Andric{
28620b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
2863*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _Ostream;
2864*e8d8bef9SDimitry Andric    __os.flags(_Ostream::dec | _Ostream::left);
28650b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
28660b57cec5SDimitry Andric    __os.fill(__sp);
28670b57cec5SDimitry Andric    __os << __x.__x_[__x.__i_];
28680b57cec5SDimitry Andric    for (size_t __j = __x.__i_ + 1; __j < _Rp; ++__j)
28690b57cec5SDimitry Andric        __os << __sp << __x.__x_[__j];
28700b57cec5SDimitry Andric    for (size_t __j = 0; __j < __x.__i_; ++__j)
28710b57cec5SDimitry Andric        __os << __sp << __x.__x_[__j];
28720b57cec5SDimitry Andric    __os << __sp << __x.__c_;
28730b57cec5SDimitry Andric    return __os;
28740b57cec5SDimitry Andric}
28750b57cec5SDimitry Andric
28760b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
28770b57cec5SDimitry Andric          class _UInt, size_t _Wp, size_t _Sp, size_t _Rp>
28780b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
28790b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
28800b57cec5SDimitry Andric           subtract_with_carry_engine<_UInt, _Wp, _Sp, _Rp>& __x)
28810b57cec5SDimitry Andric{
28820b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
2883*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
2884*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
28850b57cec5SDimitry Andric    _UInt __t[_Rp+1];
28860b57cec5SDimitry Andric    for (size_t __i = 0; __i < _Rp+1; ++__i)
28870b57cec5SDimitry Andric        __is >> __t[__i];
28880b57cec5SDimitry Andric    if (!__is.fail())
28890b57cec5SDimitry Andric    {
28900b57cec5SDimitry Andric        for (size_t __i = 0; __i < _Rp; ++__i)
28910b57cec5SDimitry Andric            __x.__x_[__i] = __t[__i];
28920b57cec5SDimitry Andric        __x.__c_ = __t[_Rp];
28930b57cec5SDimitry Andric        __x.__i_ = 0;
28940b57cec5SDimitry Andric    }
28950b57cec5SDimitry Andric    return __is;
28960b57cec5SDimitry Andric}
28970b57cec5SDimitry Andric
28980b57cec5SDimitry Andrictypedef subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>     ranlux24_base;
28990b57cec5SDimitry Andrictypedef subtract_with_carry_engine<uint_fast64_t, 48,  5, 12>     ranlux48_base;
29000b57cec5SDimitry Andric
29010b57cec5SDimitry Andric// discard_block_engine
29020b57cec5SDimitry Andric
29030b57cec5SDimitry Andrictemplate<class _Engine, size_t __p, size_t __r>
29040b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS discard_block_engine
29050b57cec5SDimitry Andric{
29060b57cec5SDimitry Andric    _Engine __e_;
29070b57cec5SDimitry Andric    int     __n_;
29080b57cec5SDimitry Andric
29090b57cec5SDimitry Andric    static_assert(  0 <  __r, "discard_block_engine invalid parameters");
29100b57cec5SDimitry Andric    static_assert(__r <= __p, "discard_block_engine invalid parameters");
29110b57cec5SDimitry Andric    static_assert(__r <= INT_MAX, "discard_block_engine invalid parameters");
29120b57cec5SDimitry Andricpublic:
29130b57cec5SDimitry Andric    // types
29140b57cec5SDimitry Andric    typedef typename _Engine::result_type result_type;
29150b57cec5SDimitry Andric
29160b57cec5SDimitry Andric    // engine characteristics
29170b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t block_size = __p;
29180b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t used_block = __r;
29190b57cec5SDimitry Andric
29200b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
29210b57cec5SDimitry Andric    static const result_type _Min = _Engine::_Min;
29220b57cec5SDimitry Andric    static const result_type _Max = _Engine::_Max;
29230b57cec5SDimitry Andric#else
29240b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Min = _Engine::min();
29250b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Max = _Engine::max();
29260b57cec5SDimitry Andric#endif
29270b57cec5SDimitry Andric
29280b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
29290b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR result_type min() { return _Engine::min(); }
29300b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
29310b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR result_type max() { return _Engine::max(); }
29320b57cec5SDimitry Andric
29330b57cec5SDimitry Andric    // constructors and seeding functions
29340b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
29350b57cec5SDimitry Andric    discard_block_engine() : __n_(0) {}
29360b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
29370b57cec5SDimitry Andric    explicit discard_block_engine(const _Engine& __e)
29380b57cec5SDimitry Andric        : __e_(__e), __n_(0) {}
29390b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
29400b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
29410b57cec5SDimitry Andric    explicit discard_block_engine(_Engine&& __e)
29420b57cec5SDimitry Andric        : __e_(_VSTD::move(__e)), __n_(0) {}
29430b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
29440b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
29450b57cec5SDimitry Andric    explicit discard_block_engine(result_type __sd) : __e_(__sd), __n_(0) {}
29460b57cec5SDimitry Andric    template<class _Sseq>
29470b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
29480b57cec5SDimitry Andric        explicit discard_block_engine(_Sseq& __q,
29490b57cec5SDimitry Andric        typename enable_if<__is_seed_sequence<_Sseq, discard_block_engine>::value &&
29500b57cec5SDimitry Andric                           !is_convertible<_Sseq, _Engine>::value>::type* = 0)
29510b57cec5SDimitry Andric        : __e_(__q), __n_(0) {}
29520b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
29530b57cec5SDimitry Andric    void seed() {__e_.seed(); __n_ = 0;}
29540b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
29550b57cec5SDimitry Andric    void seed(result_type __sd) {__e_.seed(__sd); __n_ = 0;}
29560b57cec5SDimitry Andric    template<class _Sseq>
29570b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
29580b57cec5SDimitry Andric        typename enable_if
29590b57cec5SDimitry Andric        <
29600b57cec5SDimitry Andric            __is_seed_sequence<_Sseq, discard_block_engine>::value,
29610b57cec5SDimitry Andric            void
29620b57cec5SDimitry Andric        >::type
29630b57cec5SDimitry Andric        seed(_Sseq& __q) {__e_.seed(__q); __n_ = 0;}
29640b57cec5SDimitry Andric
29650b57cec5SDimitry Andric    // generating functions
29660b57cec5SDimitry Andric    result_type operator()();
29670b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
29680b57cec5SDimitry Andric    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
29690b57cec5SDimitry Andric
29700b57cec5SDimitry Andric    // property functions
29710b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
29720b57cec5SDimitry Andric    const _Engine& base() const _NOEXCEPT {return __e_;}
29730b57cec5SDimitry Andric
29740b57cec5SDimitry Andric    template<class _Eng, size_t _Pp, size_t _Rp>
29750b57cec5SDimitry Andric    friend
29760b57cec5SDimitry Andric    bool
29770b57cec5SDimitry Andric    operator==(
29780b57cec5SDimitry Andric        const discard_block_engine<_Eng, _Pp, _Rp>& __x,
29790b57cec5SDimitry Andric        const discard_block_engine<_Eng, _Pp, _Rp>& __y);
29800b57cec5SDimitry Andric
29810b57cec5SDimitry Andric    template<class _Eng, size_t _Pp, size_t _Rp>
29820b57cec5SDimitry Andric    friend
29830b57cec5SDimitry Andric    bool
29840b57cec5SDimitry Andric    operator!=(
29850b57cec5SDimitry Andric        const discard_block_engine<_Eng, _Pp, _Rp>& __x,
29860b57cec5SDimitry Andric        const discard_block_engine<_Eng, _Pp, _Rp>& __y);
29870b57cec5SDimitry Andric
29880b57cec5SDimitry Andric    template <class _CharT, class _Traits,
29890b57cec5SDimitry Andric              class _Eng, size_t _Pp, size_t _Rp>
29900b57cec5SDimitry Andric    friend
29910b57cec5SDimitry Andric    basic_ostream<_CharT, _Traits>&
29920b57cec5SDimitry Andric    operator<<(basic_ostream<_CharT, _Traits>& __os,
29930b57cec5SDimitry Andric               const discard_block_engine<_Eng, _Pp, _Rp>& __x);
29940b57cec5SDimitry Andric
29950b57cec5SDimitry Andric    template <class _CharT, class _Traits,
29960b57cec5SDimitry Andric              class _Eng, size_t _Pp, size_t _Rp>
29970b57cec5SDimitry Andric    friend
29980b57cec5SDimitry Andric    basic_istream<_CharT, _Traits>&
29990b57cec5SDimitry Andric    operator>>(basic_istream<_CharT, _Traits>& __is,
30000b57cec5SDimitry Andric               discard_block_engine<_Eng, _Pp, _Rp>& __x);
30010b57cec5SDimitry Andric};
30020b57cec5SDimitry Andric
30030b57cec5SDimitry Andrictemplate<class _Engine, size_t __p, size_t __r>
30040b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::block_size;
30050b57cec5SDimitry Andric
30060b57cec5SDimitry Andrictemplate<class _Engine, size_t __p, size_t __r>
30070b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const size_t discard_block_engine<_Engine, __p, __r>::used_block;
30080b57cec5SDimitry Andric
30090b57cec5SDimitry Andrictemplate<class _Engine, size_t __p, size_t __r>
30100b57cec5SDimitry Andrictypename discard_block_engine<_Engine, __p, __r>::result_type
30110b57cec5SDimitry Andricdiscard_block_engine<_Engine, __p, __r>::operator()()
30120b57cec5SDimitry Andric{
30130b57cec5SDimitry Andric    if (__n_ >= static_cast<int>(__r))
30140b57cec5SDimitry Andric    {
30150b57cec5SDimitry Andric        __e_.discard(__p - __r);
30160b57cec5SDimitry Andric        __n_ = 0;
30170b57cec5SDimitry Andric    }
30180b57cec5SDimitry Andric    ++__n_;
30190b57cec5SDimitry Andric    return __e_();
30200b57cec5SDimitry Andric}
30210b57cec5SDimitry Andric
30220b57cec5SDimitry Andrictemplate<class _Eng, size_t _Pp, size_t _Rp>
30230b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
30240b57cec5SDimitry Andricbool
30250b57cec5SDimitry Andricoperator==(const discard_block_engine<_Eng, _Pp, _Rp>& __x,
30260b57cec5SDimitry Andric           const discard_block_engine<_Eng, _Pp, _Rp>& __y)
30270b57cec5SDimitry Andric{
30280b57cec5SDimitry Andric    return __x.__n_ == __y.__n_ && __x.__e_ == __y.__e_;
30290b57cec5SDimitry Andric}
30300b57cec5SDimitry Andric
30310b57cec5SDimitry Andrictemplate<class _Eng, size_t _Pp, size_t _Rp>
30320b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
30330b57cec5SDimitry Andricbool
30340b57cec5SDimitry Andricoperator!=(const discard_block_engine<_Eng, _Pp, _Rp>& __x,
30350b57cec5SDimitry Andric           const discard_block_engine<_Eng, _Pp, _Rp>& __y)
30360b57cec5SDimitry Andric{
30370b57cec5SDimitry Andric    return !(__x == __y);
30380b57cec5SDimitry Andric}
30390b57cec5SDimitry Andric
30400b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
30410b57cec5SDimitry Andric          class _Eng, size_t _Pp, size_t _Rp>
30420b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
30430b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
30440b57cec5SDimitry Andric           const discard_block_engine<_Eng, _Pp, _Rp>& __x)
30450b57cec5SDimitry Andric{
30460b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
3047*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _Ostream;
3048*e8d8bef9SDimitry Andric    __os.flags(_Ostream::dec | _Ostream::left);
30490b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
30500b57cec5SDimitry Andric    __os.fill(__sp);
30510b57cec5SDimitry Andric    return __os << __x.__e_ << __sp << __x.__n_;
30520b57cec5SDimitry Andric}
30530b57cec5SDimitry Andric
30540b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
30550b57cec5SDimitry Andric          class _Eng, size_t _Pp, size_t _Rp>
30560b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
30570b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
30580b57cec5SDimitry Andric           discard_block_engine<_Eng, _Pp, _Rp>& __x)
30590b57cec5SDimitry Andric{
30600b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
3061*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
3062*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
30630b57cec5SDimitry Andric    _Eng __e;
30640b57cec5SDimitry Andric    int __n;
30650b57cec5SDimitry Andric    __is >> __e >> __n;
30660b57cec5SDimitry Andric    if (!__is.fail())
30670b57cec5SDimitry Andric    {
30680b57cec5SDimitry Andric        __x.__e_ = __e;
30690b57cec5SDimitry Andric        __x.__n_ = __n;
30700b57cec5SDimitry Andric    }
30710b57cec5SDimitry Andric    return __is;
30720b57cec5SDimitry Andric}
30730b57cec5SDimitry Andric
30740b57cec5SDimitry Andrictypedef discard_block_engine<ranlux24_base, 223, 23> ranlux24;
30750b57cec5SDimitry Andrictypedef discard_block_engine<ranlux48_base, 389, 11> ranlux48;
30760b57cec5SDimitry Andric
30770b57cec5SDimitry Andric// independent_bits_engine
30780b57cec5SDimitry Andric
30790b57cec5SDimitry Andrictemplate<class _Engine, size_t __w, class _UIntType>
30800b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS independent_bits_engine
30810b57cec5SDimitry Andric{
30820b57cec5SDimitry Andric    template <class _UInt, _UInt _R0, size_t _Wp, size_t _Mp>
30830b57cec5SDimitry Andric    class __get_n
30840b57cec5SDimitry Andric    {
30850b57cec5SDimitry Andric        static _LIBCPP_CONSTEXPR const size_t _Dt = numeric_limits<_UInt>::digits;
30860b57cec5SDimitry Andric        static _LIBCPP_CONSTEXPR const size_t _Np = _Wp / _Mp + (_Wp % _Mp != 0);
30870b57cec5SDimitry Andric        static _LIBCPP_CONSTEXPR const size_t _W0 = _Wp / _Np;
30880b57cec5SDimitry Andric        static _LIBCPP_CONSTEXPR const _UInt _Y0 = _W0 >= _Dt ? 0 : (_R0 >> _W0) << _W0;
30890b57cec5SDimitry Andric    public:
30900b57cec5SDimitry Andric        static _LIBCPP_CONSTEXPR const size_t value = _R0 - _Y0 > _Y0 / _Np ? _Np + 1 : _Np;
30910b57cec5SDimitry Andric    };
30920b57cec5SDimitry Andricpublic:
30930b57cec5SDimitry Andric    // types
30940b57cec5SDimitry Andric    typedef _UIntType result_type;
30950b57cec5SDimitry Andric
30960b57cec5SDimitry Andricprivate:
30970b57cec5SDimitry Andric    _Engine __e_;
30980b57cec5SDimitry Andric
30990b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Dt = numeric_limits<result_type>::digits;
31000b57cec5SDimitry Andric    static_assert(  0 <  __w, "independent_bits_engine invalid parameters");
31010b57cec5SDimitry Andric    static_assert(__w <= _Dt, "independent_bits_engine invalid parameters");
31020b57cec5SDimitry Andric
31030b57cec5SDimitry Andric    typedef typename _Engine::result_type _Engine_result_type;
31040b57cec5SDimitry Andric    typedef typename conditional
31050b57cec5SDimitry Andric        <
31060b57cec5SDimitry Andric            sizeof(_Engine_result_type) <= sizeof(result_type),
31070b57cec5SDimitry Andric                result_type,
31080b57cec5SDimitry Andric                _Engine_result_type
31090b57cec5SDimitry Andric        >::type _Working_result_type;
31100b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
31110b57cec5SDimitry Andric    static const _Working_result_type _Rp = _Engine::_Max - _Engine::_Min
31120b57cec5SDimitry Andric                                          + _Working_result_type(1);
31130b57cec5SDimitry Andric#else
31140b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const _Working_result_type _Rp = _Engine::max() - _Engine::min()
31150b57cec5SDimitry Andric                                                            + _Working_result_type(1);
31160b57cec5SDimitry Andric#endif
31170b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t __m = __log2<_Working_result_type, _Rp>::value;
31180b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t __n = __get_n<_Working_result_type, _Rp, __w, __m>::value;
31190b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t __w0 = __w / __n;
31200b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t __n0 = __n - __w % __n;
31210b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t _WDt = numeric_limits<_Working_result_type>::digits;
31220b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t _EDt = numeric_limits<_Engine_result_type>::digits;
31230b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const _Working_result_type __y0 = __w0 >= _WDt ? 0 :
31240b57cec5SDimitry Andric                                                               (_Rp >> __w0) << __w0;
31250b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const _Working_result_type __y1 = __w0 >= _WDt - 1 ? 0 :
31260b57cec5SDimitry Andric                                                               (_Rp >> (__w0+1)) << (__w0+1);
31270b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const _Engine_result_type __mask0 = __w0 > 0 ?
31280b57cec5SDimitry Andric                                _Engine_result_type(~0) >> (_EDt - __w0) :
31290b57cec5SDimitry Andric                                _Engine_result_type(0);
31300b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const _Engine_result_type __mask1 = __w0 < _EDt - 1 ?
31310b57cec5SDimitry Andric                                _Engine_result_type(~0) >> (_EDt - (__w0 + 1)) :
31320b57cec5SDimitry Andric                                _Engine_result_type(~0);
31330b57cec5SDimitry Andricpublic:
31340b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Min = 0;
31350b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Max = __w == _Dt ? result_type(~0) :
31360b57cec5SDimitry Andric                                                      (result_type(1) << __w) - result_type(1);
31370b57cec5SDimitry Andric    static_assert(_Min < _Max, "independent_bits_engine invalid parameters");
31380b57cec5SDimitry Andric
31390b57cec5SDimitry Andric    // engine characteristics
31400b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
31410b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR result_type min() { return _Min; }
31420b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
31430b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR result_type max() { return _Max; }
31440b57cec5SDimitry Andric
31450b57cec5SDimitry Andric    // constructors and seeding functions
31460b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
31470b57cec5SDimitry Andric    independent_bits_engine() {}
31480b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
31490b57cec5SDimitry Andric    explicit independent_bits_engine(const _Engine& __e)
31500b57cec5SDimitry Andric        : __e_(__e) {}
31510b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
31520b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
31530b57cec5SDimitry Andric    explicit independent_bits_engine(_Engine&& __e)
31540b57cec5SDimitry Andric        : __e_(_VSTD::move(__e)) {}
31550b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
31560b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
31570b57cec5SDimitry Andric    explicit independent_bits_engine(result_type __sd) : __e_(__sd) {}
31580b57cec5SDimitry Andric    template<class _Sseq>
31590b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
31600b57cec5SDimitry Andric        explicit independent_bits_engine(_Sseq& __q,
31610b57cec5SDimitry Andric        typename enable_if<__is_seed_sequence<_Sseq, independent_bits_engine>::value &&
31620b57cec5SDimitry Andric                           !is_convertible<_Sseq, _Engine>::value>::type* = 0)
31630b57cec5SDimitry Andric         : __e_(__q) {}
31640b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
31650b57cec5SDimitry Andric    void seed() {__e_.seed();}
31660b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
31670b57cec5SDimitry Andric    void seed(result_type __sd) {__e_.seed(__sd);}
31680b57cec5SDimitry Andric    template<class _Sseq>
31690b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
31700b57cec5SDimitry Andric        typename enable_if
31710b57cec5SDimitry Andric        <
31720b57cec5SDimitry Andric            __is_seed_sequence<_Sseq, independent_bits_engine>::value,
31730b57cec5SDimitry Andric            void
31740b57cec5SDimitry Andric        >::type
31750b57cec5SDimitry Andric        seed(_Sseq& __q) {__e_.seed(__q);}
31760b57cec5SDimitry Andric
31770b57cec5SDimitry Andric    // generating functions
31780b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
31790b57cec5SDimitry Andric    result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
31800b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
31810b57cec5SDimitry Andric    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
31820b57cec5SDimitry Andric
31830b57cec5SDimitry Andric    // property functions
31840b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
31850b57cec5SDimitry Andric    const _Engine& base() const _NOEXCEPT {return __e_;}
31860b57cec5SDimitry Andric
31870b57cec5SDimitry Andric    template<class _Eng, size_t _Wp, class _UInt>
31880b57cec5SDimitry Andric    friend
31890b57cec5SDimitry Andric    bool
31900b57cec5SDimitry Andric    operator==(
31910b57cec5SDimitry Andric        const independent_bits_engine<_Eng, _Wp, _UInt>& __x,
31920b57cec5SDimitry Andric        const independent_bits_engine<_Eng, _Wp, _UInt>& __y);
31930b57cec5SDimitry Andric
31940b57cec5SDimitry Andric    template<class _Eng, size_t _Wp, class _UInt>
31950b57cec5SDimitry Andric    friend
31960b57cec5SDimitry Andric    bool
31970b57cec5SDimitry Andric    operator!=(
31980b57cec5SDimitry Andric        const independent_bits_engine<_Eng, _Wp, _UInt>& __x,
31990b57cec5SDimitry Andric        const independent_bits_engine<_Eng, _Wp, _UInt>& __y);
32000b57cec5SDimitry Andric
32010b57cec5SDimitry Andric    template <class _CharT, class _Traits,
32020b57cec5SDimitry Andric              class _Eng, size_t _Wp, class _UInt>
32030b57cec5SDimitry Andric    friend
32040b57cec5SDimitry Andric    basic_ostream<_CharT, _Traits>&
32050b57cec5SDimitry Andric    operator<<(basic_ostream<_CharT, _Traits>& __os,
32060b57cec5SDimitry Andric               const independent_bits_engine<_Eng, _Wp, _UInt>& __x);
32070b57cec5SDimitry Andric
32080b57cec5SDimitry Andric    template <class _CharT, class _Traits,
32090b57cec5SDimitry Andric              class _Eng, size_t _Wp, class _UInt>
32100b57cec5SDimitry Andric    friend
32110b57cec5SDimitry Andric    basic_istream<_CharT, _Traits>&
32120b57cec5SDimitry Andric    operator>>(basic_istream<_CharT, _Traits>& __is,
32130b57cec5SDimitry Andric               independent_bits_engine<_Eng, _Wp, _UInt>& __x);
32140b57cec5SDimitry Andric
32150b57cec5SDimitry Andricprivate:
32160b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
32170b57cec5SDimitry Andric    result_type __eval(false_type);
32180b57cec5SDimitry Andric    result_type __eval(true_type);
32190b57cec5SDimitry Andric
32200b57cec5SDimitry Andric    template <size_t __count>
32210b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
32220b57cec5SDimitry Andric        static
32230b57cec5SDimitry Andric        typename enable_if
32240b57cec5SDimitry Andric        <
32250b57cec5SDimitry Andric            __count < _Dt,
32260b57cec5SDimitry Andric            result_type
32270b57cec5SDimitry Andric        >::type
32280b57cec5SDimitry Andric        __lshift(result_type __x) {return __x << __count;}
32290b57cec5SDimitry Andric
32300b57cec5SDimitry Andric    template <size_t __count>
32310b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
32320b57cec5SDimitry Andric        static
32330b57cec5SDimitry Andric        typename enable_if
32340b57cec5SDimitry Andric        <
32350b57cec5SDimitry Andric            (__count >= _Dt),
32360b57cec5SDimitry Andric            result_type
32370b57cec5SDimitry Andric        >::type
32380b57cec5SDimitry Andric        __lshift(result_type) {return result_type(0);}
32390b57cec5SDimitry Andric};
32400b57cec5SDimitry Andric
32410b57cec5SDimitry Andrictemplate<class _Engine, size_t __w, class _UIntType>
32420b57cec5SDimitry Andricinline
32430b57cec5SDimitry Andric_UIntType
32440b57cec5SDimitry Andricindependent_bits_engine<_Engine, __w, _UIntType>::__eval(false_type)
32450b57cec5SDimitry Andric{
32460b57cec5SDimitry Andric    return static_cast<result_type>(__e_() & __mask0);
32470b57cec5SDimitry Andric}
32480b57cec5SDimitry Andric
32490b57cec5SDimitry Andrictemplate<class _Engine, size_t __w, class _UIntType>
32500b57cec5SDimitry Andric_UIntType
32510b57cec5SDimitry Andricindependent_bits_engine<_Engine, __w, _UIntType>::__eval(true_type)
32520b57cec5SDimitry Andric{
32530b57cec5SDimitry Andric    result_type _Sp = 0;
32540b57cec5SDimitry Andric    for (size_t __k = 0; __k < __n0; ++__k)
32550b57cec5SDimitry Andric    {
32560b57cec5SDimitry Andric        _Engine_result_type __u;
32570b57cec5SDimitry Andric        do
32580b57cec5SDimitry Andric        {
32590b57cec5SDimitry Andric            __u = __e_() - _Engine::min();
32600b57cec5SDimitry Andric        } while (__u >= __y0);
32610b57cec5SDimitry Andric        _Sp = static_cast<result_type>(__lshift<__w0>(_Sp) + (__u & __mask0));
32620b57cec5SDimitry Andric    }
32630b57cec5SDimitry Andric    for (size_t __k = __n0; __k < __n; ++__k)
32640b57cec5SDimitry Andric    {
32650b57cec5SDimitry Andric        _Engine_result_type __u;
32660b57cec5SDimitry Andric        do
32670b57cec5SDimitry Andric        {
32680b57cec5SDimitry Andric            __u = __e_() - _Engine::min();
32690b57cec5SDimitry Andric        } while (__u >= __y1);
32700b57cec5SDimitry Andric        _Sp = static_cast<result_type>(__lshift<__w0+1>(_Sp) + (__u & __mask1));
32710b57cec5SDimitry Andric    }
32720b57cec5SDimitry Andric    return _Sp;
32730b57cec5SDimitry Andric}
32740b57cec5SDimitry Andric
32750b57cec5SDimitry Andrictemplate<class _Eng, size_t _Wp, class _UInt>
32760b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
32770b57cec5SDimitry Andricbool
32780b57cec5SDimitry Andricoperator==(
32790b57cec5SDimitry Andric    const independent_bits_engine<_Eng, _Wp, _UInt>& __x,
32800b57cec5SDimitry Andric    const independent_bits_engine<_Eng, _Wp, _UInt>& __y)
32810b57cec5SDimitry Andric{
32820b57cec5SDimitry Andric    return __x.base() == __y.base();
32830b57cec5SDimitry Andric}
32840b57cec5SDimitry Andric
32850b57cec5SDimitry Andrictemplate<class _Eng, size_t _Wp, class _UInt>
32860b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
32870b57cec5SDimitry Andricbool
32880b57cec5SDimitry Andricoperator!=(
32890b57cec5SDimitry Andric    const independent_bits_engine<_Eng, _Wp, _UInt>& __x,
32900b57cec5SDimitry Andric    const independent_bits_engine<_Eng, _Wp, _UInt>& __y)
32910b57cec5SDimitry Andric{
32920b57cec5SDimitry Andric    return !(__x == __y);
32930b57cec5SDimitry Andric}
32940b57cec5SDimitry Andric
32950b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
32960b57cec5SDimitry Andric          class _Eng, size_t _Wp, class _UInt>
32970b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
32980b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
32990b57cec5SDimitry Andric           const independent_bits_engine<_Eng, _Wp, _UInt>& __x)
33000b57cec5SDimitry Andric{
33010b57cec5SDimitry Andric    return __os << __x.base();
33020b57cec5SDimitry Andric}
33030b57cec5SDimitry Andric
33040b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
33050b57cec5SDimitry Andric          class _Eng, size_t _Wp, class _UInt>
33060b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
33070b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
33080b57cec5SDimitry Andric           independent_bits_engine<_Eng, _Wp, _UInt>& __x)
33090b57cec5SDimitry Andric{
33100b57cec5SDimitry Andric    _Eng __e;
33110b57cec5SDimitry Andric    __is >> __e;
33120b57cec5SDimitry Andric    if (!__is.fail())
33130b57cec5SDimitry Andric        __x.__e_ = __e;
33140b57cec5SDimitry Andric    return __is;
33150b57cec5SDimitry Andric}
33160b57cec5SDimitry Andric
33170b57cec5SDimitry Andric// shuffle_order_engine
33180b57cec5SDimitry Andric
33190b57cec5SDimitry Andrictemplate <uint64_t _Xp, uint64_t _Yp>
33200b57cec5SDimitry Andricstruct __ugcd
33210b57cec5SDimitry Andric{
33220b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const uint64_t value = __ugcd<_Yp, _Xp % _Yp>::value;
33230b57cec5SDimitry Andric};
33240b57cec5SDimitry Andric
33250b57cec5SDimitry Andrictemplate <uint64_t _Xp>
33260b57cec5SDimitry Andricstruct __ugcd<_Xp, 0>
33270b57cec5SDimitry Andric{
33280b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const uint64_t value = _Xp;
33290b57cec5SDimitry Andric};
33300b57cec5SDimitry Andric
33310b57cec5SDimitry Andrictemplate <uint64_t _Np, uint64_t _Dp>
33320b57cec5SDimitry Andricclass __uratio
33330b57cec5SDimitry Andric{
33340b57cec5SDimitry Andric    static_assert(_Dp != 0, "__uratio divide by 0");
33350b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const uint64_t __gcd = __ugcd<_Np, _Dp>::value;
33360b57cec5SDimitry Andricpublic:
33370b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const uint64_t num = _Np / __gcd;
33380b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const uint64_t den = _Dp / __gcd;
33390b57cec5SDimitry Andric
33400b57cec5SDimitry Andric    typedef __uratio<num, den> type;
33410b57cec5SDimitry Andric};
33420b57cec5SDimitry Andric
33430b57cec5SDimitry Andrictemplate<class _Engine, size_t __k>
33440b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS shuffle_order_engine
33450b57cec5SDimitry Andric{
33460b57cec5SDimitry Andric    static_assert(0 < __k, "shuffle_order_engine invalid parameters");
33470b57cec5SDimitry Andricpublic:
33480b57cec5SDimitry Andric    // types
33490b57cec5SDimitry Andric    typedef typename _Engine::result_type result_type;
33500b57cec5SDimitry Andric
33510b57cec5SDimitry Andricprivate:
33520b57cec5SDimitry Andric    _Engine __e_;
33530b57cec5SDimitry Andric    result_type _V_[__k];
33540b57cec5SDimitry Andric    result_type _Y_;
33550b57cec5SDimitry Andric
33560b57cec5SDimitry Andricpublic:
33570b57cec5SDimitry Andric    // engine characteristics
33580b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const size_t table_size = __k;
33590b57cec5SDimitry Andric
33600b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
33610b57cec5SDimitry Andric    static const result_type _Min = _Engine::_Min;
33620b57cec5SDimitry Andric    static const result_type _Max = _Engine::_Max;
33630b57cec5SDimitry Andric#else
33640b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Min = _Engine::min();
33650b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Max = _Engine::max();
33660b57cec5SDimitry Andric#endif
33670b57cec5SDimitry Andric    static_assert(_Min < _Max, "shuffle_order_engine invalid parameters");
33680b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
33690b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR result_type min() { return _Min; }
33700b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
33710b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR result_type max() { return _Max; }
33720b57cec5SDimitry Andric
33730b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const unsigned long long _Rp = _Max - _Min + 1ull;
33740b57cec5SDimitry Andric
33750b57cec5SDimitry Andric    // constructors and seeding functions
33760b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
33770b57cec5SDimitry Andric    shuffle_order_engine() {__init();}
33780b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
33790b57cec5SDimitry Andric    explicit shuffle_order_engine(const _Engine& __e)
33800b57cec5SDimitry Andric        : __e_(__e) {__init();}
33810b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
33820b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
33830b57cec5SDimitry Andric    explicit shuffle_order_engine(_Engine&& __e)
33840b57cec5SDimitry Andric        : __e_(_VSTD::move(__e)) {__init();}
33850b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
33860b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
33870b57cec5SDimitry Andric    explicit shuffle_order_engine(result_type __sd) : __e_(__sd) {__init();}
33880b57cec5SDimitry Andric    template<class _Sseq>
33890b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
33900b57cec5SDimitry Andric        explicit shuffle_order_engine(_Sseq& __q,
33910b57cec5SDimitry Andric        typename enable_if<__is_seed_sequence<_Sseq, shuffle_order_engine>::value &&
33920b57cec5SDimitry Andric                           !is_convertible<_Sseq, _Engine>::value>::type* = 0)
33930b57cec5SDimitry Andric         : __e_(__q) {__init();}
33940b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
33950b57cec5SDimitry Andric    void seed() {__e_.seed(); __init();}
33960b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
33970b57cec5SDimitry Andric    void seed(result_type __sd) {__e_.seed(__sd); __init();}
33980b57cec5SDimitry Andric    template<class _Sseq>
33990b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
34000b57cec5SDimitry Andric        typename enable_if
34010b57cec5SDimitry Andric        <
34020b57cec5SDimitry Andric            __is_seed_sequence<_Sseq, shuffle_order_engine>::value,
34030b57cec5SDimitry Andric            void
34040b57cec5SDimitry Andric        >::type
34050b57cec5SDimitry Andric        seed(_Sseq& __q) {__e_.seed(__q); __init();}
34060b57cec5SDimitry Andric
34070b57cec5SDimitry Andric    // generating functions
34080b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34090b57cec5SDimitry Andric    result_type operator()() {return __eval(integral_constant<bool, _Rp != 0>());}
34100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34110b57cec5SDimitry Andric    void discard(unsigned long long __z) {for (; __z; --__z) operator()();}
34120b57cec5SDimitry Andric
34130b57cec5SDimitry Andric    // property functions
34140b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34150b57cec5SDimitry Andric    const _Engine& base() const _NOEXCEPT {return __e_;}
34160b57cec5SDimitry Andric
34170b57cec5SDimitry Andricprivate:
34180b57cec5SDimitry Andric    template<class _Eng, size_t _Kp>
34190b57cec5SDimitry Andric    friend
34200b57cec5SDimitry Andric    bool
34210b57cec5SDimitry Andric    operator==(
34220b57cec5SDimitry Andric        const shuffle_order_engine<_Eng, _Kp>& __x,
34230b57cec5SDimitry Andric        const shuffle_order_engine<_Eng, _Kp>& __y);
34240b57cec5SDimitry Andric
34250b57cec5SDimitry Andric    template<class _Eng, size_t _Kp>
34260b57cec5SDimitry Andric    friend
34270b57cec5SDimitry Andric    bool
34280b57cec5SDimitry Andric    operator!=(
34290b57cec5SDimitry Andric        const shuffle_order_engine<_Eng, _Kp>& __x,
34300b57cec5SDimitry Andric        const shuffle_order_engine<_Eng, _Kp>& __y);
34310b57cec5SDimitry Andric
34320b57cec5SDimitry Andric    template <class _CharT, class _Traits,
34330b57cec5SDimitry Andric              class _Eng, size_t _Kp>
34340b57cec5SDimitry Andric    friend
34350b57cec5SDimitry Andric    basic_ostream<_CharT, _Traits>&
34360b57cec5SDimitry Andric    operator<<(basic_ostream<_CharT, _Traits>& __os,
34370b57cec5SDimitry Andric               const shuffle_order_engine<_Eng, _Kp>& __x);
34380b57cec5SDimitry Andric
34390b57cec5SDimitry Andric    template <class _CharT, class _Traits,
34400b57cec5SDimitry Andric              class _Eng, size_t _Kp>
34410b57cec5SDimitry Andric    friend
34420b57cec5SDimitry Andric    basic_istream<_CharT, _Traits>&
34430b57cec5SDimitry Andric    operator>>(basic_istream<_CharT, _Traits>& __is,
34440b57cec5SDimitry Andric               shuffle_order_engine<_Eng, _Kp>& __x);
34450b57cec5SDimitry Andric
34460b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34470b57cec5SDimitry Andric    void __init()
34480b57cec5SDimitry Andric    {
34490b57cec5SDimitry Andric        for (size_t __i = 0; __i < __k; ++__i)
34500b57cec5SDimitry Andric            _V_[__i] = __e_();
34510b57cec5SDimitry Andric        _Y_ = __e_();
34520b57cec5SDimitry Andric    }
34530b57cec5SDimitry Andric
34540b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34550b57cec5SDimitry Andric    result_type __eval(false_type) {return __eval2(integral_constant<bool, __k & 1>());}
34560b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34570b57cec5SDimitry Andric    result_type __eval(true_type) {return __eval(__uratio<__k, _Rp>());}
34580b57cec5SDimitry Andric
34590b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34600b57cec5SDimitry Andric    result_type __eval2(false_type) {return __eval(__uratio<__k/2, 0x8000000000000000ull>());}
34610b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
34620b57cec5SDimitry Andric    result_type __eval2(true_type) {return __evalf<__k, 0>();}
34630b57cec5SDimitry Andric
34640b57cec5SDimitry Andric    template <uint64_t _Np, uint64_t _Dp>
34650b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
34660b57cec5SDimitry Andric        typename enable_if
34670b57cec5SDimitry Andric        <
34680b57cec5SDimitry Andric            (__uratio<_Np, _Dp>::num > 0xFFFFFFFFFFFFFFFFull / (_Max - _Min)),
34690b57cec5SDimitry Andric            result_type
34700b57cec5SDimitry Andric        >::type
34710b57cec5SDimitry Andric        __eval(__uratio<_Np, _Dp>)
34720b57cec5SDimitry Andric            {return __evalf<__uratio<_Np, _Dp>::num, __uratio<_Np, _Dp>::den>();}
34730b57cec5SDimitry Andric
34740b57cec5SDimitry Andric    template <uint64_t _Np, uint64_t _Dp>
34750b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
34760b57cec5SDimitry Andric        typename enable_if
34770b57cec5SDimitry Andric        <
34780b57cec5SDimitry Andric            __uratio<_Np, _Dp>::num <= 0xFFFFFFFFFFFFFFFFull / (_Max - _Min),
34790b57cec5SDimitry Andric            result_type
34800b57cec5SDimitry Andric        >::type
34810b57cec5SDimitry Andric        __eval(__uratio<_Np, _Dp>)
34820b57cec5SDimitry Andric        {
34830b57cec5SDimitry Andric            const size_t __j = static_cast<size_t>(__uratio<_Np, _Dp>::num * (_Y_ - _Min)
34840b57cec5SDimitry Andric                                                   / __uratio<_Np, _Dp>::den);
34850b57cec5SDimitry Andric            _Y_ = _V_[__j];
34860b57cec5SDimitry Andric            _V_[__j] = __e_();
34870b57cec5SDimitry Andric            return _Y_;
34880b57cec5SDimitry Andric        }
34890b57cec5SDimitry Andric
34900b57cec5SDimitry Andric    template <uint64_t __n, uint64_t __d>
34910b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
34920b57cec5SDimitry Andric        result_type __evalf()
34930b57cec5SDimitry Andric        {
34940b57cec5SDimitry Andric            const double _Fp = __d == 0 ?
34950b57cec5SDimitry Andric                __n / (2. * 0x8000000000000000ull) :
34960b57cec5SDimitry Andric                __n / (double)__d;
34970b57cec5SDimitry Andric            const size_t __j = static_cast<size_t>(_Fp * (_Y_ - _Min));
34980b57cec5SDimitry Andric            _Y_ = _V_[__j];
34990b57cec5SDimitry Andric            _V_[__j] = __e_();
35000b57cec5SDimitry Andric            return _Y_;
35010b57cec5SDimitry Andric        }
35020b57cec5SDimitry Andric};
35030b57cec5SDimitry Andric
35040b57cec5SDimitry Andrictemplate<class _Engine, size_t __k>
35050b57cec5SDimitry Andric    _LIBCPP_CONSTEXPR const size_t shuffle_order_engine<_Engine, __k>::table_size;
35060b57cec5SDimitry Andric
35070b57cec5SDimitry Andrictemplate<class _Eng, size_t _Kp>
35080b57cec5SDimitry Andricbool
35090b57cec5SDimitry Andricoperator==(
35100b57cec5SDimitry Andric    const shuffle_order_engine<_Eng, _Kp>& __x,
35110b57cec5SDimitry Andric    const shuffle_order_engine<_Eng, _Kp>& __y)
35120b57cec5SDimitry Andric{
35130b57cec5SDimitry Andric    return __x._Y_ == __y._Y_ && _VSTD::equal(__x._V_, __x._V_ + _Kp, __y._V_) &&
35140b57cec5SDimitry Andric           __x.__e_ == __y.__e_;
35150b57cec5SDimitry Andric}
35160b57cec5SDimitry Andric
35170b57cec5SDimitry Andrictemplate<class _Eng, size_t _Kp>
35180b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
35190b57cec5SDimitry Andricbool
35200b57cec5SDimitry Andricoperator!=(
35210b57cec5SDimitry Andric    const shuffle_order_engine<_Eng, _Kp>& __x,
35220b57cec5SDimitry Andric    const shuffle_order_engine<_Eng, _Kp>& __y)
35230b57cec5SDimitry Andric{
35240b57cec5SDimitry Andric    return !(__x == __y);
35250b57cec5SDimitry Andric}
35260b57cec5SDimitry Andric
35270b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
35280b57cec5SDimitry Andric          class _Eng, size_t _Kp>
35290b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
35300b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
35310b57cec5SDimitry Andric           const shuffle_order_engine<_Eng, _Kp>& __x)
35320b57cec5SDimitry Andric{
35330b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
3534*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _Ostream;
3535*e8d8bef9SDimitry Andric    __os.flags(_Ostream::dec | _Ostream::left);
35360b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
35370b57cec5SDimitry Andric    __os.fill(__sp);
35380b57cec5SDimitry Andric    __os << __x.__e_ << __sp << __x._V_[0];
35390b57cec5SDimitry Andric    for (size_t __i = 1; __i < _Kp; ++__i)
35400b57cec5SDimitry Andric        __os << __sp << __x._V_[__i];
35410b57cec5SDimitry Andric    return __os << __sp << __x._Y_;
35420b57cec5SDimitry Andric}
35430b57cec5SDimitry Andric
35440b57cec5SDimitry Andrictemplate <class _CharT, class _Traits,
35450b57cec5SDimitry Andric          class _Eng, size_t _Kp>
35460b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
35470b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
35480b57cec5SDimitry Andric           shuffle_order_engine<_Eng, _Kp>& __x)
35490b57cec5SDimitry Andric{
35500b57cec5SDimitry Andric    typedef typename shuffle_order_engine<_Eng, _Kp>::result_type result_type;
35510b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
3552*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
3553*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
35540b57cec5SDimitry Andric    _Eng __e;
35550b57cec5SDimitry Andric    result_type _Vp[_Kp+1];
35560b57cec5SDimitry Andric    __is >> __e;
35570b57cec5SDimitry Andric    for (size_t __i = 0; __i < _Kp+1; ++__i)
35580b57cec5SDimitry Andric        __is >> _Vp[__i];
35590b57cec5SDimitry Andric    if (!__is.fail())
35600b57cec5SDimitry Andric    {
35610b57cec5SDimitry Andric        __x.__e_ = __e;
35620b57cec5SDimitry Andric        for (size_t __i = 0; __i < _Kp; ++__i)
35630b57cec5SDimitry Andric            __x._V_[__i] = _Vp[__i];
35640b57cec5SDimitry Andric        __x._Y_ = _Vp[_Kp];
35650b57cec5SDimitry Andric    }
35660b57cec5SDimitry Andric    return __is;
35670b57cec5SDimitry Andric}
35680b57cec5SDimitry Andric
35690b57cec5SDimitry Andrictypedef shuffle_order_engine<minstd_rand0, 256>                         knuth_b;
35700b57cec5SDimitry Andric
35710b57cec5SDimitry Andric// random_device
35720b57cec5SDimitry Andric
3573*e8d8bef9SDimitry Andric#if !defined(_LIBCPP_HAS_NO_RANDOM_DEVICE)
3574*e8d8bef9SDimitry Andric
35750b57cec5SDimitry Andricclass _LIBCPP_TYPE_VIS random_device
35760b57cec5SDimitry Andric{
35770b57cec5SDimitry Andric#ifdef _LIBCPP_USING_DEV_RANDOM
35780b57cec5SDimitry Andric    int __f_;
35790b57cec5SDimitry Andric#endif // defined(_LIBCPP_USING_DEV_RANDOM)
35800b57cec5SDimitry Andricpublic:
35810b57cec5SDimitry Andric    // types
35820b57cec5SDimitry Andric    typedef unsigned result_type;
35830b57cec5SDimitry Andric
35840b57cec5SDimitry Andric    // generator characteristics
35850b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Min = 0;
35860b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR const result_type _Max = 0xFFFFFFFFu;
35870b57cec5SDimitry Andric
35880b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
35890b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR result_type min() { return _Min;}
35900b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
35910b57cec5SDimitry Andric    static _LIBCPP_CONSTEXPR result_type max() { return _Max;}
35920b57cec5SDimitry Andric
35930b57cec5SDimitry Andric    // constructors
3594*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
3595*e8d8bef9SDimitry Andric    random_device() : random_device("/dev/urandom") {}
3596*e8d8bef9SDimitry Andric    explicit random_device(const string& __token);
3597*e8d8bef9SDimitry Andric#else
35980b57cec5SDimitry Andric    explicit random_device(const string& __token = "/dev/urandom");
3599*e8d8bef9SDimitry Andric#endif
36000b57cec5SDimitry Andric    ~random_device();
36010b57cec5SDimitry Andric
36020b57cec5SDimitry Andric    // generating functions
36030b57cec5SDimitry Andric    result_type operator()();
36040b57cec5SDimitry Andric
36050b57cec5SDimitry Andric    // property functions
36060b57cec5SDimitry Andric    double entropy() const _NOEXCEPT;
36070b57cec5SDimitry Andric
36080b57cec5SDimitry Andricprivate:
36090b57cec5SDimitry Andric    // no copy functions
36100b57cec5SDimitry Andric    random_device(const random_device&); // = delete;
36110b57cec5SDimitry Andric    random_device& operator=(const random_device&); // = delete;
36120b57cec5SDimitry Andric};
36130b57cec5SDimitry Andric
3614*e8d8bef9SDimitry Andric#endif // !_LIBCPP_HAS_NO_RANDOM_DEVICE
3615*e8d8bef9SDimitry Andric
36160b57cec5SDimitry Andric// seed_seq
36170b57cec5SDimitry Andric
36180b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS seed_seq
36190b57cec5SDimitry Andric{
36200b57cec5SDimitry Andricpublic:
36210b57cec5SDimitry Andric    // types
36220b57cec5SDimitry Andric    typedef uint32_t result_type;
36230b57cec5SDimitry Andric
36240b57cec5SDimitry Andricprivate:
36250b57cec5SDimitry Andric    vector<result_type> __v_;
36260b57cec5SDimitry Andric
36270b57cec5SDimitry Andric    template<class _InputIterator>
36280b57cec5SDimitry Andric        void init(_InputIterator __first, _InputIterator __last);
36290b57cec5SDimitry Andricpublic:
36300b57cec5SDimitry Andric    // constructors
36310b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
36320b57cec5SDimitry Andric    seed_seq() _NOEXCEPT {}
36330b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
36340b57cec5SDimitry Andric    template<class _Tp>
36350b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
36360b57cec5SDimitry Andric        seed_seq(initializer_list<_Tp> __il) {init(__il.begin(), __il.end());}
36370b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
36380b57cec5SDimitry Andric
36390b57cec5SDimitry Andric    template<class _InputIterator>
36400b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
36410b57cec5SDimitry Andric        seed_seq(_InputIterator __first, _InputIterator __last)
36420b57cec5SDimitry Andric             {init(__first, __last);}
36430b57cec5SDimitry Andric
36440b57cec5SDimitry Andric    // generating functions
36450b57cec5SDimitry Andric    template<class _RandomAccessIterator>
36460b57cec5SDimitry Andric        void generate(_RandomAccessIterator __first, _RandomAccessIterator __last);
36470b57cec5SDimitry Andric
36480b57cec5SDimitry Andric    // property functions
36490b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
36500b57cec5SDimitry Andric    size_t size() const _NOEXCEPT {return __v_.size();}
36510b57cec5SDimitry Andric    template<class _OutputIterator>
36520b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
36530b57cec5SDimitry Andric        void param(_OutputIterator __dest) const
36540b57cec5SDimitry Andric            {_VSTD::copy(__v_.begin(), __v_.end(), __dest);}
36550b57cec5SDimitry Andric
36560b57cec5SDimitry Andricprivate:
36570b57cec5SDimitry Andric    // no copy functions
36580b57cec5SDimitry Andric    seed_seq(const seed_seq&); // = delete;
36590b57cec5SDimitry Andric    void operator=(const seed_seq&); // = delete;
36600b57cec5SDimitry Andric
36610b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
36620b57cec5SDimitry Andric    static result_type _Tp(result_type __x) {return __x ^ (__x >> 27);}
36630b57cec5SDimitry Andric};
36640b57cec5SDimitry Andric
36650b57cec5SDimitry Andrictemplate<class _InputIterator>
36660b57cec5SDimitry Andricvoid
36670b57cec5SDimitry Andricseed_seq::init(_InputIterator __first, _InputIterator __last)
36680b57cec5SDimitry Andric{
36690b57cec5SDimitry Andric    for (_InputIterator __s = __first; __s != __last; ++__s)
36700b57cec5SDimitry Andric        __v_.push_back(*__s & 0xFFFFFFFF);
36710b57cec5SDimitry Andric}
36720b57cec5SDimitry Andric
36730b57cec5SDimitry Andrictemplate<class _RandomAccessIterator>
36740b57cec5SDimitry Andricvoid
36750b57cec5SDimitry Andricseed_seq::generate(_RandomAccessIterator __first, _RandomAccessIterator __last)
36760b57cec5SDimitry Andric{
36770b57cec5SDimitry Andric    if (__first != __last)
36780b57cec5SDimitry Andric    {
36790b57cec5SDimitry Andric        _VSTD::fill(__first, __last, 0x8b8b8b8b);
36800b57cec5SDimitry Andric        const size_t __n = static_cast<size_t>(__last - __first);
36810b57cec5SDimitry Andric        const size_t __s = __v_.size();
36820b57cec5SDimitry Andric        const size_t __t = (__n >= 623) ? 11
36830b57cec5SDimitry Andric                         : (__n >= 68) ? 7
36840b57cec5SDimitry Andric                         : (__n >= 39) ? 5
36850b57cec5SDimitry Andric                         : (__n >= 7)  ? 3
36860b57cec5SDimitry Andric                         : (__n - 1) / 2;
36870b57cec5SDimitry Andric        const size_t __p = (__n - __t) / 2;
36880b57cec5SDimitry Andric        const size_t __q = __p + __t;
36890b57cec5SDimitry Andric        const size_t __m = _VSTD::max(__s + 1, __n);
36900b57cec5SDimitry Andric        // __k = 0;
36910b57cec5SDimitry Andric        {
36920b57cec5SDimitry Andric            result_type __r = 1664525 * _Tp(__first[0] ^ __first[__p]
36930b57cec5SDimitry Andric                                                      ^  __first[__n - 1]);
36940b57cec5SDimitry Andric            __first[__p] += __r;
36950b57cec5SDimitry Andric            __r += __s;
36960b57cec5SDimitry Andric            __first[__q] += __r;
36970b57cec5SDimitry Andric            __first[0] = __r;
36980b57cec5SDimitry Andric        }
36990b57cec5SDimitry Andric        for (size_t __k = 1; __k <= __s; ++__k)
37000b57cec5SDimitry Andric        {
37010b57cec5SDimitry Andric            const size_t __kmodn = __k % __n;
37020b57cec5SDimitry Andric            const size_t __kpmodn = (__k + __p) % __n;
37030b57cec5SDimitry Andric            result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn]
37040b57cec5SDimitry Andric                                           ^ __first[(__k - 1) % __n]);
37050b57cec5SDimitry Andric            __first[__kpmodn] += __r;
37060b57cec5SDimitry Andric            __r +=  __kmodn + __v_[__k-1];
37070b57cec5SDimitry Andric            __first[(__k + __q) % __n] += __r;
37080b57cec5SDimitry Andric            __first[__kmodn] = __r;
37090b57cec5SDimitry Andric        }
37100b57cec5SDimitry Andric        for (size_t __k = __s + 1; __k < __m; ++__k)
37110b57cec5SDimitry Andric        {
37120b57cec5SDimitry Andric            const size_t __kmodn = __k % __n;
37130b57cec5SDimitry Andric            const size_t __kpmodn = (__k + __p) % __n;
37140b57cec5SDimitry Andric            result_type __r = 1664525 * _Tp(__first[__kmodn] ^ __first[__kpmodn]
37150b57cec5SDimitry Andric                                           ^ __first[(__k - 1) % __n]);
37160b57cec5SDimitry Andric            __first[__kpmodn] += __r;
37170b57cec5SDimitry Andric            __r +=  __kmodn;
37180b57cec5SDimitry Andric            __first[(__k + __q) % __n] += __r;
37190b57cec5SDimitry Andric            __first[__kmodn] = __r;
37200b57cec5SDimitry Andric        }
37210b57cec5SDimitry Andric        for (size_t __k = __m; __k < __m + __n; ++__k)
37220b57cec5SDimitry Andric        {
37230b57cec5SDimitry Andric            const size_t __kmodn = __k % __n;
37240b57cec5SDimitry Andric            const size_t __kpmodn = (__k + __p) % __n;
37250b57cec5SDimitry Andric            result_type __r = 1566083941 * _Tp(__first[__kmodn] +
37260b57cec5SDimitry Andric                                              __first[__kpmodn] +
37270b57cec5SDimitry Andric                                              __first[(__k - 1) % __n]);
37280b57cec5SDimitry Andric            __first[__kpmodn] ^= __r;
37290b57cec5SDimitry Andric            __r -= __kmodn;
37300b57cec5SDimitry Andric            __first[(__k + __q) % __n] ^= __r;
37310b57cec5SDimitry Andric            __first[__kmodn] = __r;
37320b57cec5SDimitry Andric        }
37330b57cec5SDimitry Andric    }
37340b57cec5SDimitry Andric}
37350b57cec5SDimitry Andric
37360b57cec5SDimitry Andric// generate_canonical
37370b57cec5SDimitry Andric
37380b57cec5SDimitry Andrictemplate<class _RealType, size_t __bits, class _URNG>
37390b57cec5SDimitry Andric_RealType
37400b57cec5SDimitry Andricgenerate_canonical(_URNG& __g)
37410b57cec5SDimitry Andric{
37420b57cec5SDimitry Andric    const size_t _Dt = numeric_limits<_RealType>::digits;
37430b57cec5SDimitry Andric    const size_t __b = _Dt < __bits ? _Dt : __bits;
37440b57cec5SDimitry Andric#ifdef _LIBCPP_CXX03_LANG
37450b57cec5SDimitry Andric    const size_t __logR = __log2<uint64_t, _URNG::_Max - _URNG::_Min + uint64_t(1)>::value;
37460b57cec5SDimitry Andric#else
37470b57cec5SDimitry Andric    const size_t __logR = __log2<uint64_t, _URNG::max() - _URNG::min() + uint64_t(1)>::value;
37480b57cec5SDimitry Andric#endif
37490b57cec5SDimitry Andric    const size_t __k = __b / __logR + (__b % __logR != 0) + (__b == 0);
3750e40139ffSDimitry Andric    const _RealType _Rp = static_cast<_RealType>(_URNG::max() - _URNG::min()) + _RealType(1);
37510b57cec5SDimitry Andric    _RealType __base = _Rp;
37520b57cec5SDimitry Andric    _RealType _Sp = __g() - _URNG::min();
37530b57cec5SDimitry Andric    for (size_t __i = 1; __i < __k; ++__i, __base *= _Rp)
37540b57cec5SDimitry Andric        _Sp += (__g() - _URNG::min()) * __base;
37550b57cec5SDimitry Andric    return _Sp / __base;
37560b57cec5SDimitry Andric}
37570b57cec5SDimitry Andric
37580b57cec5SDimitry Andric// uniform_int_distribution
37590b57cec5SDimitry Andric
37600b57cec5SDimitry Andric// in <algorithm>
37610b57cec5SDimitry Andric
37620b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _IT>
37630b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
37640b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
37650b57cec5SDimitry Andric           const uniform_int_distribution<_IT>& __x)
37660b57cec5SDimitry Andric{
37670b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
3768*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _Ostream;
3769*e8d8bef9SDimitry Andric    __os.flags(_Ostream::dec | _Ostream::left);
37700b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
37710b57cec5SDimitry Andric    __os.fill(__sp);
37720b57cec5SDimitry Andric    return __os << __x.a() << __sp << __x.b();
37730b57cec5SDimitry Andric}
37740b57cec5SDimitry Andric
37750b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _IT>
37760b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
37770b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
37780b57cec5SDimitry Andric           uniform_int_distribution<_IT>& __x)
37790b57cec5SDimitry Andric{
37800b57cec5SDimitry Andric    typedef uniform_int_distribution<_IT> _Eng;
37810b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
37820b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
37830b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
3784*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
3785*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
37860b57cec5SDimitry Andric    result_type __a;
37870b57cec5SDimitry Andric    result_type __b;
37880b57cec5SDimitry Andric    __is >> __a >> __b;
37890b57cec5SDimitry Andric    if (!__is.fail())
37900b57cec5SDimitry Andric        __x.param(param_type(__a, __b));
37910b57cec5SDimitry Andric    return __is;
37920b57cec5SDimitry Andric}
37930b57cec5SDimitry Andric
37940b57cec5SDimitry Andric// uniform_real_distribution
37950b57cec5SDimitry Andric
37960b57cec5SDimitry Andrictemplate<class _RealType = double>
37970b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS uniform_real_distribution
37980b57cec5SDimitry Andric{
37990b57cec5SDimitry Andricpublic:
38000b57cec5SDimitry Andric    // types
38010b57cec5SDimitry Andric    typedef _RealType result_type;
38020b57cec5SDimitry Andric
38030b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
38040b57cec5SDimitry Andric    {
38050b57cec5SDimitry Andric        result_type __a_;
38060b57cec5SDimitry Andric        result_type __b_;
38070b57cec5SDimitry Andric    public:
38080b57cec5SDimitry Andric        typedef uniform_real_distribution distribution_type;
38090b57cec5SDimitry Andric
38100b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
38110b57cec5SDimitry Andric        explicit param_type(result_type __a = 0,
38120b57cec5SDimitry Andric                            result_type __b = 1)
38130b57cec5SDimitry Andric            : __a_(__a), __b_(__b) {}
38140b57cec5SDimitry Andric
38150b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
38160b57cec5SDimitry Andric        result_type a() const {return __a_;}
38170b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
38180b57cec5SDimitry Andric        result_type b() const {return __b_;}
38190b57cec5SDimitry Andric
38200b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
38210b57cec5SDimitry Andric        bool operator==(const param_type& __x, const param_type& __y)
38220b57cec5SDimitry Andric            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
38230b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
38240b57cec5SDimitry Andric        bool operator!=(const param_type& __x, const param_type& __y)
38250b57cec5SDimitry Andric            {return !(__x == __y);}
38260b57cec5SDimitry Andric    };
38270b57cec5SDimitry Andric
38280b57cec5SDimitry Andricprivate:
38290b57cec5SDimitry Andric    param_type __p_;
38300b57cec5SDimitry Andric
38310b57cec5SDimitry Andricpublic:
38320b57cec5SDimitry Andric    // constructors and reset functions
3833*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
3834*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3835*e8d8bef9SDimitry Andric    uniform_real_distribution() : uniform_real_distribution(0) {}
3836*e8d8bef9SDimitry Andric    explicit uniform_real_distribution(result_type __a, result_type __b = 1)
3837*e8d8bef9SDimitry Andric        : __p_(param_type(__a, __b)) {}
3838*e8d8bef9SDimitry Andric#else
38390b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38400b57cec5SDimitry Andric    explicit uniform_real_distribution(result_type __a = 0, result_type __b = 1)
38410b57cec5SDimitry Andric        : __p_(param_type(__a, __b)) {}
3842*e8d8bef9SDimitry Andric#endif
38430b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38440b57cec5SDimitry Andric    explicit uniform_real_distribution(const param_type& __p) : __p_(__p) {}
38450b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38460b57cec5SDimitry Andric    void reset() {}
38470b57cec5SDimitry Andric
38480b57cec5SDimitry Andric    // generating functions
38490b57cec5SDimitry Andric    template<class _URNG>
38500b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
38510b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
38520b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
38530b57cec5SDimitry Andric    template<class _URNG> _LIBCPP_INLINE_VISIBILITY result_type operator()(_URNG& __g, const param_type& __p);
38540b57cec5SDimitry Andric
38550b57cec5SDimitry Andric    // property functions
38560b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38570b57cec5SDimitry Andric    result_type a() const {return __p_.a();}
38580b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38590b57cec5SDimitry Andric    result_type b() const {return __p_.b();}
38600b57cec5SDimitry Andric
38610b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38620b57cec5SDimitry Andric    param_type param() const {return __p_;}
38630b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38640b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
38650b57cec5SDimitry Andric
38660b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38670b57cec5SDimitry Andric    result_type min() const {return a();}
38680b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
38690b57cec5SDimitry Andric    result_type max() const {return b();}
38700b57cec5SDimitry Andric
38710b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
38720b57cec5SDimitry Andric        bool operator==(const uniform_real_distribution& __x,
38730b57cec5SDimitry Andric                        const uniform_real_distribution& __y)
38740b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
38750b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
38760b57cec5SDimitry Andric        bool operator!=(const uniform_real_distribution& __x,
38770b57cec5SDimitry Andric                        const uniform_real_distribution& __y)
38780b57cec5SDimitry Andric        {return !(__x == __y);}
38790b57cec5SDimitry Andric};
38800b57cec5SDimitry Andric
38810b57cec5SDimitry Andrictemplate<class _RealType>
38820b57cec5SDimitry Andrictemplate<class _URNG>
38830b57cec5SDimitry Andricinline
38840b57cec5SDimitry Andrictypename uniform_real_distribution<_RealType>::result_type
38850b57cec5SDimitry Andricuniform_real_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
38860b57cec5SDimitry Andric{
38870b57cec5SDimitry Andric    return (__p.b() - __p.a())
38880b57cec5SDimitry Andric        * _VSTD::generate_canonical<_RealType, numeric_limits<_RealType>::digits>(__g)
38890b57cec5SDimitry Andric        + __p.a();
38900b57cec5SDimitry Andric}
38910b57cec5SDimitry Andric
38920b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
38930b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
38940b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
38950b57cec5SDimitry Andric           const uniform_real_distribution<_RT>& __x)
38960b57cec5SDimitry Andric{
38970b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
3898*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
3899*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
3900*e8d8bef9SDimitry Andric               _OStream::scientific);
39010b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
39020b57cec5SDimitry Andric    __os.fill(__sp);
39030b57cec5SDimitry Andric    return __os << __x.a() << __sp << __x.b();
39040b57cec5SDimitry Andric}
39050b57cec5SDimitry Andric
39060b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
39070b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
39080b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
39090b57cec5SDimitry Andric           uniform_real_distribution<_RT>& __x)
39100b57cec5SDimitry Andric{
39110b57cec5SDimitry Andric    typedef uniform_real_distribution<_RT> _Eng;
39120b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
39130b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
39140b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
3915*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
3916*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
39170b57cec5SDimitry Andric    result_type __a;
39180b57cec5SDimitry Andric    result_type __b;
39190b57cec5SDimitry Andric    __is >> __a >> __b;
39200b57cec5SDimitry Andric    if (!__is.fail())
39210b57cec5SDimitry Andric        __x.param(param_type(__a, __b));
39220b57cec5SDimitry Andric    return __is;
39230b57cec5SDimitry Andric}
39240b57cec5SDimitry Andric
39250b57cec5SDimitry Andric// bernoulli_distribution
39260b57cec5SDimitry Andric
39270b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS bernoulli_distribution
39280b57cec5SDimitry Andric{
39290b57cec5SDimitry Andricpublic:
39300b57cec5SDimitry Andric    // types
39310b57cec5SDimitry Andric    typedef bool result_type;
39320b57cec5SDimitry Andric
39330b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
39340b57cec5SDimitry Andric    {
39350b57cec5SDimitry Andric        double __p_;
39360b57cec5SDimitry Andric    public:
39370b57cec5SDimitry Andric        typedef bernoulli_distribution distribution_type;
39380b57cec5SDimitry Andric
39390b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
39400b57cec5SDimitry Andric        explicit param_type(double __p = 0.5) : __p_(__p) {}
39410b57cec5SDimitry Andric
39420b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
39430b57cec5SDimitry Andric        double p() const {return __p_;}
39440b57cec5SDimitry Andric
39450b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
39460b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
39470b57cec5SDimitry Andric            {return __x.__p_ == __y.__p_;}
39480b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
39490b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
39500b57cec5SDimitry Andric            {return !(__x == __y);}
39510b57cec5SDimitry Andric    };
39520b57cec5SDimitry Andric
39530b57cec5SDimitry Andricprivate:
39540b57cec5SDimitry Andric    param_type __p_;
39550b57cec5SDimitry Andric
39560b57cec5SDimitry Andricpublic:
39570b57cec5SDimitry Andric    // constructors and reset functions
3958*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
39590b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3960*e8d8bef9SDimitry Andric    bernoulli_distribution() : bernoulli_distribution(0.5) {}
3961*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3962*e8d8bef9SDimitry Andric    explicit bernoulli_distribution(double __p) : __p_(param_type(__p)) {}
3963*e8d8bef9SDimitry Andric#else
3964*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
3965*e8d8bef9SDimitry Andric    explicit bernoulli_distribution(double __p = 0.5) : __p_(param_type(__p)) {}
3966*e8d8bef9SDimitry Andric#endif
39670b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39680b57cec5SDimitry Andric    explicit bernoulli_distribution(const param_type& __p) : __p_(__p) {}
39690b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39700b57cec5SDimitry Andric    void reset() {}
39710b57cec5SDimitry Andric
39720b57cec5SDimitry Andric    // generating functions
39730b57cec5SDimitry Andric    template<class _URNG>
39740b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
39750b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
39760b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
39770b57cec5SDimitry Andric    template<class _URNG> _LIBCPP_INLINE_VISIBILITY result_type operator()(_URNG& __g, const param_type& __p);
39780b57cec5SDimitry Andric
39790b57cec5SDimitry Andric    // property functions
39800b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39810b57cec5SDimitry Andric    double p() const {return __p_.p();}
39820b57cec5SDimitry Andric
39830b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39840b57cec5SDimitry Andric    param_type param() const {return __p_;}
39850b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39860b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
39870b57cec5SDimitry Andric
39880b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39890b57cec5SDimitry Andric    result_type min() const {return false;}
39900b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
39910b57cec5SDimitry Andric    result_type max() const {return true;}
39920b57cec5SDimitry Andric
39930b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
39940b57cec5SDimitry Andric        bool operator==(const bernoulli_distribution& __x,
39950b57cec5SDimitry Andric                        const bernoulli_distribution& __y)
39960b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
39970b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
39980b57cec5SDimitry Andric        bool operator!=(const bernoulli_distribution& __x,
39990b57cec5SDimitry Andric                        const bernoulli_distribution& __y)
40000b57cec5SDimitry Andric        {return !(__x == __y);}
40010b57cec5SDimitry Andric};
40020b57cec5SDimitry Andric
40030b57cec5SDimitry Andrictemplate<class _URNG>
40040b57cec5SDimitry Andricinline
40050b57cec5SDimitry Andricbernoulli_distribution::result_type
40060b57cec5SDimitry Andricbernoulli_distribution::operator()(_URNG& __g, const param_type& __p)
40070b57cec5SDimitry Andric{
40080b57cec5SDimitry Andric    uniform_real_distribution<double> __gen;
40090b57cec5SDimitry Andric    return __gen(__g) < __p.p();
40100b57cec5SDimitry Andric}
40110b57cec5SDimitry Andric
40120b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
40130b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
40140b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os, const bernoulli_distribution& __x)
40150b57cec5SDimitry Andric{
40160b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
4017*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
4018*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
4019*e8d8bef9SDimitry Andric               _OStream::scientific);
40200b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
40210b57cec5SDimitry Andric    __os.fill(__sp);
40220b57cec5SDimitry Andric    return __os << __x.p();
40230b57cec5SDimitry Andric}
40240b57cec5SDimitry Andric
40250b57cec5SDimitry Andrictemplate <class _CharT, class _Traits>
40260b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
40270b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is, bernoulli_distribution& __x)
40280b57cec5SDimitry Andric{
40290b57cec5SDimitry Andric    typedef bernoulli_distribution _Eng;
40300b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
40310b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
4032*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
4033*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
40340b57cec5SDimitry Andric    double __p;
40350b57cec5SDimitry Andric    __is >> __p;
40360b57cec5SDimitry Andric    if (!__is.fail())
40370b57cec5SDimitry Andric        __x.param(param_type(__p));
40380b57cec5SDimitry Andric    return __is;
40390b57cec5SDimitry Andric}
40400b57cec5SDimitry Andric
40410b57cec5SDimitry Andric// binomial_distribution
40420b57cec5SDimitry Andric
40430b57cec5SDimitry Andrictemplate<class _IntType = int>
40440b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS binomial_distribution
40450b57cec5SDimitry Andric{
40460b57cec5SDimitry Andricpublic:
40470b57cec5SDimitry Andric    // types
40480b57cec5SDimitry Andric    typedef _IntType result_type;
40490b57cec5SDimitry Andric
40500b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
40510b57cec5SDimitry Andric    {
40520b57cec5SDimitry Andric        result_type __t_;
40530b57cec5SDimitry Andric        double __p_;
40540b57cec5SDimitry Andric        double __pr_;
40550b57cec5SDimitry Andric        double __odds_ratio_;
40560b57cec5SDimitry Andric        result_type __r0_;
40570b57cec5SDimitry Andric    public:
40580b57cec5SDimitry Andric        typedef binomial_distribution distribution_type;
40590b57cec5SDimitry Andric
40600b57cec5SDimitry Andric        explicit param_type(result_type __t = 1, double __p = 0.5);
40610b57cec5SDimitry Andric
40620b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
40630b57cec5SDimitry Andric        result_type t() const {return __t_;}
40640b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
40650b57cec5SDimitry Andric        double p() const {return __p_;}
40660b57cec5SDimitry Andric
40670b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
40680b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
40690b57cec5SDimitry Andric            {return __x.__t_ == __y.__t_ && __x.__p_ == __y.__p_;}
40700b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
40710b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
40720b57cec5SDimitry Andric            {return !(__x == __y);}
40730b57cec5SDimitry Andric
40740b57cec5SDimitry Andric        friend class binomial_distribution;
40750b57cec5SDimitry Andric    };
40760b57cec5SDimitry Andric
40770b57cec5SDimitry Andricprivate:
40780b57cec5SDimitry Andric    param_type __p_;
40790b57cec5SDimitry Andric
40800b57cec5SDimitry Andricpublic:
40810b57cec5SDimitry Andric    // constructors and reset functions
4082*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
4083*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4084*e8d8bef9SDimitry Andric    binomial_distribution() : binomial_distribution(1) {}
4085*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4086*e8d8bef9SDimitry Andric    explicit binomial_distribution(result_type __t, double __p = 0.5)
4087*e8d8bef9SDimitry Andric        : __p_(param_type(__t, __p)) {}
4088*e8d8bef9SDimitry Andric#else
40890b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
40900b57cec5SDimitry Andric    explicit binomial_distribution(result_type __t = 1, double __p = 0.5)
40910b57cec5SDimitry Andric        : __p_(param_type(__t, __p)) {}
4092*e8d8bef9SDimitry Andric#endif
40930b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
40940b57cec5SDimitry Andric    explicit binomial_distribution(const param_type& __p) : __p_(__p) {}
40950b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
40960b57cec5SDimitry Andric    void reset() {}
40970b57cec5SDimitry Andric
40980b57cec5SDimitry Andric    // generating functions
40990b57cec5SDimitry Andric    template<class _URNG>
41000b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
41010b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
41020b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
41030b57cec5SDimitry Andric    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
41040b57cec5SDimitry Andric
41050b57cec5SDimitry Andric    // property functions
41060b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
41070b57cec5SDimitry Andric    result_type t() const {return __p_.t();}
41080b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
41090b57cec5SDimitry Andric    double p() const {return __p_.p();}
41100b57cec5SDimitry Andric
41110b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
41120b57cec5SDimitry Andric    param_type param() const {return __p_;}
41130b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
41140b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
41150b57cec5SDimitry Andric
41160b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
41170b57cec5SDimitry Andric    result_type min() const {return 0;}
41180b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
41190b57cec5SDimitry Andric    result_type max() const {return t();}
41200b57cec5SDimitry Andric
41210b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
41220b57cec5SDimitry Andric        bool operator==(const binomial_distribution& __x,
41230b57cec5SDimitry Andric                        const binomial_distribution& __y)
41240b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
41250b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
41260b57cec5SDimitry Andric        bool operator!=(const binomial_distribution& __x,
41270b57cec5SDimitry Andric                        const binomial_distribution& __y)
41280b57cec5SDimitry Andric        {return !(__x == __y);}
41290b57cec5SDimitry Andric};
41300b57cec5SDimitry Andric
4131*e8d8bef9SDimitry Andric#ifndef _LIBCPP_MSVCRT_LIKE
41320b57cec5SDimitry Andricextern "C" double lgamma_r(double, int *);
41330b57cec5SDimitry Andric#endif
41340b57cec5SDimitry Andric
41350b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY double __libcpp_lgamma(double __d) {
4136*e8d8bef9SDimitry Andric#if defined(_LIBCPP_MSVCRT_LIKE)
41370b57cec5SDimitry Andric  return lgamma(__d);
41380b57cec5SDimitry Andric#else
41390b57cec5SDimitry Andric  int __sign;
41400b57cec5SDimitry Andric  return lgamma_r(__d, &__sign);
41410b57cec5SDimitry Andric#endif
41420b57cec5SDimitry Andric}
41430b57cec5SDimitry Andric
41440b57cec5SDimitry Andrictemplate<class _IntType>
41450b57cec5SDimitry Andricbinomial_distribution<_IntType>::param_type::param_type(const result_type __t, const double __p)
41460b57cec5SDimitry Andric    : __t_(__t), __p_(__p)
41470b57cec5SDimitry Andric{
41480b57cec5SDimitry Andric    if (0 < __p_ && __p_ < 1)
41490b57cec5SDimitry Andric    {
41500b57cec5SDimitry Andric        __r0_ = static_cast<result_type>((__t_ + 1) * __p_);
41510b57cec5SDimitry Andric        __pr_ = _VSTD::exp(__libcpp_lgamma(__t_ + 1.) -
41520b57cec5SDimitry Andric                           __libcpp_lgamma(__r0_ + 1.) -
41530b57cec5SDimitry Andric                           __libcpp_lgamma(__t_ - __r0_ + 1.) + __r0_ * _VSTD::log(__p_) +
41540b57cec5SDimitry Andric                           (__t_ - __r0_) * _VSTD::log(1 - __p_));
41550b57cec5SDimitry Andric        __odds_ratio_ = __p_ / (1 - __p_);
41560b57cec5SDimitry Andric    }
41570b57cec5SDimitry Andric}
41580b57cec5SDimitry Andric
41590b57cec5SDimitry Andric// Reference: Kemp, C.D. (1986). `A modal method for generating binomial
41600b57cec5SDimitry Andric//           variables', Commun. Statist. - Theor. Meth. 15(3), 805-813.
41610b57cec5SDimitry Andrictemplate<class _IntType>
41620b57cec5SDimitry Andrictemplate<class _URNG>
41630b57cec5SDimitry Andric_IntType
41640b57cec5SDimitry Andricbinomial_distribution<_IntType>::operator()(_URNG& __g, const param_type& __pr)
41650b57cec5SDimitry Andric{
41660b57cec5SDimitry Andric    if (__pr.__t_ == 0 || __pr.__p_ == 0)
41670b57cec5SDimitry Andric        return 0;
41680b57cec5SDimitry Andric    if (__pr.__p_ == 1)
41690b57cec5SDimitry Andric        return __pr.__t_;
41700b57cec5SDimitry Andric    uniform_real_distribution<double> __gen;
41710b57cec5SDimitry Andric    double __u = __gen(__g) - __pr.__pr_;
41720b57cec5SDimitry Andric    if (__u < 0)
41730b57cec5SDimitry Andric        return __pr.__r0_;
41740b57cec5SDimitry Andric    double __pu = __pr.__pr_;
41750b57cec5SDimitry Andric    double __pd = __pu;
41760b57cec5SDimitry Andric    result_type __ru = __pr.__r0_;
41770b57cec5SDimitry Andric    result_type __rd = __ru;
41780b57cec5SDimitry Andric    while (true)
41790b57cec5SDimitry Andric    {
41805ffd83dbSDimitry Andric        bool __break = true;
41810b57cec5SDimitry Andric        if (__rd >= 1)
41820b57cec5SDimitry Andric        {
41830b57cec5SDimitry Andric            __pd *= __rd / (__pr.__odds_ratio_ * (__pr.__t_ - __rd + 1));
41840b57cec5SDimitry Andric            __u -= __pd;
41855ffd83dbSDimitry Andric            __break = false;
41860b57cec5SDimitry Andric            if (__u < 0)
41870b57cec5SDimitry Andric                return __rd - 1;
41880b57cec5SDimitry Andric        }
41890b57cec5SDimitry Andric        if ( __rd != 0 )
41900b57cec5SDimitry Andric            --__rd;
41910b57cec5SDimitry Andric        ++__ru;
41920b57cec5SDimitry Andric        if (__ru <= __pr.__t_)
41930b57cec5SDimitry Andric        {
41940b57cec5SDimitry Andric            __pu *= (__pr.__t_ - __ru + 1) * __pr.__odds_ratio_ / __ru;
41950b57cec5SDimitry Andric            __u -= __pu;
41965ffd83dbSDimitry Andric            __break = false;
41970b57cec5SDimitry Andric            if (__u < 0)
41980b57cec5SDimitry Andric                return __ru;
41990b57cec5SDimitry Andric        }
42005ffd83dbSDimitry Andric        if (__break)
42015ffd83dbSDimitry Andric            return 0;
42020b57cec5SDimitry Andric    }
42030b57cec5SDimitry Andric}
42040b57cec5SDimitry Andric
42050b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _IntType>
42060b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
42070b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
42080b57cec5SDimitry Andric           const binomial_distribution<_IntType>& __x)
42090b57cec5SDimitry Andric{
42100b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
4211*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
4212*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
4213*e8d8bef9SDimitry Andric               _OStream::scientific);
42140b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
42150b57cec5SDimitry Andric    __os.fill(__sp);
42160b57cec5SDimitry Andric    return __os << __x.t() << __sp << __x.p();
42170b57cec5SDimitry Andric}
42180b57cec5SDimitry Andric
42190b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _IntType>
42200b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
42210b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
42220b57cec5SDimitry Andric           binomial_distribution<_IntType>& __x)
42230b57cec5SDimitry Andric{
42240b57cec5SDimitry Andric    typedef binomial_distribution<_IntType> _Eng;
42250b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
42260b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
42270b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
4228*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
4229*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
42300b57cec5SDimitry Andric    result_type __t;
42310b57cec5SDimitry Andric    double __p;
42320b57cec5SDimitry Andric    __is >> __t >> __p;
42330b57cec5SDimitry Andric    if (!__is.fail())
42340b57cec5SDimitry Andric        __x.param(param_type(__t, __p));
42350b57cec5SDimitry Andric    return __is;
42360b57cec5SDimitry Andric}
42370b57cec5SDimitry Andric
42380b57cec5SDimitry Andric// exponential_distribution
42390b57cec5SDimitry Andric
42400b57cec5SDimitry Andrictemplate<class _RealType = double>
42410b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS exponential_distribution
42420b57cec5SDimitry Andric{
42430b57cec5SDimitry Andricpublic:
42440b57cec5SDimitry Andric    // types
42450b57cec5SDimitry Andric    typedef _RealType result_type;
42460b57cec5SDimitry Andric
42470b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
42480b57cec5SDimitry Andric    {
42490b57cec5SDimitry Andric        result_type __lambda_;
42500b57cec5SDimitry Andric    public:
42510b57cec5SDimitry Andric        typedef exponential_distribution distribution_type;
42520b57cec5SDimitry Andric
42530b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
42540b57cec5SDimitry Andric        explicit param_type(result_type __lambda = 1) : __lambda_(__lambda) {}
42550b57cec5SDimitry Andric
42560b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
42570b57cec5SDimitry Andric        result_type lambda() const {return __lambda_;}
42580b57cec5SDimitry Andric
42590b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
42600b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
42610b57cec5SDimitry Andric            {return __x.__lambda_ == __y.__lambda_;}
42620b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
42630b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
42640b57cec5SDimitry Andric            {return !(__x == __y);}
42650b57cec5SDimitry Andric    };
42660b57cec5SDimitry Andric
42670b57cec5SDimitry Andricprivate:
42680b57cec5SDimitry Andric    param_type __p_;
42690b57cec5SDimitry Andric
42700b57cec5SDimitry Andricpublic:
42710b57cec5SDimitry Andric    // constructors and reset functions
4272*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
4273*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4274*e8d8bef9SDimitry Andric    exponential_distribution() : exponential_distribution(1) {}
4275*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4276*e8d8bef9SDimitry Andric    explicit exponential_distribution(result_type __lambda)
4277*e8d8bef9SDimitry Andric        : __p_(param_type(__lambda)) {}
4278*e8d8bef9SDimitry Andric#else
42790b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
42800b57cec5SDimitry Andric    explicit exponential_distribution(result_type __lambda = 1)
42810b57cec5SDimitry Andric        : __p_(param_type(__lambda)) {}
4282*e8d8bef9SDimitry Andric#endif
42830b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
42840b57cec5SDimitry Andric    explicit exponential_distribution(const param_type& __p) : __p_(__p) {}
42850b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
42860b57cec5SDimitry Andric    void reset() {}
42870b57cec5SDimitry Andric
42880b57cec5SDimitry Andric    // generating functions
42890b57cec5SDimitry Andric    template<class _URNG>
42900b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
42910b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
42920b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
42930b57cec5SDimitry Andric    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
42940b57cec5SDimitry Andric
42950b57cec5SDimitry Andric    // property functions
42960b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
42970b57cec5SDimitry Andric    result_type lambda() const {return __p_.lambda();}
42980b57cec5SDimitry Andric
42990b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
43000b57cec5SDimitry Andric    param_type param() const {return __p_;}
43010b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
43020b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
43030b57cec5SDimitry Andric
43040b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
43050b57cec5SDimitry Andric    result_type min() const {return 0;}
43060b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
43070b57cec5SDimitry Andric    result_type max() const {return numeric_limits<result_type>::infinity();}
43080b57cec5SDimitry Andric
43090b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
43100b57cec5SDimitry Andric        bool operator==(const exponential_distribution& __x,
43110b57cec5SDimitry Andric                        const exponential_distribution& __y)
43120b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
43130b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
43140b57cec5SDimitry Andric        bool operator!=(const exponential_distribution& __x,
43150b57cec5SDimitry Andric                        const exponential_distribution& __y)
43160b57cec5SDimitry Andric        {return !(__x == __y);}
43170b57cec5SDimitry Andric};
43180b57cec5SDimitry Andric
43190b57cec5SDimitry Andrictemplate <class _RealType>
43200b57cec5SDimitry Andrictemplate<class _URNG>
43210b57cec5SDimitry Andric_RealType
43220b57cec5SDimitry Andricexponential_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
43230b57cec5SDimitry Andric{
43240b57cec5SDimitry Andric    return -_VSTD::log
43250b57cec5SDimitry Andric                  (
43260b57cec5SDimitry Andric                      result_type(1) -
43270b57cec5SDimitry Andric                      _VSTD::generate_canonical<result_type,
43280b57cec5SDimitry Andric                                       numeric_limits<result_type>::digits>(__g)
43290b57cec5SDimitry Andric                  )
43300b57cec5SDimitry Andric                  / __p.lambda();
43310b57cec5SDimitry Andric}
43320b57cec5SDimitry Andric
43330b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RealType>
43340b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
43350b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
43360b57cec5SDimitry Andric           const exponential_distribution<_RealType>& __x)
43370b57cec5SDimitry Andric{
43380b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
4339*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
4340*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
4341*e8d8bef9SDimitry Andric               _OStream::scientific);
43420b57cec5SDimitry Andric    return __os << __x.lambda();
43430b57cec5SDimitry Andric}
43440b57cec5SDimitry Andric
43450b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RealType>
43460b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
43470b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
43480b57cec5SDimitry Andric           exponential_distribution<_RealType>& __x)
43490b57cec5SDimitry Andric{
43500b57cec5SDimitry Andric    typedef exponential_distribution<_RealType> _Eng;
43510b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
43520b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
43530b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
4354*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
4355*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
43560b57cec5SDimitry Andric    result_type __lambda;
43570b57cec5SDimitry Andric    __is >> __lambda;
43580b57cec5SDimitry Andric    if (!__is.fail())
43590b57cec5SDimitry Andric        __x.param(param_type(__lambda));
43600b57cec5SDimitry Andric    return __is;
43610b57cec5SDimitry Andric}
43620b57cec5SDimitry Andric
43630b57cec5SDimitry Andric// normal_distribution
43640b57cec5SDimitry Andric
43650b57cec5SDimitry Andrictemplate<class _RealType = double>
43660b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS normal_distribution
43670b57cec5SDimitry Andric{
43680b57cec5SDimitry Andricpublic:
43690b57cec5SDimitry Andric    // types
43700b57cec5SDimitry Andric    typedef _RealType result_type;
43710b57cec5SDimitry Andric
43720b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
43730b57cec5SDimitry Andric    {
43740b57cec5SDimitry Andric        result_type __mean_;
43750b57cec5SDimitry Andric        result_type __stddev_;
43760b57cec5SDimitry Andric    public:
43770b57cec5SDimitry Andric        typedef normal_distribution distribution_type;
43780b57cec5SDimitry Andric
43790b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
43800b57cec5SDimitry Andric        explicit param_type(result_type __mean = 0, result_type __stddev = 1)
43810b57cec5SDimitry Andric            : __mean_(__mean), __stddev_(__stddev) {}
43820b57cec5SDimitry Andric
43830b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
43840b57cec5SDimitry Andric        result_type mean() const {return __mean_;}
43850b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
43860b57cec5SDimitry Andric        result_type stddev() const {return __stddev_;}
43870b57cec5SDimitry Andric
43880b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
43890b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
43900b57cec5SDimitry Andric            {return __x.__mean_ == __y.__mean_ && __x.__stddev_ == __y.__stddev_;}
43910b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
43920b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
43930b57cec5SDimitry Andric            {return !(__x == __y);}
43940b57cec5SDimitry Andric    };
43950b57cec5SDimitry Andric
43960b57cec5SDimitry Andricprivate:
43970b57cec5SDimitry Andric    param_type __p_;
43980b57cec5SDimitry Andric    result_type _V_;
43990b57cec5SDimitry Andric    bool _V_hot_;
44000b57cec5SDimitry Andric
44010b57cec5SDimitry Andricpublic:
44020b57cec5SDimitry Andric    // constructors and reset functions
4403*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
44040b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4405*e8d8bef9SDimitry Andric    normal_distribution() : normal_distribution(0) {}
4406*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4407*e8d8bef9SDimitry Andric    explicit normal_distribution(result_type __mean, result_type __stddev = 1)
44080b57cec5SDimitry Andric        : __p_(param_type(__mean, __stddev)), _V_hot_(false) {}
4409*e8d8bef9SDimitry Andric#else
4410*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4411*e8d8bef9SDimitry Andric    explicit normal_distribution(result_type __mean = 0,
4412*e8d8bef9SDimitry Andric                                 result_type __stddev = 1)
4413*e8d8bef9SDimitry Andric        : __p_(param_type(__mean, __stddev)), _V_hot_(false) {}
4414*e8d8bef9SDimitry Andric#endif
44150b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
44160b57cec5SDimitry Andric    explicit normal_distribution(const param_type& __p)
44170b57cec5SDimitry Andric        : __p_(__p), _V_hot_(false) {}
44180b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
44190b57cec5SDimitry Andric    void reset() {_V_hot_ = false;}
44200b57cec5SDimitry Andric
44210b57cec5SDimitry Andric    // generating functions
44220b57cec5SDimitry Andric    template<class _URNG>
44230b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
44240b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
44250b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
44260b57cec5SDimitry Andric    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
44270b57cec5SDimitry Andric
44280b57cec5SDimitry Andric    // property functions
44290b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
44300b57cec5SDimitry Andric    result_type mean() const {return __p_.mean();}
44310b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
44320b57cec5SDimitry Andric    result_type stddev() const {return __p_.stddev();}
44330b57cec5SDimitry Andric
44340b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
44350b57cec5SDimitry Andric    param_type param() const {return __p_;}
44360b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
44370b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
44380b57cec5SDimitry Andric
44390b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
44400b57cec5SDimitry Andric    result_type min() const {return -numeric_limits<result_type>::infinity();}
44410b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
44420b57cec5SDimitry Andric    result_type max() const {return numeric_limits<result_type>::infinity();}
44430b57cec5SDimitry Andric
44440b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
44450b57cec5SDimitry Andric        bool operator==(const normal_distribution& __x,
44460b57cec5SDimitry Andric                        const normal_distribution& __y)
44470b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_ && __x._V_hot_ == __y._V_hot_ &&
44480b57cec5SDimitry Andric                (!__x._V_hot_ || __x._V_ == __y._V_);}
44490b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
44500b57cec5SDimitry Andric        bool operator!=(const normal_distribution& __x,
44510b57cec5SDimitry Andric                        const normal_distribution& __y)
44520b57cec5SDimitry Andric        {return !(__x == __y);}
44530b57cec5SDimitry Andric
44540b57cec5SDimitry Andric    template <class _CharT, class _Traits, class _RT>
44550b57cec5SDimitry Andric    friend
44560b57cec5SDimitry Andric    basic_ostream<_CharT, _Traits>&
44570b57cec5SDimitry Andric    operator<<(basic_ostream<_CharT, _Traits>& __os,
44580b57cec5SDimitry Andric               const normal_distribution<_RT>& __x);
44590b57cec5SDimitry Andric
44600b57cec5SDimitry Andric    template <class _CharT, class _Traits, class _RT>
44610b57cec5SDimitry Andric    friend
44620b57cec5SDimitry Andric    basic_istream<_CharT, _Traits>&
44630b57cec5SDimitry Andric    operator>>(basic_istream<_CharT, _Traits>& __is,
44640b57cec5SDimitry Andric               normal_distribution<_RT>& __x);
44650b57cec5SDimitry Andric};
44660b57cec5SDimitry Andric
44670b57cec5SDimitry Andrictemplate <class _RealType>
44680b57cec5SDimitry Andrictemplate<class _URNG>
44690b57cec5SDimitry Andric_RealType
44700b57cec5SDimitry Andricnormal_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
44710b57cec5SDimitry Andric{
44720b57cec5SDimitry Andric    result_type _Up;
44730b57cec5SDimitry Andric    if (_V_hot_)
44740b57cec5SDimitry Andric    {
44750b57cec5SDimitry Andric        _V_hot_ = false;
44760b57cec5SDimitry Andric        _Up = _V_;
44770b57cec5SDimitry Andric    }
44780b57cec5SDimitry Andric    else
44790b57cec5SDimitry Andric    {
44800b57cec5SDimitry Andric        uniform_real_distribution<result_type> _Uni(-1, 1);
44810b57cec5SDimitry Andric        result_type __u;
44820b57cec5SDimitry Andric        result_type __v;
44830b57cec5SDimitry Andric        result_type __s;
44840b57cec5SDimitry Andric        do
44850b57cec5SDimitry Andric        {
44860b57cec5SDimitry Andric            __u = _Uni(__g);
44870b57cec5SDimitry Andric            __v = _Uni(__g);
44880b57cec5SDimitry Andric            __s = __u * __u + __v * __v;
44890b57cec5SDimitry Andric        } while (__s > 1 || __s == 0);
44900b57cec5SDimitry Andric        result_type _Fp = _VSTD::sqrt(-2 * _VSTD::log(__s) / __s);
44910b57cec5SDimitry Andric        _V_ = __v * _Fp;
44920b57cec5SDimitry Andric        _V_hot_ = true;
44930b57cec5SDimitry Andric        _Up = __u * _Fp;
44940b57cec5SDimitry Andric    }
44950b57cec5SDimitry Andric    return _Up * __p.stddev() + __p.mean();
44960b57cec5SDimitry Andric}
44970b57cec5SDimitry Andric
44980b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
44990b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
45000b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
45010b57cec5SDimitry Andric           const normal_distribution<_RT>& __x)
45020b57cec5SDimitry Andric{
45030b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
4504*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
4505*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
4506*e8d8bef9SDimitry Andric               _OStream::scientific);
45070b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
45080b57cec5SDimitry Andric    __os.fill(__sp);
45090b57cec5SDimitry Andric    __os << __x.mean() << __sp << __x.stddev() << __sp << __x._V_hot_;
45100b57cec5SDimitry Andric    if (__x._V_hot_)
45110b57cec5SDimitry Andric        __os << __sp << __x._V_;
45120b57cec5SDimitry Andric    return __os;
45130b57cec5SDimitry Andric}
45140b57cec5SDimitry Andric
45150b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
45160b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
45170b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
45180b57cec5SDimitry Andric           normal_distribution<_RT>& __x)
45190b57cec5SDimitry Andric{
45200b57cec5SDimitry Andric    typedef normal_distribution<_RT> _Eng;
45210b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
45220b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
45230b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
4524*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
4525*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
45260b57cec5SDimitry Andric    result_type __mean;
45270b57cec5SDimitry Andric    result_type __stddev;
45280b57cec5SDimitry Andric    result_type _Vp = 0;
45290b57cec5SDimitry Andric    bool _V_hot = false;
45300b57cec5SDimitry Andric    __is >> __mean >> __stddev >> _V_hot;
45310b57cec5SDimitry Andric    if (_V_hot)
45320b57cec5SDimitry Andric        __is >> _Vp;
45330b57cec5SDimitry Andric    if (!__is.fail())
45340b57cec5SDimitry Andric    {
45350b57cec5SDimitry Andric        __x.param(param_type(__mean, __stddev));
45360b57cec5SDimitry Andric        __x._V_hot_ = _V_hot;
45370b57cec5SDimitry Andric        __x._V_ = _Vp;
45380b57cec5SDimitry Andric    }
45390b57cec5SDimitry Andric    return __is;
45400b57cec5SDimitry Andric}
45410b57cec5SDimitry Andric
45420b57cec5SDimitry Andric// lognormal_distribution
45430b57cec5SDimitry Andric
45440b57cec5SDimitry Andrictemplate<class _RealType = double>
45450b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS lognormal_distribution
45460b57cec5SDimitry Andric{
45470b57cec5SDimitry Andricpublic:
45480b57cec5SDimitry Andric    // types
45490b57cec5SDimitry Andric    typedef _RealType result_type;
45500b57cec5SDimitry Andric
45510b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
45520b57cec5SDimitry Andric    {
45530b57cec5SDimitry Andric        normal_distribution<result_type> __nd_;
45540b57cec5SDimitry Andric    public:
45550b57cec5SDimitry Andric        typedef lognormal_distribution distribution_type;
45560b57cec5SDimitry Andric
45570b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
45580b57cec5SDimitry Andric        explicit param_type(result_type __m = 0, result_type __s = 1)
45590b57cec5SDimitry Andric            : __nd_(__m, __s) {}
45600b57cec5SDimitry Andric
45610b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
45620b57cec5SDimitry Andric        result_type m() const {return __nd_.mean();}
45630b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
45640b57cec5SDimitry Andric        result_type s() const {return __nd_.stddev();}
45650b57cec5SDimitry Andric
45660b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
45670b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
45680b57cec5SDimitry Andric            {return __x.__nd_ == __y.__nd_;}
45690b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
45700b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
45710b57cec5SDimitry Andric            {return !(__x == __y);}
45720b57cec5SDimitry Andric        friend class lognormal_distribution;
45730b57cec5SDimitry Andric
45740b57cec5SDimitry Andric        template <class _CharT, class _Traits, class _RT>
45750b57cec5SDimitry Andric        friend
45760b57cec5SDimitry Andric        basic_ostream<_CharT, _Traits>&
45770b57cec5SDimitry Andric        operator<<(basic_ostream<_CharT, _Traits>& __os,
45780b57cec5SDimitry Andric                   const lognormal_distribution<_RT>& __x);
45790b57cec5SDimitry Andric
45800b57cec5SDimitry Andric        template <class _CharT, class _Traits, class _RT>
45810b57cec5SDimitry Andric        friend
45820b57cec5SDimitry Andric        basic_istream<_CharT, _Traits>&
45830b57cec5SDimitry Andric        operator>>(basic_istream<_CharT, _Traits>& __is,
45840b57cec5SDimitry Andric                   lognormal_distribution<_RT>& __x);
45850b57cec5SDimitry Andric    };
45860b57cec5SDimitry Andric
45870b57cec5SDimitry Andricprivate:
45880b57cec5SDimitry Andric    param_type __p_;
45890b57cec5SDimitry Andric
45900b57cec5SDimitry Andricpublic:
45910b57cec5SDimitry Andric    // constructor and reset functions
4592*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
45930b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4594*e8d8bef9SDimitry Andric    lognormal_distribution() : lognormal_distribution(0) {}
4595*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4596*e8d8bef9SDimitry Andric    explicit lognormal_distribution(result_type __m, result_type __s = 1)
45970b57cec5SDimitry Andric        : __p_(param_type(__m, __s)) {}
4598*e8d8bef9SDimitry Andric#else
4599*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4600*e8d8bef9SDimitry Andric    explicit lognormal_distribution(result_type __m = 0,
4601*e8d8bef9SDimitry Andric                                    result_type __s = 1)
4602*e8d8bef9SDimitry Andric        : __p_(param_type(__m, __s)) {}
4603*e8d8bef9SDimitry Andric#endif
46040b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46050b57cec5SDimitry Andric    explicit lognormal_distribution(const param_type& __p)
46060b57cec5SDimitry Andric        : __p_(__p) {}
46070b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46080b57cec5SDimitry Andric    void reset() {__p_.__nd_.reset();}
46090b57cec5SDimitry Andric
46100b57cec5SDimitry Andric    // generating functions
46110b57cec5SDimitry Andric    template<class _URNG>
46120b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
46130b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
46140b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
46150b57cec5SDimitry Andric    template<class _URNG>
46160b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
46170b57cec5SDimitry Andric        result_type operator()(_URNG& __g, const param_type& __p)
46180b57cec5SDimitry Andric        {return _VSTD::exp(const_cast<normal_distribution<result_type>&>(__p.__nd_)(__g));}
46190b57cec5SDimitry Andric
46200b57cec5SDimitry Andric    // property functions
46210b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46220b57cec5SDimitry Andric    result_type m() const {return __p_.m();}
46230b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46240b57cec5SDimitry Andric    result_type s() const {return __p_.s();}
46250b57cec5SDimitry Andric
46260b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46270b57cec5SDimitry Andric    param_type param() const {return __p_;}
46280b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46290b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
46300b57cec5SDimitry Andric
46310b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46320b57cec5SDimitry Andric    result_type min() const {return 0;}
46330b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
46340b57cec5SDimitry Andric    result_type max() const {return numeric_limits<result_type>::infinity();}
46350b57cec5SDimitry Andric
46360b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
46370b57cec5SDimitry Andric        bool operator==(const lognormal_distribution& __x,
46380b57cec5SDimitry Andric                        const lognormal_distribution& __y)
46390b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
46400b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
46410b57cec5SDimitry Andric        bool operator!=(const lognormal_distribution& __x,
46420b57cec5SDimitry Andric                        const lognormal_distribution& __y)
46430b57cec5SDimitry Andric        {return !(__x == __y);}
46440b57cec5SDimitry Andric
46450b57cec5SDimitry Andric    template <class _CharT, class _Traits, class _RT>
46460b57cec5SDimitry Andric    friend
46470b57cec5SDimitry Andric    basic_ostream<_CharT, _Traits>&
46480b57cec5SDimitry Andric    operator<<(basic_ostream<_CharT, _Traits>& __os,
46490b57cec5SDimitry Andric               const lognormal_distribution<_RT>& __x);
46500b57cec5SDimitry Andric
46510b57cec5SDimitry Andric    template <class _CharT, class _Traits, class _RT>
46520b57cec5SDimitry Andric    friend
46530b57cec5SDimitry Andric    basic_istream<_CharT, _Traits>&
46540b57cec5SDimitry Andric    operator>>(basic_istream<_CharT, _Traits>& __is,
46550b57cec5SDimitry Andric               lognormal_distribution<_RT>& __x);
46560b57cec5SDimitry Andric};
46570b57cec5SDimitry Andric
46580b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
46590b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
46600b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
46610b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
46620b57cec5SDimitry Andric           const lognormal_distribution<_RT>& __x)
46630b57cec5SDimitry Andric{
46640b57cec5SDimitry Andric    return __os << __x.__p_.__nd_;
46650b57cec5SDimitry Andric}
46660b57cec5SDimitry Andric
46670b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
46680b57cec5SDimitry Andricinline _LIBCPP_INLINE_VISIBILITY
46690b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
46700b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
46710b57cec5SDimitry Andric           lognormal_distribution<_RT>& __x)
46720b57cec5SDimitry Andric{
46730b57cec5SDimitry Andric    return __is >> __x.__p_.__nd_;
46740b57cec5SDimitry Andric}
46750b57cec5SDimitry Andric
46760b57cec5SDimitry Andric// poisson_distribution
46770b57cec5SDimitry Andric
46780b57cec5SDimitry Andrictemplate<class _IntType = int>
46790b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS poisson_distribution
46800b57cec5SDimitry Andric{
46810b57cec5SDimitry Andricpublic:
46820b57cec5SDimitry Andric    // types
46830b57cec5SDimitry Andric    typedef _IntType result_type;
46840b57cec5SDimitry Andric
46850b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
46860b57cec5SDimitry Andric    {
46870b57cec5SDimitry Andric        double __mean_;
46880b57cec5SDimitry Andric        double __s_;
46890b57cec5SDimitry Andric        double __d_;
46900b57cec5SDimitry Andric        double __l_;
46910b57cec5SDimitry Andric        double __omega_;
46920b57cec5SDimitry Andric        double __c0_;
46930b57cec5SDimitry Andric        double __c1_;
46940b57cec5SDimitry Andric        double __c2_;
46950b57cec5SDimitry Andric        double __c3_;
46960b57cec5SDimitry Andric        double __c_;
46970b57cec5SDimitry Andric
46980b57cec5SDimitry Andric    public:
46990b57cec5SDimitry Andric        typedef poisson_distribution distribution_type;
47000b57cec5SDimitry Andric
47010b57cec5SDimitry Andric        explicit param_type(double __mean = 1.0);
47020b57cec5SDimitry Andric
47030b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
47040b57cec5SDimitry Andric        double mean() const {return __mean_;}
47050b57cec5SDimitry Andric
47060b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
47070b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
47080b57cec5SDimitry Andric            {return __x.__mean_ == __y.__mean_;}
47090b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
47100b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
47110b57cec5SDimitry Andric            {return !(__x == __y);}
47120b57cec5SDimitry Andric
47130b57cec5SDimitry Andric        friend class poisson_distribution;
47140b57cec5SDimitry Andric    };
47150b57cec5SDimitry Andric
47160b57cec5SDimitry Andricprivate:
47170b57cec5SDimitry Andric    param_type __p_;
47180b57cec5SDimitry Andric
47190b57cec5SDimitry Andricpublic:
47200b57cec5SDimitry Andric    // constructors and reset functions
4721*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
47220b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4723*e8d8bef9SDimitry Andric    poisson_distribution() : poisson_distribution(1.0) {}
4724*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4725*e8d8bef9SDimitry Andric    explicit poisson_distribution(double __mean)
4726*e8d8bef9SDimitry Andric        : __p_(__mean) {}
4727*e8d8bef9SDimitry Andric#else
4728*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4729*e8d8bef9SDimitry Andric    explicit poisson_distribution(double __mean = 1.0)
4730*e8d8bef9SDimitry Andric        : __p_(__mean) {}
4731*e8d8bef9SDimitry Andric#endif
47320b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
47330b57cec5SDimitry Andric    explicit poisson_distribution(const param_type& __p) : __p_(__p) {}
47340b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
47350b57cec5SDimitry Andric    void reset() {}
47360b57cec5SDimitry Andric
47370b57cec5SDimitry Andric    // generating functions
47380b57cec5SDimitry Andric    template<class _URNG>
47390b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
47400b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
47410b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
47420b57cec5SDimitry Andric    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
47430b57cec5SDimitry Andric
47440b57cec5SDimitry Andric    // property functions
47450b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
47460b57cec5SDimitry Andric    double mean() const {return __p_.mean();}
47470b57cec5SDimitry Andric
47480b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
47490b57cec5SDimitry Andric    param_type param() const {return __p_;}
47500b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
47510b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
47520b57cec5SDimitry Andric
47530b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
47540b57cec5SDimitry Andric    result_type min() const {return 0;}
47550b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
47560b57cec5SDimitry Andric    result_type max() const {return numeric_limits<result_type>::max();}
47570b57cec5SDimitry Andric
47580b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
47590b57cec5SDimitry Andric        bool operator==(const poisson_distribution& __x,
47600b57cec5SDimitry Andric                        const poisson_distribution& __y)
47610b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
47620b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
47630b57cec5SDimitry Andric        bool operator!=(const poisson_distribution& __x,
47640b57cec5SDimitry Andric                        const poisson_distribution& __y)
47650b57cec5SDimitry Andric        {return !(__x == __y);}
47660b57cec5SDimitry Andric};
47670b57cec5SDimitry Andric
47680b57cec5SDimitry Andrictemplate<class _IntType>
47690b57cec5SDimitry Andricpoisson_distribution<_IntType>::param_type::param_type(double __mean)
47700b57cec5SDimitry Andric    // According to the standard `inf` is a valid input, but it causes the
47710b57cec5SDimitry Andric    // distribution to hang, so we replace it with the maximum representable
47720b57cec5SDimitry Andric    // mean.
47730b57cec5SDimitry Andric    : __mean_(isinf(__mean) ? numeric_limits<double>::max() : __mean)
47740b57cec5SDimitry Andric{
47750b57cec5SDimitry Andric    if (__mean_ < 10)
47760b57cec5SDimitry Andric    {
47770b57cec5SDimitry Andric        __s_ = 0;
47780b57cec5SDimitry Andric        __d_ = 0;
47790b57cec5SDimitry Andric        __l_ = _VSTD::exp(-__mean_);
47800b57cec5SDimitry Andric        __omega_ = 0;
47810b57cec5SDimitry Andric        __c3_ = 0;
47820b57cec5SDimitry Andric        __c2_ = 0;
47830b57cec5SDimitry Andric        __c1_ = 0;
47840b57cec5SDimitry Andric        __c0_ = 0;
47850b57cec5SDimitry Andric        __c_ = 0;
47860b57cec5SDimitry Andric    }
47870b57cec5SDimitry Andric    else
47880b57cec5SDimitry Andric    {
47890b57cec5SDimitry Andric        __s_ = _VSTD::sqrt(__mean_);
47900b57cec5SDimitry Andric        __d_ = 6 * __mean_ * __mean_;
4791*e8d8bef9SDimitry Andric        __l_ = _VSTD::trunc(__mean_ - 1.1484);
47920b57cec5SDimitry Andric        __omega_ = .3989423 / __s_;
47930b57cec5SDimitry Andric        double __b1_ = .4166667E-1 / __mean_;
47940b57cec5SDimitry Andric        double __b2_ = .3 * __b1_ * __b1_;
47950b57cec5SDimitry Andric        __c3_ = .1428571 * __b1_ * __b2_;
47960b57cec5SDimitry Andric        __c2_ = __b2_ - 15. * __c3_;
47970b57cec5SDimitry Andric        __c1_ = __b1_ - 6. * __b2_ + 45. * __c3_;
47980b57cec5SDimitry Andric        __c0_ = 1. - __b1_ + 3. * __b2_ - 15. * __c3_;
47990b57cec5SDimitry Andric        __c_ = .1069 / __mean_;
48000b57cec5SDimitry Andric    }
48010b57cec5SDimitry Andric}
48020b57cec5SDimitry Andric
48030b57cec5SDimitry Andrictemplate <class _IntType>
48040b57cec5SDimitry Andrictemplate<class _URNG>
48050b57cec5SDimitry Andric_IntType
48060b57cec5SDimitry Andricpoisson_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr)
48070b57cec5SDimitry Andric{
48080b57cec5SDimitry Andric    double __tx;
48090b57cec5SDimitry Andric    uniform_real_distribution<double> __urd;
48100b57cec5SDimitry Andric    if (__pr.__mean_ < 10)
48110b57cec5SDimitry Andric    {
48120b57cec5SDimitry Andric         __tx = 0;
48130b57cec5SDimitry Andric        for (double __p = __urd(__urng); __p > __pr.__l_; ++__tx)
48140b57cec5SDimitry Andric            __p *= __urd(__urng);
48150b57cec5SDimitry Andric    }
48160b57cec5SDimitry Andric    else
48170b57cec5SDimitry Andric    {
48180b57cec5SDimitry Andric        double __difmuk;
48190b57cec5SDimitry Andric        double __g = __pr.__mean_ + __pr.__s_ * normal_distribution<double>()(__urng);
48200b57cec5SDimitry Andric        double __u;
48210b57cec5SDimitry Andric        if (__g > 0)
48220b57cec5SDimitry Andric        {
4823*e8d8bef9SDimitry Andric            __tx = _VSTD::trunc(__g);
48240b57cec5SDimitry Andric            if (__tx >= __pr.__l_)
4825*e8d8bef9SDimitry Andric                return _VSTD::__clamp_to_integral<result_type>(__tx);
48260b57cec5SDimitry Andric            __difmuk = __pr.__mean_ - __tx;
48270b57cec5SDimitry Andric            __u = __urd(__urng);
48280b57cec5SDimitry Andric            if (__pr.__d_ * __u >= __difmuk * __difmuk * __difmuk)
4829*e8d8bef9SDimitry Andric                return _VSTD::__clamp_to_integral<result_type>(__tx);
48300b57cec5SDimitry Andric        }
48310b57cec5SDimitry Andric        exponential_distribution<double> __edist;
48320b57cec5SDimitry Andric        for (bool __using_exp_dist = false; true; __using_exp_dist = true)
48330b57cec5SDimitry Andric        {
48340b57cec5SDimitry Andric            double __e;
48350b57cec5SDimitry Andric            if (__using_exp_dist || __g <= 0)
48360b57cec5SDimitry Andric            {
48370b57cec5SDimitry Andric                double __t;
48380b57cec5SDimitry Andric                do
48390b57cec5SDimitry Andric                {
48400b57cec5SDimitry Andric                    __e = __edist(__urng);
48410b57cec5SDimitry Andric                    __u = __urd(__urng);
48420b57cec5SDimitry Andric                    __u += __u - 1;
48430b57cec5SDimitry Andric                    __t = 1.8 + (__u < 0 ? -__e : __e);
48440b57cec5SDimitry Andric                } while (__t <= -.6744);
4845*e8d8bef9SDimitry Andric                __tx = _VSTD::trunc(__pr.__mean_ + __pr.__s_ * __t);
48460b57cec5SDimitry Andric                __difmuk = __pr.__mean_ - __tx;
48470b57cec5SDimitry Andric                __using_exp_dist = true;
48480b57cec5SDimitry Andric            }
48490b57cec5SDimitry Andric            double __px;
48500b57cec5SDimitry Andric            double __py;
48510b57cec5SDimitry Andric            if (__tx < 10 && __tx >= 0)
48520b57cec5SDimitry Andric            {
48530b57cec5SDimitry Andric                const double __fac[] = {1, 1, 2, 6, 24, 120, 720, 5040,
48540b57cec5SDimitry Andric                                             40320, 362880};
48550b57cec5SDimitry Andric                __px = -__pr.__mean_;
48560b57cec5SDimitry Andric                __py = _VSTD::pow(__pr.__mean_, (double)__tx) / __fac[static_cast<int>(__tx)];
48570b57cec5SDimitry Andric            }
48580b57cec5SDimitry Andric            else
48590b57cec5SDimitry Andric            {
48600b57cec5SDimitry Andric                double __del = .8333333E-1 / __tx;
48610b57cec5SDimitry Andric                __del -= 4.8 * __del * __del * __del;
48620b57cec5SDimitry Andric                double __v = __difmuk / __tx;
48630b57cec5SDimitry Andric                if (_VSTD::abs(__v) > 0.25)
48640b57cec5SDimitry Andric                    __px = __tx * _VSTD::log(1 + __v) - __difmuk - __del;
48650b57cec5SDimitry Andric                else
48660b57cec5SDimitry Andric                    __px = __tx * __v * __v * (((((((.1250060 * __v + -.1384794) *
48670b57cec5SDimitry Andric                           __v + .1421878) * __v + -.1661269) * __v + .2000118) *
48680b57cec5SDimitry Andric                           __v + -.2500068) * __v + .3333333) * __v + -.5) - __del;
48690b57cec5SDimitry Andric                __py = .3989423 / _VSTD::sqrt(__tx);
48700b57cec5SDimitry Andric            }
48710b57cec5SDimitry Andric            double __r = (0.5 - __difmuk) / __pr.__s_;
48720b57cec5SDimitry Andric            double __r2 = __r * __r;
48730b57cec5SDimitry Andric            double __fx = -0.5 * __r2;
48740b57cec5SDimitry Andric            double __fy = __pr.__omega_ * (((__pr.__c3_ * __r2 + __pr.__c2_) *
48750b57cec5SDimitry Andric                                        __r2 + __pr.__c1_) * __r2 + __pr.__c0_);
48760b57cec5SDimitry Andric            if (__using_exp_dist)
48770b57cec5SDimitry Andric            {
48780b57cec5SDimitry Andric                if (__pr.__c_ * _VSTD::abs(__u) <= __py * _VSTD::exp(__px + __e) -
48790b57cec5SDimitry Andric                                                   __fy * _VSTD::exp(__fx + __e))
48800b57cec5SDimitry Andric                    break;
48810b57cec5SDimitry Andric            }
48820b57cec5SDimitry Andric            else
48830b57cec5SDimitry Andric            {
48840b57cec5SDimitry Andric                if (__fy - __u * __fy <= __py * _VSTD::exp(__px - __fx))
48850b57cec5SDimitry Andric                    break;
48860b57cec5SDimitry Andric            }
48870b57cec5SDimitry Andric        }
48880b57cec5SDimitry Andric    }
4889*e8d8bef9SDimitry Andric    return _VSTD::__clamp_to_integral<result_type>(__tx);
48900b57cec5SDimitry Andric}
48910b57cec5SDimitry Andric
48920b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _IntType>
48930b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
48940b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
48950b57cec5SDimitry Andric           const poisson_distribution<_IntType>& __x)
48960b57cec5SDimitry Andric{
48970b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
4898*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
4899*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
4900*e8d8bef9SDimitry Andric               _OStream::scientific);
49010b57cec5SDimitry Andric    return __os << __x.mean();
49020b57cec5SDimitry Andric}
49030b57cec5SDimitry Andric
49040b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _IntType>
49050b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
49060b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
49070b57cec5SDimitry Andric           poisson_distribution<_IntType>& __x)
49080b57cec5SDimitry Andric{
49090b57cec5SDimitry Andric    typedef poisson_distribution<_IntType> _Eng;
49100b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
49110b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
4912*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
4913*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
49140b57cec5SDimitry Andric    double __mean;
49150b57cec5SDimitry Andric    __is >> __mean;
49160b57cec5SDimitry Andric    if (!__is.fail())
49170b57cec5SDimitry Andric        __x.param(param_type(__mean));
49180b57cec5SDimitry Andric    return __is;
49190b57cec5SDimitry Andric}
49200b57cec5SDimitry Andric
49210b57cec5SDimitry Andric// weibull_distribution
49220b57cec5SDimitry Andric
49230b57cec5SDimitry Andrictemplate<class _RealType = double>
49240b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS weibull_distribution
49250b57cec5SDimitry Andric{
49260b57cec5SDimitry Andricpublic:
49270b57cec5SDimitry Andric    // types
49280b57cec5SDimitry Andric    typedef _RealType result_type;
49290b57cec5SDimitry Andric
49300b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
49310b57cec5SDimitry Andric    {
49320b57cec5SDimitry Andric        result_type __a_;
49330b57cec5SDimitry Andric        result_type __b_;
49340b57cec5SDimitry Andric    public:
49350b57cec5SDimitry Andric        typedef weibull_distribution distribution_type;
49360b57cec5SDimitry Andric
49370b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
49380b57cec5SDimitry Andric        explicit param_type(result_type __a = 1, result_type __b = 1)
49390b57cec5SDimitry Andric            : __a_(__a), __b_(__b) {}
49400b57cec5SDimitry Andric
49410b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
49420b57cec5SDimitry Andric        result_type a() const {return __a_;}
49430b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
49440b57cec5SDimitry Andric        result_type b() const {return __b_;}
49450b57cec5SDimitry Andric
49460b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
49470b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
49480b57cec5SDimitry Andric            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
49490b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
49500b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
49510b57cec5SDimitry Andric            {return !(__x == __y);}
49520b57cec5SDimitry Andric    };
49530b57cec5SDimitry Andric
49540b57cec5SDimitry Andricprivate:
49550b57cec5SDimitry Andric    param_type __p_;
49560b57cec5SDimitry Andric
49570b57cec5SDimitry Andricpublic:
49580b57cec5SDimitry Andric    // constructor and reset functions
4959*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
4960*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4961*e8d8bef9SDimitry Andric    weibull_distribution() : weibull_distribution(1) {}
4962*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
4963*e8d8bef9SDimitry Andric    explicit weibull_distribution(result_type __a, result_type __b = 1)
4964*e8d8bef9SDimitry Andric        : __p_(param_type(__a, __b)) {}
4965*e8d8bef9SDimitry Andric#else
49660b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49670b57cec5SDimitry Andric    explicit weibull_distribution(result_type __a = 1, result_type __b = 1)
49680b57cec5SDimitry Andric        : __p_(param_type(__a, __b)) {}
4969*e8d8bef9SDimitry Andric#endif
49700b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49710b57cec5SDimitry Andric    explicit weibull_distribution(const param_type& __p)
49720b57cec5SDimitry Andric        : __p_(__p) {}
49730b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49740b57cec5SDimitry Andric    void reset() {}
49750b57cec5SDimitry Andric
49760b57cec5SDimitry Andric    // generating functions
49770b57cec5SDimitry Andric    template<class _URNG>
49780b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
49790b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
49800b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
49810b57cec5SDimitry Andric    template<class _URNG>
49820b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
49830b57cec5SDimitry Andric        result_type operator()(_URNG& __g, const param_type& __p)
49840b57cec5SDimitry Andric        {return __p.b() *
49850b57cec5SDimitry Andric            _VSTD::pow(exponential_distribution<result_type>()(__g), 1/__p.a());}
49860b57cec5SDimitry Andric
49870b57cec5SDimitry Andric    // property functions
49880b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49890b57cec5SDimitry Andric    result_type a() const {return __p_.a();}
49900b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49910b57cec5SDimitry Andric    result_type b() const {return __p_.b();}
49920b57cec5SDimitry Andric
49930b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49940b57cec5SDimitry Andric    param_type param() const {return __p_;}
49950b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49960b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
49970b57cec5SDimitry Andric
49980b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
49990b57cec5SDimitry Andric    result_type min() const {return 0;}
50000b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
50010b57cec5SDimitry Andric    result_type max() const {return numeric_limits<result_type>::infinity();}
50020b57cec5SDimitry Andric
50030b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
50040b57cec5SDimitry Andric        bool operator==(const weibull_distribution& __x,
50050b57cec5SDimitry Andric                        const weibull_distribution& __y)
50060b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
50070b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
50080b57cec5SDimitry Andric        bool operator!=(const weibull_distribution& __x,
50090b57cec5SDimitry Andric                        const weibull_distribution& __y)
50100b57cec5SDimitry Andric        {return !(__x == __y);}
50110b57cec5SDimitry Andric};
50120b57cec5SDimitry Andric
50130b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
50140b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
50150b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
50160b57cec5SDimitry Andric           const weibull_distribution<_RT>& __x)
50170b57cec5SDimitry Andric{
50180b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
5019*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
5020*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
5021*e8d8bef9SDimitry Andric               _OStream::scientific);
50220b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
50230b57cec5SDimitry Andric    __os.fill(__sp);
50240b57cec5SDimitry Andric    __os << __x.a() << __sp << __x.b();
50250b57cec5SDimitry Andric    return __os;
50260b57cec5SDimitry Andric}
50270b57cec5SDimitry Andric
50280b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
50290b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
50300b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
50310b57cec5SDimitry Andric           weibull_distribution<_RT>& __x)
50320b57cec5SDimitry Andric{
50330b57cec5SDimitry Andric    typedef weibull_distribution<_RT> _Eng;
50340b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
50350b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
50360b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
5037*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
5038*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
50390b57cec5SDimitry Andric    result_type __a;
50400b57cec5SDimitry Andric    result_type __b;
50410b57cec5SDimitry Andric    __is >> __a >> __b;
50420b57cec5SDimitry Andric    if (!__is.fail())
50430b57cec5SDimitry Andric        __x.param(param_type(__a, __b));
50440b57cec5SDimitry Andric    return __is;
50450b57cec5SDimitry Andric}
50460b57cec5SDimitry Andric
50470b57cec5SDimitry Andrictemplate<class _RealType = double>
50480b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS extreme_value_distribution
50490b57cec5SDimitry Andric{
50500b57cec5SDimitry Andricpublic:
50510b57cec5SDimitry Andric    // types
50520b57cec5SDimitry Andric    typedef _RealType result_type;
50530b57cec5SDimitry Andric
50540b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
50550b57cec5SDimitry Andric    {
50560b57cec5SDimitry Andric        result_type __a_;
50570b57cec5SDimitry Andric        result_type __b_;
50580b57cec5SDimitry Andric    public:
50590b57cec5SDimitry Andric        typedef extreme_value_distribution distribution_type;
50600b57cec5SDimitry Andric
50610b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
50620b57cec5SDimitry Andric        explicit param_type(result_type __a = 0, result_type __b = 1)
50630b57cec5SDimitry Andric            : __a_(__a), __b_(__b) {}
50640b57cec5SDimitry Andric
50650b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
50660b57cec5SDimitry Andric        result_type a() const {return __a_;}
50670b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
50680b57cec5SDimitry Andric        result_type b() const {return __b_;}
50690b57cec5SDimitry Andric
50700b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
50710b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
50720b57cec5SDimitry Andric            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
50730b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
50740b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
50750b57cec5SDimitry Andric            {return !(__x == __y);}
50760b57cec5SDimitry Andric    };
50770b57cec5SDimitry Andric
50780b57cec5SDimitry Andricprivate:
50790b57cec5SDimitry Andric    param_type __p_;
50800b57cec5SDimitry Andric
50810b57cec5SDimitry Andricpublic:
50820b57cec5SDimitry Andric    // constructor and reset functions
5083*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
50840b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5085*e8d8bef9SDimitry Andric    extreme_value_distribution() : extreme_value_distribution(0) {}
5086*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5087*e8d8bef9SDimitry Andric    explicit extreme_value_distribution(result_type __a, result_type __b = 1)
50880b57cec5SDimitry Andric        : __p_(param_type(__a, __b)) {}
5089*e8d8bef9SDimitry Andric#else
5090*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5091*e8d8bef9SDimitry Andric    explicit extreme_value_distribution(result_type __a = 0,
5092*e8d8bef9SDimitry Andric                                        result_type __b = 1)
5093*e8d8bef9SDimitry Andric        : __p_(param_type(__a, __b)) {}
5094*e8d8bef9SDimitry Andric#endif
50950b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
50960b57cec5SDimitry Andric    explicit extreme_value_distribution(const param_type& __p)
50970b57cec5SDimitry Andric        : __p_(__p) {}
50980b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
50990b57cec5SDimitry Andric    void reset() {}
51000b57cec5SDimitry Andric
51010b57cec5SDimitry Andric    // generating functions
51020b57cec5SDimitry Andric    template<class _URNG>
51030b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
51040b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
51050b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
51060b57cec5SDimitry Andric    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
51070b57cec5SDimitry Andric
51080b57cec5SDimitry Andric    // property functions
51090b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
51100b57cec5SDimitry Andric    result_type a() const {return __p_.a();}
51110b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
51120b57cec5SDimitry Andric    result_type b() const {return __p_.b();}
51130b57cec5SDimitry Andric
51140b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
51150b57cec5SDimitry Andric    param_type param() const {return __p_;}
51160b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
51170b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
51180b57cec5SDimitry Andric
51190b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
51200b57cec5SDimitry Andric    result_type min() const {return -numeric_limits<result_type>::infinity();}
51210b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
51220b57cec5SDimitry Andric    result_type max() const {return numeric_limits<result_type>::infinity();}
51230b57cec5SDimitry Andric
51240b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
51250b57cec5SDimitry Andric        bool operator==(const extreme_value_distribution& __x,
51260b57cec5SDimitry Andric                        const extreme_value_distribution& __y)
51270b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
51280b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
51290b57cec5SDimitry Andric        bool operator!=(const extreme_value_distribution& __x,
51300b57cec5SDimitry Andric                        const extreme_value_distribution& __y)
51310b57cec5SDimitry Andric        {return !(__x == __y);}
51320b57cec5SDimitry Andric};
51330b57cec5SDimitry Andric
51340b57cec5SDimitry Andrictemplate<class _RealType>
51350b57cec5SDimitry Andrictemplate<class _URNG>
51360b57cec5SDimitry Andric_RealType
51370b57cec5SDimitry Andricextreme_value_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
51380b57cec5SDimitry Andric{
51390b57cec5SDimitry Andric    return __p.a() - __p.b() *
51400b57cec5SDimitry Andric         _VSTD::log(-_VSTD::log(1-uniform_real_distribution<result_type>()(__g)));
51410b57cec5SDimitry Andric}
51420b57cec5SDimitry Andric
51430b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
51440b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
51450b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
51460b57cec5SDimitry Andric           const extreme_value_distribution<_RT>& __x)
51470b57cec5SDimitry Andric{
51480b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
5149*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
5150*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
5151*e8d8bef9SDimitry Andric               _OStream::scientific);
51520b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
51530b57cec5SDimitry Andric    __os.fill(__sp);
51540b57cec5SDimitry Andric    __os << __x.a() << __sp << __x.b();
51550b57cec5SDimitry Andric    return __os;
51560b57cec5SDimitry Andric}
51570b57cec5SDimitry Andric
51580b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
51590b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
51600b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
51610b57cec5SDimitry Andric           extreme_value_distribution<_RT>& __x)
51620b57cec5SDimitry Andric{
51630b57cec5SDimitry Andric    typedef extreme_value_distribution<_RT> _Eng;
51640b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
51650b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
51660b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
5167*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
5168*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
51690b57cec5SDimitry Andric    result_type __a;
51700b57cec5SDimitry Andric    result_type __b;
51710b57cec5SDimitry Andric    __is >> __a >> __b;
51720b57cec5SDimitry Andric    if (!__is.fail())
51730b57cec5SDimitry Andric        __x.param(param_type(__a, __b));
51740b57cec5SDimitry Andric    return __is;
51750b57cec5SDimitry Andric}
51760b57cec5SDimitry Andric
51770b57cec5SDimitry Andric// gamma_distribution
51780b57cec5SDimitry Andric
51790b57cec5SDimitry Andrictemplate<class _RealType = double>
51800b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS gamma_distribution
51810b57cec5SDimitry Andric{
51820b57cec5SDimitry Andricpublic:
51830b57cec5SDimitry Andric    // types
51840b57cec5SDimitry Andric    typedef _RealType result_type;
51850b57cec5SDimitry Andric
51860b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
51870b57cec5SDimitry Andric    {
51880b57cec5SDimitry Andric        result_type __alpha_;
51890b57cec5SDimitry Andric        result_type __beta_;
51900b57cec5SDimitry Andric    public:
51910b57cec5SDimitry Andric        typedef gamma_distribution distribution_type;
51920b57cec5SDimitry Andric
51930b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
51940b57cec5SDimitry Andric        explicit param_type(result_type __alpha = 1, result_type __beta = 1)
51950b57cec5SDimitry Andric            : __alpha_(__alpha), __beta_(__beta) {}
51960b57cec5SDimitry Andric
51970b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
51980b57cec5SDimitry Andric        result_type alpha() const {return __alpha_;}
51990b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
52000b57cec5SDimitry Andric        result_type beta() const {return __beta_;}
52010b57cec5SDimitry Andric
52020b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
52030b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
52040b57cec5SDimitry Andric            {return __x.__alpha_ == __y.__alpha_ && __x.__beta_ == __y.__beta_;}
52050b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
52060b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
52070b57cec5SDimitry Andric            {return !(__x == __y);}
52080b57cec5SDimitry Andric    };
52090b57cec5SDimitry Andric
52100b57cec5SDimitry Andricprivate:
52110b57cec5SDimitry Andric    param_type __p_;
52120b57cec5SDimitry Andric
52130b57cec5SDimitry Andricpublic:
52140b57cec5SDimitry Andric    // constructors and reset functions
5215*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
52160b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5217*e8d8bef9SDimitry Andric    gamma_distribution() : gamma_distribution(1) {}
5218*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5219*e8d8bef9SDimitry Andric    explicit gamma_distribution(result_type __alpha, result_type __beta = 1)
52200b57cec5SDimitry Andric        : __p_(param_type(__alpha, __beta)) {}
5221*e8d8bef9SDimitry Andric#else
5222*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5223*e8d8bef9SDimitry Andric    explicit gamma_distribution(result_type __alpha = 1,
5224*e8d8bef9SDimitry Andric                                result_type __beta = 1)
5225*e8d8bef9SDimitry Andric        : __p_(param_type(__alpha, __beta)) {}
5226*e8d8bef9SDimitry Andric#endif
52270b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
52280b57cec5SDimitry Andric    explicit gamma_distribution(const param_type& __p)
52290b57cec5SDimitry Andric        : __p_(__p) {}
52300b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
52310b57cec5SDimitry Andric    void reset() {}
52320b57cec5SDimitry Andric
52330b57cec5SDimitry Andric    // generating functions
52340b57cec5SDimitry Andric    template<class _URNG>
52350b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
52360b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
52370b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
52380b57cec5SDimitry Andric    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
52390b57cec5SDimitry Andric
52400b57cec5SDimitry Andric    // property functions
52410b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
52420b57cec5SDimitry Andric    result_type alpha() const {return __p_.alpha();}
52430b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
52440b57cec5SDimitry Andric    result_type beta() const {return __p_.beta();}
52450b57cec5SDimitry Andric
52460b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
52470b57cec5SDimitry Andric    param_type param() const {return __p_;}
52480b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
52490b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
52500b57cec5SDimitry Andric
52510b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
52520b57cec5SDimitry Andric    result_type min() const {return 0;}
52530b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
52540b57cec5SDimitry Andric    result_type max() const {return numeric_limits<result_type>::infinity();}
52550b57cec5SDimitry Andric
52560b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
52570b57cec5SDimitry Andric        bool operator==(const gamma_distribution& __x,
52580b57cec5SDimitry Andric                        const gamma_distribution& __y)
52590b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
52600b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
52610b57cec5SDimitry Andric        bool operator!=(const gamma_distribution& __x,
52620b57cec5SDimitry Andric                        const gamma_distribution& __y)
52630b57cec5SDimitry Andric        {return !(__x == __y);}
52640b57cec5SDimitry Andric};
52650b57cec5SDimitry Andric
52660b57cec5SDimitry Andrictemplate <class _RealType>
52670b57cec5SDimitry Andrictemplate<class _URNG>
52680b57cec5SDimitry Andric_RealType
52690b57cec5SDimitry Andricgamma_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
52700b57cec5SDimitry Andric{
52710b57cec5SDimitry Andric    result_type __a = __p.alpha();
52720b57cec5SDimitry Andric    uniform_real_distribution<result_type> __gen(0, 1);
52730b57cec5SDimitry Andric    exponential_distribution<result_type> __egen;
52740b57cec5SDimitry Andric    result_type __x;
52750b57cec5SDimitry Andric    if (__a == 1)
52760b57cec5SDimitry Andric        __x = __egen(__g);
52770b57cec5SDimitry Andric    else if (__a > 1)
52780b57cec5SDimitry Andric    {
52790b57cec5SDimitry Andric        const result_type __b = __a - 1;
52800b57cec5SDimitry Andric        const result_type __c = 3 * __a - result_type(0.75);
52810b57cec5SDimitry Andric        while (true)
52820b57cec5SDimitry Andric        {
52830b57cec5SDimitry Andric            const result_type __u = __gen(__g);
52840b57cec5SDimitry Andric            const result_type __v = __gen(__g);
52850b57cec5SDimitry Andric            const result_type __w = __u * (1 - __u);
52860b57cec5SDimitry Andric            if (__w != 0)
52870b57cec5SDimitry Andric            {
52880b57cec5SDimitry Andric                const result_type __y = _VSTD::sqrt(__c / __w) *
52890b57cec5SDimitry Andric                                        (__u - result_type(0.5));
52900b57cec5SDimitry Andric                __x = __b + __y;
52910b57cec5SDimitry Andric                if (__x >= 0)
52920b57cec5SDimitry Andric                {
52930b57cec5SDimitry Andric                    const result_type __z = 64 * __w * __w * __w * __v * __v;
52940b57cec5SDimitry Andric                    if (__z <= 1 - 2 * __y * __y / __x)
52950b57cec5SDimitry Andric                        break;
52960b57cec5SDimitry Andric                    if (_VSTD::log(__z) <= 2 * (__b * _VSTD::log(__x / __b) - __y))
52970b57cec5SDimitry Andric                        break;
52980b57cec5SDimitry Andric                }
52990b57cec5SDimitry Andric            }
53000b57cec5SDimitry Andric        }
53010b57cec5SDimitry Andric    }
53020b57cec5SDimitry Andric    else  // __a < 1
53030b57cec5SDimitry Andric    {
53040b57cec5SDimitry Andric        while (true)
53050b57cec5SDimitry Andric        {
53060b57cec5SDimitry Andric            const result_type __u = __gen(__g);
53070b57cec5SDimitry Andric            const result_type __es = __egen(__g);
53080b57cec5SDimitry Andric            if (__u <= 1 - __a)
53090b57cec5SDimitry Andric            {
53100b57cec5SDimitry Andric                __x = _VSTD::pow(__u, 1 / __a);
53110b57cec5SDimitry Andric                if (__x <= __es)
53120b57cec5SDimitry Andric                    break;
53130b57cec5SDimitry Andric            }
53140b57cec5SDimitry Andric            else
53150b57cec5SDimitry Andric            {
53160b57cec5SDimitry Andric                const result_type __e = -_VSTD::log((1-__u)/__a);
53170b57cec5SDimitry Andric                __x = _VSTD::pow(1 - __a + __a * __e, 1 / __a);
53180b57cec5SDimitry Andric                if (__x <= __e + __es)
53190b57cec5SDimitry Andric                    break;
53200b57cec5SDimitry Andric            }
53210b57cec5SDimitry Andric        }
53220b57cec5SDimitry Andric    }
53230b57cec5SDimitry Andric    return __x * __p.beta();
53240b57cec5SDimitry Andric}
53250b57cec5SDimitry Andric
53260b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
53270b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
53280b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
53290b57cec5SDimitry Andric           const gamma_distribution<_RT>& __x)
53300b57cec5SDimitry Andric{
53310b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
5332*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
5333*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
5334*e8d8bef9SDimitry Andric               _OStream::scientific);
53350b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
53360b57cec5SDimitry Andric    __os.fill(__sp);
53370b57cec5SDimitry Andric    __os << __x.alpha() << __sp << __x.beta();
53380b57cec5SDimitry Andric    return __os;
53390b57cec5SDimitry Andric}
53400b57cec5SDimitry Andric
53410b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
53420b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
53430b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
53440b57cec5SDimitry Andric           gamma_distribution<_RT>& __x)
53450b57cec5SDimitry Andric{
53460b57cec5SDimitry Andric    typedef gamma_distribution<_RT> _Eng;
53470b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
53480b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
53490b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
5350*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
5351*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
53520b57cec5SDimitry Andric    result_type __alpha;
53530b57cec5SDimitry Andric    result_type __beta;
53540b57cec5SDimitry Andric    __is >> __alpha >> __beta;
53550b57cec5SDimitry Andric    if (!__is.fail())
53560b57cec5SDimitry Andric        __x.param(param_type(__alpha, __beta));
53570b57cec5SDimitry Andric    return __is;
53580b57cec5SDimitry Andric}
53590b57cec5SDimitry Andric
53600b57cec5SDimitry Andric// negative_binomial_distribution
53610b57cec5SDimitry Andric
53620b57cec5SDimitry Andrictemplate<class _IntType = int>
53630b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS negative_binomial_distribution
53640b57cec5SDimitry Andric{
53650b57cec5SDimitry Andricpublic:
53660b57cec5SDimitry Andric    // types
53670b57cec5SDimitry Andric    typedef _IntType result_type;
53680b57cec5SDimitry Andric
53690b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
53700b57cec5SDimitry Andric    {
53710b57cec5SDimitry Andric        result_type __k_;
53720b57cec5SDimitry Andric        double __p_;
53730b57cec5SDimitry Andric    public:
53740b57cec5SDimitry Andric        typedef negative_binomial_distribution distribution_type;
53750b57cec5SDimitry Andric
53760b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
53770b57cec5SDimitry Andric        explicit param_type(result_type __k = 1, double __p = 0.5)
53780b57cec5SDimitry Andric            : __k_(__k), __p_(__p) {}
53790b57cec5SDimitry Andric
53800b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
53810b57cec5SDimitry Andric        result_type k() const {return __k_;}
53820b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
53830b57cec5SDimitry Andric        double p() const {return __p_;}
53840b57cec5SDimitry Andric
53850b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
53860b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
53870b57cec5SDimitry Andric            {return __x.__k_ == __y.__k_ && __x.__p_ == __y.__p_;}
53880b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
53890b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
53900b57cec5SDimitry Andric            {return !(__x == __y);}
53910b57cec5SDimitry Andric    };
53920b57cec5SDimitry Andric
53930b57cec5SDimitry Andricprivate:
53940b57cec5SDimitry Andric    param_type __p_;
53950b57cec5SDimitry Andric
53960b57cec5SDimitry Andricpublic:
53970b57cec5SDimitry Andric    // constructor and reset functions
5398*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
53990b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5400*e8d8bef9SDimitry Andric    negative_binomial_distribution() : negative_binomial_distribution(1) {}
5401*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5402*e8d8bef9SDimitry Andric    explicit negative_binomial_distribution(result_type __k, double __p = 0.5)
54030b57cec5SDimitry Andric        : __p_(__k, __p) {}
5404*e8d8bef9SDimitry Andric#else
5405*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5406*e8d8bef9SDimitry Andric    explicit negative_binomial_distribution(result_type __k = 1,
5407*e8d8bef9SDimitry Andric                                            double __p = 0.5)
5408*e8d8bef9SDimitry Andric        : __p_(__k, __p) {}
5409*e8d8bef9SDimitry Andric#endif
54100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
54110b57cec5SDimitry Andric    explicit negative_binomial_distribution(const param_type& __p) : __p_(__p) {}
54120b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
54130b57cec5SDimitry Andric    void reset() {}
54140b57cec5SDimitry Andric
54150b57cec5SDimitry Andric    // generating functions
54160b57cec5SDimitry Andric    template<class _URNG>
54170b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
54180b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
54190b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
54200b57cec5SDimitry Andric    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
54210b57cec5SDimitry Andric
54220b57cec5SDimitry Andric    // property functions
54230b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
54240b57cec5SDimitry Andric    result_type k() const {return __p_.k();}
54250b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
54260b57cec5SDimitry Andric    double p() const {return __p_.p();}
54270b57cec5SDimitry Andric
54280b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
54290b57cec5SDimitry Andric    param_type param() const {return __p_;}
54300b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
54310b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
54320b57cec5SDimitry Andric
54330b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
54340b57cec5SDimitry Andric    result_type min() const {return 0;}
54350b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
54360b57cec5SDimitry Andric    result_type max() const {return numeric_limits<result_type>::max();}
54370b57cec5SDimitry Andric
54380b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
54390b57cec5SDimitry Andric        bool operator==(const negative_binomial_distribution& __x,
54400b57cec5SDimitry Andric                        const negative_binomial_distribution& __y)
54410b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
54420b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
54430b57cec5SDimitry Andric        bool operator!=(const negative_binomial_distribution& __x,
54440b57cec5SDimitry Andric                        const negative_binomial_distribution& __y)
54450b57cec5SDimitry Andric        {return !(__x == __y);}
54460b57cec5SDimitry Andric};
54470b57cec5SDimitry Andric
54480b57cec5SDimitry Andrictemplate <class _IntType>
54490b57cec5SDimitry Andrictemplate<class _URNG>
54500b57cec5SDimitry Andric_IntType
54510b57cec5SDimitry Andricnegative_binomial_distribution<_IntType>::operator()(_URNG& __urng, const param_type& __pr)
54520b57cec5SDimitry Andric{
54530b57cec5SDimitry Andric    result_type __k = __pr.k();
54540b57cec5SDimitry Andric    double __p = __pr.p();
54550b57cec5SDimitry Andric    if (__k <= 21 * __p)
54560b57cec5SDimitry Andric    {
54570b57cec5SDimitry Andric        bernoulli_distribution __gen(__p);
54580b57cec5SDimitry Andric        result_type __f = 0;
54590b57cec5SDimitry Andric        result_type __s = 0;
54600b57cec5SDimitry Andric        while (__s < __k)
54610b57cec5SDimitry Andric        {
54620b57cec5SDimitry Andric            if (__gen(__urng))
54630b57cec5SDimitry Andric                ++__s;
54640b57cec5SDimitry Andric            else
54650b57cec5SDimitry Andric                ++__f;
54660b57cec5SDimitry Andric        }
54670b57cec5SDimitry Andric        return __f;
54680b57cec5SDimitry Andric    }
54690b57cec5SDimitry Andric    return poisson_distribution<result_type>(gamma_distribution<double>
54700b57cec5SDimitry Andric                                            (__k, (1-__p)/__p)(__urng))(__urng);
54710b57cec5SDimitry Andric}
54720b57cec5SDimitry Andric
54730b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _IntType>
54740b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
54750b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
54760b57cec5SDimitry Andric           const negative_binomial_distribution<_IntType>& __x)
54770b57cec5SDimitry Andric{
54780b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
5479*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
5480*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
5481*e8d8bef9SDimitry Andric               _OStream::scientific);
54820b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
54830b57cec5SDimitry Andric    __os.fill(__sp);
54840b57cec5SDimitry Andric    return __os << __x.k() << __sp << __x.p();
54850b57cec5SDimitry Andric}
54860b57cec5SDimitry Andric
54870b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _IntType>
54880b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
54890b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
54900b57cec5SDimitry Andric           negative_binomial_distribution<_IntType>& __x)
54910b57cec5SDimitry Andric{
54920b57cec5SDimitry Andric    typedef negative_binomial_distribution<_IntType> _Eng;
54930b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
54940b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
54950b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
5496*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
5497*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
54980b57cec5SDimitry Andric    result_type __k;
54990b57cec5SDimitry Andric    double __p;
55000b57cec5SDimitry Andric    __is >> __k >> __p;
55010b57cec5SDimitry Andric    if (!__is.fail())
55020b57cec5SDimitry Andric        __x.param(param_type(__k, __p));
55030b57cec5SDimitry Andric    return __is;
55040b57cec5SDimitry Andric}
55050b57cec5SDimitry Andric
55060b57cec5SDimitry Andric// geometric_distribution
55070b57cec5SDimitry Andric
55080b57cec5SDimitry Andrictemplate<class _IntType = int>
55090b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS geometric_distribution
55100b57cec5SDimitry Andric{
55110b57cec5SDimitry Andricpublic:
55120b57cec5SDimitry Andric    // types
55130b57cec5SDimitry Andric    typedef _IntType result_type;
55140b57cec5SDimitry Andric
55150b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
55160b57cec5SDimitry Andric    {
55170b57cec5SDimitry Andric        double __p_;
55180b57cec5SDimitry Andric    public:
55190b57cec5SDimitry Andric        typedef geometric_distribution distribution_type;
55200b57cec5SDimitry Andric
55210b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
55220b57cec5SDimitry Andric        explicit param_type(double __p = 0.5) : __p_(__p) {}
55230b57cec5SDimitry Andric
55240b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
55250b57cec5SDimitry Andric        double p() const {return __p_;}
55260b57cec5SDimitry Andric
55270b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
55280b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
55290b57cec5SDimitry Andric            {return __x.__p_ == __y.__p_;}
55300b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
55310b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
55320b57cec5SDimitry Andric            {return !(__x == __y);}
55330b57cec5SDimitry Andric    };
55340b57cec5SDimitry Andric
55350b57cec5SDimitry Andricprivate:
55360b57cec5SDimitry Andric    param_type __p_;
55370b57cec5SDimitry Andric
55380b57cec5SDimitry Andricpublic:
55390b57cec5SDimitry Andric    // constructors and reset functions
5540*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
55410b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5542*e8d8bef9SDimitry Andric    geometric_distribution() : geometric_distribution(0.5) {}
5543*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5544*e8d8bef9SDimitry Andric    explicit geometric_distribution(double __p)
5545*e8d8bef9SDimitry Andric        : __p_(__p) {}
5546*e8d8bef9SDimitry Andric#else
5547*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5548*e8d8bef9SDimitry Andric    explicit geometric_distribution(double __p = 0.5)
5549*e8d8bef9SDimitry Andric        : __p_(__p) {}
5550*e8d8bef9SDimitry Andric#endif
55510b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
55520b57cec5SDimitry Andric    explicit geometric_distribution(const param_type& __p) : __p_(__p) {}
55530b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
55540b57cec5SDimitry Andric    void reset() {}
55550b57cec5SDimitry Andric
55560b57cec5SDimitry Andric    // generating functions
55570b57cec5SDimitry Andric    template<class _URNG>
55580b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
55590b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
55600b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
55610b57cec5SDimitry Andric    template<class _URNG>
55620b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
55630b57cec5SDimitry Andric        result_type operator()(_URNG& __g, const param_type& __p)
55640b57cec5SDimitry Andric        {return negative_binomial_distribution<result_type>(1, __p.p())(__g);}
55650b57cec5SDimitry Andric
55660b57cec5SDimitry Andric    // property functions
55670b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
55680b57cec5SDimitry Andric    double p() const {return __p_.p();}
55690b57cec5SDimitry Andric
55700b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
55710b57cec5SDimitry Andric    param_type param() const {return __p_;}
55720b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
55730b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
55740b57cec5SDimitry Andric
55750b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
55760b57cec5SDimitry Andric    result_type min() const {return 0;}
55770b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
55780b57cec5SDimitry Andric    result_type max() const {return numeric_limits<result_type>::max();}
55790b57cec5SDimitry Andric
55800b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
55810b57cec5SDimitry Andric        bool operator==(const geometric_distribution& __x,
55820b57cec5SDimitry Andric                        const geometric_distribution& __y)
55830b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
55840b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
55850b57cec5SDimitry Andric        bool operator!=(const geometric_distribution& __x,
55860b57cec5SDimitry Andric                        const geometric_distribution& __y)
55870b57cec5SDimitry Andric        {return !(__x == __y);}
55880b57cec5SDimitry Andric};
55890b57cec5SDimitry Andric
55900b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _IntType>
55910b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
55920b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
55930b57cec5SDimitry Andric           const geometric_distribution<_IntType>& __x)
55940b57cec5SDimitry Andric{
55950b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
5596*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
5597*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
5598*e8d8bef9SDimitry Andric               _OStream::scientific);
55990b57cec5SDimitry Andric    return __os << __x.p();
56000b57cec5SDimitry Andric}
56010b57cec5SDimitry Andric
56020b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _IntType>
56030b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
56040b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
56050b57cec5SDimitry Andric           geometric_distribution<_IntType>& __x)
56060b57cec5SDimitry Andric{
56070b57cec5SDimitry Andric    typedef geometric_distribution<_IntType> _Eng;
56080b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
56090b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
5610*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
5611*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
56120b57cec5SDimitry Andric    double __p;
56130b57cec5SDimitry Andric    __is >> __p;
56140b57cec5SDimitry Andric    if (!__is.fail())
56150b57cec5SDimitry Andric        __x.param(param_type(__p));
56160b57cec5SDimitry Andric    return __is;
56170b57cec5SDimitry Andric}
56180b57cec5SDimitry Andric
56190b57cec5SDimitry Andric// chi_squared_distribution
56200b57cec5SDimitry Andric
56210b57cec5SDimitry Andrictemplate<class _RealType = double>
56220b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS chi_squared_distribution
56230b57cec5SDimitry Andric{
56240b57cec5SDimitry Andricpublic:
56250b57cec5SDimitry Andric    // types
56260b57cec5SDimitry Andric    typedef _RealType result_type;
56270b57cec5SDimitry Andric
56280b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
56290b57cec5SDimitry Andric    {
56300b57cec5SDimitry Andric        result_type __n_;
56310b57cec5SDimitry Andric    public:
56320b57cec5SDimitry Andric        typedef chi_squared_distribution distribution_type;
56330b57cec5SDimitry Andric
56340b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
56350b57cec5SDimitry Andric        explicit param_type(result_type __n = 1) : __n_(__n) {}
56360b57cec5SDimitry Andric
56370b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
56380b57cec5SDimitry Andric        result_type n() const {return __n_;}
56390b57cec5SDimitry Andric
56400b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
56410b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
56420b57cec5SDimitry Andric            {return __x.__n_ == __y.__n_;}
56430b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
56440b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
56450b57cec5SDimitry Andric            {return !(__x == __y);}
56460b57cec5SDimitry Andric    };
56470b57cec5SDimitry Andric
56480b57cec5SDimitry Andricprivate:
56490b57cec5SDimitry Andric    param_type __p_;
56500b57cec5SDimitry Andric
56510b57cec5SDimitry Andricpublic:
56520b57cec5SDimitry Andric    // constructor and reset functions
5653*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
5654*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5655*e8d8bef9SDimitry Andric    chi_squared_distribution() : chi_squared_distribution(1) {}
5656*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5657*e8d8bef9SDimitry Andric    explicit chi_squared_distribution(result_type __n)
5658*e8d8bef9SDimitry Andric        : __p_(param_type(__n)) {}
5659*e8d8bef9SDimitry Andric#else
56600b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
56610b57cec5SDimitry Andric    explicit chi_squared_distribution(result_type __n = 1)
56620b57cec5SDimitry Andric        : __p_(param_type(__n)) {}
5663*e8d8bef9SDimitry Andric#endif
56640b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
56650b57cec5SDimitry Andric    explicit chi_squared_distribution(const param_type& __p)
56660b57cec5SDimitry Andric        : __p_(__p) {}
56670b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
56680b57cec5SDimitry Andric    void reset() {}
56690b57cec5SDimitry Andric
56700b57cec5SDimitry Andric    // generating functions
56710b57cec5SDimitry Andric    template<class _URNG>
56720b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
56730b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
56740b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
56750b57cec5SDimitry Andric    template<class _URNG>
56760b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
56770b57cec5SDimitry Andric        result_type operator()(_URNG& __g, const param_type& __p)
56780b57cec5SDimitry Andric        {return gamma_distribution<result_type>(__p.n() / 2, 2)(__g);}
56790b57cec5SDimitry Andric
56800b57cec5SDimitry Andric    // property functions
56810b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
56820b57cec5SDimitry Andric    result_type n() const {return __p_.n();}
56830b57cec5SDimitry Andric
56840b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
56850b57cec5SDimitry Andric    param_type param() const {return __p_;}
56860b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
56870b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
56880b57cec5SDimitry Andric
56890b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
56900b57cec5SDimitry Andric    result_type min() const {return 0;}
56910b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
56920b57cec5SDimitry Andric    result_type max() const {return numeric_limits<result_type>::infinity();}
56930b57cec5SDimitry Andric
56940b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
56950b57cec5SDimitry Andric        bool operator==(const chi_squared_distribution& __x,
56960b57cec5SDimitry Andric                        const chi_squared_distribution& __y)
56970b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
56980b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
56990b57cec5SDimitry Andric        bool operator!=(const chi_squared_distribution& __x,
57000b57cec5SDimitry Andric                        const chi_squared_distribution& __y)
57010b57cec5SDimitry Andric        {return !(__x == __y);}
57020b57cec5SDimitry Andric};
57030b57cec5SDimitry Andric
57040b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
57050b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
57060b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
57070b57cec5SDimitry Andric           const chi_squared_distribution<_RT>& __x)
57080b57cec5SDimitry Andric{
57090b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
5710*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
5711*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
5712*e8d8bef9SDimitry Andric               _OStream::scientific);
57130b57cec5SDimitry Andric    __os << __x.n();
57140b57cec5SDimitry Andric    return __os;
57150b57cec5SDimitry Andric}
57160b57cec5SDimitry Andric
57170b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
57180b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
57190b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
57200b57cec5SDimitry Andric           chi_squared_distribution<_RT>& __x)
57210b57cec5SDimitry Andric{
57220b57cec5SDimitry Andric    typedef chi_squared_distribution<_RT> _Eng;
57230b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
57240b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
57250b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
5726*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
5727*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
57280b57cec5SDimitry Andric    result_type __n;
57290b57cec5SDimitry Andric    __is >> __n;
57300b57cec5SDimitry Andric    if (!__is.fail())
57310b57cec5SDimitry Andric        __x.param(param_type(__n));
57320b57cec5SDimitry Andric    return __is;
57330b57cec5SDimitry Andric}
57340b57cec5SDimitry Andric
57350b57cec5SDimitry Andric// cauchy_distribution
57360b57cec5SDimitry Andric
57370b57cec5SDimitry Andrictemplate<class _RealType = double>
57380b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS cauchy_distribution
57390b57cec5SDimitry Andric{
57400b57cec5SDimitry Andricpublic:
57410b57cec5SDimitry Andric    // types
57420b57cec5SDimitry Andric    typedef _RealType result_type;
57430b57cec5SDimitry Andric
57440b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
57450b57cec5SDimitry Andric    {
57460b57cec5SDimitry Andric        result_type __a_;
57470b57cec5SDimitry Andric        result_type __b_;
57480b57cec5SDimitry Andric    public:
57490b57cec5SDimitry Andric        typedef cauchy_distribution distribution_type;
57500b57cec5SDimitry Andric
57510b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
57520b57cec5SDimitry Andric        explicit param_type(result_type __a = 0, result_type __b = 1)
57530b57cec5SDimitry Andric            : __a_(__a), __b_(__b) {}
57540b57cec5SDimitry Andric
57550b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
57560b57cec5SDimitry Andric        result_type a() const {return __a_;}
57570b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
57580b57cec5SDimitry Andric        result_type b() const {return __b_;}
57590b57cec5SDimitry Andric
57600b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
57610b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
57620b57cec5SDimitry Andric            {return __x.__a_ == __y.__a_ && __x.__b_ == __y.__b_;}
57630b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
57640b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
57650b57cec5SDimitry Andric            {return !(__x == __y);}
57660b57cec5SDimitry Andric    };
57670b57cec5SDimitry Andric
57680b57cec5SDimitry Andricprivate:
57690b57cec5SDimitry Andric    param_type __p_;
57700b57cec5SDimitry Andric
57710b57cec5SDimitry Andricpublic:
57720b57cec5SDimitry Andric    // constructor and reset functions
5773*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
5774*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5775*e8d8bef9SDimitry Andric    cauchy_distribution() : cauchy_distribution(0) {}
5776*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5777*e8d8bef9SDimitry Andric    explicit cauchy_distribution(result_type __a, result_type __b = 1)
5778*e8d8bef9SDimitry Andric        : __p_(param_type(__a, __b)) {}
5779*e8d8bef9SDimitry Andric#else
57800b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
57810b57cec5SDimitry Andric    explicit cauchy_distribution(result_type __a = 0, result_type __b = 1)
57820b57cec5SDimitry Andric        : __p_(param_type(__a, __b)) {}
5783*e8d8bef9SDimitry Andric#endif
57840b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
57850b57cec5SDimitry Andric    explicit cauchy_distribution(const param_type& __p)
57860b57cec5SDimitry Andric        : __p_(__p) {}
57870b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
57880b57cec5SDimitry Andric    void reset() {}
57890b57cec5SDimitry Andric
57900b57cec5SDimitry Andric    // generating functions
57910b57cec5SDimitry Andric    template<class _URNG>
57920b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
57930b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
57940b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
57950b57cec5SDimitry Andric    template<class _URNG> _LIBCPP_INLINE_VISIBILITY result_type operator()(_URNG& __g, const param_type& __p);
57960b57cec5SDimitry Andric
57970b57cec5SDimitry Andric    // property functions
57980b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
57990b57cec5SDimitry Andric    result_type a() const {return __p_.a();}
58000b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
58010b57cec5SDimitry Andric    result_type b() const {return __p_.b();}
58020b57cec5SDimitry Andric
58030b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
58040b57cec5SDimitry Andric    param_type param() const {return __p_;}
58050b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
58060b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
58070b57cec5SDimitry Andric
58080b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
58090b57cec5SDimitry Andric    result_type min() const {return -numeric_limits<result_type>::infinity();}
58100b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
58110b57cec5SDimitry Andric    result_type max() const {return numeric_limits<result_type>::infinity();}
58120b57cec5SDimitry Andric
58130b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
58140b57cec5SDimitry Andric        bool operator==(const cauchy_distribution& __x,
58150b57cec5SDimitry Andric                        const cauchy_distribution& __y)
58160b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
58170b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
58180b57cec5SDimitry Andric        bool operator!=(const cauchy_distribution& __x,
58190b57cec5SDimitry Andric                        const cauchy_distribution& __y)
58200b57cec5SDimitry Andric        {return !(__x == __y);}
58210b57cec5SDimitry Andric};
58220b57cec5SDimitry Andric
58230b57cec5SDimitry Andrictemplate <class _RealType>
58240b57cec5SDimitry Andrictemplate<class _URNG>
58250b57cec5SDimitry Andricinline
58260b57cec5SDimitry Andric_RealType
58270b57cec5SDimitry Andriccauchy_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
58280b57cec5SDimitry Andric{
58290b57cec5SDimitry Andric    uniform_real_distribution<result_type> __gen;
58300b57cec5SDimitry Andric    // purposefully let tan arg get as close to pi/2 as it wants, tan will return a finite
58310b57cec5SDimitry Andric    return __p.a() + __p.b() * _VSTD::tan(3.1415926535897932384626433832795 * __gen(__g));
58320b57cec5SDimitry Andric}
58330b57cec5SDimitry Andric
58340b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
58350b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
58360b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
58370b57cec5SDimitry Andric           const cauchy_distribution<_RT>& __x)
58380b57cec5SDimitry Andric{
58390b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
5840*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
5841*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
5842*e8d8bef9SDimitry Andric               _OStream::scientific);
58430b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
58440b57cec5SDimitry Andric    __os.fill(__sp);
58450b57cec5SDimitry Andric    __os << __x.a() << __sp << __x.b();
58460b57cec5SDimitry Andric    return __os;
58470b57cec5SDimitry Andric}
58480b57cec5SDimitry Andric
58490b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
58500b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
58510b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
58520b57cec5SDimitry Andric           cauchy_distribution<_RT>& __x)
58530b57cec5SDimitry Andric{
58540b57cec5SDimitry Andric    typedef cauchy_distribution<_RT> _Eng;
58550b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
58560b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
58570b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
5858*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
5859*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
58600b57cec5SDimitry Andric    result_type __a;
58610b57cec5SDimitry Andric    result_type __b;
58620b57cec5SDimitry Andric    __is >> __a >> __b;
58630b57cec5SDimitry Andric    if (!__is.fail())
58640b57cec5SDimitry Andric        __x.param(param_type(__a, __b));
58650b57cec5SDimitry Andric    return __is;
58660b57cec5SDimitry Andric}
58670b57cec5SDimitry Andric
58680b57cec5SDimitry Andric// fisher_f_distribution
58690b57cec5SDimitry Andric
58700b57cec5SDimitry Andrictemplate<class _RealType = double>
58710b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS fisher_f_distribution
58720b57cec5SDimitry Andric{
58730b57cec5SDimitry Andricpublic:
58740b57cec5SDimitry Andric    // types
58750b57cec5SDimitry Andric    typedef _RealType result_type;
58760b57cec5SDimitry Andric
58770b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
58780b57cec5SDimitry Andric    {
58790b57cec5SDimitry Andric        result_type __m_;
58800b57cec5SDimitry Andric        result_type __n_;
58810b57cec5SDimitry Andric    public:
58820b57cec5SDimitry Andric        typedef fisher_f_distribution distribution_type;
58830b57cec5SDimitry Andric
58840b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
58850b57cec5SDimitry Andric        explicit param_type(result_type __m = 1, result_type __n = 1)
58860b57cec5SDimitry Andric            : __m_(__m), __n_(__n) {}
58870b57cec5SDimitry Andric
58880b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
58890b57cec5SDimitry Andric        result_type m() const {return __m_;}
58900b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
58910b57cec5SDimitry Andric        result_type n() const {return __n_;}
58920b57cec5SDimitry Andric
58930b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
58940b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
58950b57cec5SDimitry Andric            {return __x.__m_ == __y.__m_ && __x.__n_ == __y.__n_;}
58960b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
58970b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
58980b57cec5SDimitry Andric            {return !(__x == __y);}
58990b57cec5SDimitry Andric    };
59000b57cec5SDimitry Andric
59010b57cec5SDimitry Andricprivate:
59020b57cec5SDimitry Andric    param_type __p_;
59030b57cec5SDimitry Andric
59040b57cec5SDimitry Andricpublic:
59050b57cec5SDimitry Andric    // constructor and reset functions
5906*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
5907*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5908*e8d8bef9SDimitry Andric    fisher_f_distribution() : fisher_f_distribution(1) {}
5909*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
5910*e8d8bef9SDimitry Andric    explicit fisher_f_distribution(result_type __m, result_type __n = 1)
5911*e8d8bef9SDimitry Andric        : __p_(param_type(__m, __n)) {}
5912*e8d8bef9SDimitry Andric#else
59130b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
59140b57cec5SDimitry Andric    explicit fisher_f_distribution(result_type __m = 1, result_type __n = 1)
59150b57cec5SDimitry Andric        : __p_(param_type(__m, __n)) {}
5916*e8d8bef9SDimitry Andric#endif
59170b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
59180b57cec5SDimitry Andric    explicit fisher_f_distribution(const param_type& __p)
59190b57cec5SDimitry Andric        : __p_(__p) {}
59200b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
59210b57cec5SDimitry Andric    void reset() {}
59220b57cec5SDimitry Andric
59230b57cec5SDimitry Andric    // generating functions
59240b57cec5SDimitry Andric    template<class _URNG>
59250b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
59260b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
59270b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
59280b57cec5SDimitry Andric    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
59290b57cec5SDimitry Andric
59300b57cec5SDimitry Andric    // property functions
59310b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
59320b57cec5SDimitry Andric    result_type m() const {return __p_.m();}
59330b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
59340b57cec5SDimitry Andric    result_type n() const {return __p_.n();}
59350b57cec5SDimitry Andric
59360b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
59370b57cec5SDimitry Andric    param_type param() const {return __p_;}
59380b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
59390b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
59400b57cec5SDimitry Andric
59410b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
59420b57cec5SDimitry Andric    result_type min() const {return 0;}
59430b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
59440b57cec5SDimitry Andric    result_type max() const {return numeric_limits<result_type>::infinity();}
59450b57cec5SDimitry Andric
59460b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
59470b57cec5SDimitry Andric        bool operator==(const fisher_f_distribution& __x,
59480b57cec5SDimitry Andric                        const fisher_f_distribution& __y)
59490b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
59500b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
59510b57cec5SDimitry Andric        bool operator!=(const fisher_f_distribution& __x,
59520b57cec5SDimitry Andric                        const fisher_f_distribution& __y)
59530b57cec5SDimitry Andric        {return !(__x == __y);}
59540b57cec5SDimitry Andric};
59550b57cec5SDimitry Andric
59560b57cec5SDimitry Andrictemplate <class _RealType>
59570b57cec5SDimitry Andrictemplate<class _URNG>
59580b57cec5SDimitry Andric_RealType
59590b57cec5SDimitry Andricfisher_f_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
59600b57cec5SDimitry Andric{
59610b57cec5SDimitry Andric    gamma_distribution<result_type> __gdm(__p.m() * result_type(.5));
59620b57cec5SDimitry Andric    gamma_distribution<result_type> __gdn(__p.n() * result_type(.5));
59630b57cec5SDimitry Andric    return __p.n() * __gdm(__g) / (__p.m() * __gdn(__g));
59640b57cec5SDimitry Andric}
59650b57cec5SDimitry Andric
59660b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
59670b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
59680b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
59690b57cec5SDimitry Andric           const fisher_f_distribution<_RT>& __x)
59700b57cec5SDimitry Andric{
59710b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
5972*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
5973*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
5974*e8d8bef9SDimitry Andric               _OStream::scientific);
59750b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
59760b57cec5SDimitry Andric    __os.fill(__sp);
59770b57cec5SDimitry Andric    __os << __x.m() << __sp << __x.n();
59780b57cec5SDimitry Andric    return __os;
59790b57cec5SDimitry Andric}
59800b57cec5SDimitry Andric
59810b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
59820b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
59830b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
59840b57cec5SDimitry Andric           fisher_f_distribution<_RT>& __x)
59850b57cec5SDimitry Andric{
59860b57cec5SDimitry Andric    typedef fisher_f_distribution<_RT> _Eng;
59870b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
59880b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
59890b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
5990*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
5991*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
59920b57cec5SDimitry Andric    result_type __m;
59930b57cec5SDimitry Andric    result_type __n;
59940b57cec5SDimitry Andric    __is >> __m >> __n;
59950b57cec5SDimitry Andric    if (!__is.fail())
59960b57cec5SDimitry Andric        __x.param(param_type(__m, __n));
59970b57cec5SDimitry Andric    return __is;
59980b57cec5SDimitry Andric}
59990b57cec5SDimitry Andric
60000b57cec5SDimitry Andric// student_t_distribution
60010b57cec5SDimitry Andric
60020b57cec5SDimitry Andrictemplate<class _RealType = double>
60030b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS student_t_distribution
60040b57cec5SDimitry Andric{
60050b57cec5SDimitry Andricpublic:
60060b57cec5SDimitry Andric    // types
60070b57cec5SDimitry Andric    typedef _RealType result_type;
60080b57cec5SDimitry Andric
60090b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
60100b57cec5SDimitry Andric    {
60110b57cec5SDimitry Andric        result_type __n_;
60120b57cec5SDimitry Andric    public:
60130b57cec5SDimitry Andric        typedef student_t_distribution distribution_type;
60140b57cec5SDimitry Andric
60150b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
60160b57cec5SDimitry Andric        explicit param_type(result_type __n = 1) : __n_(__n) {}
60170b57cec5SDimitry Andric
60180b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
60190b57cec5SDimitry Andric        result_type n() const {return __n_;}
60200b57cec5SDimitry Andric
60210b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
60220b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
60230b57cec5SDimitry Andric            {return __x.__n_ == __y.__n_;}
60240b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
60250b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
60260b57cec5SDimitry Andric            {return !(__x == __y);}
60270b57cec5SDimitry Andric    };
60280b57cec5SDimitry Andric
60290b57cec5SDimitry Andricprivate:
60300b57cec5SDimitry Andric    param_type __p_;
60310b57cec5SDimitry Andric    normal_distribution<result_type> __nd_;
60320b57cec5SDimitry Andric
60330b57cec5SDimitry Andricpublic:
60340b57cec5SDimitry Andric    // constructor and reset functions
6035*e8d8bef9SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
6036*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
6037*e8d8bef9SDimitry Andric    student_t_distribution() : student_t_distribution(1) {}
6038*e8d8bef9SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
6039*e8d8bef9SDimitry Andric    explicit student_t_distribution(result_type __n)
6040*e8d8bef9SDimitry Andric        : __p_(param_type(__n)) {}
6041*e8d8bef9SDimitry Andric#else
60420b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
60430b57cec5SDimitry Andric    explicit student_t_distribution(result_type __n = 1)
60440b57cec5SDimitry Andric        : __p_(param_type(__n)) {}
6045*e8d8bef9SDimitry Andric#endif
60460b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
60470b57cec5SDimitry Andric    explicit student_t_distribution(const param_type& __p)
60480b57cec5SDimitry Andric        : __p_(__p) {}
60490b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
60500b57cec5SDimitry Andric    void reset() {__nd_.reset();}
60510b57cec5SDimitry Andric
60520b57cec5SDimitry Andric    // generating functions
60530b57cec5SDimitry Andric    template<class _URNG>
60540b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
60550b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
60560b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
60570b57cec5SDimitry Andric    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
60580b57cec5SDimitry Andric
60590b57cec5SDimitry Andric    // property functions
60600b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
60610b57cec5SDimitry Andric    result_type n() const {return __p_.n();}
60620b57cec5SDimitry Andric
60630b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
60640b57cec5SDimitry Andric    param_type param() const {return __p_;}
60650b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
60660b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
60670b57cec5SDimitry Andric
60680b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
60690b57cec5SDimitry Andric    result_type min() const {return -numeric_limits<result_type>::infinity();}
60700b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
60710b57cec5SDimitry Andric    result_type max() const {return numeric_limits<result_type>::infinity();}
60720b57cec5SDimitry Andric
60730b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
60740b57cec5SDimitry Andric        bool operator==(const student_t_distribution& __x,
60750b57cec5SDimitry Andric                        const student_t_distribution& __y)
60760b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
60770b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
60780b57cec5SDimitry Andric        bool operator!=(const student_t_distribution& __x,
60790b57cec5SDimitry Andric                        const student_t_distribution& __y)
60800b57cec5SDimitry Andric        {return !(__x == __y);}
60810b57cec5SDimitry Andric};
60820b57cec5SDimitry Andric
60830b57cec5SDimitry Andrictemplate <class _RealType>
60840b57cec5SDimitry Andrictemplate<class _URNG>
60850b57cec5SDimitry Andric_RealType
60860b57cec5SDimitry Andricstudent_t_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
60870b57cec5SDimitry Andric{
60880b57cec5SDimitry Andric    gamma_distribution<result_type> __gd(__p.n() * .5, 2);
60890b57cec5SDimitry Andric    return __nd_(__g) * _VSTD::sqrt(__p.n()/__gd(__g));
60900b57cec5SDimitry Andric}
60910b57cec5SDimitry Andric
60920b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
60930b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
60940b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
60950b57cec5SDimitry Andric           const student_t_distribution<_RT>& __x)
60960b57cec5SDimitry Andric{
60970b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
6098*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
6099*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
6100*e8d8bef9SDimitry Andric               _OStream::scientific);
61010b57cec5SDimitry Andric    __os << __x.n();
61020b57cec5SDimitry Andric    return __os;
61030b57cec5SDimitry Andric}
61040b57cec5SDimitry Andric
61050b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
61060b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
61070b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
61080b57cec5SDimitry Andric           student_t_distribution<_RT>& __x)
61090b57cec5SDimitry Andric{
61100b57cec5SDimitry Andric    typedef student_t_distribution<_RT> _Eng;
61110b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
61120b57cec5SDimitry Andric    typedef typename _Eng::param_type param_type;
61130b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
6114*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
6115*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
61160b57cec5SDimitry Andric    result_type __n;
61170b57cec5SDimitry Andric    __is >> __n;
61180b57cec5SDimitry Andric    if (!__is.fail())
61190b57cec5SDimitry Andric        __x.param(param_type(__n));
61200b57cec5SDimitry Andric    return __is;
61210b57cec5SDimitry Andric}
61220b57cec5SDimitry Andric
61230b57cec5SDimitry Andric// discrete_distribution
61240b57cec5SDimitry Andric
61250b57cec5SDimitry Andrictemplate<class _IntType = int>
61260b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS discrete_distribution
61270b57cec5SDimitry Andric{
61280b57cec5SDimitry Andricpublic:
61290b57cec5SDimitry Andric    // types
61300b57cec5SDimitry Andric    typedef _IntType result_type;
61310b57cec5SDimitry Andric
61320b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
61330b57cec5SDimitry Andric    {
61340b57cec5SDimitry Andric        vector<double> __p_;
61350b57cec5SDimitry Andric    public:
61360b57cec5SDimitry Andric        typedef discrete_distribution distribution_type;
61370b57cec5SDimitry Andric
61380b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
61390b57cec5SDimitry Andric        param_type() {}
61400b57cec5SDimitry Andric        template<class _InputIterator>
61410b57cec5SDimitry Andric            _LIBCPP_INLINE_VISIBILITY
61420b57cec5SDimitry Andric            param_type(_InputIterator __f, _InputIterator __l)
61430b57cec5SDimitry Andric            : __p_(__f, __l) {__init();}
61440b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
61450b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
61460b57cec5SDimitry Andric        param_type(initializer_list<double> __wl)
61470b57cec5SDimitry Andric            : __p_(__wl.begin(), __wl.end()) {__init();}
61480b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
61490b57cec5SDimitry Andric        template<class _UnaryOperation>
61500b57cec5SDimitry Andric            param_type(size_t __nw, double __xmin, double __xmax,
61510b57cec5SDimitry Andric                       _UnaryOperation __fw);
61520b57cec5SDimitry Andric
61530b57cec5SDimitry Andric        vector<double> probabilities() const;
61540b57cec5SDimitry Andric
61550b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
61560b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
61570b57cec5SDimitry Andric            {return __x.__p_ == __y.__p_;}
61580b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
61590b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
61600b57cec5SDimitry Andric            {return !(__x == __y);}
61610b57cec5SDimitry Andric
61620b57cec5SDimitry Andric    private:
61630b57cec5SDimitry Andric        void __init();
61640b57cec5SDimitry Andric
61650b57cec5SDimitry Andric        friend class discrete_distribution;
61660b57cec5SDimitry Andric
61670b57cec5SDimitry Andric        template <class _CharT, class _Traits, class _IT>
61680b57cec5SDimitry Andric        friend
61690b57cec5SDimitry Andric        basic_ostream<_CharT, _Traits>&
61700b57cec5SDimitry Andric        operator<<(basic_ostream<_CharT, _Traits>& __os,
61710b57cec5SDimitry Andric                   const discrete_distribution<_IT>& __x);
61720b57cec5SDimitry Andric
61730b57cec5SDimitry Andric        template <class _CharT, class _Traits, class _IT>
61740b57cec5SDimitry Andric        friend
61750b57cec5SDimitry Andric        basic_istream<_CharT, _Traits>&
61760b57cec5SDimitry Andric        operator>>(basic_istream<_CharT, _Traits>& __is,
61770b57cec5SDimitry Andric                   discrete_distribution<_IT>& __x);
61780b57cec5SDimitry Andric    };
61790b57cec5SDimitry Andric
61800b57cec5SDimitry Andricprivate:
61810b57cec5SDimitry Andric    param_type __p_;
61820b57cec5SDimitry Andric
61830b57cec5SDimitry Andricpublic:
61840b57cec5SDimitry Andric    // constructor and reset functions
61850b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
61860b57cec5SDimitry Andric    discrete_distribution() {}
61870b57cec5SDimitry Andric    template<class _InputIterator>
61880b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
61890b57cec5SDimitry Andric        discrete_distribution(_InputIterator __f, _InputIterator __l)
61900b57cec5SDimitry Andric            : __p_(__f, __l) {}
61910b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
61920b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
61930b57cec5SDimitry Andric    discrete_distribution(initializer_list<double> __wl)
61940b57cec5SDimitry Andric        : __p_(__wl) {}
61950b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
61960b57cec5SDimitry Andric    template<class _UnaryOperation>
61970b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
61980b57cec5SDimitry Andric        discrete_distribution(size_t __nw, double __xmin, double __xmax,
61990b57cec5SDimitry Andric                              _UnaryOperation __fw)
62000b57cec5SDimitry Andric        : __p_(__nw, __xmin, __xmax, __fw) {}
62010b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
62020b57cec5SDimitry Andric    explicit discrete_distribution(const param_type& __p)
62030b57cec5SDimitry Andric        : __p_(__p) {}
62040b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
62050b57cec5SDimitry Andric    void reset() {}
62060b57cec5SDimitry Andric
62070b57cec5SDimitry Andric    // generating functions
62080b57cec5SDimitry Andric    template<class _URNG>
62090b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
62100b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
62110b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
62120b57cec5SDimitry Andric    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
62130b57cec5SDimitry Andric
62140b57cec5SDimitry Andric    // property functions
62150b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
62160b57cec5SDimitry Andric    vector<double> probabilities() const {return __p_.probabilities();}
62170b57cec5SDimitry Andric
62180b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
62190b57cec5SDimitry Andric    param_type param() const {return __p_;}
62200b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
62210b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
62220b57cec5SDimitry Andric
62230b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
62240b57cec5SDimitry Andric    result_type min() const {return 0;}
62250b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
62260b57cec5SDimitry Andric    result_type max() const {return __p_.__p_.size();}
62270b57cec5SDimitry Andric
62280b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
62290b57cec5SDimitry Andric        bool operator==(const discrete_distribution& __x,
62300b57cec5SDimitry Andric                        const discrete_distribution& __y)
62310b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
62320b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
62330b57cec5SDimitry Andric        bool operator!=(const discrete_distribution& __x,
62340b57cec5SDimitry Andric                        const discrete_distribution& __y)
62350b57cec5SDimitry Andric        {return !(__x == __y);}
62360b57cec5SDimitry Andric
62370b57cec5SDimitry Andric    template <class _CharT, class _Traits, class _IT>
62380b57cec5SDimitry Andric    friend
62390b57cec5SDimitry Andric    basic_ostream<_CharT, _Traits>&
62400b57cec5SDimitry Andric    operator<<(basic_ostream<_CharT, _Traits>& __os,
62410b57cec5SDimitry Andric               const discrete_distribution<_IT>& __x);
62420b57cec5SDimitry Andric
62430b57cec5SDimitry Andric    template <class _CharT, class _Traits, class _IT>
62440b57cec5SDimitry Andric    friend
62450b57cec5SDimitry Andric    basic_istream<_CharT, _Traits>&
62460b57cec5SDimitry Andric    operator>>(basic_istream<_CharT, _Traits>& __is,
62470b57cec5SDimitry Andric               discrete_distribution<_IT>& __x);
62480b57cec5SDimitry Andric};
62490b57cec5SDimitry Andric
62500b57cec5SDimitry Andrictemplate<class _IntType>
62510b57cec5SDimitry Andrictemplate<class _UnaryOperation>
62520b57cec5SDimitry Andricdiscrete_distribution<_IntType>::param_type::param_type(size_t __nw,
62530b57cec5SDimitry Andric                                                        double __xmin,
62540b57cec5SDimitry Andric                                                        double __xmax,
62550b57cec5SDimitry Andric                                                        _UnaryOperation __fw)
62560b57cec5SDimitry Andric{
62570b57cec5SDimitry Andric    if (__nw > 1)
62580b57cec5SDimitry Andric    {
62590b57cec5SDimitry Andric        __p_.reserve(__nw - 1);
62600b57cec5SDimitry Andric        double __d = (__xmax - __xmin) / __nw;
62610b57cec5SDimitry Andric        double __d2 = __d / 2;
62620b57cec5SDimitry Andric        for (size_t __k = 0; __k < __nw; ++__k)
62630b57cec5SDimitry Andric            __p_.push_back(__fw(__xmin + __k * __d + __d2));
62640b57cec5SDimitry Andric        __init();
62650b57cec5SDimitry Andric    }
62660b57cec5SDimitry Andric}
62670b57cec5SDimitry Andric
62680b57cec5SDimitry Andrictemplate<class _IntType>
62690b57cec5SDimitry Andricvoid
62700b57cec5SDimitry Andricdiscrete_distribution<_IntType>::param_type::__init()
62710b57cec5SDimitry Andric{
62720b57cec5SDimitry Andric    if (!__p_.empty())
62730b57cec5SDimitry Andric    {
62740b57cec5SDimitry Andric        if (__p_.size() > 1)
62750b57cec5SDimitry Andric        {
62760b57cec5SDimitry Andric            double __s = _VSTD::accumulate(__p_.begin(), __p_.end(), 0.0);
62770b57cec5SDimitry Andric            for (_VSTD::vector<double>::iterator __i = __p_.begin(), __e = __p_.end();
62780b57cec5SDimitry Andric                                                                       __i < __e; ++__i)
62790b57cec5SDimitry Andric                *__i /= __s;
62800b57cec5SDimitry Andric            vector<double> __t(__p_.size() - 1);
62810b57cec5SDimitry Andric            _VSTD::partial_sum(__p_.begin(), __p_.end() - 1, __t.begin());
62820b57cec5SDimitry Andric            swap(__p_, __t);
62830b57cec5SDimitry Andric        }
62840b57cec5SDimitry Andric        else
62850b57cec5SDimitry Andric        {
62860b57cec5SDimitry Andric            __p_.clear();
62870b57cec5SDimitry Andric            __p_.shrink_to_fit();
62880b57cec5SDimitry Andric        }
62890b57cec5SDimitry Andric    }
62900b57cec5SDimitry Andric}
62910b57cec5SDimitry Andric
62920b57cec5SDimitry Andrictemplate<class _IntType>
62930b57cec5SDimitry Andricvector<double>
62940b57cec5SDimitry Andricdiscrete_distribution<_IntType>::param_type::probabilities() const
62950b57cec5SDimitry Andric{
62960b57cec5SDimitry Andric    size_t __n = __p_.size();
62970b57cec5SDimitry Andric    _VSTD::vector<double> __p(__n+1);
62980b57cec5SDimitry Andric    _VSTD::adjacent_difference(__p_.begin(), __p_.end(), __p.begin());
62990b57cec5SDimitry Andric    if (__n > 0)
63000b57cec5SDimitry Andric        __p[__n] = 1 - __p_[__n-1];
63010b57cec5SDimitry Andric    else
63020b57cec5SDimitry Andric        __p[0] = 1;
63030b57cec5SDimitry Andric    return __p;
63040b57cec5SDimitry Andric}
63050b57cec5SDimitry Andric
63060b57cec5SDimitry Andrictemplate<class _IntType>
63070b57cec5SDimitry Andrictemplate<class _URNG>
63080b57cec5SDimitry Andric_IntType
63090b57cec5SDimitry Andricdiscrete_distribution<_IntType>::operator()(_URNG& __g, const param_type& __p)
63100b57cec5SDimitry Andric{
63110b57cec5SDimitry Andric    uniform_real_distribution<double> __gen;
63120b57cec5SDimitry Andric    return static_cast<_IntType>(
63130b57cec5SDimitry Andric           _VSTD::upper_bound(__p.__p_.begin(), __p.__p_.end(), __gen(__g)) -
63140b57cec5SDimitry Andric                                                              __p.__p_.begin());
63150b57cec5SDimitry Andric}
63160b57cec5SDimitry Andric
63170b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _IT>
63180b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
63190b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
63200b57cec5SDimitry Andric           const discrete_distribution<_IT>& __x)
63210b57cec5SDimitry Andric{
63220b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
6323*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
6324*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
6325*e8d8bef9SDimitry Andric               _OStream::scientific);
63260b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
63270b57cec5SDimitry Andric    __os.fill(__sp);
63280b57cec5SDimitry Andric    size_t __n = __x.__p_.__p_.size();
63290b57cec5SDimitry Andric    __os << __n;
63300b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
63310b57cec5SDimitry Andric        __os << __sp << __x.__p_.__p_[__i];
63320b57cec5SDimitry Andric    return __os;
63330b57cec5SDimitry Andric}
63340b57cec5SDimitry Andric
63350b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _IT>
63360b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
63370b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
63380b57cec5SDimitry Andric           discrete_distribution<_IT>& __x)
63390b57cec5SDimitry Andric{
63400b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
6341*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
6342*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
63430b57cec5SDimitry Andric    size_t __n;
63440b57cec5SDimitry Andric    __is >> __n;
63450b57cec5SDimitry Andric    vector<double> __p(__n);
63460b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
63470b57cec5SDimitry Andric        __is >> __p[__i];
63480b57cec5SDimitry Andric    if (!__is.fail())
63490b57cec5SDimitry Andric        swap(__x.__p_.__p_, __p);
63500b57cec5SDimitry Andric    return __is;
63510b57cec5SDimitry Andric}
63520b57cec5SDimitry Andric
63530b57cec5SDimitry Andric// piecewise_constant_distribution
63540b57cec5SDimitry Andric
63550b57cec5SDimitry Andrictemplate<class _RealType = double>
63560b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS piecewise_constant_distribution
63570b57cec5SDimitry Andric{
63580b57cec5SDimitry Andricpublic:
63590b57cec5SDimitry Andric    // types
63600b57cec5SDimitry Andric    typedef _RealType result_type;
63610b57cec5SDimitry Andric
63620b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
63630b57cec5SDimitry Andric    {
63640b57cec5SDimitry Andric        vector<result_type> __b_;
63650b57cec5SDimitry Andric        vector<result_type> __densities_;
63660b57cec5SDimitry Andric        vector<result_type> __areas_;
63670b57cec5SDimitry Andric    public:
63680b57cec5SDimitry Andric        typedef piecewise_constant_distribution distribution_type;
63690b57cec5SDimitry Andric
63700b57cec5SDimitry Andric        param_type();
63710b57cec5SDimitry Andric        template<class _InputIteratorB, class _InputIteratorW>
63720b57cec5SDimitry Andric            param_type(_InputIteratorB __fB, _InputIteratorB __lB,
63730b57cec5SDimitry Andric                       _InputIteratorW __fW);
63740b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
63750b57cec5SDimitry Andric        template<class _UnaryOperation>
63760b57cec5SDimitry Andric            param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
63770b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
63780b57cec5SDimitry Andric        template<class _UnaryOperation>
63790b57cec5SDimitry Andric            param_type(size_t __nw, result_type __xmin, result_type __xmax,
63800b57cec5SDimitry Andric                       _UnaryOperation __fw);
6381cd0c3137SDimitry Andric        param_type(param_type const&) = default;
63820b57cec5SDimitry Andric        param_type & operator=(const param_type& __rhs);
63830b57cec5SDimitry Andric
63840b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
63850b57cec5SDimitry Andric        vector<result_type> intervals() const {return __b_;}
63860b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
63870b57cec5SDimitry Andric        vector<result_type> densities() const {return __densities_;}
63880b57cec5SDimitry Andric
63890b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
63900b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
63910b57cec5SDimitry Andric            {return __x.__densities_ == __y.__densities_ && __x.__b_ == __y.__b_;}
63920b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
63930b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
63940b57cec5SDimitry Andric            {return !(__x == __y);}
63950b57cec5SDimitry Andric
63960b57cec5SDimitry Andric    private:
63970b57cec5SDimitry Andric        void __init();
63980b57cec5SDimitry Andric
63990b57cec5SDimitry Andric        friend class piecewise_constant_distribution;
64000b57cec5SDimitry Andric
64010b57cec5SDimitry Andric        template <class _CharT, class _Traits, class _RT>
64020b57cec5SDimitry Andric        friend
64030b57cec5SDimitry Andric        basic_ostream<_CharT, _Traits>&
64040b57cec5SDimitry Andric        operator<<(basic_ostream<_CharT, _Traits>& __os,
64050b57cec5SDimitry Andric                   const piecewise_constant_distribution<_RT>& __x);
64060b57cec5SDimitry Andric
64070b57cec5SDimitry Andric        template <class _CharT, class _Traits, class _RT>
64080b57cec5SDimitry Andric        friend
64090b57cec5SDimitry Andric        basic_istream<_CharT, _Traits>&
64100b57cec5SDimitry Andric        operator>>(basic_istream<_CharT, _Traits>& __is,
64110b57cec5SDimitry Andric                   piecewise_constant_distribution<_RT>& __x);
64120b57cec5SDimitry Andric    };
64130b57cec5SDimitry Andric
64140b57cec5SDimitry Andricprivate:
64150b57cec5SDimitry Andric    param_type __p_;
64160b57cec5SDimitry Andric
64170b57cec5SDimitry Andricpublic:
64180b57cec5SDimitry Andric    // constructor and reset functions
64190b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
64200b57cec5SDimitry Andric    piecewise_constant_distribution() {}
64210b57cec5SDimitry Andric    template<class _InputIteratorB, class _InputIteratorW>
64220b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
64230b57cec5SDimitry Andric        piecewise_constant_distribution(_InputIteratorB __fB,
64240b57cec5SDimitry Andric                                        _InputIteratorB __lB,
64250b57cec5SDimitry Andric                                        _InputIteratorW __fW)
64260b57cec5SDimitry Andric        : __p_(__fB, __lB, __fW) {}
64270b57cec5SDimitry Andric
64280b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
64290b57cec5SDimitry Andric    template<class _UnaryOperation>
64300b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
64310b57cec5SDimitry Andric        piecewise_constant_distribution(initializer_list<result_type> __bl,
64320b57cec5SDimitry Andric                                        _UnaryOperation __fw)
64330b57cec5SDimitry Andric        : __p_(__bl, __fw) {}
64340b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
64350b57cec5SDimitry Andric
64360b57cec5SDimitry Andric    template<class _UnaryOperation>
64370b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
64380b57cec5SDimitry Andric        piecewise_constant_distribution(size_t __nw, result_type __xmin,
64390b57cec5SDimitry Andric                                        result_type __xmax, _UnaryOperation __fw)
64400b57cec5SDimitry Andric        : __p_(__nw, __xmin, __xmax, __fw) {}
64410b57cec5SDimitry Andric
64420b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
64430b57cec5SDimitry Andric    explicit piecewise_constant_distribution(const param_type& __p)
64440b57cec5SDimitry Andric        : __p_(__p) {}
64450b57cec5SDimitry Andric
64460b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
64470b57cec5SDimitry Andric    void reset() {}
64480b57cec5SDimitry Andric
64490b57cec5SDimitry Andric    // generating functions
64500b57cec5SDimitry Andric    template<class _URNG>
64510b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
64520b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
64530b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
64540b57cec5SDimitry Andric    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
64550b57cec5SDimitry Andric
64560b57cec5SDimitry Andric    // property functions
64570b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
64580b57cec5SDimitry Andric    vector<result_type> intervals() const {return __p_.intervals();}
64590b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
64600b57cec5SDimitry Andric    vector<result_type> densities() const {return __p_.densities();}
64610b57cec5SDimitry Andric
64620b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
64630b57cec5SDimitry Andric    param_type param() const {return __p_;}
64640b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
64650b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
64660b57cec5SDimitry Andric
64670b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
64680b57cec5SDimitry Andric    result_type min() const {return __p_.__b_.front();}
64690b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
64700b57cec5SDimitry Andric    result_type max() const {return __p_.__b_.back();}
64710b57cec5SDimitry Andric
64720b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
64730b57cec5SDimitry Andric        bool operator==(const piecewise_constant_distribution& __x,
64740b57cec5SDimitry Andric                        const piecewise_constant_distribution& __y)
64750b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
64760b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
64770b57cec5SDimitry Andric        bool operator!=(const piecewise_constant_distribution& __x,
64780b57cec5SDimitry Andric                           const piecewise_constant_distribution& __y)
64790b57cec5SDimitry Andric        {return !(__x == __y);}
64800b57cec5SDimitry Andric
64810b57cec5SDimitry Andric    template <class _CharT, class _Traits, class _RT>
64820b57cec5SDimitry Andric    friend
64830b57cec5SDimitry Andric    basic_ostream<_CharT, _Traits>&
64840b57cec5SDimitry Andric    operator<<(basic_ostream<_CharT, _Traits>& __os,
64850b57cec5SDimitry Andric               const piecewise_constant_distribution<_RT>& __x);
64860b57cec5SDimitry Andric
64870b57cec5SDimitry Andric    template <class _CharT, class _Traits, class _RT>
64880b57cec5SDimitry Andric    friend
64890b57cec5SDimitry Andric    basic_istream<_CharT, _Traits>&
64900b57cec5SDimitry Andric    operator>>(basic_istream<_CharT, _Traits>& __is,
64910b57cec5SDimitry Andric               piecewise_constant_distribution<_RT>& __x);
64920b57cec5SDimitry Andric};
64930b57cec5SDimitry Andric
64940b57cec5SDimitry Andrictemplate<class _RealType>
64950b57cec5SDimitry Andrictypename piecewise_constant_distribution<_RealType>::param_type &
64960b57cec5SDimitry Andricpiecewise_constant_distribution<_RealType>::param_type::operator=
64970b57cec5SDimitry Andric                                                       (const param_type& __rhs)
64980b57cec5SDimitry Andric{
64990b57cec5SDimitry Andric//  These can throw
65000b57cec5SDimitry Andric    __b_.reserve        (__rhs.__b_.size ());
65010b57cec5SDimitry Andric    __densities_.reserve(__rhs.__densities_.size());
65020b57cec5SDimitry Andric    __areas_.reserve    (__rhs.__areas_.size());
65030b57cec5SDimitry Andric
65040b57cec5SDimitry Andric//  These can not throw
65050b57cec5SDimitry Andric    __b_         = __rhs.__b_;
65060b57cec5SDimitry Andric    __densities_ = __rhs.__densities_;
65070b57cec5SDimitry Andric    __areas_     =  __rhs.__areas_;
65080b57cec5SDimitry Andric    return *this;
65090b57cec5SDimitry Andric}
65100b57cec5SDimitry Andric
65110b57cec5SDimitry Andrictemplate<class _RealType>
65120b57cec5SDimitry Andricvoid
65130b57cec5SDimitry Andricpiecewise_constant_distribution<_RealType>::param_type::__init()
65140b57cec5SDimitry Andric{
65150b57cec5SDimitry Andric    // __densities_ contains non-normalized areas
65160b57cec5SDimitry Andric    result_type __total_area = _VSTD::accumulate(__densities_.begin(),
65170b57cec5SDimitry Andric                                                __densities_.end(),
65180b57cec5SDimitry Andric                                                result_type());
65190b57cec5SDimitry Andric    for (size_t __i = 0; __i < __densities_.size(); ++__i)
65200b57cec5SDimitry Andric        __densities_[__i] /= __total_area;
65210b57cec5SDimitry Andric    // __densities_ contains normalized areas
65220b57cec5SDimitry Andric    __areas_.assign(__densities_.size(), result_type());
65230b57cec5SDimitry Andric    _VSTD::partial_sum(__densities_.begin(), __densities_.end() - 1,
65240b57cec5SDimitry Andric                                                          __areas_.begin() + 1);
65250b57cec5SDimitry Andric    // __areas_ contains partial sums of normalized areas: [0, __densities_ - 1]
65260b57cec5SDimitry Andric    __densities_.back() = 1 - __areas_.back();  // correct round off error
65270b57cec5SDimitry Andric    for (size_t __i = 0; __i < __densities_.size(); ++__i)
65280b57cec5SDimitry Andric        __densities_[__i] /= (__b_[__i+1] - __b_[__i]);
65290b57cec5SDimitry Andric    // __densities_ now contains __densities_
65300b57cec5SDimitry Andric}
65310b57cec5SDimitry Andric
65320b57cec5SDimitry Andrictemplate<class _RealType>
65330b57cec5SDimitry Andricpiecewise_constant_distribution<_RealType>::param_type::param_type()
65340b57cec5SDimitry Andric    : __b_(2),
65350b57cec5SDimitry Andric      __densities_(1, 1.0),
65360b57cec5SDimitry Andric      __areas_(1, 0.0)
65370b57cec5SDimitry Andric{
65380b57cec5SDimitry Andric    __b_[1] = 1;
65390b57cec5SDimitry Andric}
65400b57cec5SDimitry Andric
65410b57cec5SDimitry Andrictemplate<class _RealType>
65420b57cec5SDimitry Andrictemplate<class _InputIteratorB, class _InputIteratorW>
65430b57cec5SDimitry Andricpiecewise_constant_distribution<_RealType>::param_type::param_type(
65440b57cec5SDimitry Andric        _InputIteratorB __fB, _InputIteratorB __lB, _InputIteratorW __fW)
65450b57cec5SDimitry Andric    : __b_(__fB, __lB)
65460b57cec5SDimitry Andric{
65470b57cec5SDimitry Andric    if (__b_.size() < 2)
65480b57cec5SDimitry Andric    {
65490b57cec5SDimitry Andric        __b_.resize(2);
65500b57cec5SDimitry Andric        __b_[0] = 0;
65510b57cec5SDimitry Andric        __b_[1] = 1;
65520b57cec5SDimitry Andric        __densities_.assign(1, 1.0);
65530b57cec5SDimitry Andric        __areas_.assign(1, 0.0);
65540b57cec5SDimitry Andric    }
65550b57cec5SDimitry Andric    else
65560b57cec5SDimitry Andric    {
65570b57cec5SDimitry Andric        __densities_.reserve(__b_.size() - 1);
65580b57cec5SDimitry Andric        for (size_t __i = 0; __i < __b_.size() - 1; ++__i, ++__fW)
65590b57cec5SDimitry Andric            __densities_.push_back(*__fW);
65600b57cec5SDimitry Andric        __init();
65610b57cec5SDimitry Andric    }
65620b57cec5SDimitry Andric}
65630b57cec5SDimitry Andric
65640b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
65650b57cec5SDimitry Andric
65660b57cec5SDimitry Andrictemplate<class _RealType>
65670b57cec5SDimitry Andrictemplate<class _UnaryOperation>
65680b57cec5SDimitry Andricpiecewise_constant_distribution<_RealType>::param_type::param_type(
65690b57cec5SDimitry Andric        initializer_list<result_type> __bl, _UnaryOperation __fw)
65700b57cec5SDimitry Andric    : __b_(__bl.begin(), __bl.end())
65710b57cec5SDimitry Andric{
65720b57cec5SDimitry Andric    if (__b_.size() < 2)
65730b57cec5SDimitry Andric    {
65740b57cec5SDimitry Andric        __b_.resize(2);
65750b57cec5SDimitry Andric        __b_[0] = 0;
65760b57cec5SDimitry Andric        __b_[1] = 1;
65770b57cec5SDimitry Andric        __densities_.assign(1, 1.0);
65780b57cec5SDimitry Andric        __areas_.assign(1, 0.0);
65790b57cec5SDimitry Andric    }
65800b57cec5SDimitry Andric    else
65810b57cec5SDimitry Andric    {
65820b57cec5SDimitry Andric        __densities_.reserve(__b_.size() - 1);
65830b57cec5SDimitry Andric        for (size_t __i = 0; __i < __b_.size() - 1; ++__i)
65840b57cec5SDimitry Andric            __densities_.push_back(__fw((__b_[__i+1] + __b_[__i])*.5));
65850b57cec5SDimitry Andric        __init();
65860b57cec5SDimitry Andric    }
65870b57cec5SDimitry Andric}
65880b57cec5SDimitry Andric
65890b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
65900b57cec5SDimitry Andric
65910b57cec5SDimitry Andrictemplate<class _RealType>
65920b57cec5SDimitry Andrictemplate<class _UnaryOperation>
65930b57cec5SDimitry Andricpiecewise_constant_distribution<_RealType>::param_type::param_type(
65940b57cec5SDimitry Andric        size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw)
65950b57cec5SDimitry Andric    : __b_(__nw == 0 ? 2 : __nw + 1)
65960b57cec5SDimitry Andric{
65970b57cec5SDimitry Andric    size_t __n = __b_.size() - 1;
65980b57cec5SDimitry Andric    result_type __d = (__xmax - __xmin) / __n;
65990b57cec5SDimitry Andric    __densities_.reserve(__n);
66000b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
66010b57cec5SDimitry Andric    {
66020b57cec5SDimitry Andric        __b_[__i] = __xmin + __i * __d;
66030b57cec5SDimitry Andric        __densities_.push_back(__fw(__b_[__i] + __d*.5));
66040b57cec5SDimitry Andric    }
66050b57cec5SDimitry Andric    __b_[__n] = __xmax;
66060b57cec5SDimitry Andric    __init();
66070b57cec5SDimitry Andric}
66080b57cec5SDimitry Andric
66090b57cec5SDimitry Andrictemplate<class _RealType>
66100b57cec5SDimitry Andrictemplate<class _URNG>
66110b57cec5SDimitry Andric_RealType
66120b57cec5SDimitry Andricpiecewise_constant_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
66130b57cec5SDimitry Andric{
66140b57cec5SDimitry Andric    typedef uniform_real_distribution<result_type> _Gen;
66150b57cec5SDimitry Andric    result_type __u = _Gen()(__g);
66160b57cec5SDimitry Andric    ptrdiff_t __k = _VSTD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(),
66170b57cec5SDimitry Andric                                      __u) - __p.__areas_.begin() - 1;
66180b57cec5SDimitry Andric    return (__u - __p.__areas_[__k]) / __p.__densities_[__k] + __p.__b_[__k];
66190b57cec5SDimitry Andric}
66200b57cec5SDimitry Andric
66210b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
66220b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
66230b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
66240b57cec5SDimitry Andric           const piecewise_constant_distribution<_RT>& __x)
66250b57cec5SDimitry Andric{
66260b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
6627*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
6628*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
6629*e8d8bef9SDimitry Andric               _OStream::scientific);
66300b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
66310b57cec5SDimitry Andric    __os.fill(__sp);
66320b57cec5SDimitry Andric    size_t __n = __x.__p_.__b_.size();
66330b57cec5SDimitry Andric    __os << __n;
66340b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
66350b57cec5SDimitry Andric        __os << __sp << __x.__p_.__b_[__i];
66360b57cec5SDimitry Andric    __n = __x.__p_.__densities_.size();
66370b57cec5SDimitry Andric    __os << __sp << __n;
66380b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
66390b57cec5SDimitry Andric        __os << __sp << __x.__p_.__densities_[__i];
66400b57cec5SDimitry Andric    __n = __x.__p_.__areas_.size();
66410b57cec5SDimitry Andric    __os << __sp << __n;
66420b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
66430b57cec5SDimitry Andric        __os << __sp << __x.__p_.__areas_[__i];
66440b57cec5SDimitry Andric    return __os;
66450b57cec5SDimitry Andric}
66460b57cec5SDimitry Andric
66470b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
66480b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
66490b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
66500b57cec5SDimitry Andric           piecewise_constant_distribution<_RT>& __x)
66510b57cec5SDimitry Andric{
66520b57cec5SDimitry Andric    typedef piecewise_constant_distribution<_RT> _Eng;
66530b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
66540b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
6655*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
6656*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
66570b57cec5SDimitry Andric    size_t __n;
66580b57cec5SDimitry Andric    __is >> __n;
66590b57cec5SDimitry Andric    vector<result_type> __b(__n);
66600b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
66610b57cec5SDimitry Andric        __is >> __b[__i];
66620b57cec5SDimitry Andric    __is >> __n;
66630b57cec5SDimitry Andric    vector<result_type> __densities(__n);
66640b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
66650b57cec5SDimitry Andric        __is >> __densities[__i];
66660b57cec5SDimitry Andric    __is >> __n;
66670b57cec5SDimitry Andric    vector<result_type> __areas(__n);
66680b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
66690b57cec5SDimitry Andric        __is >> __areas[__i];
66700b57cec5SDimitry Andric    if (!__is.fail())
66710b57cec5SDimitry Andric    {
66720b57cec5SDimitry Andric        swap(__x.__p_.__b_, __b);
66730b57cec5SDimitry Andric        swap(__x.__p_.__densities_, __densities);
66740b57cec5SDimitry Andric        swap(__x.__p_.__areas_, __areas);
66750b57cec5SDimitry Andric    }
66760b57cec5SDimitry Andric    return __is;
66770b57cec5SDimitry Andric}
66780b57cec5SDimitry Andric
66790b57cec5SDimitry Andric// piecewise_linear_distribution
66800b57cec5SDimitry Andric
66810b57cec5SDimitry Andrictemplate<class _RealType = double>
66820b57cec5SDimitry Andricclass _LIBCPP_TEMPLATE_VIS piecewise_linear_distribution
66830b57cec5SDimitry Andric{
66840b57cec5SDimitry Andricpublic:
66850b57cec5SDimitry Andric    // types
66860b57cec5SDimitry Andric    typedef _RealType result_type;
66870b57cec5SDimitry Andric
66880b57cec5SDimitry Andric    class _LIBCPP_TEMPLATE_VIS param_type
66890b57cec5SDimitry Andric    {
66900b57cec5SDimitry Andric        vector<result_type> __b_;
66910b57cec5SDimitry Andric        vector<result_type> __densities_;
66920b57cec5SDimitry Andric        vector<result_type> __areas_;
66930b57cec5SDimitry Andric    public:
66940b57cec5SDimitry Andric        typedef piecewise_linear_distribution distribution_type;
66950b57cec5SDimitry Andric
66960b57cec5SDimitry Andric        param_type();
66970b57cec5SDimitry Andric        template<class _InputIteratorB, class _InputIteratorW>
66980b57cec5SDimitry Andric            param_type(_InputIteratorB __fB, _InputIteratorB __lB,
66990b57cec5SDimitry Andric                       _InputIteratorW __fW);
67000b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
67010b57cec5SDimitry Andric        template<class _UnaryOperation>
67020b57cec5SDimitry Andric            param_type(initializer_list<result_type> __bl, _UnaryOperation __fw);
67030b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
67040b57cec5SDimitry Andric        template<class _UnaryOperation>
67050b57cec5SDimitry Andric            param_type(size_t __nw, result_type __xmin, result_type __xmax,
67060b57cec5SDimitry Andric                       _UnaryOperation __fw);
6707cd0c3137SDimitry Andric        param_type(param_type const&) = default;
67080b57cec5SDimitry Andric        param_type & operator=(const param_type& __rhs);
67090b57cec5SDimitry Andric
67100b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
67110b57cec5SDimitry Andric        vector<result_type> intervals() const {return __b_;}
67120b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
67130b57cec5SDimitry Andric        vector<result_type> densities() const {return __densities_;}
67140b57cec5SDimitry Andric
67150b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
67160b57cec5SDimitry Andric            bool operator==(const param_type& __x, const param_type& __y)
67170b57cec5SDimitry Andric            {return __x.__densities_ == __y.__densities_ && __x.__b_ == __y.__b_;}
67180b57cec5SDimitry Andric        friend _LIBCPP_INLINE_VISIBILITY
67190b57cec5SDimitry Andric            bool operator!=(const param_type& __x, const param_type& __y)
67200b57cec5SDimitry Andric            {return !(__x == __y);}
67210b57cec5SDimitry Andric
67220b57cec5SDimitry Andric    private:
67230b57cec5SDimitry Andric        void __init();
67240b57cec5SDimitry Andric
67250b57cec5SDimitry Andric        friend class piecewise_linear_distribution;
67260b57cec5SDimitry Andric
67270b57cec5SDimitry Andric        template <class _CharT, class _Traits, class _RT>
67280b57cec5SDimitry Andric        friend
67290b57cec5SDimitry Andric        basic_ostream<_CharT, _Traits>&
67300b57cec5SDimitry Andric        operator<<(basic_ostream<_CharT, _Traits>& __os,
67310b57cec5SDimitry Andric                   const piecewise_linear_distribution<_RT>& __x);
67320b57cec5SDimitry Andric
67330b57cec5SDimitry Andric        template <class _CharT, class _Traits, class _RT>
67340b57cec5SDimitry Andric        friend
67350b57cec5SDimitry Andric        basic_istream<_CharT, _Traits>&
67360b57cec5SDimitry Andric        operator>>(basic_istream<_CharT, _Traits>& __is,
67370b57cec5SDimitry Andric                   piecewise_linear_distribution<_RT>& __x);
67380b57cec5SDimitry Andric    };
67390b57cec5SDimitry Andric
67400b57cec5SDimitry Andricprivate:
67410b57cec5SDimitry Andric    param_type __p_;
67420b57cec5SDimitry Andric
67430b57cec5SDimitry Andricpublic:
67440b57cec5SDimitry Andric    // constructor and reset functions
67450b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
67460b57cec5SDimitry Andric    piecewise_linear_distribution() {}
67470b57cec5SDimitry Andric    template<class _InputIteratorB, class _InputIteratorW>
67480b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
67490b57cec5SDimitry Andric        piecewise_linear_distribution(_InputIteratorB __fB,
67500b57cec5SDimitry Andric                                      _InputIteratorB __lB,
67510b57cec5SDimitry Andric                                      _InputIteratorW __fW)
67520b57cec5SDimitry Andric        : __p_(__fB, __lB, __fW) {}
67530b57cec5SDimitry Andric
67540b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
67550b57cec5SDimitry Andric    template<class _UnaryOperation>
67560b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
67570b57cec5SDimitry Andric        piecewise_linear_distribution(initializer_list<result_type> __bl,
67580b57cec5SDimitry Andric                                      _UnaryOperation __fw)
67590b57cec5SDimitry Andric        : __p_(__bl, __fw) {}
67600b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
67610b57cec5SDimitry Andric
67620b57cec5SDimitry Andric    template<class _UnaryOperation>
67630b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
67640b57cec5SDimitry Andric        piecewise_linear_distribution(size_t __nw, result_type __xmin,
67650b57cec5SDimitry Andric                                      result_type __xmax, _UnaryOperation __fw)
67660b57cec5SDimitry Andric        : __p_(__nw, __xmin, __xmax, __fw) {}
67670b57cec5SDimitry Andric
67680b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
67690b57cec5SDimitry Andric    explicit piecewise_linear_distribution(const param_type& __p)
67700b57cec5SDimitry Andric        : __p_(__p) {}
67710b57cec5SDimitry Andric
67720b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
67730b57cec5SDimitry Andric    void reset() {}
67740b57cec5SDimitry Andric
67750b57cec5SDimitry Andric    // generating functions
67760b57cec5SDimitry Andric    template<class _URNG>
67770b57cec5SDimitry Andric        _LIBCPP_INLINE_VISIBILITY
67780b57cec5SDimitry Andric        result_type operator()(_URNG& __g)
67790b57cec5SDimitry Andric        {return (*this)(__g, __p_);}
67800b57cec5SDimitry Andric    template<class _URNG> result_type operator()(_URNG& __g, const param_type& __p);
67810b57cec5SDimitry Andric
67820b57cec5SDimitry Andric    // property functions
67830b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
67840b57cec5SDimitry Andric    vector<result_type> intervals() const {return __p_.intervals();}
67850b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
67860b57cec5SDimitry Andric    vector<result_type> densities() const {return __p_.densities();}
67870b57cec5SDimitry Andric
67880b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
67890b57cec5SDimitry Andric    param_type param() const {return __p_;}
67900b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
67910b57cec5SDimitry Andric    void param(const param_type& __p) {__p_ = __p;}
67920b57cec5SDimitry Andric
67930b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
67940b57cec5SDimitry Andric    result_type min() const {return __p_.__b_.front();}
67950b57cec5SDimitry Andric    _LIBCPP_INLINE_VISIBILITY
67960b57cec5SDimitry Andric    result_type max() const {return __p_.__b_.back();}
67970b57cec5SDimitry Andric
67980b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
67990b57cec5SDimitry Andric        bool operator==(const piecewise_linear_distribution& __x,
68000b57cec5SDimitry Andric                        const piecewise_linear_distribution& __y)
68010b57cec5SDimitry Andric        {return __x.__p_ == __y.__p_;}
68020b57cec5SDimitry Andric    friend _LIBCPP_INLINE_VISIBILITY
68030b57cec5SDimitry Andric        bool operator!=(const piecewise_linear_distribution& __x,
68040b57cec5SDimitry Andric                        const piecewise_linear_distribution& __y)
68050b57cec5SDimitry Andric        {return !(__x == __y);}
68060b57cec5SDimitry Andric
68070b57cec5SDimitry Andric    template <class _CharT, class _Traits, class _RT>
68080b57cec5SDimitry Andric    friend
68090b57cec5SDimitry Andric    basic_ostream<_CharT, _Traits>&
68100b57cec5SDimitry Andric    operator<<(basic_ostream<_CharT, _Traits>& __os,
68110b57cec5SDimitry Andric               const piecewise_linear_distribution<_RT>& __x);
68120b57cec5SDimitry Andric
68130b57cec5SDimitry Andric    template <class _CharT, class _Traits, class _RT>
68140b57cec5SDimitry Andric    friend
68150b57cec5SDimitry Andric    basic_istream<_CharT, _Traits>&
68160b57cec5SDimitry Andric    operator>>(basic_istream<_CharT, _Traits>& __is,
68170b57cec5SDimitry Andric               piecewise_linear_distribution<_RT>& __x);
68180b57cec5SDimitry Andric};
68190b57cec5SDimitry Andric
68200b57cec5SDimitry Andrictemplate<class _RealType>
68210b57cec5SDimitry Andrictypename piecewise_linear_distribution<_RealType>::param_type &
68220b57cec5SDimitry Andricpiecewise_linear_distribution<_RealType>::param_type::operator=
68230b57cec5SDimitry Andric                                                       (const param_type& __rhs)
68240b57cec5SDimitry Andric{
68250b57cec5SDimitry Andric//  These can throw
68260b57cec5SDimitry Andric    __b_.reserve        (__rhs.__b_.size ());
68270b57cec5SDimitry Andric    __densities_.reserve(__rhs.__densities_.size());
68280b57cec5SDimitry Andric    __areas_.reserve    (__rhs.__areas_.size());
68290b57cec5SDimitry Andric
68300b57cec5SDimitry Andric//  These can not throw
68310b57cec5SDimitry Andric    __b_         = __rhs.__b_;
68320b57cec5SDimitry Andric    __densities_ = __rhs.__densities_;
68330b57cec5SDimitry Andric    __areas_     =  __rhs.__areas_;
68340b57cec5SDimitry Andric    return *this;
68350b57cec5SDimitry Andric}
68360b57cec5SDimitry Andric
68370b57cec5SDimitry Andric
68380b57cec5SDimitry Andrictemplate<class _RealType>
68390b57cec5SDimitry Andricvoid
68400b57cec5SDimitry Andricpiecewise_linear_distribution<_RealType>::param_type::__init()
68410b57cec5SDimitry Andric{
68420b57cec5SDimitry Andric    __areas_.assign(__densities_.size() - 1, result_type());
68430b57cec5SDimitry Andric    result_type _Sp = 0;
68440b57cec5SDimitry Andric    for (size_t __i = 0; __i < __areas_.size(); ++__i)
68450b57cec5SDimitry Andric    {
68460b57cec5SDimitry Andric        __areas_[__i] = (__densities_[__i+1] + __densities_[__i]) *
68470b57cec5SDimitry Andric                        (__b_[__i+1] - __b_[__i]) * .5;
68480b57cec5SDimitry Andric        _Sp += __areas_[__i];
68490b57cec5SDimitry Andric    }
68500b57cec5SDimitry Andric    for (size_t __i = __areas_.size(); __i > 1;)
68510b57cec5SDimitry Andric    {
68520b57cec5SDimitry Andric        --__i;
68530b57cec5SDimitry Andric        __areas_[__i] = __areas_[__i-1] / _Sp;
68540b57cec5SDimitry Andric    }
68550b57cec5SDimitry Andric    __areas_[0] = 0;
68560b57cec5SDimitry Andric    for (size_t __i = 1; __i < __areas_.size(); ++__i)
68570b57cec5SDimitry Andric        __areas_[__i] += __areas_[__i-1];
68580b57cec5SDimitry Andric    for (size_t __i = 0; __i < __densities_.size(); ++__i)
68590b57cec5SDimitry Andric        __densities_[__i] /= _Sp;
68600b57cec5SDimitry Andric}
68610b57cec5SDimitry Andric
68620b57cec5SDimitry Andrictemplate<class _RealType>
68630b57cec5SDimitry Andricpiecewise_linear_distribution<_RealType>::param_type::param_type()
68640b57cec5SDimitry Andric    : __b_(2),
68650b57cec5SDimitry Andric      __densities_(2, 1.0),
68660b57cec5SDimitry Andric      __areas_(1, 0.0)
68670b57cec5SDimitry Andric{
68680b57cec5SDimitry Andric    __b_[1] = 1;
68690b57cec5SDimitry Andric}
68700b57cec5SDimitry Andric
68710b57cec5SDimitry Andrictemplate<class _RealType>
68720b57cec5SDimitry Andrictemplate<class _InputIteratorB, class _InputIteratorW>
68730b57cec5SDimitry Andricpiecewise_linear_distribution<_RealType>::param_type::param_type(
68740b57cec5SDimitry Andric        _InputIteratorB __fB, _InputIteratorB __lB, _InputIteratorW __fW)
68750b57cec5SDimitry Andric    : __b_(__fB, __lB)
68760b57cec5SDimitry Andric{
68770b57cec5SDimitry Andric    if (__b_.size() < 2)
68780b57cec5SDimitry Andric    {
68790b57cec5SDimitry Andric        __b_.resize(2);
68800b57cec5SDimitry Andric        __b_[0] = 0;
68810b57cec5SDimitry Andric        __b_[1] = 1;
68820b57cec5SDimitry Andric        __densities_.assign(2, 1.0);
68830b57cec5SDimitry Andric        __areas_.assign(1, 0.0);
68840b57cec5SDimitry Andric    }
68850b57cec5SDimitry Andric    else
68860b57cec5SDimitry Andric    {
68870b57cec5SDimitry Andric        __densities_.reserve(__b_.size());
68880b57cec5SDimitry Andric        for (size_t __i = 0; __i < __b_.size(); ++__i, ++__fW)
68890b57cec5SDimitry Andric            __densities_.push_back(*__fW);
68900b57cec5SDimitry Andric        __init();
68910b57cec5SDimitry Andric    }
68920b57cec5SDimitry Andric}
68930b57cec5SDimitry Andric
68940b57cec5SDimitry Andric#ifndef _LIBCPP_CXX03_LANG
68950b57cec5SDimitry Andric
68960b57cec5SDimitry Andrictemplate<class _RealType>
68970b57cec5SDimitry Andrictemplate<class _UnaryOperation>
68980b57cec5SDimitry Andricpiecewise_linear_distribution<_RealType>::param_type::param_type(
68990b57cec5SDimitry Andric        initializer_list<result_type> __bl, _UnaryOperation __fw)
69000b57cec5SDimitry Andric    : __b_(__bl.begin(), __bl.end())
69010b57cec5SDimitry Andric{
69020b57cec5SDimitry Andric    if (__b_.size() < 2)
69030b57cec5SDimitry Andric    {
69040b57cec5SDimitry Andric        __b_.resize(2);
69050b57cec5SDimitry Andric        __b_[0] = 0;
69060b57cec5SDimitry Andric        __b_[1] = 1;
69070b57cec5SDimitry Andric        __densities_.assign(2, 1.0);
69080b57cec5SDimitry Andric        __areas_.assign(1, 0.0);
69090b57cec5SDimitry Andric    }
69100b57cec5SDimitry Andric    else
69110b57cec5SDimitry Andric    {
69120b57cec5SDimitry Andric        __densities_.reserve(__b_.size());
69130b57cec5SDimitry Andric        for (size_t __i = 0; __i < __b_.size(); ++__i)
69140b57cec5SDimitry Andric            __densities_.push_back(__fw(__b_[__i]));
69150b57cec5SDimitry Andric        __init();
69160b57cec5SDimitry Andric    }
69170b57cec5SDimitry Andric}
69180b57cec5SDimitry Andric
69190b57cec5SDimitry Andric#endif  // _LIBCPP_CXX03_LANG
69200b57cec5SDimitry Andric
69210b57cec5SDimitry Andrictemplate<class _RealType>
69220b57cec5SDimitry Andrictemplate<class _UnaryOperation>
69230b57cec5SDimitry Andricpiecewise_linear_distribution<_RealType>::param_type::param_type(
69240b57cec5SDimitry Andric        size_t __nw, result_type __xmin, result_type __xmax, _UnaryOperation __fw)
69250b57cec5SDimitry Andric    : __b_(__nw == 0 ? 2 : __nw + 1)
69260b57cec5SDimitry Andric{
69270b57cec5SDimitry Andric    size_t __n = __b_.size() - 1;
69280b57cec5SDimitry Andric    result_type __d = (__xmax - __xmin) / __n;
69290b57cec5SDimitry Andric    __densities_.reserve(__b_.size());
69300b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
69310b57cec5SDimitry Andric    {
69320b57cec5SDimitry Andric        __b_[__i] = __xmin + __i * __d;
69330b57cec5SDimitry Andric        __densities_.push_back(__fw(__b_[__i]));
69340b57cec5SDimitry Andric    }
69350b57cec5SDimitry Andric    __b_[__n] = __xmax;
69360b57cec5SDimitry Andric    __densities_.push_back(__fw(__b_[__n]));
69370b57cec5SDimitry Andric    __init();
69380b57cec5SDimitry Andric}
69390b57cec5SDimitry Andric
69400b57cec5SDimitry Andrictemplate<class _RealType>
69410b57cec5SDimitry Andrictemplate<class _URNG>
69420b57cec5SDimitry Andric_RealType
69430b57cec5SDimitry Andricpiecewise_linear_distribution<_RealType>::operator()(_URNG& __g, const param_type& __p)
69440b57cec5SDimitry Andric{
69450b57cec5SDimitry Andric    typedef uniform_real_distribution<result_type> _Gen;
69460b57cec5SDimitry Andric    result_type __u = _Gen()(__g);
69470b57cec5SDimitry Andric    ptrdiff_t __k = _VSTD::upper_bound(__p.__areas_.begin(), __p.__areas_.end(),
69480b57cec5SDimitry Andric                                      __u) - __p.__areas_.begin() - 1;
69490b57cec5SDimitry Andric    __u -= __p.__areas_[__k];
69500b57cec5SDimitry Andric    const result_type __dk = __p.__densities_[__k];
69510b57cec5SDimitry Andric    const result_type __dk1 = __p.__densities_[__k+1];
69520b57cec5SDimitry Andric    const result_type __deltad = __dk1 - __dk;
69530b57cec5SDimitry Andric    const result_type __bk = __p.__b_[__k];
69540b57cec5SDimitry Andric    if (__deltad == 0)
69550b57cec5SDimitry Andric        return __u / __dk + __bk;
69560b57cec5SDimitry Andric    const result_type __bk1 = __p.__b_[__k+1];
69570b57cec5SDimitry Andric    const result_type __deltab = __bk1 - __bk;
69580b57cec5SDimitry Andric    return (__bk * __dk1 - __bk1 * __dk +
69590b57cec5SDimitry Andric        _VSTD::sqrt(__deltab * (__deltab * __dk * __dk + 2 * __deltad * __u))) /
69600b57cec5SDimitry Andric        __deltad;
69610b57cec5SDimitry Andric}
69620b57cec5SDimitry Andric
69630b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
69640b57cec5SDimitry Andricbasic_ostream<_CharT, _Traits>&
69650b57cec5SDimitry Andricoperator<<(basic_ostream<_CharT, _Traits>& __os,
69660b57cec5SDimitry Andric           const piecewise_linear_distribution<_RT>& __x)
69670b57cec5SDimitry Andric{
69680b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__os);
6969*e8d8bef9SDimitry Andric    typedef basic_ostream<_CharT, _Traits> _OStream;
6970*e8d8bef9SDimitry Andric    __os.flags(_OStream::dec | _OStream::left | _OStream::fixed |
6971*e8d8bef9SDimitry Andric               _OStream::scientific);
69720b57cec5SDimitry Andric    _CharT __sp = __os.widen(' ');
69730b57cec5SDimitry Andric    __os.fill(__sp);
69740b57cec5SDimitry Andric    size_t __n = __x.__p_.__b_.size();
69750b57cec5SDimitry Andric    __os << __n;
69760b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
69770b57cec5SDimitry Andric        __os << __sp << __x.__p_.__b_[__i];
69780b57cec5SDimitry Andric    __n = __x.__p_.__densities_.size();
69790b57cec5SDimitry Andric    __os << __sp << __n;
69800b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
69810b57cec5SDimitry Andric        __os << __sp << __x.__p_.__densities_[__i];
69820b57cec5SDimitry Andric    __n = __x.__p_.__areas_.size();
69830b57cec5SDimitry Andric    __os << __sp << __n;
69840b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
69850b57cec5SDimitry Andric        __os << __sp << __x.__p_.__areas_[__i];
69860b57cec5SDimitry Andric    return __os;
69870b57cec5SDimitry Andric}
69880b57cec5SDimitry Andric
69890b57cec5SDimitry Andrictemplate <class _CharT, class _Traits, class _RT>
69900b57cec5SDimitry Andricbasic_istream<_CharT, _Traits>&
69910b57cec5SDimitry Andricoperator>>(basic_istream<_CharT, _Traits>& __is,
69920b57cec5SDimitry Andric           piecewise_linear_distribution<_RT>& __x)
69930b57cec5SDimitry Andric{
69940b57cec5SDimitry Andric    typedef piecewise_linear_distribution<_RT> _Eng;
69950b57cec5SDimitry Andric    typedef typename _Eng::result_type result_type;
69960b57cec5SDimitry Andric    __save_flags<_CharT, _Traits> __lx(__is);
6997*e8d8bef9SDimitry Andric    typedef basic_istream<_CharT, _Traits> _Istream;
6998*e8d8bef9SDimitry Andric    __is.flags(_Istream::dec | _Istream::skipws);
69990b57cec5SDimitry Andric    size_t __n;
70000b57cec5SDimitry Andric    __is >> __n;
70010b57cec5SDimitry Andric    vector<result_type> __b(__n);
70020b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
70030b57cec5SDimitry Andric        __is >> __b[__i];
70040b57cec5SDimitry Andric    __is >> __n;
70050b57cec5SDimitry Andric    vector<result_type> __densities(__n);
70060b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
70070b57cec5SDimitry Andric        __is >> __densities[__i];
70080b57cec5SDimitry Andric    __is >> __n;
70090b57cec5SDimitry Andric    vector<result_type> __areas(__n);
70100b57cec5SDimitry Andric    for (size_t __i = 0; __i < __n; ++__i)
70110b57cec5SDimitry Andric        __is >> __areas[__i];
70120b57cec5SDimitry Andric    if (!__is.fail())
70130b57cec5SDimitry Andric    {
70140b57cec5SDimitry Andric        swap(__x.__p_.__b_, __b);
70150b57cec5SDimitry Andric        swap(__x.__p_.__densities_, __densities);
70160b57cec5SDimitry Andric        swap(__x.__p_.__areas_, __areas);
70170b57cec5SDimitry Andric    }
70180b57cec5SDimitry Andric    return __is;
70190b57cec5SDimitry Andric}
70200b57cec5SDimitry Andric
70210b57cec5SDimitry Andric_LIBCPP_END_NAMESPACE_STD
70220b57cec5SDimitry Andric
70230b57cec5SDimitry Andric_LIBCPP_POP_MACROS
70240b57cec5SDimitry Andric
70250b57cec5SDimitry Andric#endif  // _LIBCPP_RANDOM
7026