---------------
void f(double d, int i)
{
    char classification[numeric_limits<unsigned char>::max()];

    if (numeric_limits<unsigned char>::digits==numeric_limits<char>::digits ) {
        // typ char jest bez znaku
    }

    if (i<numeric_limits<shor t>::min() || numeric_limits<short>::max()<i) {
        // i nie mona zapisa w typie short bez utraty cyfr
    }

    if (0<d && d<numeric_limits<double>::epsilon()) d = 0;

    if (numeric_limits<Quad>::is_specialized) {
        // informacje o granicach s dostpne dla typu Quad
    }
}
---------------
template<typename T>
class numeric_limits {
public:
    static const bool is_specialized = false; // czy dostpne s informacje dla numeric_limits<T>?
    //... nieciekawe ustawienia domylne...
};
---------------
template<>
class numeric_limits<char> {
public:
    static const bool is_specialized = true; // tak, mamy informacje

    static const int digits = 7;             // liczba bitw (cyfr binarnych), nie liczc znakowego

    static const bool is_signed = true;      // w tej implementacji typ char ma znak
    static const bool is_integer = true;     // char jest typem cakowitoliczbowym

    static constexpr char min() noexcept { return -128; } // najmniejsza warto
    static constexpr char max() noexcept { return 127; }  // najwiksza warto

    // mnstwo deklaracji, ktre nie maj zwizku z typem char
};
---------------
template<>
class numeric_limits<float> {
public:
    static const bool is_specialized = true;

    static const int radix = 2;    // podstawa systemu liczbowego wykadnika
    static const int digits = 24;  // liczba cyfr podstawy systemu liczbowego w mantysie
    static const int digits10 = 9; // liczba cyfr podstawy dziesitnego systemu liczbowego w mantysie

    static const bool is_signed = true;
    static const bool is_integer = false;
    static const bool is_exact = false;

    static constexpr float min() noexcept { return 1.17549435E-38F; } // najmniejsza warto dodatnia
    static constexpr float max() noexcept { return 3.40282347E+38F; } // najwiksza warto dodatnia
    static constexpr float lowest() noexcept { return -3.40282347E+38F; } // najmniejsza warto

    static constexpr float epsilon() noexcept { return 1.19209290E-07F; }
    static constexpr float round_error() noexcept { return 0.5F; } // maksymalny bd zaokrglania

    static constexpr float infinity() noexcept { return /* jaka warto */; }

    static constexpr float quiet_NaN() noexcept { return /* jaka warto */; }
    static constexpr float signaling_NaN() noexcept { return /* jaka warto */; }
    static constexpr float denorm_min() noexcept { return min(); }

    static const int min_exponent = -125;
    static const int min_exponent10 = -37;
    static const int max_exponent = +128;
    static const int max_exponent10 = +38;

    static const bool has_infinity = true;
    static const bool has_quiet_NaN = true;
    static const bool has_signaling_NaN = true;
    static const float_denorm_style has_denorm = denorm_absent;
    static const bool has_denorm_loss = false;

    static const bool is_iec559 = true; // zgodnie z IEC-559
    static const bool is_bounded = true;
    static const bool is_modulo = false;
    static const bool traps = true;
    static const bool tinyness_before = true;

    static const float_round_style round_style = round_to_nearest;
};
---------------
void f()
{
    errno = 0; // kasuje stary stan bdu
    sqrt(-1);
    if (errno==EDOM) cerr << "Funkcja sqrt() nie dziaa na ujemnych argumentach";
    pow(numeric_limits<double>::max(),2);
    if (errno == ERANGE) cerr << "Wynik funkcji pow() jest za duy dla typu double";
}
---------------
template<typename Scalar>
class complex {
    // obiekt typu complex to para wartoci skalarnych, zasadniczo para wsprzdnych
    Scalar re, im;
public:
    complex(const Scalar & r = Scalar{}, const Scalar & i = Scalar{}) :re(r), im(i) { }

    Scalar real() const { return re; } // cz rzeczywista
    void real(Scalar r) { re=r; }

    Scalar imag() const { return im; } // cz urojona
    void imag(Scalar i) { im = i; }

    template<typename X>
        complex(const complex<X>&);

    complex<T>& operator=(const T&);
    complex& operator=(const complex&);
    template<typename X>
        complex<T>& operator=(const complex<X>&);

    complex<T>& operator+=(const T&);
    template<typename X>
        complex<T>& operator+=(const complex<X>&);

    // podobny kod dla operatorw -=, *=, /=
};
---------------
complex<float> z1 = 1.33333333333333333;  // zawenie
complex<double> z2 = 1.33333333333333333; // zawenie
z1=z2;                                    // zawenie
---------------
complex<float> z3 {1.33333333333333333};  // bd: konwersja zawajca
---------------
valarray<double> v0;             // do v0 mona przypisa pniej
valarray<float> v1(1000);        // 1000 elementw o wartoci float()==0.0F

valarray<int> v2(-1,2000);       // 2000 elementw o wartoci -1
valarray<double> v3(100,9.8064); // powany bd: zmiennoprzecinkowy rozmiar valarray

valarray<double> v4 = v3;        // v4 zawiera v3.size() elementw

valarray<int> v5 {-1,2000};      // dwa elementy
---------------
void f(const int* p, int n)
{
    const double vd[] = {0,1,2,3,4};
    const int vi[] = {0,1,2,3,4};

    valarray<double> v1{vd,4}; // 4 elementy: 0,1,2,3
    valarray<double> v2{vi,4}; // bd typu: vi nie jest wskanikiem do double
    valarray<double> v3{vd,8}; // niezdefiniowane: za mao elementw w inicjatorze
    valarray<int> v4{p,n};     // lepiej eby p wskazywa przynajmniej n liczb typu int
}

---------------
valarray<int> v {1,2,3,4,5,6,7,8};
v*=2; // v=={2,4,6,10,12,14,16}
v=7;  // v=={7,7,7,7,7,7,7,7}
---------------
void f(valarray<double>& v, valarray<double>& v2, double d)
{
    valarray<double> v3 = v*v2;   // v3[i] = v[i]*v2[i] dla wszystkich i
    valarray<double> v4 = v*d;    // v4[i] = v[i]*d dla wszystkich i
    valarray<double> v5 = d*v2;   // v5[i] = d*v2[i] dla wszystkich i
    valarray<double> v6 = cos(v); // v6[i] = cos(v[i]) dla wszystkich i
}
---------------
double incr(double d) { return d+1; }

void f(valarray<double>& v)
{
    valarray<double> v2 = v.apply(incr);  // tworzy zwikszony o jeden obiekt valarray
    //...
}
---------------
void f()
{
    int alpha[] = { 1, 2, 3, 4, 5 ,6, 7, 8 };
    valarray<int> v(alpha,8);         // 1, 2, 3, 4, 5, 6, 7, 8
    valarray<int> v2 = v.shift(2);    // 3, 4, 5, 6, 7, 8, 0, 0
    valarray<int> v3 = v<<2;          // 4, 8, 12, 16, 20, 24, 28, 32
    valarray<int> v4 = v.shift(-2);   // 0, 0, 1, 2, 3, 4, 5, 6
    valarray<int> v5 = v>>2;          // 0, 0, 0, 1, 1, 1, 1, 2
    valarray<int> v6 = v.cshift(2);   // 3, 4, 5, 6, 7, 8, 1, 2
    valarray<int> v7 = v.cshift(-2);  // 7, 8, 1, 2, 3, 4, 5, 6
}
---------------
void f(valarray<int> vi, valarray<double> vd)
{
    vi <<= 2; // vi[i]<<=2 dla wszystkich elementw vi
    vd <<= 2; // bd: przesunicie nie jest zdefiniowane dla typw zmiennoprzecinkowych
}
---------------
class std::slice {
    // indeks pocztkowy, dugo i krok
public:
    slice();               // slice{0,0,0}
    slice(size_t star t, size_t size , size_t stride);
    size_t start() const;  // indeks pierwszego elementu
    size_t size() const;   // liczba elementw
    size_t stride() const; // element n znajduje si na pozycji start()+n*stride()
};
---------------
valarray<int> v {
    {00,01,02,03}, // wiersz 0
    {10,11,12,13}, // wiersz 1
    {20,21,22,23}  // wiersz 2
};
---------------
for (int x : v) cout << x << ' ' ;
---------------
0 1 2 3 10 11 12 13 20 21 22 23
---------------
template<typename T>
class Slice_iter {
    valarray<T>* v;
    slice s;
    size_t curr; // indeks biecego elementu

    T& ref(size_t i) const { return (*v)[s.start()+i*s.stride()]; }
public:
    Slice_iter(valarray<T>* vv, slice ss, size_t pos =0)
        :v{vv}, s{ss}, curr{pos} { }

    Slice_iter end() const { return {v,s,s.size()}; }

    Slice_iter& operator++() { ++curr; return* this; }
    Slice_iter operator++(int) { Slice_iter t = *this; ++curr; return t; }

    T& operator[](size_t i) { return ref(i); } // indeks w stylu C
    T& operator()(size_t i) { return ref(i); } // indeks w stylu Fortrana
    T& operator*() { return ref(curr); }       // biecy element

    bool operator==(const Slice_iter& q) const
    {
        return curr==q.curr && s.stride()==q.s.stride() && s.start()==q.s.start();
    }

    bool operator!=(const Slice_iter& q ) const
    {
        return !(*this==q);
    }

    bool operator<(const Slice_iter& q) const
    {
        return curr<q.curr && s.stride()==q.s.stride() && s.start()==q.s.start();
    }
};

---------------
void f(valarray<double>& d)
{
    slice_array<double>& v_even = d[slice(0,d.size()/2+d.size()%2,2)];
    slice_array<double>& v_odd = d[slice(1,d.size()/2,2)];

    v_even *= v_odd; // mnoy pary elementw i zapisuje wyniki w parzystych elementach
    v_odd = 0;       // przypisuje 0 do kadego nieparzystego elementu d
}
---------------
slice_array<double> row(valarray<double>& d, int i)
{
    slice_array<double> v = d[slice(0,2,d.size()/2)];
    //...
    return d[slice(i%2,i,d.size()/2)];
}
---------------
class std::gslice {
    // zamiast jednego kroku i jednego rozmiaru gslice zawiera n krokw i n rozmiarw
public:
    gslice();
    gslice(size_t sz, const valarray<size_t>& lengths, const valarray<size_t>& strides);

    size_t start() const;            // indeks pierwszego elementu
    valarray<size_t> size() const;   // liczba elementw w wymiarze
    valarray<size_t> stride() const; // krok dla index[0], index[1] ...
};
---------------
size_t gslice_index(const gslice& s, size_t i, size_t j) // odwzorowuje (i,j) na odpowiadajcy im indeks
{
    return s.start()+i*s.stride()[0]+j*s.stride()[1];
}

valarray<size_t> lengths {2,3}; // 2 elementy w pierwszym wymiarze
                                // 3 elementy w drugim wymiarze
valarray<size_t> strides {3,1}; // krok w pierwszym indeksie to 3
                                // krok w drugim indeksie to 1

void f()
{
    gslice s(0,lengths,strides);

    for (int i=0; i<3; ++i)     // dla kadego wiersza
        for (int j=0; j<2; ++j) // dla kadego elementu w wierszu
            cout << "(" << i << "," << j << ")->" << gslice_index(s,i,j) << "; "; // drukuje 
                                                                                  // odwzorowanie
}
---------------
(0,0)->0; (0,1)->1; (1,0)->3; (1,1)->4; (2,0)->6; (2,1)->7
---------------
void f(valarray<float>& v)
{
    gslice m(0,lengths,strides);
    v[m] = 0; // przypisuje 0 do v[0],v[1],v[3],v[4],v[6],v[7]
}

---------------
template<typename In, typename T>
T accumulate(In first, In last, T init)
{
    for (; first!=last; ++first) // dla wszystkich elementw w <first,last)
        init = init + *first;    // plus
    return init;
}
---------------
void f(vector<int>& price, list<float>& incr)
{
    int i = accumulate(price.begin(),price.end(),0); // akumulacja w int
    double d = 0;
    d = accumulate(incr.begin(),incr.end(),d);       // akumulacja w double

    int prod = accumulate(price.begin,price.end(),1,[](int a, int b) { return a*b; });
    //...
}
---------------
struct Record {
    //...
    int unit_price;
    int number_of_units;
};

long price(long val, const Record& r)
{
    return val + r.unit_price * r.number_of_units;
}
void f(const vector<Record>& v)
{
    cout << "Ostateczna warto: " << accumulate(v.begin(),v.end(),0,price) << '\n';
}
---------------
template<typename In, typename In2, typename T>
T inner_product(In first, In last, In2 first2, T init)
{
    while (first != last)
        init = init + *first++ * *first2++;
    return init;
}

template<typename In, typename In2, typename T, typename BinOp, typename BinOp2>
T inner_product(In first, In last, In2 first2, T init, BinOp op, BinOp2 op2)
{
    while (first != last)
        init = op(init,op2(*first++,*first2++));
    return init;
}
---------------
valarray<double> operator*(const Matrix& m, valarray<double>& v)
{
    valarray<double> res(m.dim2());

    for (size_ti=0;i<m.dim2(); i++) {
        auto& ri = m.row(i);
        res[i] = inner_product(ri,ri.end(),&v[0],double(0));
    }
    return res;
}

valarray<double> operator*(valarray<double>& v, const Matrix& m)
{
    valarray<double> res(m.dim1());

    for (size_ti=0;i<m.dim1(); i++) {
        auto& ci = m.column(i);
        res[i] = inner_product(ci,ci.end(),&v[0],double(0));
    }
    return res;
}
---------------
vector<double> temps;

void f()
{
    adjacent_difference(temps.begin(),temps.end(),temps.begin());
}
---------------
template<typename In, typename Out, typename BinOp>
Out partial_sum(In first, In last, Out res, BinOp op)
{
    if (first==last) return res;
    *res = *first;
    T val = *first;
    while (++first != last) {
        val = op(val,*first);
        *++res = val;
    }
    return ++res;
}

template<typename In, typename Out>
Out partial_sum(In first, In last, Out res)
{
    return partial_sum(first,last,res,plus);  // uycie std::plus (33.4)
}
---------------
void f()
{
    partial_sum(temps.begin(),temps.end(),temps.begin());
}
---------------
partial_sum(v.begin(),v.end(),v.begin());
---------------
adjacent_difference(v.begin(),v.end(),v.begin());
---------------
vector<int> v(5);
iota(v.begin(),v.end(),50);
vector<int> v2 {50,51,52,53,54};

if (v!=v2)
    error("poskar si dostawcy implementacji");
---------------
auto gen = bind(normal_distribution<double>{15,4.0},default_random_engine{});

for (int i=0; i<500; ++i) cout << gen();
---------------
3 **
4 *
5 *****
6 ****
7 ****
8 ******
9 ************
10 ***************************
11 ***************************
12 **************************************
13 **********************************************************
14 ***************************************************
15 *******************************************************
16 ********************************
17 **************************************************
18 *************************************
19 **********************************
20 ***************
21 ************
22 ************
23 *******
24 *****
25 ****
26 *
27 *
---------------
void test()
{
    Rand_int ri {10,20};     // rwnomierny rozkad liczb typu int w przedziale <10,20>
    Rand_double rd {0,0.5};  // rwnomierny rozkad liczb typu double w przedziale <0,0.5)

    for (int i=0; i<100; ++i)
        cout << ri() << ' ';
    for (int i=0; i<100; ++i)
        cout << rd() << ' ';
}
---------------
class Rand_int {
public:
    Rand_int(int lo, int hi) : p{lo,hi} { } // przechowuje parametry
    int operator()() const { return r(); }
private:
    uniform_int_distribution<>::param_type p;
    auto r = bind(uniform_int_distribution<>{p},default_random_engine{});
};
---------------
class Rand_double {
public:
    Rand_double(double low, double high)
        :r(bind(uniform_real_distribution<>(low,high),default_random_engine())) { }
    double operator()() { return r(); }
private:
    function<double()> r;
};
---------------
template<typename Iter, typename Size, typename Out, typename Gen>
Out random_sample(Iter first, Iter last, Out result, Size n, Gen&& gen)
{
    using Dist = uniform_int_distribution<Size>;
    using Param = typename Dist::param_type;

    // znajduje zbiornik i przesuwa first do przodu:
    copy(first,n,result);
    advance(first,n);

    // prbkuje pozostae wartoci w przedziale <first+n,last), wybierajc losow
    // liczb r z przedziau <0:k> i jeli r<n, zamienia j
    // warto k jest zwikszana w kadej iteracji, co zmniejsza prawdopodobiestwo
    // dla iteratorw o dostpie swobodnym, k = i-first (przy zaoeniu, e zwiksza si i, ale nie first)

    Dist dist;
    for (Size k=n;first!=last; ++first,++k) {
        Size r = dist(gen,Param{0,k});
        if(r < n)
            *(result + r) = *first;
    }
    return result;
}

---------------
map<int,int> m;
linear_congruential_engine<unsigned int,17,5,0> linc_eng;
for (int i=0; i<1000000; ++i)
    if (1<++m[linc_eng()]) cout << i << '\n';

---------------
independent_bits_engine<default_random_engine ,4,unsigned int> ibe;
for (int i=0; i<100; ++i)
    cout << '0'+ibe() << ' ';
---------------
using minstd_rand0 = linear_congruential_engine<uint_fast32_t, 16807, 0, 2147483647>;
using minstd_rand = linear_congruential_engine<uint_fast32_t, 48271, 0, 2147483647>;
using mt19937 = mersenne_twister_engine<uint_fast32_t, 32,624,397,
                      31,0x9908b0df,
                      11,0xffffffff,
                      7,0x9d2c5680,
                      15,0xefc60000,
                      18,1812433253>
using mt19937_64 = mersenne_twister_engine<uint_fast64_t, 64,312,156,
                      31,0xb5026f5aa96619e9,
                      29, 0x5555555555555555,
                      17, 0x71d67fffeda60000,
                      37, 0xfff7eee000000000,
                      43, 6364136223846793005>;
using ranlux24_base = subtract_with_carry_engine<uint_fast32_t, 24, 10, 24>;
using ranlux48_base = subtract_with_carry_engine<uint_fast64_t, 48, 5, 12>;
using ranlux24 = discard_block_engine<ranlux24_base, 223, 23>;
using ranlux48 = discard_block_engine<ranlux48_base, 389, 11>;
using knuth_b = shuffle_order_engine<minstd_rand0,256>;

---------------
uniform_int_distribution<int> uid1 {1,100}; // OK
uniform_int_distribution<int> uid2 {100,1}; // bd: a>b
---------------
uniform_real_distribution<double> urd1 {};      // uywa a==0.0 i b==1.0
uniform_real_distribution<double> urd2 {10,20}; // uywa a==10.0 i b==20.0
uniform_real_distribution<> urd3 {};            // uywa double ia==0.0 i b==1.0
---------------
uniform_int_distribution<> uid3 {0,5};
default_random_engine e;
for (int i=0; i<20; ++i)
    cout << uid3(e) << ' ';
---------------
2 0 2 5 4 1 5 5 0 1 1 5 0 0 5 0 3 4 1 4
---------------
#define RAND_MAX implementation_defined /* dua dodatnia liczba cakowita */

int rand();                 // liczba pseudolosowa z przedziau od 0 do RAND_MAX
void srand(unsigned int i); // podanie ziarna i do generatora liczb losowych