---------------
template<typename T, typename A = allocator<T>>
class vector {
    //...
};
---------------
template<typename Ran>
    void sort(Ran first, Ran last);          // uywa < do porwnywania
template<typename Ran, typename Cmp>
    void sort(Ran first, Ran last, Cmp cmp); // uywa cmp
---------------
class Nocase { // porwnywanie acuchw bez rozrniania wielkoci liter
public:
    bool operator()(const string&, const string&) const;
};

bool Nocase::operator()(const string& x, const string& y) const
    // zwraca true, jeli x jest leksykograficznie mniejszy ni y, nie uwzgldniajc wielkoci liter
{
    auto p = x.begin();
    auto q = y.begin();

    while (p!=x.end() && q!=y.end() && toupper(*p)==toupper(*q)) {
        ++p;
        ++q;
    }
    if (p == x.end()) return q != y.end();
    if (q == y.end()) return false;
    return toupper(*p) < toupper(*q);
}
---------------
owoce:
jabko gruszka Jabko Gruszka cytryna
---------------
owoce:
cytryna Gruszka gruszka Jabko jabko
---------------
owoce:
Gruszka Jabko cytryna gruszka jabko
---------------
struct Cstring_less {
    bool operator()(const char* p, const char* q) const { return strcmp(p,q)<0; }
};

map<char*,int,Cstring_less> m; // sownik wykorzystujcy strcmp() do porwnywania kluczy const char*
---------------
if (x == y)                  // nie wykonywane, gdy uytkownik dostarczy porwnywanie
if (!cmp(x,y) && !cmp(y,x))  // wykonywane, gdy uytkownik dostarczy porwnanie cmp
---------------
void use()
{
    vector<int> vi {1,3,5,7,9}; // wektor inicjowany picioma liczbami cakowitymi
    vector<string> vs(7);       // wektor inicjowany siedmioma pustymi acuchami

    vector<int> vi2;
    vi2 = {2,4,6,8};            // przypisanie sekwencji czterech liczb cakowitych do vi2
    vi2.assign(&vi[1],&vi[4]);  // przypisanie sekwencji 3,5,7 do vi2

    vector<string> vs2;
    vs2 = {"Mapka", "Mapka i abka"};                     // przypisanie dwch acuchw do vs2
    vs2.assign("Niedwied", "Stary niedwied mocno pi"); // bd wykonawczy
}
---------------
void task(vector<int>&& v);

vector<int> user(vector<int>& large)
{
    vector<int> res;
    //...
    task(move(large)); // przekazuje prawa wasnoci do danych do task()
    //...
    return res;
}
---------------
for (auto& x : v) // niejawne uycie v.begin() i v.end()
    cout << x << '\n';
---------------
for (auto p = v.begin(); p!=v.end(); ++p) {
    if (p!=v.begin() &&*(p-1)==*p)
        cout << "powielenie " << *p << '\n';
---------------
for (auto p = v.cbegin(); p!=v.cend(); ++p) { // uycie iteratorw staych
    if (p!=v.cbegin() &&*(p-1)==*p)
        cout << "powielenie " << *p << '\n';
}
---------------
auto beg = v.cbegin();
auto end = v.cend();

for (auto p = beg; p!=end; ++p) {
    if (p!=beg &&*(p-1)==*p)
        cout << "powielenie " << *p << '\n';
}
---------------
vector<complex<double>> vc;
for (double re,im; cin>>re>>im; ) // wczytuje dwie liczby typu double
    vc.emplace_back(re,im);       // dodaje complex<double>{re,im} na kocu
---------------
vector<int> v {4,3,5,1};
auto p = v.begin()+2;   // wskazuje element v[2], czyli 5
v.push_back(6);         // p staje si bezuyteczny; v == {4,3,5,1,6}
p = v.begin()+2;        // wskazuje element v[2], czyli 5
auto p2 = v.begin()+4;  // p2 wskazuje element v[4], czyli 6
v.erase(v.begin()+3);   // v == {4,3,5,6}; p jest nadal przydatny; p2 jest nieprzydatny
---------------
void user(list<pair<string,double>>& lst)
{
    auto p = lst.begin();
    while (p!=lst.end()&& p->first!="Dania")            // znajduje miejsce wstawiania
        /* nic nie robi */;
    p=lst.emplace(p,"Anglia",7.5);                      // zwize i eleganckie
    p=lst.insert(p,make_pair("Francja",9.8));           // funkcja pomocnicza
    p=lst.insert(p,pair<string,double>{"Grecja",3.14}); // rozwleke
}
---------------
template<typename T, typename Allocator = allocator<T>>
class vector {
public:
    using reference = value_type&;
    using const_reference = const value_type&;
    using iterator = /* zalene od implementacji */;
    using const_iterator = /* zalene od implementacji */;
    using size_type = /* zalene od implementacji */;
    using difference_type = /* zalene od implementacji */;
    using value_type = T;
    using allocator_type = Allocator;
    using pointer = typename allocator_traits<Allocator>::pointer;
    using const_pointer = typename allocator_traits<Allocator>::const_pointer;
    using reverse_iterator = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
    //...
};
---------------
vector<char> chars;  // bufor wejciowy na znaki
constexpr int max = 20000;
chars.reserve(max);
vector<char*> words; // wskaniki do pocztkw sw

bool in_word = false;
for (char c; cin.get(c); ) {
    if (isalpha(c)) {
        if (!in_word) {         // znaleziono pocztek sowa
            in_word = true;
            chars.push_back(0); // koniec poprzedniego sowa
            chars.push_back(c);
            words.push_back(&chars.back());
        }
        else
            chars.push_back(c);
    }
    else
        in_word = false;
}
if (in_word)
    chars.push_back(0); // koniec ostatniego sowa

if (max<chars.size()) { // ups: rozmiar wektora chars przekroczy pojemno; sowa s niepoprawne
    //...
}
chars.shrink_to_fit();  // zwolnienie nadmiarowej pojemnoci
---------------
void read()
{
    array<int,MAX> a;
    for (auto& x : a)
        cin.get(&x);
}
---------------
void use()
{
    list<int> lst {2,3,2,3,5};
    lst.remove(3);              // lst zawiera teraz {2,2,5}
    lst.unique();               // lst zawiera teraz {2,5}
    cout << lst.size() << '\n'; // drukuje 2
}

---------------
list<int> lst1 {1,2,3};
list<int> lst2 {5,6,7};

auto p = lst1.begin();
++p; // p wskazuje 2

auto q = lst2.begin();
++q; // q wskazuje 6

lst1.splice(p,lst2); // lst1 to teraz {1,5,6,7,2,3}; lst2 to {}
                     // p nadal wskazuje 2, a q wskazuje 6

---------------
template<typename Key,
    typename T,
    typename Compare = less<Key>,
    typename Allocator = allocator<pair<const Key, T>>>
class map {
public:
    using key_type = Key;
    using mapped_type = T;
    using value_type = pair<const Key, T>;
    using key_compare = Compare;
    using allocator_type = Allocator;
    using reference = value_type&;
    using const_reference = const value_type&;
    using iterator = /* zaley od implementacji */;
    using const_iterator = /* zaley od implementacji */;
    using size_type = /* zaley od implementacji */;
    using difference_type = /* zaley od implementacji */;
    using pointer = typename allocator_traits<Allocator>::pointer;
    using const_pointer = typename allocator_traits<Allocator>::const_pointer;
    using reverse_iterator = std::reverse_iterator<iterator>;
    using const_reverse_iterator = std::reverse_iterator<const_iterator>;
    class value_compare { /* operator()(k1,k2) wykonuje key_compare()(k1,k2)*/};
    //...
};
---------------
map<string,pair<Coordinate ,Coordinate>> locations
{
    {"Kopenhaga",{"55:40N","12:34E"}},
    {"Rzym",{"41:54N","12:30E"}},
    {"Nowy Jork",{"40:40N","73:56W"}
};
---------------
map<string,string> dictionary;

dictionary["morze"]="duo wody";  // wstawienie lub przypisanie do elementu

cout << dictionary["foka"];       // odczytanie wartoci
---------------
auto q = dictionary.find("foka");  // szuka, nie wstawia

if (q==dictionary.end()) {
    cout << "nie znaleziono pozycji";
    dictionary.insert(make_pair("foka","lubi ryby"));
}
else
    cout q->second;
---------------
dictionary.emplace("krowa morska","wygina");
---------------
multimap<string,int> mm {{"apple",2}, { "pear",2}, {"apple",7}, {"orange",2}, {"apple",9}};
const string k {"apple"};
auto pp = mm.equal_range(k);
    if (pp.first==pp.second)
cout << "brak elementu o wartoci '" << k << "'\n";
else {
    cout << "elementy o wartoci '" << k << "':\n";
    for (auto p=pp.first; p!=pp.second; ++p)
        cout << p->second << ' ';
}
---------------
auto pp = make_pair(m.lower_bound(),m.upper_bound());
//...
---------------
struct Record {
    string label;
    int value;
};
---------------
bool operator<(const Record& a, const Record& b)
{
    return a.label<b.label;
}
---------------
set<Record> mr {{"duck",10}, {"pork",12}};

void read_test()
{
    for (auto& r : mr) {
        cout << '{' << r.label << ':' << r.value << '}';
    }
    cout << endl;
}
---------------
void modify_test()
{
    for (auto& r : mr)
        ++r.value; // bd: elementy zbioru s niezmienne
}
---------------
unordered_map<string,int> score1 {
    {"andrzej", 7}, {"robert",9}, {"wojtek",-3}, {"barbara",12}
};

map<string,int> score2 {
    {"andrzej", 7}, {"robert",9}, {"wojtek",-3}, {"barbara",12}
};

template<typename X, typename Y>
ostream& operator<<(ostream& os, const pair<X,Y>& p)
{
    return os << '{' << p.first << ',' << p.second << '}';
}

void user()
{
    cout <<"nieuporzdkowany: ";
    for (const auto& x : score1)
        cout << x << ", ";

    cout << "\nuporzdkowany: ";
    for (const auto& x : score2)
        cout << x << ", ";
}
---------------
nieuporzdkowany: {andrzej,7}, {robert,9}, {wojtek,-3}, {barbara,12},
uporzdkowany: {andrzej,9}, {robert, 7}, {wojtek,-3}, {barbara,12},
---------------
template<typename Key,
    typename T,
    typename Hash = hash<Key>,
    typename Pred = std::equal_to<Key>,
    typename Allocator = std::allocator<std::pair<const Key, T>>>
class unordered_map {
public:
    using key_type = Key;
    using value_type = std::pair<const Key, T>;
    using mapped_type = T;
    using hasher = Hash;
    using key_equal = Pred;
    using allocator_type = Allocator;
    using pointer = typename allocator_traits<Allocator>::pointer;
    using const_pointer= typename allocator_traits<Allocator>::const_pointer;
    using reference = value_type&;
    using const_reference = const value_type&
    using size_type = /* zalene od implementacji */;
    using difference_type = /* zalene od implementacji */;
    using iterator = /* zalene od implementacji */;
    using const_iterator = /* zalene od implementacji */;
    using local_iterator = /* zalene od implementacji */;
    using const_local_iterator = /* zalene od implementacji */;
    //...
};

---------------
map<string,int> m {My_comparator};        // OK
unordered_map<string,int> um {My_hasher}; // bd
---------------
unordered_map<string,int> um {100,My_hasher}; // OK
---------------
struct Record {
    string name;
    int val;
};
---------------
struct Nocase_hash {
    int d = 1; // przesuwa kod d o pewn liczb bitw w kadej iteracji
    size_t operator()(const Record& r) const
    {
        size_th=0;
        for (auto x : r.name) {
            h <<= d;
            h ^= toupper(x);
        }
        return h;
    }
};

struct Nocase_equal {
    bool operator()(const Record& r,const Record& r2) const
    {
        if (r.name.size()!=r2.name.size()) return false;
        for (int i = 0; i<r.name.size(); ++i)
            if (toupper(r.name[i])!=toupper(r2.name[i]))
                return false;
        return true;
    }
};
---------------
unordered_set<Record,Nocase_hash,Nocase_equal> m {
    { {"andrzej", 7}, {"robert",9}, {"wojtek",-3}, {"barbara",12} },
    20, /* liczba kubekw */
    Nocase_hash{2},
    Nocase_equal{}
};

for (auto r : m)
    cout << "{" << r.name << ',' << r.val << "}\n";
---------------
unordered_set<Record,Nocase_hash,Nocase_equal> m {
    {"andrzej", 7}, {"robert",9}, {"wojtek",-3}, {"barbara",12}
    // uycie 4 kubekw, Nocase_hash{} oraz Nocase_equal{}
};
---------------
size_t hf(const Record& r) { return hash<string>()(r.name)^hash<int>()(r.val); };

bool eq (const Record& r, const Record& r2) { return r.name==r2.name && r.val==r2.val; };
---------------
unordered_set<Record,decltype(&hf),decltype(&eq)> m {
    { {"andrzej", 7}, {"robert",9}, {"wojtek",-3}, {"barbara",12} },
    20, /* liczba kubekw */
    hf,
    eq
};

for (auto r : m)
    cout << "{" << r.name << ',' << r.val << "}\n";
}
---------------
unordered_set<Record,decltype(&hf),decltype(&eq)> m {10,hf,eq};
---------------
unordered_set<Record,                                 // typ wartoci
         function<size_t(const Record&)>,             // typ funkcji mieszajcej
         function<bool(const Record&,const Record&)>  // typ funkcji porwnujcej
     >m{10,
      [](const Record& r) { return hash<string>{}(r.name)^hash<int>{}(r.val); },
      [](const Record& r, const Record& r2) { return r.name==r2.name && r.val==r2.val; }
};
---------------
auto hf = [](const Record& r) { return hash<string>()(r.name)^hash<int>()(r.val); };
auto eq = [](const Record& r, const Record& r2) { return r.name==r2.name && r.val==r2.val; };

unordered_set<Record,decltype(hf),decltype(eq)> m {10,hf,eq};
---------------
namespace std {
    template<>
    struct hash<Record>{
        size_t operator()(const Record &r) const
        {
            return hash<string>{}(r.name)^hash<int>{}(r.val);
        }
    };

    template<>
    struct equal_to<Record> {
        bool operator()(const Record& r, const Record& r2) const
        {
            return r.name==r2.name && r.val==r2.val;
        }
    };
}

unordered_set<Record> m1;
unordered_set<Record> m2;
---------------
unordered_set<Record,[](const Record& r) { return hash(r.name); }> people;
//...
constexpr int expected = 1000000; // oczekiwana maksymalna liczba elementw
people.max_load_factor(0.7);      // stopie zapenienia przynajmniej 70%
people.reserve(expected);         // okoo 1 430 000 kubekw
---------------
template<typename T, typename C = deque<T>>
class stack {  // iso.23.6.5.2
public:
    using value_type = typename C::value_type;
    using reference = typename C::reference;
    using const_reference = typename C::const_reference;
    using size_type = typename C::size_type;
    using container_type = C;
public:
    explicit stack(const C&);  // kopiuje z kontenera
    explicit stack(C&& = C{}); // przenosi z kontenera

    // domylne kopiowanie, przeniesienie, przypisanie i destruktor

    template<typename A>
        explicit stack(const A& a);    // domylny kontener, alokator a
    template<typename A>
        stack(const C& c, const A& a); // elementy z c, alokator a
    template<typename A>
        stack(C&&, const A&);
    template<typename A>
        stack(const stack&, const A&);
    template<typename A>
        stack(stack&&, const A&);

    bool empty() const { return c.empty(); }
    siz e_type size() const { return c.size(); }
    reference top() { return c.back(); }
    const_reference top() const { return c.back(); }
    void push(const value_type& x) { c.push_back(x); }
    void push(value_type&& x) { c.push_back(std::move(x)); }
    void pop() { c.pop_back(); } // usuwa ostatni element

    template<typename... Args>
    void emplace(Args&&... args)
    {
        c.emplace_back(std::forward<Args>(args)...);
    }

    void swap(stack& s) noexcept(noexcept(swap(c, s.c)))
    {
        using std::swap;  // pamitaj, by uy standardowej funkcji swap()
        swap(c,s.c);
    }
protected:
    Cc;
};
---------------
stack<char> s1;            // przechowuje elementy w deque<char>
stack<int,vector<int>> s2; // przechowuje elementy w vector<int>
---------------
void f()
{
    stack<int> s;
    s.push(2);
    if (s.empty()) { // niedopenieniu mona zapobiec
        // nie usuwa
    }
    else {           // ale jest ono moliwe
        s.pop();     // w porzdku: s.size() wynosi 0
        s.pop();     // nie wiadomo, jaki bdzie tego skutek, ale pewnie nieprzyjemny
    }
}
---------------
void f(stack<char>& s)
{
    if (s.top()=='c') s.pop(); // opcjonalnie usuwa opcjonalne pocztkowe 'c'
    //...
}
---------------
template<typename T, typename C = deque<T> >
class queue { // iso.23.6.3.1
    //... jak stos ...
    void pop() { c.pop_front(); } // pobiera pierwszy element
};
---------------
void server(queue<Message>& q, mutex& m)
{
    while (!q.empty()) {
        Message mess;
        { lock_guard<mutex> lck(m);  // blokada na czas pobierania wiadomoci
          if (q.empty()) return;     // kto inny otrzyma wiadomo
              mess = q.front();
              q.pop();
        }
        // obsuga dania
    }
}
---------------
template<typename T, typename C = vector<T>, typename Cmp = less<typename C::value_type>>
class priority_queue { // iso.23.6.4
protected:
    Cc;
    Cmp comp;
public:
    priority_queue(const Cmp& x, const C&);
    explicit priority_queue(const Cmp& x = Cmp{}, C&& = C{});
    template<typename In>
    priority_queue(In b, In e, const Cmp& x, const C& c); // wstawia <b,e) do c
    //...
};
---------------
struct Message {
    int priority;
    bool operator<(const Message& x) const { return priority < x.priority; }
    //...
};

void server(priority_queue<Message>& q, mutex& m)
{
    while (!q.empty()) {
        Message mess;
        { lock_guard<mutex> lck(m);  // blokada na czas pobierania komunikatu
          if (q.empty()) return;     // kto inny otrzyma wiadomo
          mess = q.top();
          q.pop();
        }
        // obsuga dania o najwyszym priorytecie
    }
}