// A few common random functions. (1.02)

#include <algorithm>
#include <experimental/iterator>
#include <random>
#include <iostream>
using namespace std;

static thread_local default_random_engine re_(random_device{}());

// Real in the range [0, 1).
double randreal() {
    uniform_real_distribution<double> pick(0, 1);
    return pick(re_);
}

// Integer in the range [lo, hi].
int randint(int lo, int hi) {
    uniform_int_distribution<> pick(lo, hi);
    return pick(re_);
}

// Boolean where probability of true is p and false is (1-p).
bool randbool(double p) {
    bernoulli_distribution pick(p);
    return pick(re_);
}

// Show.

template<typename Func, typename... Args>
void show(int n, Func f, Args... args) {
    generate_n(experimental::make_ostream_joiner(cout, " "), n,
               [=]{ return f(args...); });
    cout << endl;
}

int main() {
    show(10, randreal);
    show(10, randint, -5, 5);
    show(10, randbool, 0.5);
}