#include <iostream>
#include <initializer_list>

struct list
{
    list() { std::cout << "default constructor\n" ; }

    list( std::initializer_list<int> il )
    {
        std::cout << "constructor from initializer_list\n" ;
        for( int v : il ) push_back(v) ;
    }

    list( const list& that )
    {
        std::cout << "copy constructor\n" ;
        for( node* n = that.first ; n ; n = n->next ) push_back( n->value ) ;
    }

    list( list&& that ) noexcept
    {
        std::cout << "move constructor\n" ;
        first = that.first ; that.first = nullptr ;
        last = that.last ; that.last = nullptr ;
    }

    ~list()
    {
        std::cout << "destructor\n" ;
        while(first) pop_back() ;
    }

    list& operator=( const list& that ) ; // TODO
    list& operator=( list&& that ) noexcept ; // TODO

    void push_back( int v )
    {
        if(last) { last->next = new node( v, last ) ; last = last->next ; }
        else first = last = new node(v) ;
    }

    void pop_back()
    {
        if( last != first ) { last = last->prev ; delete last->next ; last->next = nullptr ; }
        if( last && last == first ) { delete last ; last = first = nullptr ; }
    }

    struct node
    {
        node( int v ) : value(v) {}
        node( int v, node* p ) : value(v), prev(p) {}

        int value ;
        node* next = nullptr ;
        node* prev = nullptr ;
    };

    node* first = nullptr ;
    node* last = nullptr ;
};

list foo()
{
    std::cout << "in function foo\n" ;
    return { 1, 2, 3, 4, 5 } ;
}

list bar()
{
    std::cout << "in function bar\n" ;
    list temp ;
    for( int i = 1 ; i < 6 ; ++i ) temp.push_back(i) ;
    return temp ;
}

int main()
{
    {
        list a = foo() ;
        std::cout << "back in main\n" ;
        for( auto n = a.first ; n ; n = n->next ) std::cout << n->value << ' ' ;
        std::cout << '\n' ;
    }

    std::cout << "----------------------------\n" ;

    {
        list b = bar() ;
        std::cout << "back in main\n" ;
        for( auto n = b.first ; n ; n = n->next ) std::cout << n->value << ' ' ;
        std::cout << '\n' ;
    }
}
