BDE 4.14.0 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 template <class ELEM_TYPE>
229 struct ValueSetter {
230 const ELEM_TYPE *d_value;
231
232 public:
233 ValueSetter(const ELEM_TYPE* value) : d_value(value) { }
234 int operator()(value_type* element) {
235 bdlat_ValueTypeFunctions::assign(element, *d_value);
236 return 0;
237 }
238 };
239
240 public:
241 // CREATORS
242
243 /// Construct a back-insertion iterator to manipulate the specified
244 /// `array`.
245 BackInsertIterator(TYPE* array);
246
247#ifdef BSLS_COMPILERFEATURES_SUPPORT_DEFAULTED_FUNCTIONS
248 /// Construct a copy of the specified `original`.
249 BackInsertIterator(const BackInsertIterator& original) = default;
250#endif
251
252#ifdef DOXYGEN // Compiler-generated functions:
254 // Destroy this iterator
255#endif
256
257 // MANIPULATORS
258
259 /// Assign this iterator the value of the specified `rhs`.
261
262 /// Append the specified `obj` to the end of the array manipulated by
263 /// this iterator and return this iterator.
264 template <class ELEM_TYPE>
265 BackInsertIterator& operator=(const ELEM_TYPE& obj);
266
267 /// Do nothing and return a reference to this modifiable iterator. This
268 /// function is used in generic algorithms that use the expression
269 /// `*i++ = v` or `*++i = v`.
271
272 /// Do nothing and return a reference to this modifiable iterator. This
273 /// function is used in generic algorithms that use the expression
274 /// `*++i = v`
276
277 /// Do nothing and return a copy of this iterator. This function is
278 /// used in generic algorithms that use the expression `*i++ = v`
280};
281
282/// Return a `BackInsertIterator` (of the appropriate type) to manipulate
283/// the specified `array`. Specializations of this function might return a
284/// different back-inserter type.
285template <class TYPE>
287
288/// Specialization of `backInserter` for `bsl::vector`. Return
289/// `bsl::back_insert_iterator instead of `BackInsertIterator'.
290template <class TYPE, class ALLOC>
291typename bsl::back_insert_iterator<bsl::vector<TYPE, ALLOC> >
293
294} // close namespace bdlat_ArrayIterators
295
296// ============================================================================
297// INLINE DEFINITIONS
298// ============================================================================
299
300 // ------------------------------
301 // namespace bdlat_ArrayIterators
302 // ------------------------------
303
304 // ------------------------
305 // class BackInsertIterator
306 // ------------------------
307
308// CREATORS
309template <class TYPE>
310inline
315
316// MANIPULATORS
317template <class TYPE>
318inline
321 const BackInsertIterator& rhs)
322{
323 d_array = rhs.d_array;
324 return *this;
325}
326
327template <class TYPE>
328template <class ELEM_TYPE>
329inline
332{
333 const int length = static_cast<int>(bdlat_ArrayFunctions::size(*d_array));
334 bdlat_ArrayFunctions::resize(d_array, length + 1);
335 ValueSetter<ELEM_TYPE> setter(&obj);
336 bdlat_ArrayFunctions::manipulateElement(d_array, setter, length);
337
338 return *this;
339}
340
341template <class TYPE>
342inline
348
349template <class TYPE>
350inline
356
357template <class TYPE>
358inline
364
365 // -------------------------
366 // namespace-level functions
367 // -------------------------
368
369template <class TYPE>
370inline
373{
374 return BackInsertIterator<TYPE>(array);
375}
376
377template <class TYPE, class ALLOC>
378inline
379typename bsl::back_insert_iterator<bsl::vector<TYPE, ALLOC> >
381{
382 return bsl::back_insert_iterator<bsl::vector<TYPE, ALLOC> >(*array);
383}
384
385
386
387#endif
388
389// ----------------------------------------------------------------------------
390// Copyright 2015 Bloomberg Finance L.P.
391//
392// Licensed under the Apache License, Version 2.0 (the "License");
393// you may not use this file except in compliance with the License.
394// You may obtain a copy of the License at
395//
396// http://www.apache.org/licenses/LICENSE-2.0
397//
398// Unless required by applicable law or agreed to in writing, software
399// distributed under the License is distributed on an "AS IS" BASIS,
400// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
401// See the License for the specific language governing permissions and
402// limitations under the License.
403// ----------------------------- END-OF-FILE ----------------------------------
404
405/** @} */
406/** @} */
407/** @} */
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:1025
BackInsertIterator(TYPE *array)
Definition bdlat_arrayiterators.h:311
BackInsertIterator & operator++()
Definition bdlat_arrayiterators.h:352
BackInsertIterator & operator*()
Definition bdlat_arrayiterators.h:344
BackInsertIterator & operator=(const BackInsertIterator &rhs)
Assign this iterator the value of the specified rhs.
Definition bdlat_arrayiterators.h:320
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
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:712