online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code    Language
#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 = nullptr; Node *tail = nullptr; std::size_t l_size = 0; //SFINAE template <typename Iter> using required_input_iterator = std::enable_if<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: using value_type = std::remove_reference_t<T>; using difference_type = std::ptrdiff_t; using pointer = value_type*; using reference = value_type&; using iterator_category = std::bidirectional_iterator_tag; 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 = node->next; return temp; } const_iterator operator--(int) { Node* temp = this->node; 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 : public std::input_iterator_tag { Node * node = nullptr; friend class List; iterator(Node* p) : node(p) {} public: using value_type = std::remove_reference_t<T>; using difference_type = std::ptrdiff_t; using pointer = value_type*; using reference = value_type&; using iterator_category = std::bidirectional_iterator_tag; 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 = node->next; return temp; } iterator operator--(int) { Node* temp = this->node; 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; } }; using reverse_iterator = std::reverse_iterator<iterator>; using const_reverse_iterator = std::reverse_iterator<const_iterator>; List() = default; explicit List(size_type n); List(size_type n, const_reference v); List(const std::initializer_list<T>& i_list); template<typename InputIterator, typename = required_input_iterator<InputIterator>> List(InputIterator first, InputIterator last); List(const List& src); List& operator=(List src); List(List&& src); //~List(); void assign(size_type n, const_reference v); void assign(const std::initializer_list<T>& i_list); template<typename InputIterator, typename = decltype(*std::declval<InputIterator>())> void assign(InputIterator first, InputIterator last); // element acces reference front(); const_reference front() const; reference back(); const_reference back() const; // iterators iterator begin() noexcept { return iterator(head); } const_iterator begin() const noexcept { return iterator(head); } iterator end() noexcept { return iterator(tail); } const_iterator end() const noexcept { return iterator(tail); } const_iterator cbegin() const noexcept; const_iterator cend() const; reverse_iterator rbegin() noexcept; const_reverse_iterator crbegin() const noexcept; reverse_iterator rend() noexcept; const_reverse_iterator crend() const noexcept; // capacity size_type size() const noexcept; bool empty() const noexcept; // modifiers void clear() noexcept; iterator insert(const_iterator pos, const_reference v); iterator insert(const_iterator pos, const T&& v); iterator insert(const_iterator pos, size_type n, const_reference v); template<typename InputIterator, typename = decltype(*std::declval<InputIterator>())> iterator insert(InputIterator first, InputIterator last); iterator insert(const_iterator pos, std::initializer_list<T> i_list); template<typename... Args> iterator emplace(const iterator& pos, Args&&... args ); iterator erase(const_iterator pos); iterator erase(const_iterator first, const_iterator last); void push_back(const_reference v); void push_back(T&& v); template<typename... Args> reference emplace_back(Args&&...args); void pop_back(); void push_front(const_reference v); void push_front(T&& v); template<typename... Args> reference emplace_front(Args&&...args); void pop_front(); void resize(size_type new_size); void resize(size_type new_size, const_reference v); void swap(List& other) noexcept; }; template <typename T> List<T>::List(size_type n) { if (n == 0) return; head = new Node(); Node* temp = head; temp->prev = nullptr; for(int i = 0; i < n; ++i) { temp->next = new Node(T()); temp->next->prev = temp; temp = temp->next; } tail = temp->next; } template <typename T> List<T>::List(size_type n, const_reference v) : l_size(n) { if (n == 0) return; Node* temp = new Node(v); head = temp; temp->prev = nullptr; for(int i = 0; i < n; ++i) { temp->next = new Node(v); temp->next->prev = temp; temp = temp->next; } tail = temp; } template <typename T> List<T>::List(const std::initializer_list<T>& i_list) : l_size(i_list.size()) { if(l_size == 0) return; Node* temp = new Node; head = temp; temp->prev = nullptr; for(auto it = i_list.begin(); it != i_list.end(); ++it) { temp->data = *it; temp->next = new Node; temp->next->prev = temp; temp = temp->next; } tail = temp; } template<typename T> List<T>::List(const List& other) : l_size(other.l_size) { if(l_size == 0) return; Node* temp = other.head; Node* node = new Node(temp->data); head = node; node->prev = nullptr; temp = temp->next; int i = 0; while(temp->next) { node->next = new Node(temp->data); node->next->prev = node; node = node->next; temp = temp->next; } tail = node->next; } template<typename T> template<typename... Args> typename List<T>::iterator List<T>::emplace(const iterator& pos, Args&&... args ) { Node* curr = pos.node; Node* new_node = new Node(std::move(args)...); // this is where I am having a really hard time if(curr == tail) { curr = new Node(std::move(args)...); curr->next = nullptr; tail = curr->next; } else { curr->prev = new_node; new_node->next = curr; head = new_node; } } int main() { List<int> lis({1, 2, 3, 4, 5, 6}); List<int> li(4); for(auto e: li) { cout << e << ' '; } cout << '\n'; List<int> l1 = lis; l1.emplace(l1.begin(), 78); // this lne changes nothing for(auto e: l1) { cout << e << ' '; } }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text
×

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue