#include <iostream>

// For simplicity, keeping everything public
template<class T>
class Node
{
public:
  Node(T data) : data(data), prev(nullptr), next(nullptr) {}
  
  T data;
  Node* prev;
  Node* next;
};

template<class T>
class MyLinkedList
{
public:
  Node<T>* head;
  Node<T>* tail;
  
  MyLinkedList() : head(nullptr), tail(nullptr) {}
  
  void Add(T data)
  {
  	Node<T>* newData = new Node<T>(data);
  	
  	if(head == nullptr) { head = tail = newData; }
  	else 
  	{
  		newData->prev = tail;
  		tail->next = newData;
  		tail = newData;
  	}
  }
  
  void Print()
  {
  	Node<int>* ptr = head;
	while(ptr != nullptr)
	{
		std::cout << ptr->data << "\n";
		ptr = ptr->next;
	}
  }
  
  void Reverse()
  {
  	// How would you implement this in O(1)?
  	std::swap(head, tail);
  }
};

int main() {
	MyLinkedList<int> list;
	for(int i = 1; i <= 10; ++i) list.Add(i);
	list.Print();
	
	std::cout << "\nSwapping the list...\n";
	list.Reverse();
	
	list.Print();
	
	return 0;
}