BDE 4.39.x Production Release
Loading...
Searching...
No Matches
bdlat_arrayiterators.h
Go to the documentation of this file.
1/// @file bdlat_arrayiterators.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlat_arrayiterators.h -*-C++-*-
8#ifndef INCLUDED_BDLAT_ARRAYITERATORS
9#define INCLUDED_BDLAT_ARRAYITERATORS
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlat_arrayiterators bdlat_arrayiterators
15/// @brief Provide iterator support for bdlat_ArrayFunction-conformant types.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlat
19/// @{
20/// @addtogroup bdlat_arrayiterators
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlat_arrayiterators-purpose"> Purpose</a>
25/// * <a href="#bdlat_arrayiterators-classes"> Classes </a>
26/// * <a href="#bdlat_arrayiterators-description"> Description </a>
27/// * <a href="#bdlat_arrayiterators-thread-safety"> Thread Safety </a>
28/// * <a href="#bdlat_arrayiterators-usage"> Usage </a>
29/// * <a href="#bdlat_arrayiterators-example-1-basic-usage"> Example 1: Basic Usage </a>
30///
31/// # Purpose {#bdlat_arrayiterators-purpose}
32/// Provide iterator support for bdlat_ArrayFunction-conformant types.
33///
34/// # Classes {#bdlat_arrayiterators-classes}
35///
36/// - bdlat_ArrayIterators::BackInsertIterator: class for appending to arrays
37///
38/// @see bdlat_arrayfunctions
39///
40/// # Description {#bdlat_arrayiterators-description}
41/// This component provides a namespace `bdlat_ArrayIterators` that
42/// contains definitions for the `bdlat_ArrayIterators::BackInsertIterator`
43/// class template and the `backInserter` convenience function. Additional
44/// iterator types may be added in the future.
45///
46/// `BackInsertIterator<ARRAY_TYPE>` is an iterator type which, when used in an
47/// expression like "*i++ = v", appends the value `v` to the end of the
48/// `ARRAY_TYPE` object used to construct the iterator, `i`. It meets the
49/// requirements of an STL output iterator and it can be instantiated for any
50/// type that meets the requirements described in @ref bdlat_arrayfunctions .
51/// `BackInsertIterator` is similar to the standard `bsl::back_insert_iterator`
52/// class template, which works for STL sequence containers.
53///
54/// The `backInserter` function template takes a parameter of type
55/// pointer-to-`ARRAY_TYPE`, where `ARRAY_TYPE` is a type that conforms to the
56/// interface described in the @ref bdlat_arrayfunctions component, and returns an
57/// object of type `BackInsertIterator<ARRAY_TYPE>`. It is a convenience
58/// function for creating a `BackInsertIterator` without declaring its exact
59/// type. The `backInserter` function is similar to the standard
60/// `bsl::back_inserter` template function, which works for STL sequence
61/// containers. In fact, `backInserter` is specialized for `bsl::vector` so
62/// that it returns an `bsl::back_insert_iterator`, just like
63/// `bsl::back_inserter` does.
64///
65/// ## Thread Safety {#bdlat_arrayiterators-thread-safety}
66///
67///
68/// A `BackInsertIterator` contains a pointer to an array object and multiple
69/// `backInsertIterator` objects may point to the same array object. It is
70/// safe to access or modify two `BackInsertIterator` objects simultaneously,
71/// each from a separate thread, if they each refer to a different array
72/// object. It is safe to access a single `BackInsertIterator` object
73/// simultaneously from two or more separate threads, provided no other thread
74/// is simultaneously modifying the iterator or its referenced array. It is
75/// not safe to access or modify a `BackInsertIterator` object in one thread
76/// while another thread modifies the same iterator, its referenced array
77/// object, or another iterator referring to the same array.
78///
79/// ## Usage {#bdlat_arrayiterators-usage}
80///
81///
82/// This section illustrates intended use of this component.
83///
84/// ### Example 1: Basic Usage {#bdlat_arrayiterators-example-1-basic-usage}
85///
86///
87/// To use the facilities in this component, you must of course include the
88/// header file:
89/// @code
90/// #include <bdlat_arrayiterators.h>
91/// @endcode
92/// The main use of the facilities in this component is for creating generic
93/// algorithms. The following generic function appends a few integers to the
94/// end of an object of type `ARRAY` that adheres to the `bdlat_ArrayFunctions`
95/// interface. It starts by creating a `BackInsertIterator`:
96/// @code
97/// template <typename ARRAY>
98/// void appendSome(ARRAY *arrayObj)
99/// {
100/// bdlat_ArrayIterators::BackInsertIterator<ARRAY> it(arrayObj);
101/// @endcode
102/// Now, using the "*i++ = v" idiom, append the numbers 5 and 4 to the array
103/// object:
104/// @code
105/// *it++ = 5;
106/// *it++ = 4;
107/// @endcode
108/// Alternatively, one can use the iterator in a standard algorithm. For
109/// example, the following code appends the numbers 3, 2, and 1 to the array
110/// object:
111/// @code
112/// const int VALUES[] = { 3, 2, 1 };
113/// const int NUM_VALUES = sizeof(VALUES) / sizeof(VALUES[0]);
114/// bsl::copy(VALUES, VALUES + NUM_VALUES, it);
115/// }
116/// @endcode
117/// An alternative implementation of `appendSome` would use `backInserter` to
118/// create an iterator without declaring its exact type. Note that, in this
119/// case, we do not create a variable `it`, but simply pass the iterator to a
120/// standard algorithm:
121/// @code
122/// template <typename ARRAY>
123/// void appendSome2(ARRAY *arrayObj)
124/// {
125/// const int VALUES[] = { 5, 4, 3, 2, 1 };
126/// const int NUM_VALUES = sizeof(VALUES) / sizeof(VALUES[0]);
127/// bsl::copy(VALUES, VALUES + NUM_VALUES,
128/// bdlat_ArrayIterators::backInserter(arrayObj));
129/// }
130/// @endcode
131/// In our main program, we need to construct an array that adheres to the
132/// @ref bdlat_arrayfunctions interface:
133/// @code
134/// #include <vector>
135///
136/// int main()
137/// {
138/// typedef bsl::vector<int> my_IntArrayType;
139/// @endcode
140/// The result of calling `appendSome` is that the elements 5, 4, 3, 2 and 1
141/// are appended to the array:
142/// @code
143/// my_IntArrayType array1;
144/// appendSome(&array1);
145/// assert(5 == array1[0]);
146/// assert(4 == array1[1]);
147/// assert(3 == array1[2]);
148/// assert(2 == array1[3]);
149/// assert(1 == array1[4]);
150/// @endcode
151/// The result of calling `appendSome2` is the same:
152/// @code
153/// my_IntArrayType array2;
154/// appendSome2(&array2);
155/// assert(array2 == array1);
156///
157/// return 0;
158/// }
159/// @endcode
160/// @}
161/** @} */
162/** @} */
163
164/** @addtogroup bdl
165 * @{
166 */
167/** @addtogroup bdlat
168 * @{
169 */
170/** @addtogroup bdlat_arrayiterators
171 * @{
172 */
173
174#include <bdlscm_version.h>
175
176#include <bdlat_arrayfunctions.h>
177#include <bdlat_bdeatoverrides.h>
179
181#include <bsls_libraryfeatures.h>
182
183#include <bsl_iterator.h>
184
185
186
187
188 // ==============================
189 // namespace bdlat_ArrayIterators
190 // ==============================
191
193
194 // ========================
195 // class BackInsertIterator
196 // ========================
197
198/// TBD doc
199template <class TYPE>
201#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
202// Sun CC workaround: iterators must be derived from 'std::iterator' to work
203// with the native std library algorithms. However, 'std::iterator' is
204// deprecated in C++17, so do not rely on derivation unless required, to avoid
205// deprecation warnings on modern compilers.
206 : public bsl::iterator<
207 bsl::output_iterator_tag,
208 typename bdlat_ArrayFunctions::ElementType<TYPE>::Type,
209 void, void, void>
210#endif // BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD
211{
212
213 public:
214 // TYPES
215 typedef bsl::output_iterator_tag iterator_category;
218 typedef void difference_type;
219 typedef void pointer;
220 typedef void reference;
221
222 private:
223 // Random-access iterator for any type that meets the requirements of a
224 // 'bdlat' array type.
225 TYPE* d_array;
226
227 /// Manipulator to set the value of a newly-inserted element.
228 ///
229 /// See @ref bdlat_arrayiterators
230 template <class ELEM_TYPE>
231 struct ValueSetter {
232 const ELEM_TYPE *d_value;
233
234 public:
235 ValueSetter(const ELEM_TYPE* value) : d_value(value) { }
236 int operator()(value_type* element) {
237 bdlat_ValueTypeFunctions::assign(element, *d_value);
238 return 0;
239 }
240 };
241
242 public:
243 // CREATORS
244
245 /// Construct a back-insertion iterator to manipulate the specified
246 /// `array`.
247 BackInsertIterator(TYPE* array);
248
249#ifdef BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS
250 /// Construct a copy of the specified `original`.
251 BackInsertIterator(const BackInsertIterator& original) = default;
252#endif
253
254#ifdef DOXYGEN // Compiler-generated functions:
256 // Destroy this iterator
257#endif
258
259 // MANIPULATORS
260
261 /// Assign this iterator the value of the specified `rhs`.
263
264 /// Append the specified `obj` to the end of the array manipulated by
265 /// this iterator and return this iterator.
266 template <class ELEM_TYPE>
267 BackInsertIterator& operator=(const ELEM_TYPE& obj);
268
269 /// Do nothing and return a reference to this modifiable iterator. This
270 /// function is used in generic algorithms that use the expression
271 /// `*i++ = v` or `*++i = v`.
273
274 /// Do nothing and return a reference to this modifiable iterator. This
275 /// function is used in generic algorithms that use the expression
276 /// `*++i = v`
278
279 /// Do nothing and return a copy of this iterator. This function is
280 /// used in generic algorithms that use the expression `*i++ = v`
282};
283
284/// Return a `BackInsertIterator` (of the appropriate type) to manipulate
285/// the specified `array`. Specializations of this function might return a
286/// different back-inserter type.
287template <class TYPE>
289
290/// Specialization of `backInserter` for `bsl::vector`. Return
291/// `bsl::back_insert_iterator instead of `BackInsertIterator'.
292template <class TYPE, class ALLOC>
293typename bsl::back_insert_iterator<bsl::vector<TYPE, ALLOC> >
295
296} // close namespace bdlat_ArrayIterators
297
298// ============================================================================
299// INLINE DEFINITIONS
300// ============================================================================
301
302 // ------------------------------
303 // namespace bdlat_ArrayIterators
304 // ------------------------------
305
306 // ------------------------
307 // class BackInsertIterator
308 // ------------------------
309
310// CREATORS
311template <class TYPE>
312inline
317
318// MANIPULATORS
319template <class TYPE>
320inline
323 const BackInsertIterator& rhs)
324{
325 d_array = rhs.d_array;
326 return *this;
327}
328
329template <class TYPE>
330template <class ELEM_TYPE>
331inline
334{
335 const int length = static_cast<int>(bdlat_ArrayFunctions::size(*d_array));
336 bdlat_ArrayFunctions::resize(d_array, length + 1);
337 ValueSetter<ELEM_TYPE> setter(&obj);
338 bdlat_ArrayFunctions::manipulateElement(d_array, setter, length);
339
340 return *this;
341}
342
343template <class TYPE>
344inline
350
351template <class TYPE>
352inline
358
359template <class TYPE>
360inline
366
367 // -------------------------
368 // namespace-level functions
369 // -------------------------
370
371template <class TYPE>
372inline
375{
376 return BackInsertIterator<TYPE>(array);
377}
378
379template <class TYPE, class ALLOC>
380inline
381typename bsl::back_insert_iterator<bsl::vector<TYPE, ALLOC> >
383{
384 return bsl::back_insert_iterator<bsl::vector<TYPE, ALLOC> >(*array);
385}
386
387
388
389#endif
390
391// ----------------------------------------------------------------------------
392// Copyright 2015 Bloomberg Finance L.P.
393//
394// Licensed under the Apache License, Version 2.0 (the "License");
395// you may not use this file except in compliance with the License.
396// You may obtain a copy of the License at
397//
398// http://www.apache.org/licenses/LICENSE-2.0
399//
400// Unless required by applicable law or agreed to in writing, software
401// distributed under the License is distributed on an "AS IS" BASIS,
402// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
403// See the License for the specific language governing permissions and
404// limitations under the License.
405// ----------------------------- END-OF-FILE ----------------------------------
406
407/** @} */
408/** @} */
409/** @} */
TBD doc.
Definition bdlat_arrayiterators.h:211
bdlat_ArrayFunctions::ElementType< TYPE >::Type value_type
Definition bdlat_arrayiterators.h:217
void reference
Definition bdlat_arrayiterators.h:220
void difference_type
Definition bdlat_arrayiterators.h:218
void pointer
Definition bdlat_arrayiterators.h:219
BackInsertIterator & operator=(const ELEM_TYPE &obj)
bsl::output_iterator_tag iterator_category
Definition bdlat_arrayiterators.h:215
Definition bslstl_vector.h:1120
BackInsertIterator(TYPE *array)
Definition bdlat_arrayiterators.h:313
BackInsertIterator & operator++()
Definition bdlat_arrayiterators.h:354
BackInsertIterator & operator*()
Definition bdlat_arrayiterators.h:346
BackInsertIterator & operator=(const BackInsertIterator &rhs)
Assign this iterator the value of the specified rhs.
Definition bdlat_arrayiterators.h:322
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
int manipulateElement(TYPE *array, MANIPULATOR &manipulator, int index)
void resize(TYPE *array, int newSize)
bsl::size_t size(const TYPE &array)
Return the number of elements in the specified array.
Definition bdlat_arrayiterators.h:192
BackInsertIterator< TYPE > backInserter(TYPE *array)
int assign(LHS_TYPE *lhs, const RHS_TYPE &rhs)
Definition bdlat_arrayfunctions.h:756