1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef ARY_STORE_S_ITERATOR_HXX
25 #define ARY_STORE_S_ITERATOR_HXX
26 
27 // USED SERVICES
28 #include <ary/getncast.hxx>
29 #include "s_base.hxx"
30 
31 
32 
33 
34 namespace ary
35 {
36 namespace stg
37 {
38 
39 
40 template <class>        class const_iterator;
41 template <class, class> class const_filter_iterator;
42 
43 
44 /** A non-const iterator that runs on a ->Storage<>.
45 
46     @collab Storage<>
47 */
48 template <class ENTITY>
49 class iterator : public std::iterator<std::forward_iterator_tag, ENTITY>
50 {
51   public:
52     typedef iterator<ENTITY>                            self;
53     typedef typename Base<ENTITY>::impl_type            impl_container;
54     typedef typename impl_container::const_iterator     impl_type;
55 
56     // OPERATORS
iterator()57                         iterator()
58                             :   itImpl()        {}
iterator(impl_type i_impl)59     explicit            iterator(
60                             impl_type           i_impl)
61                             :   itImpl(i_impl)  {}
~iterator()62                         ~iterator()             {}
63 
operator ==(self i_other) const64     bool                operator==(
65                             self                i_other ) const
66                                                 { return itImpl == i_other.itImpl; }
operator !=(self i_other) const67     bool                operator!=(
68                             self                i_other ) const
69                                                 { return itImpl != i_other.itImpl; }
operator *() const70     ENTITY &            operator*() const       { csv_assert(*itImpl != 0);
71                                                   return *(*itImpl); }
operator ++()72     self &              operator++()            { ++itImpl; return *this; }
operator ++(int)73     self                operator++(int)         { return self(itImpl++); }
74 
75   private:
76     friend class const_iterator<ENTITY>;        // For const_iterator(iterator);
ImplIterator() const77     impl_type           ImplIterator() const    { return itImpl; }
78 
79     // DATA
80     impl_type           itImpl;
81 };
82 
83 
84 /** A const iterator that runs on a ->Storage<>.
85 
86     @collab Storage<>
87 */
88 template <class ENTITY>
89 class const_iterator :
90     public std::iterator<std::forward_iterator_tag, const ENTITY>
91 {
92   public:
93     typedef const_iterator<ENTITY>                      self;
94     typedef typename Base<ENTITY>::impl_type            impl_container;
95     typedef typename impl_container::const_iterator     impl_type;
96 
97     // OPERATORS
const_iterator()98                         const_iterator()
99                             :   itImpl()        {}
const_iterator(impl_type i_impl)100     explicit            const_iterator(
101                             impl_type           i_impl)
102                             :   itImpl(i_impl)  {}
const_iterator(::ary::stg::iterator<ENTITY> i_it)103                         const_iterator(         // implicit conversions allowed
104                             ::ary::stg::iterator<ENTITY>    i_it )
105                             :   itImpl(i_it.ImplIterator()) {}
~const_iterator()106                         ~const_iterator()       {}
107 
operator ==(self i_other) const108     bool                operator==(
109                             self                i_other ) const
110                                                 { return itImpl == i_other.itImpl; }
operator !=(self i_other) const111     bool                operator!=(
112                             self                i_other ) const
113                                                 { return itImpl != i_other.itImpl; }
operator *() const114     const ENTITY &      operator*() const       { csv_assert(*itImpl != 0);
115                                                   return *(*itImpl); }
operator ++()116     self &              operator++()            { ++itImpl; return *this; }
operator ++(int)117     self                operator++(int)         { return self(itImpl++); }
118 
119   private:
120     // DATA
121     impl_type           itImpl;
122 };
123 
124 
125 
126 
127 
128 /** A non const iterator that runs on a ->Storage<> and returns only
129     the elements of a specific type.
130 
131     @tpl ENTITY
132     The element type of the ->Storage<>
133 
134     @tpl FILTER
135     The actual type of the returned items. FILTER needs to be derived from
136     ENTITY.
137 
138     @collab Storage<>
139 */
140 template <class ENTITY, class FILTER>
141 class filter_iterator :
142     public std::iterator<std::forward_iterator_tag, FILTER>
143 {
144   public:
145     typedef filter_iterator<ENTITY,FILTER>              self;
146     typedef ::ary::stg::iterator<ENTITY>                impl_type;
147 
148     // OPERATORS
filter_iterator()149                         filter_iterator()
150                             :   itCur()         {}
filter_iterator(impl_type i_cur)151     explicit            filter_iterator(
152                             impl_type           i_cur )
153                             :   itCur(i_cur)    {}
~filter_iterator()154                         ~filter_iterator()      {}
155 
operator ==(self i_other) const156     bool                operator==(
157                             self                i_other ) const
158                                                 { return itCur == i_other.itCur; }
operator !=(self i_other) const159     bool                operator!=(
160                             self                i_other ) const
161                                                 { return itCur != i_other.itCur; }
operator *() const162     FILTER &            operator*() const       { csv_assert(IsValid());
163                                                   return static_cast< FILTER& >(*itCur); }
operator ++()164     self &              operator++()            { ++itCur;
165                                                   return *this; }
operator ++(int)166     self                operator++(int)         { return self(itCur++); }
IsValid() const167     bool                IsValid() const         { return ary::is_type<FILTER>(*itCur); }
168 
169   private:
170     friend class const_filter_iterator<ENTITY,FILTER>;  // For const_filter_iterator(filter_iterator);
ImplCur() const171     impl_type           ImplCur() const         { return itCur; }
172 
173     // DATA
174     impl_type           itCur;
175 };
176 
177 
178 /** A const iterator that runs on a ->Storage<> and returns only
179     the elements of a specific type.
180 
181     @tpl ENTITY
182     The element type of the ->Storage<>
183 
184     @tpl FILTER
185     The actual type of the returned items. FILTER needs to be derived from
186     ENTITY.
187 
188     @collab Storage<>
189 */
190 template <class ENTITY, class FILTER>
191 class const_filter_iterator :
192     public std::iterator<std::forward_iterator_tag, const FILTER>
193 {
194   public:
195     typedef const_filter_iterator<ENTITY,FILTER>        self;
196     typedef ::ary::stg::const_iterator<ENTITY>          impl_type;
197 
198     // OPERATORS
const_filter_iterator()199                         const_filter_iterator()
200                             :   itCur()         {}
const_filter_iterator(impl_type i_cur)201     explicit            const_filter_iterator(
202                             impl_type           i_cur )
203                             :   itCur(i_cur)    {}
const_filter_iterator(filter_iterator<ENTITY,FILTER> i_it)204     explicit            const_filter_iterator(  // implicit conversions allowed
205                             filter_iterator<ENTITY,FILTER>
206                                                 i_it )
207                             :   itCur(i_it.ImplCur())   {}
~const_filter_iterator()208                         ~const_filter_iterator()
209                                                 {}
operator ==(self i_other) const210     bool                operator==(
211                             self                i_other ) const
212                                                 { return itCur == i_other.itCur; }
operator !=(self i_other) const213     bool                operator!=(
214                             self                i_other ) const
215                                                 { return itCur != i_other.itCur; }
operator *() const216     const FILTER &      operator*() const       { csv_assert(IsValid());
217                                                   return static_cast< const FILTER& >(*itCur); }
operator ++()218     self &              operator++()            { ++itCur;
219                                                   return *this; }
operator ++(int)220     self                operator++(int)         { return self(itCur++); }
IsValid() const221     bool                IsValid() const         { return ary::is_type<FILTER>(*itCur); }
222 
223   private:
224     // DATA
225     impl_type           itCur;
226 };
227 
228 
229 
230 
231 }   // namespace stg
232 }   // namespace ary
233 #endif
234