list.hpp

来自「Boost provides free peer-reviewed portab」· HPP 代码 · 共 267 行

HPP
267
字号
// Copyright 2008 Daniel James.// Distributed under the Boost Software License, Version 1.0. (See accompanying// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)// Gratuitous single linked list.//// Sadly some STL implementations aren't up to scratch and I need a simple// cross-platform container. So here it is.#if !defined(UNORDERED_TEST_LIST_HEADER)#define UNORDERED_TEST_LIST_HEADER#include <boost/iterator.hpp>#include <boost/limits.hpp>#include <functional>namespace test{    template <typename T> class list;    namespace test_detail    {        template <typename T> struct list_node;        template <typename T> class list_data;        template <typename T> class list_iterator;        template <typename T> class list_const_iterator;        template <typename T>        struct list_node        {            T value_;            list_node* next_;                                list_node(T const& v) : value_(v), next_(0) {}            list_node(T const& v, list_node* n) : value_(v), next_(n) {}        };        template <typename T>        class list_data        {        public:            typedef list_node<T> node;            typedef unsigned int size_type;            node* first_;            node** last_ptr_;            size_type size_;                        list_data() : first_(0), last_ptr_(&first_), size_(0) {}            ~list_data() {                while(first_) {                    node* tmp = first_;                    first_ = first_->next_;                    delete tmp;                }            }        private:            list_data(list_data const&);            list_data& operator=(list_data const&);        };        template <typename T>        class list_iterator            : public boost::iterator<                std::forward_iterator_tag, T,                  int, T*, T&>        {            friend class list_const_iterator<T>;            friend class test::list<T>;            typedef list_node<T> node;            typedef list_const_iterator<T> const_iterator;            node* ptr_;        public:            list_iterator() : ptr_(0) {};            explicit list_iterator(node* x) : ptr_(x) {}            T& operator*() const { return ptr_->value_; }            T* operator->() const { return &ptr_->value_; }            list_iterator& operator++() {                ptr_ = ptr_->next_; return *this; }            list_iterator& operator++(int) {                list_iterator tmp = *this; ptr_ = ptr_->next_; return tmp; }            bool operator==(const_iterator y) const { return ptr_ == y.ptr_; }            bool operator!=(const_iterator y) const { return ptr_ != y.ptr_; }        };        template <typename T>        class list_const_iterator            : public boost::iterator<                std::forward_iterator_tag, T,                  int, T const*, T const&>        {            friend class list_iterator<T>;            friend class test::list<T>;            typedef list_node<T> node;            typedef list_iterator<T> iterator;            typedef list_const_iterator<T> const_iterator;            node* ptr_;        public:            list_const_iterator() : ptr_(0) {}            list_const_iterator(list_iterator<T> const& x) : ptr_(x.ptr_) {}            T const& operator*() const { return ptr_->value_; }            T const* operator->() const { return &ptr_->value_; }            list_const_iterator& operator++() {                ptr_ = ptr_->next_; return *this; }            list_const_iterator& operator++(int) {                list_const_iterator tmp = *this; ptr_ = ptr_->next_; return tmp; }            bool operator==(const_iterator y) const { return ptr_ == y.ptr_; }            bool operator!=(const_iterator y) const { return ptr_ != y.ptr_; }        };    }    template <typename T>    class list    {        typedef test::test_detail::list_data<T> data;        typedef test::test_detail::list_node<T> node;        data data_;    public:        typedef T value_type;        typedef value_type& reference;        typedef value_type const& const_reference;        typedef unsigned int size_type;        typedef test::test_detail::list_iterator<T> iterator;        typedef test::test_detail::list_const_iterator<T> const_iterator;        list() : data_() {}        list(list const& other) : data_() {            insert(other.begin(), other.end());        }        template <class InputIterator>        list(InputIterator i, InputIterator j) : data_() {            insert(i, j);        }        list& operator=(list const& other) {            clear();            insert(other.begin(), other.end());        }        iterator begin() { return iterator(data_.first_); }        iterator end() { return iterator(); }        const_iterator begin() const { return iterator(data_.first_); }        const_iterator end() const { return iterator(); }        const_iterator cbegin() const { return iterator(data_.first_); }        const_iterator cend() const { return iterator(); }        template <class InputIterator>        void insert(InputIterator i, InputIterator j) {            for(; i != j; ++i)                push_back(*i);        }        void push_front(value_type const& v) {            data_.first_ = new node(v, data_.first_);            if(!data_.size_) data_.last_ptr_ = &(*data_.last_ptr_)->next_;            ++data_.size_;        }            void push_back(value_type const& v) {            *data_.last_ptr_ = new node(v);            data_.last_ptr_ = &(*data_.last_ptr_)->next_;            ++data_.size_;        }                void clear() {            while(data_.first_) {                node* tmp = data_.first_;                data_.first_ = data_.first_->next_;                --data_.size_;                delete tmp;            }            data_.last_ptr_ = &data_.first_;        }        void erase(const_iterator start, const_iterator end) {            node** ptr = &data_.first_;            while(*ptr != start.ptr_) {                ptr = &(*ptr)->next_;            }            while(*ptr != end.ptr_) {                node* to_delete = *ptr;                *ptr = (*ptr)->next_;                --data_.size_;                delete to_delete;            }            if(!*ptr) data_.last_ptr_ = ptr;        }        bool empty() const {            return !data_.size_;        }        size_type size() const {            return data_.size_;        }        void sort() {            sort(std::less<T>());        }        template <typename Less>        void sort(Less less = Less()) {            if(!empty()) merge_sort(&data_.first_,                    (std::numeric_limits<size_type>::max)(), less);        }        bool operator==(list const& y) const {            return size() == y.size() &&                std::equal(begin(), end(), y.begin());        }        bool operator!=(list const& y) const {            return !(*this == y);        }    private:        template <typename Less>        node** merge_sort(node** l, size_type recurse_limit, Less less)        {            node** ptr = &(*l)->next_;            for(size_type count = 0; count < recurse_limit && *ptr; ++count)            {                ptr = merge_adjacent_ranges(l, ptr,                        merge_sort(ptr, count, less), less);            }            return ptr;        }                template <typename Less>        node** merge_adjacent_ranges(node** first, node** second,                node** third, Less less)        {            while(first != second) {                if(less((*second)->value_, (*first)->value_)) {                    swap_adjacent_ranges(first, second, third);                    std::swap(second, third);                }                first = &(*first)->next_;            }            return third;        }                void swap_adjacent_ranges(node** first, node** second, node** third)        {            node* tmp = *first;            *first = *second;            *second = *third;            *third = tmp;            if(!*second) data_.last_ptr_ = second;        }    };}#endif

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?