⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hash_table_impl.hpp

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 HPP
📖 第 1 页 / 共 5 页
字号:
                }                else {                    // The deleted node is at the end of the group, so the                    // first node in the group is pointing to it.                    // Find that to change its pointer.                    link_ptr it = n->group_prev_;                    while(prev_in_group(it) != *pos) {                        it = prev_in_group(it);                    }                    prev_in_group(it) = n->group_prev_;                }                *pos = next;                --size_;            }            size_type unlink_group(link_ptr* pos)            {                size_type count = group_count(*pos);                size_ -= count;                *pos = next_group(*pos);                return count;            }#else            void unlink_node(iterator_base n)            {                link_ptr* pos = get_for_erase(n);                *pos = (*pos)->next_;                --size_;            }            size_type unlink_group(link_ptr* pos)            {                *pos = (*pos)->next_;                --size_;                return 1;            }#endif            void unlink_nodes(iterator_base n)            {                link_ptr* it = get_for_erase(n);                split_group(*it);                unordered_detail::reset(*it);                size_ -= node_count(n.node_);            }            void unlink_nodes(iterator_base begin, iterator_base end)            {                BOOST_ASSERT(begin.bucket_ == end.bucket_);                size_ -= node_count(begin.node_, end.node_);                link_ptr* it = get_for_erase(begin);                split_group(*it, end.node_);                *it = end.node_;            }            void unlink_nodes(bucket_ptr base, iterator_base end)            {                BOOST_ASSERT(base == end.bucket_);                split_group(end.node_);                link_ptr ptr(base->next_);                base->next_ = end.node_;                size_ -= node_count(ptr, end.node_);            }#if BOOST_UNORDERED_EQUIVALENT_KEYS            // Break a ciruclar list into two, with split as the beginning            // of the second group (if split is at the beginning then don't            // split).            static inline link_ptr split_group(link_ptr split)            {                // If split is at the beginning of the group then there's                // nothing to split.                if(prev_in_group(split)->next_ != split)                    return unordered_detail::null_ptr<link_ptr>();                // Find the start of the group.                link_ptr start = split;                do {                    start = prev_in_group(start);                } while(prev_in_group(start)->next_ == start);                link_ptr last = prev_in_group(start);                prev_in_group(start) = prev_in_group(split);                prev_in_group(split) = last;                return start;            }            static inline void split_group(link_ptr split1, link_ptr split2)            {                link_ptr begin1 = split_group(split1);                link_ptr begin2 = split_group(split2);                if(BOOST_UNORDERED_BORLAND_BOOL(begin1) && split1 == begin2) {                    link_ptr end1 = prev_in_group(begin1);                    prev_in_group(begin1) = prev_in_group(begin2);                    prev_in_group(begin2) = end1;                }            }#else            static inline void split_group(link_ptr)            {            }            static inline void split_group(link_ptr, link_ptr)            {            }#endif            // copy_group            //            // Basic exception safety.            // If it throws, it only copies some of the nodes in the group.#if BOOST_UNORDERED_EQUIVALENT_KEYS            void copy_group(link_ptr it, bucket_ptr dst)            {                node_constructor a(allocators_);                link_ptr end = next_group(it);                a.construct(get_value(it));                     // throws                link_ptr n = link_node_in_bucket(a, dst);                for(it = it->next_; it != end; it = it->next_) {                    a.construct(get_value(it));                 // throws                    link_node(a, n);                }            }#else            void copy_group(link_ptr it, bucket_ptr dst)            {                node_constructor a(allocators_);                a.construct(get_value(it));                     // throws                link_node_in_bucket(a, dst);            }#endif            // Delete Node            //            // Remove a node, or a range of nodes, from a bucket, and destroy            // them.            //            // no throw            void delete_to_bucket_end(link_ptr begin)            {                while(begin) {                    link_ptr node = begin;                    begin = begin->next_;                    allocators_.destroy(node);                }            }            void delete_nodes(link_ptr begin, link_ptr end)            {                while(begin != end) {                    link_ptr node = begin;                    begin = begin->next_;                    allocators_.destroy(node);                }            }#if BOOST_UNORDERED_EQUIVALENT_KEYS            void delete_group(link_ptr first_node)            {                delete_nodes(first_node, prev_in_group(first_node)->next_);            }#else            void delete_group(link_ptr node)            {                allocators_.destroy(node);            }#endif            // Clear            //            // Remove all the nodes.            //            // no throw            void clear_bucket(bucket_ptr b)            {                link_ptr first_node = b->next_;                unordered_detail::reset(b->next_);                delete_to_bucket_end(first_node);            }            void clear()            {                bucket_ptr begin = cached_begin_bucket_;                bucket_ptr end = buckets_end();                size_ = 0;                cached_begin_bucket_ = end;                while(begin != end) {                    clear_bucket(begin);                    ++begin;                }            }            // Erase            //            // no throw            iterator_base erase(iterator_base r)            {                BOOST_ASSERT(r != end());                iterator_base next = r;                next.increment();                unlink_node(r);                allocators_.destroy(r.node_);                // r has been invalidated but its bucket is still valid                recompute_begin_bucket(r.bucket_, next.bucket_);                return next;            }            iterator_base erase_range(iterator_base r1, iterator_base r2)            {                if(r1 != r2)                {                    BOOST_ASSERT(r1 != end());                    if (r1.bucket_ == r2.bucket_) {                        unlink_nodes(r1, r2);                        delete_nodes(r1.node_, r2.node_);                        // No need to call recompute_begin_bucket because                        // the nodes are only deleted from one bucket, which                        // still contains r2 after the erase.                        BOOST_ASSERT(!r1.bucket_->empty());                    }                    else {                        BOOST_ASSERT(r1.bucket_ < r2.bucket_);                        unlink_nodes(r1);                        delete_to_bucket_end(r1.node_);                        bucket_ptr i = r1.bucket_;                        for(++i; i != r2.bucket_; ++i) {                            size_ -= node_count(i->next_);                            clear_bucket(i);                        }                        if(r2 != end()) {                            link_ptr first = r2.bucket_->next_;                            unlink_nodes(r2.bucket_, r2);                            delete_nodes(first, r2.node_);                        }                        // r1 has been invalidated but its bucket is still                        // valid.                        recompute_begin_bucket(r1.bucket_, r2.bucket_);                    }                }                return r2;            }            // recompute_begin_bucket            //            // After an erase cached_begin_bucket_ might be left pointing to            // an empty bucket, so this is called to update it            //            // no throw            void recompute_begin_bucket(bucket_ptr b)            {                BOOST_ASSERT(!(b < cached_begin_bucket_));                if(b == cached_begin_bucket_)                {                    if (size_ != 0) {                        while (cached_begin_bucket_->empty())                            ++cached_begin_bucket_;                    } else {                        cached_begin_bucket_ = buckets_end();                    }                }            }            // This is called when a range has been erased            //            // no throw            void recompute_begin_bucket(bucket_ptr b1, bucket_ptr b2)            {                BOOST_ASSERT(!(b1 < cached_begin_bucket_) && !(b2 < b1));                BOOST_ASSERT(b2 == buckets_end() || !b2->empty());                if(b1 == cached_begin_bucket_ && b1->empty())                    cached_begin_bucket_ = b2;            }            size_type erase_group(link_ptr* it, bucket_ptr bucket)            {                link_ptr pos = *it;                size_type count = unlink_group(it);                delete_group(pos);                this->recompute_begin_bucket(bucket);                return count;            }        };#if defined(BOOST_MPL_CFG_MSVC_ETI_BUG)        template <>        class BOOST_UNORDERED_TABLE_DATA<int>        {        public:            typedef int size_type;            typedef int iterator_base;        };#endif        //        // Hash Table        //        template <typename ValueType, typename KeyType,            typename Hash, typename Pred,            typename Alloc>        class BOOST_UNORDERED_TABLE        {            typedef BOOST_UNORDERED_TABLE_DATA<Alloc> data;            typedef BOOST_DEDUCED_TYPENAME data::node_constructor node_constructor;            typedef BOOST_DEDUCED_TYPENAME data::bucket_ptr bucket_ptr;            typedef BOOST_DEDUCED_TYPENAME data::link_ptr link_ptr;        public:            typedef BOOST_DEDUCED_TYPENAME data::value_allocator value_allocator;            typedef BOOST_DEDUCED_TYPENAME data::node_allocator node_allocator;            // Type definitions            typedef KeyType key_type;            typedef Hash hasher;            typedef Pred key_equal;            typedef ValueType value_type;            typedef std::size_t size_type;            typedef std::ptrdiff_t difference_type;            // iterators            typedef BOOST_DEDUCED_TYPENAME data::iterator_base iterator_base;        private:            typedef boost::unordered_detail::buffered_functions<Hash, Pred>                function_store;            typedef BOOST_DEDUCED_TYPENAME function_store::functions functions;            typedef BOOST_DEDUCED_TYPENAME function_store::functions_ptr                functions_ptr;            function_store functions_;            float mlf_;            size_type max_load_;        public:            data data_;            // Constructors            //            // In the constructors, if anything throws an exception,            // BOOST_UNORDERED_TABLE_DATA's destructor will clean up.

⌨️ 快捷键说明

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