source: trunk/src/xmlpatterns/iterators/qsequencemappingiterator_p.h@ 447

Last change on this file since 447 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 9.3 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the QtXmlPatterns module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42//
43// W A R N I N G
44// -------------
45//
46// This file is not part of the Qt API. It exists purely as an
47// implementation detail. This header file may change from version to
48// version without notice, or even be removed.
49//
50// We mean it.
51
52#ifndef Patternist_SequenceMappingIterator_H
53#define Patternist_SequenceMappingIterator_H
54
55#include "qabstractxmlforwarditerator_p.h"
56#include "qdynamiccontext_p.h"
57
58QT_BEGIN_HEADER
59
60QT_BEGIN_NAMESPACE
61
62namespace QPatternist
63{
64 /**
65 * @short Proxies another QAbstractXmlForwardIterator, and for each item, returns the
66 * Sequence returned from a mapping function.
67 *
68 * ItemMappingIterator is practical when the items in an QAbstractXmlForwardIterator needs to
69 * be translated to another sequence, while still doing it in a pipe-lined
70 * fashion. In contrast to ItemMappingIterator, SequenceMappingIterator maps
71 * each item into another QAbstractXmlForwardIterator, and where the SequenceMappingIterator's own
72 * result is the concatenation of all those Iterators. Hence, while ItemMappingIterator
73 * is better tailored for one-to-one or one-to-zero conversion, SequenceMappingIterator
74 * is more suitable for one-to-many conversion.
75 *
76 * This is achieved by that SequenceMappingIterator's constructor takes
77 * an instance of a class, that must have the following member:
78 *
79 * @code
80 * QAbstractXmlForwardIterator<TResult>::Ptr mapToSequence(const TSource::Ptr &item,
81 * const DynamicContext::Ptr &context) const;
82 * @endcode
83 *
84 * @author Frans Englich <[email protected]>
85 * @see ItemMappingIterator
86 * @ingroup Patternist_iterators
87 */
88 template<typename TResult, typename TSource, typename TMapper>
89 class SequenceMappingIterator : public QAbstractXmlForwardIterator<TResult>
90 {
91 public:
92 /**
93 * Constructs a SequenceMappingIterator.
94 *
95 * @param mapper the object that has the mapToItem() sequence.
96 * @param sourceIterator the QAbstractXmlForwardIterator whose items should be mapped.
97 * @param context the DynamicContext that will be passed to the map function.
98 * May be null.
99 */
100 SequenceMappingIterator(const TMapper &mapper,
101 const typename QAbstractXmlForwardIterator<TSource>::Ptr &sourceIterator,
102 const DynamicContext::Ptr &context);
103
104 virtual TResult next();
105 virtual xsInteger count();
106 virtual TResult current() const;
107 virtual xsInteger position() const;
108
109 /**
110 * The reason the implementation is placed in line here, is due to a bug
111 * in MSVC-2005 version 14.00.50727.762. Note that it works with version 14.00.50727.42.
112 */
113 virtual typename QAbstractXmlForwardIterator<TResult>::Ptr copy() const
114 {
115 return typename QAbstractXmlForwardIterator<TResult>::Ptr
116 (new SequenceMappingIterator<TResult, TSource, TMapper>(m_mapper,
117 m_mainIterator->copy(),
118 m_context));
119 }
120
121 private:
122 xsInteger m_position;
123 TResult m_current;
124 typename QAbstractXmlForwardIterator<TSource>::Ptr m_mainIterator;
125 typename QAbstractXmlForwardIterator<TResult>::Ptr m_currentIterator;
126 const typename DynamicContext::Ptr m_context;
127 const TMapper m_mapper;
128 };
129
130 template<typename TResult, typename TSource, typename TMapper>
131 SequenceMappingIterator<TResult, TSource, TMapper>::SequenceMappingIterator(
132 const TMapper &mapper,
133 const typename QAbstractXmlForwardIterator<TSource>::Ptr &iterator,
134 const DynamicContext::Ptr &context)
135 : m_position(0),
136 m_mainIterator(iterator),
137 m_context(context),
138 m_mapper(mapper)
139 {
140 Q_ASSERT(mapper);
141 Q_ASSERT(iterator);
142 }
143
144 template<typename TResult, typename TSource, typename TMapper>
145 TResult SequenceMappingIterator<TResult, TSource, TMapper>::next()
146 {
147 /* This was once implemented with a recursive function, but the stack
148 * got blown for some inputs by that approach. */
149 while(true)
150 {
151 while(!m_currentIterator)
152 {
153 const TSource mainItem(m_mainIterator->next());
154
155 if(qIsForwardIteratorEnd(mainItem)) /* We've reached the very end. */
156 {
157 m_position = -1;
158 m_current = TResult();
159 return TResult();
160 }
161 else
162 m_currentIterator = m_mapper->mapToSequence(mainItem, m_context);
163 }
164
165 m_current = m_currentIterator->next();
166
167 if(qIsForwardIteratorEnd(m_current))
168 {
169 m_currentIterator.reset();
170 continue;
171 }
172 else
173 {
174 ++m_position;
175 return m_current;
176 }
177 }
178 }
179
180 template<typename TResult, typename TSource, typename TMapper>
181 xsInteger SequenceMappingIterator<TResult, TSource, TMapper>::count()
182 {
183 TSource unit(m_mainIterator->next());
184 xsInteger c = 0;
185
186 while(!qIsForwardIteratorEnd(unit))
187 {
188 const typename QAbstractXmlForwardIterator<TResult>::Ptr sit(m_mapper->mapToSequence(unit, m_context));
189 c += sit->count();
190 unit = m_mainIterator->next();
191 }
192
193 return c;
194 }
195
196 template<typename TResult, typename TSource, typename TMapper>
197 TResult SequenceMappingIterator<TResult, TSource, TMapper>::current() const
198 {
199 return m_current;
200 }
201
202 template<typename TResult, typename TSource, typename TMapper>
203 xsInteger SequenceMappingIterator<TResult, TSource, TMapper>::position() const
204 {
205 return m_position;
206 }
207
208
209 /**
210 * @short An object generator for SequenceMappingIterator.
211 *
212 * makeSequenceMappingIterator() is a convenience function for avoiding specifying
213 * the full template instantiation for SequenceMappingIterator. Conceptually, it
214 * is identical to Qt's qMakePair().
215 *
216 * @returns a SequenceMappingIterator wrapped in a smart pointer, that has been
217 * passed the constructor arguments @p mapper, @p source, and @p context.
218 * @see makeMappingCallbackPtr()
219 * @relates QAbstractXmlForwardIterator
220 */
221 template<typename TResult, typename TSource, typename TMapper>
222 static inline
223 typename QAbstractXmlForwardIterator<TResult>::Ptr
224 makeSequenceMappingIterator(const TMapper &mapper,
225 const QExplicitlySharedDataPointer<QAbstractXmlForwardIterator<TSource> > &source,
226 const DynamicContext::Ptr &context)
227 {
228 return typename QAbstractXmlForwardIterator<TResult>::Ptr
229 (new SequenceMappingIterator<TResult, TSource, TMapper>(mapper, source, context));
230 }
231}
232
233QT_END_NAMESPACE
234
235QT_END_HEADER
236
237#endif
Note: See TracBrowser for help on using the repository browser.