1 /* Copyright 2003-2020 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/serialization/nvp.hpp>
21 #include <boost/serialization/split_member.hpp>
22 #include <boost/serialization/version.hpp>
23 #endif
24
25 namespace boost{
26
27 namespace multi_index{
28
29 namespace detail{
30
31 /* Iterator class for hashed indices.
32 */
33
34 struct hashed_index_global_iterator_tag{};
35 struct hashed_index_local_iterator_tag{};
36
37 template<
38 typename Node,typename BucketArray,
39 typename IndexCategory,typename IteratorCategory
40 >
41 class hashed_index_iterator:
42 public forward_iterator_helper<
43 hashed_index_iterator<Node,BucketArray,IndexCategory,IteratorCategory>,
44 typename Node::value_type,
45 typename Node::difference_type,
46 const typename Node::value_type*,
47 const typename Node::value_type&>
48 {
49 public:
50 /* coverity[uninit_ctor]: suppress warning */
hashed_index_iterator()51 hashed_index_iterator(){}
hashed_index_iterator(Node * node_)52 hashed_index_iterator(Node* node_):node(node_){}
53
operator *() const54 const typename Node::value_type& operator*()const
55 {
56 return node->value();
57 }
58
operator ++()59 hashed_index_iterator& operator++()
60 {
61 this->increment(IteratorCategory());
62 return *this;
63 }
64
65 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
66 /* Serialization. As for why the following is public,
67 * see explanation in safe_mode_iterator notes in safe_mode.hpp.
68 */
69
70 BOOST_SERIALIZATION_SPLIT_MEMBER()
71
72 typedef typename Node::base_type node_base_type;
73
74 template<class Archive>
save(Archive & ar,const unsigned int) const75 void save(Archive& ar,const unsigned int)const
76 {
77 node_base_type* bnode=node;
78 ar<<serialization::make_nvp("pointer",bnode);
79 }
80
81 template<class Archive>
load(Archive & ar,const unsigned int version)82 void load(Archive& ar,const unsigned int version)
83 {
84 load(ar,version,IteratorCategory());
85 }
86
87 template<class Archive>
load(Archive & ar,const unsigned int version,hashed_index_global_iterator_tag)88 void load(
89 Archive& ar,const unsigned int version,hashed_index_global_iterator_tag)
90 {
91 node_base_type* bnode;
92 ar>>serialization::make_nvp("pointer",bnode);
93 node=static_cast<Node*>(bnode);
94 if(version<1){
95 BucketArray* throw_away; /* consume unused ptr */
96 ar>>serialization::make_nvp("pointer",throw_away);
97 }
98 }
99
100 template<class Archive>
load(Archive & ar,const unsigned int version,hashed_index_local_iterator_tag)101 void load(
102 Archive& ar,const unsigned int version,hashed_index_local_iterator_tag)
103 {
104 node_base_type* bnode;
105 ar>>serialization::make_nvp("pointer",bnode);
106 node=static_cast<Node*>(bnode);
107 if(version<1){
108 BucketArray* buckets;
109 ar>>serialization::make_nvp("pointer",buckets);
110 if(buckets&&node&&node->impl()==buckets->end()->prior()){
111 /* end local_iterators used to point to end node, now they are null */
112 node=0;
113 }
114 }
115 }
116 #endif
117
118 /* get_node is not to be used by the user */
119
120 typedef Node node_type;
121
get_node() const122 Node* get_node()const{return node;}
123
124 private:
125
increment(hashed_index_global_iterator_tag)126 void increment(hashed_index_global_iterator_tag)
127 {
128 Node::template increment<IndexCategory>(node);
129 }
130
increment(hashed_index_local_iterator_tag)131 void increment(hashed_index_local_iterator_tag)
132 {
133 Node::template increment_local<IndexCategory>(node);
134 }
135
136 Node* node;
137 };
138
139 template<
140 typename Node,typename BucketArray,
141 typename IndexCategory,typename IteratorCategory
142 >
operator ==(const hashed_index_iterator<Node,BucketArray,IndexCategory,IteratorCategory> & x,const hashed_index_iterator<Node,BucketArray,IndexCategory,IteratorCategory> & y)143 bool operator==(
144 const hashed_index_iterator<
145 Node,BucketArray,IndexCategory,IteratorCategory>& x,
146 const hashed_index_iterator<
147 Node,BucketArray,IndexCategory,IteratorCategory>& y)
148 {
149 return x.get_node()==y.get_node();
150 }
151
152 } /* namespace multi_index::detail */
153
154 } /* namespace multi_index */
155
156 #if !defined(BOOST_MULTI_INDEX_DISABLE_SERIALIZATION)
157 /* class version = 1 : hashed_index_iterator does no longer serialize a bucket
158 * array pointer.
159 */
160
161 namespace serialization {
162 template<
163 typename Node,typename BucketArray,
164 typename IndexCategory,typename IteratorCategory
165 >
166 struct version<
167 boost::multi_index::detail::hashed_index_iterator<
168 Node,BucketArray,IndexCategory,IteratorCategory
169 >
170 >
171 {
172 BOOST_STATIC_CONSTANT(int,value=1);
173 };
174 } /* namespace serialization */
175 #endif
176
177 } /* namespace boost */
178
179 #endif
180