1/* Copyright 2003-2023 Joaquin M Lopez Munoz.
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * http://www.boost.org/LICENSE_1_0.txt)
5 *
6 * See http://www.boost.org/libs/multi_index for library home page.
7 */
8
9#ifndef BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP
10#define BOOST_MULTI_INDEX_DETAIL_HASH_INDEX_ITERATOR_HPP
11
12#if defined(_MSC_VER)
13#pragma once
14#endif
15
16#include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
17#include <boost/operators.hpp>
18
19#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
20#include <boost/core/serialization.hpp>
21#endif
22
23namespace boost{
24
25namespace multi_index{
26
27namespace detail{
28
29/* Iterator class for hashed indices.
30 */
31
32struct hashed_index_global_iterator_tag{};
33struct hashed_index_local_iterator_tag{};
34
35template<
36 typename Node,typename BucketArray,
37 typename IndexCategory,typename IteratorCategory
38>
39class hashed_index_iterator:
40 public forward_iterator_helper<
41 hashed_index_iterator<Node,BucketArray,IndexCategory,IteratorCategory>,
42 typename Node::value_type,
43 typename Node::difference_type,
44 const typename Node::value_type*,
45 const typename Node::value_type&>
46{
47public:
48 /* coverity[uninit_ctor]: suppress warning */
49 hashed_index_iterator(){}
50 hashed_index_iterator(Node* node_):node(node_){}
51
52 const typename Node::value_type& operator*()const
53 {
54 return node->value();
55 }
56
57 hashed_index_iterator& operator++()
58 {
59 this->increment(IteratorCategory());
60 return *this;
61 }
62
63#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
64 /* Serialization. As for why the following is public,
65 * see explanation in safe_mode_iterator notes in safe_mode.hpp.
66 */
67
68 template<class Archive>
69 void serialize(Archive& ar,const unsigned int version)
70 {
71 core::split_member(ar,*this,version);
72 }
73
74 typedef typename Node::base_type node_base_type;
75
76 template<class Archive>
77 void save(Archive& ar,const unsigned int)const
78 {
79 node_base_type* bnode=node;
80 ar<<core::make_nvp("pointer",bnode);
81 }
82
83 template<class Archive>
84 void load(Archive& ar,const unsigned int version)
85 {
86 load(ar,version,IteratorCategory());
87 }
88
89 template<class Archive>
90 void load(
91 Archive& ar,const unsigned int version,hashed_index_global_iterator_tag)
92 {
93 node_base_type* bnode;
94 ar>>core::make_nvp("pointer",bnode);
95 node=static_cast<Node*>(bnode);
96 if(version<1){
97 BucketArray* throw_away; /* consume unused ptr */
98 ar>>core::make_nvp("pointer",throw_away);
99 }
100 }
101
102 template<class Archive>
103 void load(
104 Archive& ar,const unsigned int version,hashed_index_local_iterator_tag)
105 {
106 node_base_type* bnode;
107 ar>>core::make_nvp("pointer",bnode);
108 node=static_cast<Node*>(bnode);
109 if(version<1){
110 BucketArray* buckets;
111 ar>>core::make_nvp("pointer",buckets);
112 if(buckets&&node&&node->impl()==buckets->end()->prior()){
113 /* end local_iterators used to point to end node, now they are null */
114 node=0;
115 }
116 }
117 }
118#endif
119
120 /* get_node is not to be used by the user */
121
122 typedef Node node_type;
123
124 Node* get_node()const{return node;}
125
126private:
127
128 void increment(hashed_index_global_iterator_tag)
129 {
130 Node::template increment<IndexCategory>(node);
131 }
132
133 void increment(hashed_index_local_iterator_tag)
134 {
135 Node::template increment_local<IndexCategory>(node);
136 }
137
138 Node* node;
139};
140
141template<
142 typename Node,typename BucketArray,
143 typename IndexCategory,typename IteratorCategory
144>
145bool operator==(
146 const hashed_index_iterator<
147 Node,BucketArray,IndexCategory,IteratorCategory>& x,
148 const hashed_index_iterator<
149 Node,BucketArray,IndexCategory,IteratorCategory>& y)
150{
151 return x.get_node()==y.get_node();
152}
153
154} /* namespace multi_index::detail */
155
156} /* namespace multi_index */
157
158#if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
159/* class version = 1 : hashed_index_iterator does no longer serialize a bucket
160 * array pointer.
161 */
162
163namespace serialization {
164template<
165 typename Node,typename BucketArray,
166 typename IndexCategory,typename IteratorCategory
167>
168struct version<
169 boost::multi_index::detail::hashed_index_iterator<
170 Node,BucketArray,IndexCategory,IteratorCategory
171 >
172>
173{
174 BOOST_STATIC_CONSTANT(int,value=1);
175};
176} /* namespace serialization */
177#endif
178
179} /* namespace boost */
180
181#endif
182