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