#include <iostream>
#include <stdexcept>
#include <utility>

class CjelobrojniRed {
    struct Cvor {
        int element;
        Cvor *sljedeci;

        Cvor(int element, Cvor *sljedeci = nullptr)
            : element(element), sljedeci(sljedeci) {}
    };

    Cvor *pocetak;
    Cvor *kraj;
    int broj_elemenata;

    void Unisti() {
        while (pocetak != nullptr) {
            Cvor *stari = pocetak;
            pocetak = pocetak->sljedeci;
            delete stari;
        }

        kraj = nullptr;
        broj_elemenata = 0;
    }

    void Kopiraj(const CjelobrojniRed &red) {
        pocetak = kraj = nullptr;
        broj_elemenata = 0;

        try {
            for (Cvor *p = red.pocetak; p != nullptr; p = p->sljedeci)
                *this += p->element;
        } catch (...) {
            Unisti();
            throw;
        }
    }

    void Zamijeni(CjelobrojniRed &red) noexcept {
        std::swap(pocetak, red.pocetak);
        std::swap(kraj, red.kraj);
        std::swap(broj_elemenata, red.broj_elemenata);
    }

public:
    CjelobrojniRed()
        : pocetak(nullptr), kraj(nullptr), broj_elemenata(0) {}

    ~CjelobrojniRed() {
        Unisti();
    }

    // Kopirajuci konstruktor
    CjelobrojniRed(const CjelobrojniRed &red) {
        Kopiraj(red);
    }

    // Pomjerajuci konstruktor
    CjelobrojniRed(CjelobrojniRed &&red) noexcept
        : pocetak(red.pocetak),
          kraj(red.kraj),
          broj_elemenata(red.broj_elemenata) {
        red.pocetak = nullptr;
        red.kraj = nullptr;
        red.broj_elemenata = 0;
    }

    // Kopirajuci operator dodjele
    CjelobrojniRed &operator=(const CjelobrojniRed &red) {
        if (this != &red) {
            CjelobrojniRed kopija(red);
            Zamijeni(kopija);
        }

        return *this;
    }

    // Pomjerajuci operator dodjele
    CjelobrojniRed &operator=(CjelobrojniRed &&red) noexcept {
        if (this != &red) {
            Unisti();

            pocetak = red.pocetak;
            kraj = red.kraj;
            broj_elemenata = red.broj_elemenata;

            red.pocetak = nullptr;
            red.kraj = nullptr;
            red.broj_elemenata = 0;
        }

        return *this;
    }

    // Dodavanje elementa na kraj reda
    CjelobrojniRed &operator+=(int element) {
        Cvor *novi = new Cvor(element);

        if (kraj == nullptr) {
            pocetak = kraj = novi;
        } else {
            kraj->sljedeci = novi;
            kraj = novi;
        }

        broj_elemenata++;
        return *this;
    }

    // Prvi element reda
    int &operator*() {
        if (pocetak == nullptr)
            throw std::logic_error("Red je prazan");

        return pocetak->element;
    }

    const int &operator*() const {
        if (pocetak == nullptr)
            throw std::logic_error("Red je prazan");

        return pocetak->element;
    }

    // Posljednji element reda
    int &operator~() {
        if (kraj == nullptr)
            throw std::logic_error("Red je prazan");

        return kraj->element;
    }

    const int &operator~() const {
        if (kraj == nullptr)
            throw std::logic_error("Red je prazan");

        return kraj->element;
    }

    // Prefiksno -- uklanja prvi element
    CjelobrojniRed &operator--() {
        if (pocetak == nullptr)
            throw std::logic_error("Red je prazan");

        Cvor *stari = pocetak;
        pocetak = pocetak->sljedeci;
        delete stari;

        broj_elemenata--;

        if (pocetak == nullptr)
            kraj = nullptr;

        return *this;
    }

    // Postfiksno -- vraca stanje reda prije uklanjanja
    CjelobrojniRed operator--(int) {
        if (pocetak == nullptr)
            throw std::logic_error("Red je prazan");

        CjelobrojniRed stari_red(*this);
        --(*this);

        return stari_red;
    }

    // U primjeru while(!s) traje dok red nije prazan
    bool operator!() const {
        return broj_elemenata != 0;
    }

    // Broj elemenata
    int operator+() const {
        return broj_elemenata;
    }

    // Mnozenje svih elemenata cijelim brojem
    CjelobrojniRed &operator*=(int broj) {
        for (Cvor *p = pocetak; p != nullptr; p = p->sljedeci)
            p->element *= broj;

        return *this;
    }

    friend CjelobrojniRed operator+(
        const CjelobrojniRed &red1,
        const CjelobrojniRed &red2
    ) {
        if (red1.broj_elemenata != red2.broj_elemenata)
            throw std::domain_error("Redovi nisu iste velicine");

        CjelobrojniRed rezultat;

        Cvor *p1 = red1.pocetak;
        Cvor *p2 = red2.pocetak;

        while (p1 != nullptr) {
            rezultat += p1->element + p2->element;
            p1 = p1->sljedeci;
            p2 = p2->sljedeci;
        }

        return rezultat;
    }

    friend std::ostream &operator<<(
        std::ostream &tok,
        const CjelobrojniRed &red
    ) {
        for (Cvor *p = red.pocetak; p != nullptr; p = p->sljedeci) {
            tok << p->element;

            if (p->sljedeci != nullptr)
                tok << ",";
        }

        return tok;
    }
};

int main() {
    CjelobrojniRed s;

    s += 3;
    s += 1;
    s += 5;
    s += 2;
    s += 4;

    while (!s)
        std::cout << *(s--) << " ";

    return 0;
}

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: