namespace ThrosAnvil
{
template<typename T>
class LinkedList
{
struct Node
{
Node(Node* prev, Node* next)
: prev(prev)
, next(next)
{
prev->next = this;
next->prev = this;
}
virtual ~Node() {}
Node* next;
Node* prev;
};
struct DataNode: public Node
{
DataNode(Node* prev, Node* next, T const& data)
: Node(prev, next)
, data(data)
{}
DataNode(Node* prev, Node* next, T&& data)
: Node(prev, next)
, data(std::forward<T>(data))
{}
template<typename... Args>
DataNode(Node* prev, Node* next, Args&& ...args)
: Node(prev, next)
, data(std::forward<Args>(args)...)
{}
T data;
};
Node sentinel;
template<typename ResultType>
struct IteratorBase
{
Node* current;
IteratorBase(Node* node)
: current(node)
{}
bool operator==(IteratorBase const& rhs) const {return current == rhs.current;}
bool operator!=(IteratorBase const& rhs) const {return !(*this == rhs);}
IteratorBase& operator++() {current = current->next;return *this;}
IteratorBase& operator--() {current = current->prev;return *this;}
IteratorBase operator++(int) {IteratorBase result(*this); ++(*this);return result;}
IteratorBase operator--(int) {IteratorBase result(*this); --(*this);return result;}
ResultType& operator*() const {return static_cast<DataNode*>(current)->data;}
ResultType* operator->() const {return &static_cast<DataNode*>(current)->data;}
};
public:
using iterator = IteratorBase<T>;
using const_iterator = IteratorBase<T const>;
// Default
LinkedList()
: sentinel(&sentinel, &sentinel)
{}
// Copying␣
LinkedList(LinkedList const& copy)
: LinkedList()
{
for(auto const& val: copy) {
push_back(val);
}
}
LinkedList& operator=(LinkedList const& rhs)
{
LinkedList tmp(rhs);
tmp.swap(*this);
return *this;
}
// Moving
LinkedList(LinkedList&& move) noexcept
: LinkedList()
{
move.swap(*this);
}
LinkedList& operator=(LinkedList&& rhs) noexcept
{
rhs.swap(*this);
return *this;
}
// Destroying
~LinkedList()
{
Node* next;
for(Node* loop = sentinel.next; loop != &sentinel; loop = next)
{
next = loop->next;
delete loop;
}
}
// Swap
void swap(LinkedList& other) noexcept
{
using std::swap;
swap(sentinel.next->prev, other.sentinel.next->prev);
swap(sentinel.prev->next, other.sentinel.prev->next);
swap(sentinel.next, other.sentinel.next);
swap(sentinel.prev, other.sentinel.prev);
}
// Copying value into list
void push_back(T const& value) {new DataNode(sentinel.prev, &sentinel, value);}
void push_front(T const& value) {new DataNode(&sentinel, sentinel.next, value);}
// Moving value into list
void push_back(T&& value) {new DataNode(sentinel.prev, &sentinel, std::forward<T>(value));}
void push_front(T&& value) {new DataNode(&sentinel, sentinel.next, std::forward<T>(value));}
// Emplaning value into list
template<typename... Args>
void emplace_back(Args&& ...args) {new DataNode(sentinel.prev, &sentinel, std::forward<Args>(args)...);}
template<typename... Args>
void emplace_front(Args&& ...args) {new DataNode(&sentinel, sentinel.next, std::forward<Args>(args)...);}
iterator begin() {return iterator(sentinel.next);}
iterator end() {return iterator(&sentinel);}
const_iterator begin() const {return const_iterator(sentinel.next);}
const_iterator end() const {return const_iterator(&sentinel);}
const_iterator cbegin() const {return const_iterator(sentinel.next);}
const_iterator cend() const {return const_iterator(&sentinel);}
};
template<typename T>
void swap(LinkedList<T>& lhs, LinkedList<T>& rhs)
{
lhs.swap(rhs);
}
}
namespace ThrosAnvil
{
template<typename T>
class LinkedList
{
struct Node
{
Node(Node* prev, Node* next)
: prev(prev)
, next(next)
{
prev->next = this;
next->prev = this;
}
virtual ~Node() {}
Node* next;
Node* prev;
};
struct DataNode: public Node
{
DataNode(Node* prev, Node* next, T const& data)
: Node(prev, next)
, data(data)
{}
DataNode(Node* prev, Node* next, T&& data)
: Node(prev, next)
, data(std::forward<T>(data))
{}
template<typename... Args>
DataNode(Node* prev, Node* next, Args&& ...args)
: Node(prev, next)
, data(std::forward<Args>(args)...)
{}
T data;
};
Node sentinel;
template<typename ResultType>
struct IteratorBase
{
Node* current;
IteratorBase(Node* node)
: current(node)
{}
bool operator==(IteratorBase const& rhs) const {return current == rhs.current;}
bool operator!=(IteratorBase const& rhs) const {return !(*this == rhs);}
IteratorBase& operator++() {current = current->next;return *this;}
IteratorBase& operator--() {current = current->prev;return *this;}
IteratorBase operator++(int) {IteratorBase result(*this); ++(*this);return result;}
IteratorBase operator--(int) {IteratorBase result(*this); --(*this);return result;}
ResultType& operator*() const {return static_cast<DataNode*>(current)->data;}
ResultType* operator->() const {return &static_cast<DataNode*>(current)->data;}
};
public:
using iterator = IteratorBase<T>;
using const_iterator = IteratorBase<T const>;
// Default
LinkedList()
: sentinel(&sentinel, &sentinel)
{}
// Copying␣
LinkedList(LinkedList const& copy)
: LinkedList()
{
for(auto const& val: copy) {
push_back(val);
}
}
LinkedList& operator=(LinkedList const& rhs)
{
LinkedList tmp(rhs);
tmp.swap(*this);
return *this;
}
// Moving
LinkedList(LinkedList&& move) noexcept
{
move.swap(*this);
}
LinkedList& operator=(LinkedList&& rhs) noexcept
{
rhs.swap(*this);
return *this;
}
// Destroying
~LinkedList()
{
Node* next;
for(Node* loop = sentinel.next; loop != &sentinel; loop = next)
{
next = loop->next;
delete loop;
}
}
// Swap
void swap(LinkedList& other) noexcept
{
using std::swap;
swap(sentinel.next->prev, other.sentinel.next->prev);
swap(sentinel.prev->next, other.sentinel.prev->next);
swap(sentinel.next, other.sentinel.next);
swap(sentinel.prev, other.sentinel.prev);
}
// Copying value into list
void push_back(T const& value) {new DataNode(sentinel.prev, &sentinel, value);}
void push_front(T const& value) {new DataNode(&sentinel, sentinel.next, value);}
// Moving value into list
void push_back(T&& value) {new DataNode(sentinel.prev, &sentinel, std::forward<T>(value));}
void push_front(T&& value) {new DataNode(&sentinel, sentinel.next, std::forward<T>(value));}
// Emplaning value into list
template<typename... Args>
void emplace_back(Args&& ...args) {new DataNode(sentinel.prev, &sentinel, std::forward<Args>(args)...);}
template<typename... Args>
void emplace_front(Args&& ...args) {new DataNode(&sentinel, sentinel.next, std::forward<Args>(args)...);}
iterator begin() {return iterator(sentinel.next);}
iterator end() {return iterator(&sentinel);}
const_iterator begin() const {return const_iterator(sentinel.next);}
const_iterator end() const {return const_iterator(&sentinel);}
const_iterator cbegin() const {return const_iterator(sentinel.next);}
const_iterator cend() const {return const_iterator(&sentinel);}
};
template<typename T>
void swap(LinkedList<T>& lhs, LinkedList<T>& rhs)
{
lhs.swap(rhs);
}
}
namespace ThrosAnvil
{
template<typename T>
class LinkedList
{
struct Node
{
Node(Node* prev, Node* next)
: prev(prev)
, next(next)
{
prev->next = this;
next->prev = this;
}
virtual ~Node() {}
Node* next;
Node* prev;
};
struct DataNode: public Node
{
DataNode(Node* prev, Node* next, T const& data)
: Node(prev, next)
, data(data)
{}
DataNode(Node* prev, Node* next, T&& data)
: Node(prev, next)
, data(std::forward<T>(data))
{}
template<typename... Args>
DataNode(Node* prev, Node* next, Args&& ...args)
: Node(prev, next)
, data(std::forward<Args>(args)...)
{}
T data;
};
Node sentinel;
template<typename ResultType>
struct IteratorBase
{
Node* current;
IteratorBase(Node* node)
: current(node)
{}
bool operator==(IteratorBase const& rhs) const {return current == rhs.current;}
bool operator!=(IteratorBase const& rhs) const {return !(*this == rhs);}
IteratorBase& operator++() {current = current->next;return *this;}
IteratorBase& operator--() {current = current->prev;return *this;}
IteratorBase operator++(int) {IteratorBase result(*this); ++(*this);return result;}
IteratorBase operator--(int) {IteratorBase result(*this); --(*this);return result;}
ResultType& operator*() const {return static_cast<DataNode*>(current)->data;}
ResultType* operator->() const {return &static_cast<DataNode*>(current)->data;}
};
public:
using iterator = IteratorBase<T>;
using const_iterator = IteratorBase<T const>;
// Default
LinkedList()
: sentinel(&sentinel, &sentinel)
{}
// Copying␣
LinkedList(LinkedList const& copy)
: LinkedList()
{
for(auto const& val: copy) {
push_back(val);
}
}
LinkedList& operator=(LinkedList const& rhs)
{
LinkedList tmp(rhs);
tmp.swap(*this);
return *this;
}
// Moving
LinkedList(LinkedList&& move) noexcept
: LinkedList()
{
move.swap(*this);
}
LinkedList& operator=(LinkedList&& rhs) noexcept
{
rhs.swap(*this);
return *this;
}
// Destroying
~LinkedList()
{
Node* next;
for(Node* loop = sentinel.next; loop != &sentinel; loop = next)
{
next = loop->next;
delete loop;
}
}
// Swap
void swap(LinkedList& other) noexcept
{
using std::swap;
swap(sentinel.next->prev, other.sentinel.next->prev);
swap(sentinel.prev->next, other.sentinel.prev->next);
swap(sentinel.next, other.sentinel.next);
swap(sentinel.prev, other.sentinel.prev);
}
// Copying value into list
void push_back(T const& value) {new DataNode(sentinel.prev, &sentinel, value);}
void push_front(T const& value) {new DataNode(&sentinel, sentinel.next, value);}
// Moving value into list
void push_back(T&& value) {new DataNode(sentinel.prev, &sentinel, std::forward<T>(value));}
void push_front(T&& value) {new DataNode(&sentinel, sentinel.next, std::forward<T>(value));}
// Emplaning value into list
template<typename... Args>
void emplace_back(Args&& ...args) {new DataNode(sentinel.prev, &sentinel, std::forward<Args>(args)...);}
template<typename... Args>
void emplace_front(Args&& ...args) {new DataNode(&sentinel, sentinel.next, std::forward<Args>(args)...);}
iterator begin() {return iterator(sentinel.next);}
iterator end() {return iterator(&sentinel);}
const_iterator begin() const {return const_iterator(sentinel.next);}
const_iterator end() const {return const_iterator(&sentinel);}
const_iterator cbegin() const {return const_iterator(sentinel.next);}
const_iterator cend() const {return const_iterator(&sentinel);}
};
template<typename T>
void swap(LinkedList<T>& lhs, LinkedList<T>& rhs)
{
lhs.swap(rhs);
}
}
##I would do it like this:
I would do it like this:
##I would do it like this:
I would do it like this:
namespace ThrosAnvil
{
template<typename T>
class LinkedList
{
struct Node
{
Node(Node* prev, Node* next)
: prev(prev)
, next(next)
{
prev->next = this;
next->prev = this;
}
virtual ~Node() {}
Node* next;
Node* prev;
};
struct DataNode: public Node
{
DataNode(Node* prev, Node* next, T const& data)
: Node(prev, next)
, data(data)
{}
DataNode(Node* prev, Node* next, T&& data)
: Node(prev, next)
, data(std::forward<T>(data))
{}
template<typename... Args>
DataNode(Node* prev, Node* next, Args&& ...args)
: Node(prev, next)
, data(std::forward<Args>(args)...)
{}
T data;
};
Node sentinel;
template<typename ResultType>
struct IteratorBase
{
Node* current;
IteratorBase(Node* node)
: current(node)
{}
bool operator==(IteratorBase const& rhs) const {return current == rhs.current;}
bool operator!=(IteratorBase const& rhs) const {return !(*this == rhs);}
IteratorBase& operator++() {current = current->next;return *this;}
IteratorBase& operator--() {current = current->prev;return *this;}
IteratorBase operator++(int) {IteratorBase result(*this); ++(*this);return result;}
IteratorBase operator--(int) {IteratorBase result(*this); --(*this);return result;}
ResultType& operator*() const {return static_cast<DataNode*>(current)->data;}
ResultType* operator->() const {return &static_cast<DataNode*>(current)->data;}
};
public:
using iterator = IteratorBase<T>;
using const_iterator = IteratorBase<T const>;
// Default
LinkedList()
: sentinel(&sentinel, &sentinel)
{}
// Copying␣
LinkedList(LinkedList const& copy)
: LinkedList()
{
for(auto const& val: copy) {
push_back(val);
}
}
LinkedList& operator=(LinkedList const& rhs)
{
LinkedList tmp(rhs);
tmp.swap(*this);
return *this;
}
// Moving
LinkedList(LinkedList&& move) noexcept
{
move.swap(*this);
}
LinkedList& operator=(LinkedList&& rhs) noexcept
{
rhs.swap(*this);
return *this;
}
// Destroying
~LinkedList()
{
Node* next;
for(Node* loop = sentinel.next; loop != &sentinel; loop = next)
{
next = loop->next;
delete loop;
}
}
// Swap
void swap(LinkedList& other) noexcept
{
using std::swap;
swap(sentinel.next->prev, other.sentinel.next->prev);
swap(sentinel.prev->next, other.sentinel.prev->next);
swap(sentinel.next, other.sentinel.next);
swap(sentinel.prev, other.sentinel.prev);
}
// Copying value into list
void push_back(T const& value) {new DataNode(sentinel.prev, &sentinel, value);}
void push_front(T const& value) {new DataNode(&sentinel, sentinel.next, value);}
// Moving value into list
void push_back(T&& value) {new DataNode(sentinel.prev, &sentinel, std::forward<T>(value));}
void push_front(T&& value) {new DataNode(&sentinel, sentinel.next, std::forward<T>(value));}
// Emplaning value into list
template<typename... Args>
void emplace_back(Args&& ...args) {new DataNode(sentinel.prev, &sentinel, std::forward<Args>(args)...);}
template<typename... Args>
void emplace_front(Args&& ...args) {new DataNode(&sentinel, sentinel.next, std::forward<Args>(args)...);}
iterator begin() {return iterator(sentinel.next);}
iterator end() {return iterator(&sentinel);}
const_iterator begin() const {return const_iterator(sentinel.next);}
const_iterator end() const {return const_iterator(&sentinel);}
const_iterator cbegin() const {return const_iterator(sentinel.next);}
const_iterator cend() const {return const_iterator(&sentinel);}
};
template<typename T>
void swap(LinkedList<T>& lhs, LinkedList<T>& rhs)
{
lhs.swap(rhs);
}
}
namespace ThrosAnvil
{
template<typename T>
class LinkedList
{
struct Node
{
Node(Node* prev, Node* next)
: prev(prev)
, next(next)
{
prev->next = this;
next->prev = this;
}
virtual ~Node() {}
Node* next;
Node* prev;
};
struct DataNode: public Node
{
DataNode(Node* prev, Node* next, T const& data)
: Node(prev, next)
, data(data)
{}
DataNode(Node* prev, Node* next, T&& data)
: Node(prev, next)
, data(std::forward<T>(data))
{}
template<typename... Args>
DataNode(Node* prev, Node* next, Args&& ...args)
: Node(prev, next)
, data(std::forward<Args>(args)...)
{}
T data;
};
Node sentinel;
template<typename ResultType>
struct IteratorBase
{
Node* current;
IteratorBase(Node* node)
: current(node)
{}
bool operator==(IteratorBase const& rhs) const {return current == rhs.current;}
bool operator!=(IteratorBase const& rhs) const {return !(*this == rhs);}
IteratorBase& operator++() {current = current->next;return *this;}
IteratorBase& operator--() {current = current->prev;return *this;}
IteratorBase operator++(int) {IteratorBase result(*this); ++(*this);return result;}
IteratorBase operator--(int) {IteratorBase result(*this); --(*this);return result;}
ResultType& operator*() const {return static_cast<DataNode*>(current)->data;}
ResultType* operator->() const {return &static_cast<DataNode*>(current)->data;}
};
public:
using iterator = IteratorBase<T>;
using const_iterator = IteratorBase<T const>;
// Default
LinkedList()
: sentinel(&sentinel, &sentinel)
{}
// Copying␣
LinkedList(LinkedList const& copy)
: LinkedList()
{
for(auto const& val: copy) {
push_back(val);
}
}
LinkedList& operator=(LinkedList const& rhs)
{
LinkedList tmp(rhs);
tmp.swap(*this);
return *this;
}
// Moving
LinkedList(LinkedList&& move) noexcept
{
move.swap(*this);
}
LinkedList& operator=(LinkedList&& rhs) noexcept
{
rhs.swap(*this);
return *this;
}
// Destroying
~LinkedList()
{
Node* next;
for(Node* loop = sentinel.next; loop != &sentinel; loop = next)
{
next = loop->next;
delete loop;
}
}
// Swap
void swap(LinkedList& other) noexcept
{
using std::swap;
swap(sentinel.next, other.sentinel.next);
swap(sentinel.prev, other.sentinel.prev);
}
// Copying value into list
void push_back(T const& value) {new DataNode(sentinel.prev, &sentinel, value);}
void push_front(T const& value) {new DataNode(&sentinel, sentinel.next, value);}
// Moving value into list
void push_back(T&& value) {new DataNode(sentinel.prev, &sentinel, std::forward<T>(value));}
void push_front(T&& value) {new DataNode(&sentinel, sentinel.next, std::forward<T>(value));}
// Emplaning value into list
template<typename... Args>
void emplace_back(Args&& ...args) {new DataNode(sentinel.prev, &sentinel, std::forward<Args>(args)...);}
template<typename... Args>
void emplace_front(Args&& ...args) {new DataNode(&sentinel, sentinel.next, std::forward<Args>(args)...);}
iterator begin() {return iterator(sentinel.next);}
iterator end() {return iterator(&sentinel);}
const_iterator begin() const {return const_iterator(sentinel.next);}
const_iterator end() const {return const_iterator(&sentinel);}
const_iterator cbegin() const {return const_iterator(sentinel.next);}
const_iterator cend() const {return const_iterator(&sentinel);}
};
template<typename T>
void swap(LinkedList<T>& lhs, LinkedList<T>& rhs)
{
lhs.swap(rhs);
}
}
namespace ThrosAnvil
{
template<typename T>
class LinkedList
{
struct Node
{
Node(Node* prev, Node* next)
: prev(prev)
, next(next)
{
prev->next = this;
next->prev = this;
}
virtual ~Node() {}
Node* next;
Node* prev;
};
struct DataNode: public Node
{
DataNode(Node* prev, Node* next, T const& data)
: Node(prev, next)
, data(data)
{}
DataNode(Node* prev, Node* next, T&& data)
: Node(prev, next)
, data(std::forward<T>(data))
{}
template<typename... Args>
DataNode(Node* prev, Node* next, Args&& ...args)
: Node(prev, next)
, data(std::forward<Args>(args)...)
{}
T data;
};
Node sentinel;
template<typename ResultType>
struct IteratorBase
{
Node* current;
IteratorBase(Node* node)
: current(node)
{}
bool operator==(IteratorBase const& rhs) const {return current == rhs.current;}
bool operator!=(IteratorBase const& rhs) const {return !(*this == rhs);}
IteratorBase& operator++() {current = current->next;return *this;}
IteratorBase& operator--() {current = current->prev;return *this;}
IteratorBase operator++(int) {IteratorBase result(*this); ++(*this);return result;}
IteratorBase operator--(int) {IteratorBase result(*this); --(*this);return result;}
ResultType& operator*() const {return static_cast<DataNode*>(current)->data;}
ResultType* operator->() const {return &static_cast<DataNode*>(current)->data;}
};
public:
using iterator = IteratorBase<T>;
using const_iterator = IteratorBase<T const>;
// Default
LinkedList()
: sentinel(&sentinel, &sentinel)
{}
// Copying␣
LinkedList(LinkedList const& copy)
: LinkedList()
{
for(auto const& val: copy) {
push_back(val);
}
}
LinkedList& operator=(LinkedList const& rhs)
{
LinkedList tmp(rhs);
tmp.swap(*this);
return *this;
}
// Moving
LinkedList(LinkedList&& move) noexcept
{
move.swap(*this);
}
LinkedList& operator=(LinkedList&& rhs) noexcept
{
rhs.swap(*this);
return *this;
}
// Destroying
~LinkedList()
{
Node* next;
for(Node* loop = sentinel.next; loop != &sentinel; loop = next)
{
next = loop->next;
delete loop;
}
}
// Swap
void swap(LinkedList& other) noexcept
{
using std::swap;
swap(sentinel.next->prev, other.sentinel.next->prev);
swap(sentinel.prev->next, other.sentinel.prev->next);
swap(sentinel.next, other.sentinel.next);
swap(sentinel.prev, other.sentinel.prev);
}
// Copying value into list
void push_back(T const& value) {new DataNode(sentinel.prev, &sentinel, value);}
void push_front(T const& value) {new DataNode(&sentinel, sentinel.next, value);}
// Moving value into list
void push_back(T&& value) {new DataNode(sentinel.prev, &sentinel, std::forward<T>(value));}
void push_front(T&& value) {new DataNode(&sentinel, sentinel.next, std::forward<T>(value));}
// Emplaning value into list
template<typename... Args>
void emplace_back(Args&& ...args) {new DataNode(sentinel.prev, &sentinel, std::forward<Args>(args)...);}
template<typename... Args>
void emplace_front(Args&& ...args) {new DataNode(&sentinel, sentinel.next, std::forward<Args>(args)...);}
iterator begin() {return iterator(sentinel.next);}
iterator end() {return iterator(&sentinel);}
const_iterator begin() const {return const_iterator(sentinel.next);}
const_iterator end() const {return const_iterator(&sentinel);}
const_iterator cbegin() const {return const_iterator(sentinel.next);}
const_iterator cend() const {return const_iterator(&sentinel);}
};
template<typename T>
void swap(LinkedList<T>& lhs, LinkedList<T>& rhs)
{
lhs.swap(rhs);
}
}
Loading
Loading
Loading
Loading
lang-cpp