---------------
class complex {
    double re, im; // reprezentacja: dwie liczby typu double public:
    complex(double r, double i) :re{r}, im{i} {} // tworzy liczb zespolon z dwch skalarw
    complex(double r) :re{r}, im{0} {}           // tworzy liczb zespolon z jednego skalara
    complex() :re{0}, im{0} {}                   // domylna warto: {0,0}

    double real() const { return re; }
    void real(double d) { re=d; }
    double imag() const { return im; }
    void imag(double d) { im=d; }

    complex& operator+=(complex z) { re+=z.re , im+=z.im; return*this; } // dodaje do re i im
                                                                         // i zwraca wynik

    complex& operator-=(complex z) { re-=z.re , im-=z.im; return*this; }
    complex& operator*=(complex); // zdefiniowane gdzie poza klas
    complex& operator/=(complex); // zdefiniowane gdzie poza klas
};
---------------
complex operator+(complex a, complex b) { return a+=b; }
complex operator-(complex a, complex b) { return a-=b; }
complex operator-(complex a) { return {-a.real(), -a.imag()}; } // jednoargumentowy minus
complex operator*(complex a, complex b) { return a*=b; }
complex operator/(complex a, complex b) { return a/=b; }
---------------
bool operator==(complex a, complex b) // rwno
{
    return a.real()==b.real() && a.imag()==b.imag();
}
bool operator!=(complex a, complex b) // nierwno
{
    return !(a==b);
}
complex sqrt(complex);
//...
---------------
void f(complex z)
{
    complex a {2.3}; // tworzy {2.3,0.0} z 2.3
    complex b {1/a};
    complex c {a+z*complex{1,2.3}};
    //...
    if (c != b)
        c = -(b/a)+2*b;
}
---------------
class Vector {
private:
    double*elem; // elem wskazuje tablic sz liczb typu double
    int sz;
public:
    Vector(int s) :elem{new double[s]}, sz{s} // konstruktor: zajmuje zasoby
    {
        for (int i=0; i!=s; ++i) elem[i]=0;   // inicjacja elementw
    }
    ~Vector() { delete[] elem; }              // destruktor: zwalnia zasoby

    double& operator[](int i);
    int size() const;
};
---------------
void fct(int n)
{
    Vector v(n);
    // ... uycie v...
    {
        Vector v2(2*n);
        //... uycie v i v2...
    } // zniszczenie v2

    //... uycie v ..
} // zniszczenie v
---------------
class Vector {
public:
    Vector(std::initializer_list<double>); // inicjacja przy uyciu listy
    //...
    void push_back(double);                // dodanie elementu na kocu i zwikszenie rozmiaru o jeden
    //...
};
---------------
Vector read(istream& is)
{
    Vector v;
    for (double d; is>>d;) // wczytanie wartoci zmiennoprzecinkowych do d
        v.push_back(d);    // dodanie d do v
    return v;
}
---------------
Vector v1 = {1,2,3,4,5};          // v1 zawiera 5 elementw
Vector v2 = {1.23, 3.45, 6.7, 8}; // v2 zawiera 4 elementy
---------------
Vector::Vector(std::initializ er_list<double> lst) // inicjacja przy uyciu listy
    :elem{new double[lst.siz e()]}, sz{lst.siz e()}
{
    copy(lst.begin(),lst.end(),elem);              // kopiowanie z lst do elem
}
---------------
class Container {
public:
    virtual double& operator[](int) = 0; // funkcja czysto wirtualna
    virtual int size() const = 0;        // funkcja skadowa const (3.2.1.1)
    virtual ~Container() {}              // destruktor (3.2.1.2)
};
---------------
void use(Container& c)
{
    const int sz = c.size();

    for (int i=0; i!=sz; ++i)
        cout << c[i] << '\n';
}
---------------
class Vector_container : public Container { // Vector_container implementuje Container
    Vector v;
public:
    Vector_container(int s) : v(s) { } // wektor s elementw
    ~Vector_container() {}

    double& operator[](int i) { return v[i]; }
    int size() const { return v.siz e(); }
};
---------------
void g()
{
    Vector_container vc {10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0};
    use(vc);
}
---------------
class List_container : public Container { // List_container implementuje Container
    std::list<double> ld; // lista (z biblioteki standardowej) liczb typu double (4.4.2)
public:
    List_container() { }  // pusta lista
    List_container(initializer_list<double> il) : ld{il} { }
    ~List_container() {}

    double& operator[](int i);
    int size() const { return ld.size(); }

};

double& List_container::operator[](int i)
{
    for (auto& x : ld) {
        if (i==0) return x;
        --i;
    }
    throw out_of_range("Kontener listy");
}
---------------
void h()
{
    List_container lc = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    use(lc);
}
---------------
void use(Container& c)
{
    const int sz = c.size();
    for (int i=0; i!=sz; ++i)
        cout << c[i] << '\n';
}
---------------
class Shape {
public:
    virtual Point center() const =0; // czysto wirtualna
    virtual void move(Point to) =0;

    virtual void draw() const = 0;   // rysowanie na biecej kanwie
    virtual void rotate(int angle) = 0;

    virtual ~Shape() {}              // destruktor
    //...
};
---------------
void rotate_all(vector<Shape*>& v, int angle) // obraca elementy v o kt podany w stopniach
{
    for (auto p : v)
        p->rotate(angle);
}
---------------
class Circle : public Shape {
public:
    Circle(Point p, int rr); // konstruktor

    Point center() const { return x; }
    void move(Point to) { x=to; }

    void draw() const;
    void rotate(int) {}      // jaki wietny prosty algorytm
private:
    Point x;                 // rodek
    int r;                   // promie
};
---------------
class Smiley : public Circle { // uycie okrgw jako bazy do budowy twarzy
public:
    Smiley(Point p, int r) : Circle{p,r}, mouth{nullptr} { }

    ~Smiley()
    {
        delete mouth;
        for (auto p : eyes) delete p;
    }

    void move(Point to);

    void draw() const;
    void rotate(int);
    
    void add_eye(Shape*s) { eyes.push_back(s); }
    void set_mouth(Shape*s);
    virtual void wink(int i); // mrugnicie okiem nr i

    //...

private:
    vector<Shape*> eyes;      // zazwyczaj dwoje oczu
    Shape*mouth;
};
---------------
void Smiley::draw()
{
    Circle::draw();
    for (auto p : eyes)
        p->draw();
    mouth->draw();
}
---------------
enum class Kind { circle, triangle , smiley };

Shape*read_shape(istream& is) // wczytuje opisy ksztatw ze strumienia wejciowego is
{
    //... wczytanie nagwka ksztatu z is i znalezienie jego rodzaju k...

    switch (k) {
    case Kind::circle:
        // wczytanie danych koa {Point,int} do p i r
        return new Circle{p,r};
    case Kind::triangle:
        // wczytanie danych trjkta {Point,Point,Point} do p1, p2 oraz p3
        return new Triangle{p1,p2,p3};
    case Kind::smiley:
        // wczytanie danych umieszku {Point,int,Shape,Shape,Shape} do p, r, e1 ,e2 oraz m
        Smiley*ps = new Smiley{p,r};
        ps->add_eye(e1);
        ps->add_eye(e2);
        ps->set_mouth(m);
        return ps;
    }
}
---------------
void user()
{
    std::vector<Shape*>v;
    while (cin)
        v.push_back(read_shape(cin));
    draw_all(v);               // wywoanie funkcji draw() dla kadego elementu
    rotate_all(v,45);          // wywoanie funkcji rotate(45) dla kadego elementu
    for (auto p : v) delete p; // nie zapomnij usun elementw
}
---------------
unique_ptr<Shape> read_shape(istream& is) // wczytuje opisy ksztatw ze strumienia wejciowego is
{
    // wczytanie nagwka ksztatu z is i znalezienie jego rodzaju k

    switch (k) {
    case Kind::circle:
        // wczytanie danych koa {Point,int} do p i r
        return unique_ptr<Shape>{new Circle{p,r}}; // 5.2.1
    //...
}

void user()
{
    vector<unique_ptr<Shape>> v;
    while (cin)
        v.push_back(read_shape(cin));
    draw_all(v); // wywoanie funkcji draw() dla kadego elementu
    rotate_all(v,45); // wywoanie funkcji rotate(45) dla kadego elementu
} // wszystkie ksztaty s niejawnie usuwane
---------------
void test(complex z1)
{
    complex z2 {z1}; // inicjacja z kopiowaniem
    complex z3;
    z3 = z2;         // przypisanie z kopiowaniem
    //...
}
---------------
void bad_copy(Vector v1)
{
    Vector v2 = v1; // kopiowanie reprezentacji v1 do v2
    v1[0] = 2;      // v2[0] teraz te wynosi 2!
    v2[1] = 3;      // v1[1] teraz te wynosi 3!
}
---------------
class Vector {
private:
    double*elem; // elem wskazuje tablic sz liczb typu double
    int sz;
public:
    Vector(int s);                      // konstruktor: ustala niezmiennik, zajmuje zasoby
    ~Vector() { delete[] elem; }        // destruktor: zwalnia zasoby

    Vector(const Vector& a);            // konstruktor kopiujcy
    Vector& operator=(const Vector& a); // przypisanie kopiujce

    double& operator[](int i);
    const double& operator[](int i) const;

    int size() const;
};
---------------
Vector::Vector(const Vector& a) // konstruktor kopiujcy
    :elem{new double[sz]},      // alokacja miejsca na elementy
    sz{a.sz}
{
    for (int i=0; i!=sz; ++i)   // kopiowanie elementw
        elem[i] = a.elem[i];
}
---------------
Vector& Vector::operator=(const Vector& a) // przypisanie kopiujce
{
    double*p = new double[a.sz];
    for (int i=0; i!=a.sz; ++i)
        p[i] = a.elem[i];
    delete[] elem; // usuwa stare elementy
    elem = p;
    sz = a.sz;
    return*this;
}
---------------
Vector operator+(const Vector& a, const Vector& b)
{
    if (a.size()!=b.siz e())
        throw Vector_siz e_mismatch{};

    Vector res(a.size());
    for (int i=0; i!=a.size(); ++i)
        res[i]=a[i]+b[i];
    return res;
}
---------------
void f(const Vector& x, const Vector& y, const Vector& z)
{
    Vector r;
    // ...
    r = x+y+z;
    // ...
}
---------------
class Vector {
    //...

    Vector(const Vector& a); // konstruktor kopiujcy
    Vector& operator=(const Vector& a); // przypisanie kopiujce

    Vector(Vector&& a); // konstruktor przenoszcy
    Vector& operator=(Vector&& a); // przypisanie przenoszce
};
---------------
Vector::Vector(Vector&& a)
    :elem{a.elem}, // "pobranie elementw" z a
    sz{a.sz}
{
    a.elem = nullptr; // teraz a nie ma elementw
    a.sz = 0;
}
---------------
Vector f()
{
    Vector x(1000);
    Vector y(1000);
    Vector z(1000);
    // ...
    z=x;              // robimy kopi
    y = std::move(x); // przenosimy
    // ...
    return z;         // przenosimy
};
---------------
std::vector<thread> my_threads;

Vector init(int n)
{
    thread t {heartbeat};          // wspbiene uruchomienie heartbeat (we wasnym wtku)
    my_threads.push_back(move(t)); // przeniesienie t do my_threads
    // ... wicej inicjacji...
    Vector vec(n);
    for (int i=0; i<vec.size(); ++i) vec[i] = 777;
    return vec;                    // przeniesienie res poza init()
}

auto v = init(); // uruchomienie heartbeat i inicjacja v
---------------
class Shape {
public:
    Shape(const Shape&) =delete; // adnych operacji kopiowania
    Shape& operator=(const Shape&) =delete;

    Shape(Shape&&) =delete;      // adnych operacji przenoszenia
    Shape& operator=(Shape&&) =delete;

    ~Shape();
    //...
};
---------------
template<typename T>
class Vector {
private:
    T*elem; // elem wskazuje tablic sz elementw typu T
    int sz;
public:
    Vector(int s);               // konstruktor: ustala niezmiennik, zajmuje zasoby
    ~Vector() { delete[] elem; } // destruktor: zwalnia zasoby

    //... operacje kopiowania i przenoszenia...

    T& operator[](int i);
    const T& operator[](int i) const;
    int size() const { return sz; }
};
---------------
template<typename T>
Vector<T>::Vector(int s)
{
    if (s<0) throw Negative_siz e{};
    elem = new T[s];
    sz = s;
}

template<typename T>
const T& Vector<T>::operator[](int i) const
{
    if (i<0 || size()<=i)
        throw out_of_range{"Vector::operator[]"};
    return elem[i];
}
---------------
Vector<char> vc(200);      // wektor 200 znakw
Vector<string> vs(17);     // wektor 17 acuchw
Vector<list<int>> vli(45); // wektor 45 list liczb cakowitych
---------------
void write(const Vector<string>& vs) // wektor acuchw
{
    for (int i = 0; i!=vs.size(); ++i)
        cout << vs[i] << '\n';
}
---------------
template<typename T>
T*begin(Vector<T>& x)
{
    return &x[0]; // wskanik do pierwszego elementu
}

template<typename T>
T*end(Vector<T>& x)
{
    return x.begin()+x.size(); // wskanik do elementu za ostatnim elementem
}
---------------
void f2(const Vector<string>& vs) // wektor acuchw
{
    for (auto& s : vs)
        cout << s << '\n';
}
---------------
template<typename Container, typename Value>
Value sum(const Container& c, Value v)
{
    for (auto x : c)
        v+=x;
    return v;
}
---------------
void user(Vector<int>& vi, std::list<double>& ld, std::vector<complex<double>>& vc)
{
    int x = sum(vi,0);                  // suma wektora liczb typu int (dodawanie wartoci int)
    double d = sum(vi,0.0);             // suma wektora liczb typu int (dodawanie wartoci double)
    double dd = sum(ld,0.0);            // suma listy liczb typu double
    auto z = sum(vc,complex<double>{}); // suma wektora wartoci typu complex<double>
                                        // warto pocztkowa wynosi {0.0,0.0}
}
---------------
template<typename T>
class Less_than {
    const T val; // warto do porwnywania
public:
    Less_than(const T& v) :val(v) { }
    bool operator()(const T& x) const { return x<val; } // operator wywoania
};
---------------
Less_than<int> lti {42};          // lti(i) porwna i z 42 przy uyciu < (i<42)
Less_than<string> lts {"Backus"}; // lts(s) porwna s z "Backus" przy uyciu < (s<"Backus")
---------------
void fct(int n, const string & s)
{
    bool b1 = lti(n); // prawda, jeli n<42
    bool b2 = lts(s); // prawda, jeli s<"Backus"
    //...
}
---------------
template<typename C, typename P>
int count(const C& c, P pred)
{
    int cnt = 0;
    for (const auto& x : c)
        if (pred(x))
            ++cnt;
    return cnt;
}
---------------
void f(const Vector<int>& vec, const list<string>& lst, int x, const string& s)
{
    cout << "Liczba wartoci mniejszych ni " << x
        << ": " << count(vec,Less_than<int>{x})
        << '\n';
    cout << "Liczba wartoci mniejszych ni " << s
        << ": " << count(lst,Less_than<string>{s})
        << '\n';
}
---------------
void f(const Vector<int>& vec, const list<string>& lst, int x, const string& s)
{
    cout << "Liczba wartoci mniejszych ni " << x
        << ": " << count(vec,[&](int a){ return a<x; })
        << '\n';
    cout << "Liczba wartoci mniejszych ni " << s
        << ": " << count(lst,[&](const string& a){ return a<s; })
        << '\n';
}
---------------
template<class C, class Oper>
void for_all(C& c, Oper op) // przyjcie zaoenia, e C jest kontenerem wskanikw
{
    for (auto& x : c)
        op(*x); // przekazanie op() referencji do kadego wskazywanego elementu
}
---------------
void user()
{
    vector<unique_ptr<Shape>> v;
    while (cin)
        v.push_back(read_shape(cin));
    for_all(v,[](Shape& s){ s.draw(); });     // draw_all()
    for_all(v,[](Shape& s){ s.rotate(45); }); // rotate_all(45)
}
---------------
void f() { }    // nic nie robi

template<typename T, typename ... Tail>
void f(T head, Tail... tail)
{
    g(head);    // robi co z pierwszym argumentem
    f(tail...); // robi co z pozostaymi argumentami
}
---------------
int main()
{
    cout << "pierwszy: ";
    f(1,2.2,"cze");

    cout << "\ndrugi: "
    f(0.2,'c',"aj!",0,1,2);
    cout << "\n";
}
---------------
template<typename T>
void g(T x)
{
    cout << x << " ";
}
---------------
pierwszy: 1 2.2 cze
drugi: 0.2 c aj! 0 1 2
---------------
using size_t = unsigned int;
---------------
template<typename T>
class Vector {
public:
    using value_type = T;
    //...
};
---------------
template<typename C>
using Element_type = typename C::value_type;

template<typename Container>
void algo(Container& c)
{
    Vector<Element_type<Container>> vec; // przechowuj tu wyniki
    //...
}
---------------
template<typename Key, typename Value>
class Map {
    //...
};

template<typename Value>
using String_map = Map<string,Value>;

String_map<int> m; // m jest Map<str ing,int>







