Library of Assembled Shared Sources
access_iterator.h
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2011 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43#ifndef LASS_GUARDIAN_OF_INCLUSION_STDE_TRANSFORM_ITERATOR_H
44#define LASS_GUARDIAN_OF_INCLUSION_STDE_TRANSFORM_ITERATOR_H
45
46#include "stde_common.h"
47
48namespace lass
49{
50namespace stde
51{
52
53/** iterator adaptor to access members.
54 *
55 * A prime example is to iterate over the keys or values in a @c std::map.
56 * The value_type of the map's iterator is a @c std::pair of key and value.
57 * @c first_accessor_t is an accessor that will access the first element of
58 * the pair, and combined with @c access_iterator_t it allows you to
59 * directly iterate over just the keys of the map.
60 * A helper function @c first_iterator is provided to easily adapt a
61 * map's iterator:
62 *
63 * @code
64 * // prints spam, ham, eggs
65 * std::map<std::string, int> map;
66 * map["spam"] = 1;
67 * map["ham"] = 2;
68 * map["eggs"] = 3;
69 * std::copy(
70 * first_iterator(map.begin()),
71 * first_iterator(map.end()),
72 * std::ostream_iterator<std::string>(std::cout, ", "));
73 * @endcode
74 *
75 * @tparam Iterator the iterator type of the original sequence. In the
76 * example above, this would be @c std::map<std::string, int>::iterator
77 * @tparam Accessor functor type that takes an Iterator as argument and
78 * returns a reference to the accessed member. Accessor shall also
79 * define @c value_type, @c reference and @c pointer. An example is
80 * @c first_accessor_t
81 */
82template
83<
84 typename Iterator,
85 typename Accessor
86>
87class access_iterator_t
88{
89public:
90 typedef Iterator iterator_type;
91 typedef Accessor accessor_type;
92 typedef typename std::iterator_traits<Iterator>::iterator_category iterator_category;
93 typedef typename Accessor::value_type value_type;
94 typedef typename std::iterator_traits<Iterator>::difference_type difference_type;
95 typedef typename Accessor::pointer pointer;
96 typedef typename Accessor::reference reference;
97
98 access_iterator_t(iterator_type i = iterator_type(), accessor_type a = accessor_type()): current_(i), accessor_(a) {}
99
100 iterator_type base() const { return current_; }
101 pointer operator->() const { return &accessor_(current_); }
102 reference operator*() const { return accessor_(current_); }
103
104 access_iterator_t& operator++() { ++current_; return *this; }
105 access_iterator_t operator++(int) { return access_iterator_t(current_++, accessor_); }
106 access_iterator_t& operator--() { --current_; return *this; }
107 access_iterator_t operator--(int) { return access_iterator_t(current_--, accessor_); }
108
109 access_iterator_t& operator+=(difference_type n) { current_ += n; return *this; }
110 access_iterator_t operator+(difference_type n) { return access_iterator_t(current_ + n, accessor_); }
111 access_iterator_t& operator-=(difference_type n) { current_ -= n; return *this; }
112 access_iterator_t operator-(difference_type n) { return access_iterator_t(current_ - n, accessor_); }
113
114 reference operator[](difference_type n) const { return accessor_(current_[n]); }
115
116public:
117 iterator_type current_;
118 accessor_type accessor_;
119};
120
121/** @relates access_iterator_t */
122template <typename I, typename V>
123typename std::iterator_traits<I>::difference_type operator-(const access_iterator_t<I, V>& a, const access_iterator_t<I, V>& b) { return a.base() - b.base(); }
124/** @relates access_iterator_t */
125template <typename I, typename V>
126bool operator==(const access_iterator_t<I, V>& a, const access_iterator_t<I, V>& b) { return a.base() == b.base(); }
127/** @relates access_iterator_t */
128template <typename I, typename V>
129bool operator!=(const access_iterator_t<I, V>& a, const access_iterator_t<I, V>& b) { return a.base() != b.base(); }
130/** @relates access_iterator_t */
131template <typename I, typename V>
132bool operator<(const access_iterator_t<I, V>& a, const access_iterator_t<I, V>& b) { return a.base() < b.base(); }
133/** @relates access_iterator_t */
134template <typename I, typename V>
135bool operator>(const access_iterator_t<I, V>& a, const access_iterator_t<I, V>& b) { return a.base() > b.base(); }
136/** @relates access_iterator_t */
137template <typename I, typename V>
138bool operator<=(const access_iterator_t<I, V>& a, const access_iterator_t<I, V>& b) { return a.base() <= b.base(); }
139/** @relates access_iterator_t */
140template <typename I, typename V>
141bool operator>=(const access_iterator_t<I, V>& a, const access_iterator_t<I, V>& b) { return a.base() >= b.base(); }
142
143
144
145template <typename BaseReference, typename Value> struct accessor_helper_t;
146
147template <typename Base, typename Value>
148struct accessor_helper_t<Base&, Value>
149{
150 typedef Base& argument_type;
151 typedef Value& result_type;
152 typedef Value value_type;
153 typedef Value& reference;
154 typedef Value* pointer;
155protected:
156 ~accessor_helper_t() {}
157};
158
159template <typename Base, typename Value>
160struct accessor_helper_t<const Base&, Value>
161{
162 typedef const Base& argument_type;
163 typedef const Value& result_type;
164 typedef Value value_type;
165 typedef const Value& reference;
166 typedef const Value* pointer;
167protected:
168 ~accessor_helper_t() {}
169};
170
171
172
173template <typename It, typename First>
174struct first_accessor_t: accessor_helper_t<typename std::iterator_traits<It>::reference, First>
175{
176 typedef typename accessor_helper_t<typename std::iterator_traits<It>::reference, First>::reference reference;
177 reference operator()(It i) const { return i->first; }
178};
179
180/** @relates first_accessor_t
181 */
182template <typename It>
184first_iterator(It i)
185{
187}
188
189
190
191template <typename It, typename Second>
192struct second_accessor_t: accessor_helper_t<typename std::iterator_traits<It>::reference, Second>
193{
194 typedef typename accessor_helper_t<typename std::iterator_traits<It>::reference, Second>::reference reference;
195 reference operator()(It i) const { return i->second; }
196};
197
198/** @relates second_accessor_t
199 */
200template <typename It>
202second_iterator(It i)
203{
205}
206
207
208template <typename It, typename Value, typename Base>
209struct member_accessor_t: accessor_helper_t<Base&, Value>
210{
211 typedef Value Base::*mem_ptr_type;
212 typedef typename accessor_helper_t<Base&, Value>::reference reference;
213 member_accessor_t(mem_ptr_type mem_ptr = mem_ptr_type()): mem_ptr_(mem_ptr) {}
214 reference operator()(It i) const { return (*i).*mem_ptr_; }
215private:
216 mem_ptr_type mem_ptr_;
217};
218
219template <typename It, typename Value, typename Base>
221member_iterator(It i, Value Base::*mem_ptr)
222{
224}
225
226template <typename It, typename Value, typename Base>
228const_member_iterator(It i, Value Base::*mem_ptr)
229{
231}
232
233}
234}
235
236#endif
237
238// EOF
iterator adaptor to access members.
lass extensions to the standard library
Library for Assembled Shared Sources.
Definition config.h:53