#include <iostream>
using namespace std;
template <typename T>
class List
{
struct Node
{
T data;
Node* prev = nullptr;
Node*next = nullptr;
Node() = default;
Node(T d) : data(d), prev(nullptr), next(nullptr) {}
};
Node* head, *tail;
std::size_t l_size;
//SFINAE -> This worked for the implementation of std::vector but doesn't seem to work here
template <typename Iter>
using required_input_iterator = std::enable_if_t<std::is_base_of_v<
std::input_iterator_tag, typename std::iterator_traits<Iter>::iterator_category>>;
public:
using reference = T&;
using const_reference = const T&;
using size_type = std::size_t;
class const_iterator
{
Node* node = nullptr;
friend class List;
const_iterator (Node* p) : node(p) {}
public:
const_iterator () = default;
const_iterator(const const_iterator& other) : node(other.node) {}
reference operator*()
{
return node->data;
}
T* operator->()
{
return node->data;
}
// prefix operators
const_iterator& operator++()
{
node = node->next;
return *this;
}
const_iterator& operator--()
{
node = node->prev;
return *this;
}
// postfix operators
const_iterator operator++(int)
{
Node* temp = *this;
node = node->next;
return temp;
}
const_iterator operator--(int)
{
Node* temp = *this;
node = node->prev;
return temp;
}
friend bool operator== (const const_iterator& lhs, const const_iterator& rhs) noexcept
{
return lhs.node == rhs.node;
}
friend bool operator!= (const const_iterator& lhs, const const_iterator& rhs) noexcept
{
return lhs.node != rhs.node;
}
};
class iterator
{
Node * node = nullptr;
friend class List;
iterator(Node* p) : node(p) {}
public:
iterator () = default;
reference operator*()
{
return node->data;
}
reference operator->()
{
return node->data;
}
// prefix operators
iterator& operator++()
{
node = node->next;
return *this;
}
iterator& operator--()
{
node = node->prev;
return *this;
}
// postfix operators
iterator operator++(int)
{
Node* temp = *this;
node = node->next;
return temp;
}
iterator operator--(int)
{
Node* temp = *this;
node = node->prev;
return temp;
}
friend bool operator== (const iterator& lhs, const iterator& rhs) noexcept
{
return lhs.node == rhs.node;
}
friend bool operator!= (const iterator& lhs, const iterator& rhs) noexcept
{
return lhs.node != rhs.node;
}
};
List();
explicit List(size_type n, const_reference v){std::cout << "SECOND";}
~List() {};
template<typename InputIterator, typename = required_input_iterator<InputIterator>>
List(InputIterator first, InputIterator last)
{
std::cout << "FIRST " << std::endl;
}
// iterators
iterator begin() noexcept
{
return iterator(head->next);
}
iterator end() noexcept
{
return iterator(tail);
}
};
template<typename T>
List<T>::List() : head(nullptr), tail(nullptr), l_size(0) { }
#include <vector>
int main()
{
vector<int> lis = {1,2,3,4,6};
int arr[]{1,2,3,4,5};
List<int> lis1(std::begin(lis), std::end(lis));
List<int> lis2(arr, arr+5);
}