#include <iostream>

template <class T>
class Node {
public:
    T value;
    Node<T>* next;
    Node(T value_, Node<T>* next_) : value(value_), next(next_) {}
    Node(T value_) : value(value_), next(NULL) {}
};



using namespace std;

template <class T>
class List {
public:
    List() : head(NULL) {}

    void prepend(T val) {
        Node<T>* node_ptr = new Node<T>(val, head);
        head = node_ptr;
    }

    void print() {
        cout << "[";
        _node_loop(_print_node);
        cout << "]" << endl;
    }

    ~List() {
        _node_loop(_del_node);
    }

    static List<T> from_array(T tarray[], int N) {
        List<T> ls = List<T>();
        for (int i = 0; i < N; i++) {
            ls.prepend(tarray[i]);
        }
        return ls;
    }

private:
    Node<T>* head;

    void _node_loop(void (*kernel)(Node<T>*)) {
        Node<T>* node_ptr = head;
        Node<T>* tmp;
        while (node_ptr != NULL) {
            tmp = node_ptr;
            node_ptr = node_ptr->next;
            kernel(tmp);
        }
    }

    static void _print_node(Node<T>* node_ptr) {
        if (node_ptr->next == NULL) {
            cout << node_ptr->value;
        }
        else {
            cout << node_ptr->value << ", ";
        }
    }

    static void _del_node(Node<T>* node_ptr) {
        delete node_ptr;
    }
};



int main() {
    int my_array[] = {1, 2, 3, 4, 5};
    List<int> my_list = List<int>::from_array(my_array, 5);
    my_list.print();
    return 0;
}