本次实现只是练习而已,如有问题,欢迎指出!
编译环境:GCC 7.3、vs 2005
与标准库list的差异:
1. 没有splice
2. 没有assign
3. 没有resize
好了,直接上代码:
#ifndef __FORWARD_LIST_H__
#define __FORWARD_LIST_H__
#if __cplusplus >= 201103L
#include <type_traits> // std::forward std::move std::declval
#include <initializer_list>
#endif
#if __cplusplus >= 201103L
#define null nullptr
#else
#define null NULL
#endif
template<typename _Tp>
class forward_list
{
private:
struct _C_list_node;
typedef _C_list_node node_type;
public:
typedef _Tp value_type;
typedef value_type & reference;
typedef const value_type & const_reference;
typedef value_type * pointer;
typedef unsigned long size_type;
#if __cplusplus >= 201103L
typedef value_type && rvalue_reference;
#endif
public:
template<typename __ValueType>
struct _iterator_impl
{
#if __cplusplus >= 201103L
typedef typename std::remove_const<__ValueType>::type __IteratorValue;
typedef typename std::add_const<__IteratorValue>::type __ConstIteratorValue;
typedef _iterator_impl<__IteratorValue> __iterator;
typedef _iterator_impl<__ConstIteratorValue> __const_iterator;
#else
typedef _iterator_impl<node_type> __iterator;
typedef _iterator_impl<const node_type> __const_iterator;
#endif
__ValueType *_M_value;
_iterator_impl(const __iterator &it)
: _M_value(it._M_value) { }
_iterator_impl(__ValueType *v = null)
: _M_value(v) { }
reference operator*()
{ return *_M_value->value; }
pointer operator->()
{ return _M_value->value; }
_iterator_impl operator++()
{
_M_value = _M_value->next;
return *this;
}
_iterator_impl operator++(int)
{
_iterator_impl ret(_M_value);
_M_value = _M_value->next;
return ret;
}
bool operator==(const __iterator &it)
{ return _M_value == it._M_value; }
bool operator!=(const __iterator &it)
{ return _M_value != it._M_value; }
bool operator==(const __const_iterator &it)
{ return _M_value == it._M_value; }
bool operator!=(const __const_iterator &it)
{ return _M_value != it._M_value; }
};
public:
typedef _iterator_impl<node_type> iterator;
typedef _iterator_impl<const node_type> const_iterator;
public:
forward_list()
: _M_head(new node_type(null)), _M_size(0) { }
forward_list(const forward_list &fl)
: _M_head(new node_type(null)), _M_size(0) { }
#if __cplusplus >= 201103L
forward_list(forward_list &&fl)
: _M_head(new node_type(null)), _M_size(0)
{ swap(std::move(fl)); }
forward_list(std::initializer_list<value_type> il)
: _M_head(new node_type(null)), _M_size(0)
{ insert_after(before_begin(), il.begin(), il.end()); }
#endif
template<typename ForwardIterator>
forward_list(ForwardIterator b, ForwardIterator e)
: _M_head(new node_type(null)), _M_size(0)
{ insert_after<ForwardIterator>(before_begin(), b, e); }
~forward_list()
{
clear();
::operator delete(_M_head);
}
iterator insert_after(iterator pos, const_reference v)
{
#if __cplusplus >= 201103L
return emplace_after(pos, v);
#else
++_M_size;
return iterator(_M_construct_node(pos._M_value, v));
#endif
}
// [b, e)
template<typename ForwardIterator>
iterator insert_after(iterator pos, ForwardIterator b, ForwardIterator e)
{
iterator ret = pos;
while(b != e)
{ ret = insert_after(ret, *b++); }
return ret;
}
#if __cplusplus >= 201103L
iterator insert_after(iterator pos, rvalue_reference v)
{
++_M_size;
return iterator(_M_construct_node(pos._M_value, std::move(v)));
}
template<typename ... Args>
iterator emplace_after(iterator pos, Args && ... args)
{
++_M_size;
return iterator(_M_emplace_node(pos._M_value, std::forward<Args>(args)...));
}
#endif
void erase_after(iterator pos)
{
--_M_size;
node_type *tmp = pos._M_value->next;
if(null != tmp)
{
pos._M_value->next = tmp->next;
delete tmp;
}
else
{
pos._M_value->next = null;
_M_linked_node(pos._M_value, null);
}
}
// 删除 (pos, e) 之间的所有元素
void erase_after(iterator pos, iterator e)
{
while(++iterator(pos) != e)
{ erase_after(pos); }
}
void pop_front()
{ erase_after(before_begin()); }
void push_front(const_reference v)
{ insert_after(before_begin(), v); }
#if __cplusplus >= 201103L
void push_front(rvalue_reference v)
{ insert_after(before_begin(), std::move(v)); }
#endif
reference front()
{ return *begin(); }
const_reference front() const
{ return *begin(); }
size_type size() const
{ return _M_size; }
bool empty() const
{ return size() == 0; }
iterator before_begin()
{ return iterator(_M_head); }
const_iterator before_begin() const
{ return const_iterator(_M_head); }
iterator begin()
{ return iterator(_M_head->next); }
const_iterator begin() const
{ return const_iterator(_M_head->next); }
iterator end()
{ return iterator(); }
const_iterator end() const
{ return const_iterator(); }
const_iterator cbegin() const
{ return begin(); }
const_iterator cend() const
{ return end(); }
const_iterator cbefore_begin() const
{ return before_begin(); }
#if __cplusplus >= 201103L
void swap(forward_list &&fl)
#else
void swap(forward_list &fl)
#endif
{
_M_swap<node_type *>(_M_head, fl._M_head);
_M_swap<size_type>(_M_size, fl._M_size);
}
void clear()
{
node_type *tmp = _M_head->next;
while(_M_size > 0)
{
node_type *v = tmp;
tmp = tmp->next;
delete v;
--_M_size;
}
}
private:
struct _C_list_node
{
#if __cplusplus >= 201103L
_C_list_node(rvalue_reference v)
: next(null), value(new value_type(std::move(v))) { }
#endif
_C_list_node(const_reference v)
: next(null), value(new value_type(v)) { }
_C_list_node(value_type *v)
: next(null), value(v) { }
~_C_list_node()
{ delete value; }
_C_list_node *next;
value_type *value;
};
#if __cplusplus >= 201103L
template<typename ... Args>
node_type* _M_emplace_node(node_type *prev, Args && ... args)
{ return _M_linked_node(prev, new node_type(new value_type(std::forward<Args>(args)...))); }
node_type* _M_construct_node(node_type *prev, rvalue_reference value)
{ return _M_linked_node(prev, new node_type(std::move(value))); }
#else
node_type* _M_emplace_node(node_type *prev, const_reference value)
{ return _M_linked_node(prev, new node_type(value)); }
#endif
node_type* _M_construct_node(node_type *prev, const_reference value)
{ return _M_linked_node(prev, new node_type(value)); }
node_type* _M_linked_node(node_type *prev, node_type *cur)
{
if(null != prev)
{
if(null != cur)
{ cur->next = prev->next; }
prev->next = cur;
}
return cur;
}
template<typename __Type>
void _M_swap(__Type &t1, __Type &t2)
{
__Type tmp = t1;
t1 = t2;
t2 = tmp;
}
private:
node_type *_M_head;
size_type _M_size;
};
#endif // __FORWARD_LIST_H__