---------------
void user(vector<int>& v1, vector<int>& v2)
{
    copy(v1.begin(),v1.end(),v2.begin()); // ryzyko przepenienia v2
    sort(v1.begin(),v2.end());            // ups!
}
---------------
template<typename Cont>
void sort(Cont& c)
{
    static_assert(Range<Cont>(), "sort(): argument Cont nie jest zakresem");
    static_assert(Sortable<Iterator<Cont>>(), "sort(): argument Cont nie jest sortowalny");

    std::sort(begin(c),end(c));
}

template<typename Cont1, typename Cont2>
void copy(const Cont1& source , Cont2& target)
{
    static_assert(Range<Cont1>(), "copy(): argument Cont1 nie jest zakresem");
    static_assert(Range<Cont2>(), "copy(): argument Cont2 nie jest zakresem");
    if (target.size()<source.size()) throw out_of_range{"obiekt docelowy jest za may"};

    std::copy(source.begin(),source.end(),target.begin());
}
---------------
void user(vector<int>& v1, vector<int>& v2)
{
    copy(v1,v2); // przepenienia zostan wykryte
    sort(v1);
}
---------------
template<typename Cont, typename Pred>
vector<Value_type<Cont>*>
find_all(Cont& c, Pred p)
{
    static_assert(Range<Cont>(), "find_all(): argument Cont nie jest zakresem");
    static_assert(Predicate<Pred>(), "find_all(): argument Pred nie jest predykatem");

    vector<Value_type<Cont>*> res;
    for (auto& x : c)
        if (p(x)) res.push_back(&x);
    return res;
}
---------------
template<typename Iter>
void sort(Iter first, Iter last)
{
    //... sortowanie przy uyciu e1<e2...
}

template<typename Iter, typename Pred>
void sort(Iter first, Iter last, Pred pred)
{
    //... sortowanie przy uyciu pred(e1,e2)...
}
---------------
template<typename Ran, typename Pred = less<Value_type<Ran>>>  // uywa domylnego
                                                                // argumentu szablonowego
sort(Ran first, Ran last, Pred pred ={})
{
    //... uywa pred(x,y)...
}
---------------
bool pred(int);

auto p = find(b,e,pred);  // znajduje element pred czy stosuje predykat pred()? (to drugie)
---------------
using Predicate = bool(*)(int);

void f(vector<Predicate>& v1, vector<int>& v2)
{
    auto p1 = find(v1.begin(),v1.end(),pred);    // znajduje element o wartoci pred
    auto p2 = find_if(v2.begin(),v2.end(),pred); // liczy, dla ilu elementw pred() zwraca true
}
---------------
int n_even(vector<int>& v) // nie rb tego
    // liczy parzyste wartoci w v
{
    return find_if(v.begin(),v.end(),[](int& x) {++x; return x&1; });
}

---------------
void increment_all(vector<int>& v) // zwiksza kady element kontenera v
{
    for_each(v.begin(),v.end(), [](int& x) {++x;});
}

---------------
vector<double> scale(const vector<double>& val, const vector<double>& div)
{
    assert(val.size()<div.size());
    assert(all_of(div.begin(),div.end(),[](double x){ return 0<x; });

    vector res(val.size());
    for (int i = 0; i<val.size(); ++i)
        res[i] = val[i]/div[i];
    return res;
}

---------------
void f(const string& s)
{
    auto n_space = count(s.begin(),s.end(),' ');
    auto n_whitespace = count_if(s.begin(),s.end(),isspace);
    //...
}

---------------
void f(const string& s)
{
    auto p_space = find(s.begin(),s.end(),' ');
    auto p_whitespace = find_if(s.begin(),s.end(),isspace);
    //...
}
---------------
array<int> x = {1,3,4 };
array<int> y = {0,2,3,4,5};
void f()
{
    auto p = find_first_of(x.begin(),x.end(),y.begin(),y.end); // p = &x[1]
    auto q = find_first_of(p+1,x.end(),y.begin(),y.end());     // q = &x[2]
}

---------------
template<typename In, typename In2, typename Pred = equal_to<Value_type<In>>>
pair<In, In2> mismatch(In first, In last, In2 first2, Pred p ={})
{
    while (first != last && p(*first,*first2)) {
        ++first;
        ++first2;
    }
    return {first,first2};
}

---------------
string quote {"Po co si mczy z nauk, skoro niewiedz ma si od razu?"};

bool in_quote(const string& s)
{
    auto p = search(quote.begin(),quote.end(),s.begin(),s.end()); // znajduje s w cytacie
    return p!=quote.end();
}

void g()
{
    bool b1 = in_quote("skoro"); // b1 = true
    bool b2 = in_quote("sporo"); // b2 = false
}

---------------
template<typename In, typename Out, typename Op>
Out transform(In first, In last, Out res, Op op)
{
    while (first!=last)
        *res++ = op(*first++);
    return res;
}
---------------
void toupper(string& s) // ujednolica wielko liter
{
    transform(s.begin(),s.end(),s.begin(),toupper);
}

---------------
void f(list<Club>& lc, ostream& os)
{
    copy(lc.begin(),lc.end(),ostream_iterator<Club>(os));
}
---------------
void f(const vector<char>& vs, vector<char>& v)
{
    copy(vs.begin(),vs.end(),v.begin());        // moe nadpisa koniec v
    copy(vs.begin(),vs.end(),back_inserter(v)); // dodaje elementy z vs na kocu v
}
---------------
void f(list<int>&ld, int n, ostream& os)
{
    copy_if(ld.begin(),ld.end(),
        ostream_iterator<int>(os),
        [](int x) { return x>n); });
}

---------------
void f(list<string>& ls, vector<string>& vs)
{
    ls.sort(); // sortowanie listy (31.4.2)
    unique_copy(ls.begin(),ls.end(),back_inserter(vs));
}
---------------
void bad(vector<string>& vs)     // ostrzeenie: nie robi tego, na co wyglda!
{
    sort(vs.begin(),vs.end());   // sortuje wektor
    unique(vs.begin(),vs.end()); // eliminuje duplikaty (wcale nie!)
}
---------------
int main()
{
    string s ="abbcccde";
    auto p = unique(s.begin(),s.end());
    cout << s << ' ' << p-s.begin() << '\n';
}
---------------
abcdecde 5
---------------
template<typename C>
void eliminate_duplicates(C& c)
{
    sort(c.begin(),c.end());            // sortuje
    auto p = unique(c.begin(),c.end()); // kompaktuje
    c.erase(p,c.end());                 // zmniejsza
}

---------------
string s {"*CamelCase*IsUgly*"};
cout << s << '\n';                              // *CamelCase*IsUgly*
auto p = remove(s.begin(),s.end(),'*');
copy(s.begin(),p,ostream_iterator<char>{cout}); // CamelCaseIsUgly
cout << s << '\n';                              // CamelCaseIsUglyly*

---------------
void f(deque<Card>& dc, My_rand& r)
{
    random_shuffle(dc.begin(),dc.end(),r);
    //...
}

---------------
vector<char> v {'a','b','c'};
while(next_permutation(v.begin(),v.end()))
    cout << v[0] << v[1] << v[2] << ' ';

---------------
int v1[900];
array<int,900> v2;
vector v3;

void f()
{
    fill(begin(v1),end(v1),99);            // ustawia wszystkie elementy v1 na 99
    generate(begin(v2),end(v2),Randint{}); // ustawia na losowe wartoci (40.7)

    // zwraca 200 losowych liczb cakowitych z przedziau <0,100)
    generate_n(ostream_iterator<int>{cout},200,Urand{100}); // zobacz 40.7

    fill_n(back_inserter{v3},20,99);       // dodaje do v3 20 elementw o wartoci 99
}
---------------
vector<string> vs {"Breugel","El Greco","Delacroix","Constable"};
vector<string> vs2 {"Hals","Goya","Renoir","Turner"};
copy(vs.begin(),vs.end(),vs2.begin());               // OK
uninitialized_copy(vs.begin(),vs.end(),vs2.begin()); // wyciek!

---------------
void use(vector<int>& v, int*p)
{
    swap_ranges(v.begin(),v.end(),p); // zamienia wartoci
}

---------------
template<typename List>
void sort_list(List& lst)
{
    vector v {lst.begin(),lst.end()}; // inicjacja z lst
    sort(v);                          // sortowania kontenera (32.2)
    copy(v,lst);
}
---------------
void f(const vector<Book>& sales) // znajduje dziesi najpopularniejszych ksiek
{
    vector<Book> bestsellers(10);
    partial_sort_copy(sales.begin(),sales.end(),
        bestsellers.begin(),bestsellers.end(),
        [](const Book& b1, const Book& b2) { return b1.copies_sold()>b2.copies_sold(); });
    copy(bestsellers.begin(),bestsellers.end(),ostream_iterator<Book>{cout,"\n"});
}
---------------
vector<int> v;
for (int i=0; i<1000; ++i)
    v.push_back(randint(1000)); // 40.7
constexpr int n = 30;
nth_element(v.begin(),v.begin()+n,v.end());
cout << "n-ty: " << v[n] << '\n';
for (int i=0; i<n; ++i)
    cout << v[i] << ' ';
---------------
n-ty: 24
10 8 15 19 21 15 8 7 6 17 21 2 18 8 1 9 3 21 20 18 10 7 3 3 8 11 11 22 22 23
---------------
n-ty: 24
1 2 3 3 3 6 7 7 8 8 8 8 9 10 10 11 11 15 15 17 18 18 19 20 21 21 21 22 22 23
---------------
vector<string> vs = {"Helsinki","Copenhagen","Oslo","Stockholm"};
vector<char*> vcs = {"Helsinki","Copenhagen","Oslo","Stockholm"};

void use()
{
    sort(vs); // Zdefiniowaem zakresow wersj funkcji sort()
    sort(vcs);

    for (auto& x : vs)
        cout << x << ' '
    cout << '\n';
    for (auto& x : vcs)
        cout << x << ' ';
---------------
Copenhagen Helsinki Stockholm Oslo
Helsinki Copenhagen Oslo Stockholm
---------------
sort(vcs,[](const char*p, const char*q){ return strcmp(p,q)<0; });

---------------
void f(vector<int>& c)
{
    if (binary_search(c.begin(),c.end(),7)) { // czy w c znajduje si 7?
        //...
    }
    //...
}
---------------
void g(vector<int>& c)
{
    auto p = find(c.begin(),c.end(),7);        // zapewne wolne: O(N); c nie musi by posortowany
    auto q = lower_bound(c.begin(),c.end(),7); // zapewne szybkie: O(log(N)); c musi by posortowany
    //...
}

---------------
vector<int> v {3,1,4,2};
list<double> lst {0.5,1.5,2,2.5}; // lista lst jest uporzdkowana

sort(v.begin(),v.end());          // porzdkuje v

vector<double> v2;
merge(v.begin(),v.end(),lst.begin(),lst.end(),back_inserter(v2)); // czy v i lst w v2
for (double x : v2)
    cout << x << ", ";
---------------
0.5, 1, 1.5, 2, 2, 2.5, 3, 4,

---------------
string s1 = "qwertyasdfgzxcvb";
string s2 = "poiuyasdfg/.,mnb";
sort(s1.begin(),s1.end());          // algorytmy dziaajce na zbiorach wymagaj sekwencji posortowanych
sort(s2.begin(),s2.end());

string s3(s1.size()+s2.size(),'*'); // odoenie pamici na najwikszy moliwy wynik
cout << s3 << '\n';
auto up = set_union(s1.begin(),s1.end(),s2.begin(),s2.end(),s3.begin());
cout << s3 << '\n';
for (auto p = s3.begin(); p!=up; ++p) cout <<*p;
cout << '\n';

s3.assign(s1.size()+s2.size(),'+');
up = set_difference(s1.begin(),s1.end(),s2.begin(),s2.end(),s3.begin());
cout << s3 << '\n';
for (auto p = s3.begin(); p!=up; ++p) cout <<*p;
cout << '\n';
---------------
*******************************
,./abcdefgimnopqrstuvxyz*******
,./abcdefgimnopqrstuvxyz
ceqr tvwxz++++++++++++++++++++++
ceqr tvwxz
---------------
string s = "herewego";          // herewego
make_heap(s.begin(),s.end());   // worheege
pop_heap(s.begin(),s.end());    // rogheeew
pop_heap(s.begin(),s.end()-1);  // ohgeeerw
pop_heap(s.begin(),s.end()-2);  // hegeeorw

*(s.end()-3)='f';
push_heap(s.begin(),s.end()-2); // hegeefrw
*(s.end()-2)='x';
push_heap(s.begin(),s.end()-1); // xeheefgw
*(s.end()-1)='y';
push_heap(s.begin(),s.end());   // yxheefge
sort_heap(s.begin(),s.end());   // eeefghxy
reverse(s.begin(),s.end());     // yxhgfeee

---------------
template<typename In, typename In2>
bool lexicographical_compare(In first, In last, In2 first2, In2 last2)
{
    for (; first!=last && first2!=last2; ++first,++last) {
        if (*first<*first2)
            return true;  // <first,last) < <first2,last2)
        if (*first2<*first)
            return false; // <first2,last2) < <first,last)
    }
    return first==last && first2!=last2;  // <first,last) < <first2,last2), jeli <first,last) jest krtszy
}
---------------
string n1 {"10000"};
string n2 {"999"};

bool b1 = lexicographical_compare(n1.begin(),n1.end(),n2.begin(),n2.end());  // b1 == true

n1 = "Zebra";
n2 = "Aardvark";
bool b2 = lexicographical_compare(n1.begin(),n1.end(),n2.begin(),n2.end());  // b2 == false
---------------
int x = 7;
int y = 9;
++min(x,y);   // bd: wynikiem min(x,y) jest const int&
++min({x,y}); // bd: wynikiem min({x,y}) jest warto prawostronna (lista initializer_list jest niezmienna)
---------------
string s = "Large_Hadron_Collider";
auto p = minmax_element(s.begin(),s.end(),
                       [](char c1,char c2) { return toupper(c1)<toupper(c2); });
cout << "min==" <<*(p.first) << ' ' << "max==" <<*(p.second) << '\n';
---------------
min==a max==_