BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlb_functionoutputiterator.h
Go to the documentation of this file.
1/// @file bdlb_functionoutputiterator.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bdlb_functionoutputiterator.h -*-C++-*-
8#ifndef INCLUDED_BDLB_FUNCTIONOUTPUTITERATOR
9#define INCLUDED_BDLB_FUNCTIONOUTPUTITERATOR
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bdlb_functionoutputiterator bdlb_functionoutputiterator
15/// @brief Provides an output iterator for a client-supplied functor.
16/// @addtogroup bdl
17/// @{
18/// @addtogroup bdlb
19/// @{
20/// @addtogroup bdlb_functionoutputiterator
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bdlb_functionoutputiterator-purpose"> Purpose</a>
25/// * <a href="#bdlb_functionoutputiterator-classes"> Classes </a>
26/// * <a href="#bdlb_functionoutputiterator-description"> Description </a>
27/// * <a href="#bdlb_functionoutputiterator-usage"> Usage </a>
28/// * <a href="#bdlb_functionoutputiterator-example-1-adapting-a-free-function-to-an-output-iterator"> Example 1: Adapting a Free-Function to an Output Iterator </a>
29/// * <a href="#bdlb_functionoutputiterator-example-2-adapting-a-functor-to-an-output-iterator"> Example 2: Adapting A Functor to An Output Iterator </a>
30///
31/// # Purpose {#bdlb_functionoutputiterator-purpose}
32/// Provides an output iterator for a client-supplied functor.
33///
34/// # Classes {#bdlb_functionoutputiterator-classes}
35///
36/// - bdlb::FunctionOutputIterator: function output iterator template
37///
38/// @see bdlb_nulloutputiterator
39///
40/// # Description {#bdlb_functionoutputiterator-description}
41/// This component provides an iterator template mechanism,
42/// `bdlb::FunctionOutputIterator`, that adapts a client supplied functor (or
43/// function pointer) to a C++ compliant output iterator. This component allows
44/// clients to create custom output iterators easily.
45///
46/// A `bdlb::FunctionOutputIterator` instance's template parameter type
47/// `FUNCTION` must be a functor (or function) that can be called as if it has
48/// the following signature:
49/// @code
50/// void operator()(const TYPE&)'
51/// @endcode
52/// where `TYPE` is the type of the object that will be assigned (by clients)
53/// to the dereferenced iterator. For example:
54/// @code
55/// void myFunction(const int& value) {};
56/// typedef void (*MyFunctionPtr)(const int&);
57/// typedef bdlb::FunctionOutputIterator<MyFunctionPtr> MyFunctionIterator;
58///
59/// MyFunctionIterator it(&foo);
60/// *it = 5; // Calls 'myFunction(5)'!
61/// @endcode
62/// Notice that assigning 5 to the dereferenced output iterator invokes the
63/// function with the value 5.
64///
65/// The provided output iterator has the following attributes:
66///
67/// * Meets the requirements for an output iterator according to the
68/// C++ Standard (C++11, Section 24.2.4 [output.iterators]).
69/// * Dereferencing an iterator and assigning to the result leads to a call
70/// of the functional object owned by the iterator. The value assigned to
71/// the dereferenced iterator is passed to a call of the function or functor
72/// held by the iterator as a constant reference. In other words, the
73/// assignment `*it = value` is equivalent to `function(value)`.
74/// * Incrementing an iterator is a no-op.
75///
76/// ## Usage {#bdlb_functionoutputiterator-usage}
77///
78///
79/// This section illustrates intended use of this component.
80///
81/// ### Example 1: Adapting a Free-Function to an Output Iterator {#bdlb_functionoutputiterator-example-1-adapting-a-free-function-to-an-output-iterator}
82///
83///
84/// Suppose we want use a provided function `foo`, that prints integers in some
85/// predefined format, to print each unique element of an array. Instead of
86/// manually writing a loop and checking for duplicate elements, we would like
87/// to use a standard algorithm such as @ref unique_copy . However, @ref unique_copy
88/// takes in an output iterator instead of a free function. We can use
89/// `bdlb::FunctionOutputIterator` to adapt `foo` into an output iterator that
90/// is acceptable by @ref unique_copy .
91///
92/// First, we define the type `Function` and a function of that type `foo`:
93/// @code
94/// typedef void (*Function)(const int&);
95///
96/// void foo(const int& value)
97/// {
98/// bsl::cout << value << " ";
99/// }
100/// @endcode
101/// Then, we define a data sequence to process:
102/// @code
103/// enum { NUM_VALUES_1 = 7 };
104/// const int array1[NUM_VALUES_1] = { 2, 3, 3, 5, 7, 11, 11 };
105/// @endcode
106/// Next, we use `bdlb::FunctionOutputIterator` to wrap `foo` for use in the
107/// algorithm `bsl::unqiue_copy`:
108/// @code
109/// unique_copy(
110/// array1,
111/// array1 + NUM_VALUES,
112/// bdlb::FunctionOutputIterator<Function>(&foo));
113/// @endcode
114/// Notice, that each time `bsl::unique_copy` copies an element from the
115/// supplied range and assigns it to the output iterator, the function `foo` is
116/// called for the element.
117///
118/// Finally, the resulting console output:
119/// @code
120/// 2 3 5 7 11
121/// @endcode
122///
123/// ### Example 2: Adapting A Functor to An Output Iterator {#bdlb_functionoutputiterator-example-2-adapting-a-functor-to-an-output-iterator}
124///
125///
126/// The following example demonstrates using a `bdlb::FunctionOutputIterator`
127/// with a user defined functor object. Consider the `Accumulator` class for
128/// accumulating integer values into a total. We want to adapt `Accumulator`
129/// for use with the algorithm `bsl::unique_copy`.
130///
131/// First, we define an `Accumulator` class that will total the values supplied
132/// to the `increment` method:
133/// @code
134/// /// This class provides a value accumulating functionality.
135/// class Accumulator {
136///
137/// // DATA
138/// int d_sum;
139/// public:
140/// // CREATORS
141/// Accumulator() : d_sum(0) {};
142///
143/// // MANIPULATORS
144/// void increment(int value) { d_sum += value; };
145///
146/// // ACCESSORS
147/// int total() const { return d_sum; }
148/// };
149/// @endcode
150/// Next, we define a functor, `AccumulatorFunctor`, that adapts `Accumulator`
151/// to a function object:
152/// @code
153///
154/// /// This class implements a function object that invokes 'increment' in
155/// /// response of calling operator()(int).
156/// class AccumulatorFunctor {
157///
158/// // DATA
159/// Accumulator *d_accumulator_p; // accumulator (held, not owned)
160///
161/// public:
162/// // CREATORS
163/// explicit AccumulatorFunctor(Accumulator *accumulator)
164/// : d_accumulator_p(accumulator)
165/// {}
166///
167/// // MANIPULATORS
168/// void operator()(int value) { d_accumulator_p->increment(value); };
169/// };
170/// @endcode
171/// Then, we define data sequence to process:
172/// @code
173/// enum { NUM_VALUES_2 = 7 };
174/// const int array2[NUM_VALUES_2] = { 2, 3, 3, 5, 7, 11, 11 };
175/// @endcode
176/// Next, we create a `bdlb::FunctionOutputIterator` for `AccumulatorFunctor`
177/// and supply it to the `bsl::unique_copy` algorithm to accumulate a sequence
178/// of values:
179/// @code
180/// Accumulator accumulator;
181/// unique_copy(
182/// array2,
183/// array2 + NUM_VALUES_2,
184/// bdlb::FunctionOutputIterator<AccumulatorFunctor>(
185/// AccumulatorFunctor(&accumulator)));
186/// @endcode
187/// Finally, we observe that `accumulator` holds the accumulated total of
188/// unique values in `array`:
189/// @code
190/// assert(28 == accumulator.total());
191/// @endcode
192/// @}
193/** @} */
194/** @} */
195
196/** @addtogroup bdl
197 * @{
198 */
199/** @addtogroup bdlb
200 * @{
201 */
202/** @addtogroup bdlb_functionoutputiterator
203 * @{
204 */
205
206#include <bdlscm_version.h>
207
208#include <bsls_libraryfeatures.h>
209
210#include <bsl_iterator.h>
211
212
213namespace bdlb {
214
215#if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD)
216// Sun Studio compilers have non-standard iterator behavior requiring iterators
217// to inherit from 'iterator' (rather than simply meeting the needs of
218// 'std::iterator_traits'). In addition, Sun Studio requires the 'value_type'
219// of the iterator to be instantiable (i.e., not 'void' as permitted by the
220// C++ standard).
221#define BDLB_SUNITERATORWORKAROUND \
222 : public bsl::iterator<bsl::output_iterator_tag, void *, void, void, void>
223#else
224#define BDLB_SUNITERATORWORKAROUND
225#endif
226
227 // ============================
228 // class FunctionOutputIterator
229 // ============================
230
231/// Provide an output iterator that calls an object of the (template
232/// parameter) type `FUNCTION`. If `FUNCTION` is a functor, de-referencing
233/// this iterator and assigning to the result (of dereferencing) will call
234/// the `operator()` of the functor with the assigned value as a parameter.
235/// Similarly, if `FUNCTION` if a function pointer type, assigning to the
236/// dereferenced iterator will call the function supplied at construction
237/// with the assigned value as a parameter.
238template <class FUNCTION>
239class FunctionOutputIterator BDLB_SUNITERATORWORKAROUND {
240
241 // PRIVATE TYPES
242
243 /// Provide an object that can appear on the left side of an assignment
244 /// from `TYPE`. The assignment to an instance of `AssignmentProxy`
245 /// results in a call of `operator(TYPE)` of the functor or function
246 /// supplied at construction. Instances of this class are created every
247 /// time an object of the host class is dereferenced.
248 ///
249 /// See @ref bdlb_functionoutputiterator
250 class AssignmentProxy {
251
252 // DATA
253 FUNCTION& d_function; // reference to functional object to be invoked
254 // when value assigned to the instance of this
255 // class
256 public:
257 // CREATORS
258
259 /// Create `AssignmentProxy` object having the specified `function`
260 /// value.
261 explicit AssignmentProxy(FUNCTION& function);
262
263 // MANIPULATORS
264
265 /// Invoke `d_function` with the specified `rhs` as a parameter.
266 /// The behavior is undefined unless `FUNCTION` is a function
267 /// pointer type and a valid function pointer was supplied at
268 /// construction.
269 template <class TYPE>
270 AssignmentProxy& operator=(const TYPE& rhs);
271 };
272
273 // DATA
274 FUNCTION d_function; // functional object to be invoked when value is
275 // assigned to dereferenced instance of this class
276
277 public:
278 // TYPES
279 typedef bsl::output_iterator_tag iterator_category;
280 typedef void difference_type;
281 typedef void value_type;
282 typedef void reference;
283
284 /// Provide type aliases required by C++ standard `iterator_traits`.
285 typedef void pointer;
286
287 // CREATORS
288
289 /// Create a `FunctionOutputIterator` object that, when an assignment is
290 /// performed on the dereferenced object, will call a default
291 /// constructed instance of the (template parameter) type `FUNCTION`
292 /// passing the assigned value as the argument. Note that if `FUNCTION`
293 /// is a function pointer type, then the default constructed `FUNCTION`
294 /// will be 0, and the behavior when assigning to a dereferenced
295 /// iterator will be undefined.
297
298 /// Create `FunctionOutputIterator` object that, when an assignment is
299 /// performed on the dereferenced object, will call the specified
300 /// `function` passing the assigned value as the argument.
301 explicit FunctionOutputIterator(const FUNCTION& function);
302
303 /// Create a 'FunctionOutputIterator' object that, when an assignment is
304 /// performed on the dereferenced object, will call the same function or
305 /// functor used by the specified 'rhs' object.
306 FunctionOutputIterator(const FunctionOutputIterator &rhs) = default;
307
308 /// Destroy this object.
310
311
312 // MANIPULATORS
313
314 /// Assign to this object the value of the specified 'rhs' object, and
315 /// return a reference providing modifiable access to this object.
316 FunctionOutputIterator& operator=(
317 const FunctionOutputIterator &rhs) = default;
318
319 /// Return an object that can appear on the left-hand side of an
320 /// assignment from `TYPE`. When a value is assigned to the returned
321 /// value, invoke the functor or function indicated at construction
322 /// supplying the assigned value as the parameter. This function is
323 /// non-`const` in accordance with the input iterator requirements, even
324 /// though `*this` is not modified. Note that if `FUNCTION` is a
325 /// function pointer type and a valid function pointer was not supplied
326 /// at construction, then the behavior when assigning to a dereferenced
327 /// iterator will be undefined.
328 AssignmentProxy operator*();
329};
330
331// FREE OPERATORS
332
333/// Do nothing and return specified `iterator`.
334template <class FUNCTION>
335inline
336FunctionOutputIterator<FUNCTION>& operator++(
337 FunctionOutputIterator<FUNCTION>& iterator);
338
339/// Do nothing and return specified `iterator`.
340template <class FUNCTION>
341inline
342FunctionOutputIterator<FUNCTION> operator++(
343 FunctionOutputIterator<FUNCTION>& iterator, int);
344
345// ============================================================================
346// INLINE DEFINITIONS
347// ============================================================================
348
349 // ---------------------------------------------
350 // class FunctionOutputIterator::AssignmentProxy
351 // ---------------------------------------------
352
353// CREATORS
354template <class FUNCTION>
355inline
356FunctionOutputIterator<FUNCTION>::AssignmentProxy::AssignmentProxy(
357 FUNCTION& function)
358 : d_function(function)
359{
360}
361
362// MANIPULATORS
363template <class FUNCTION>
364template <class TYPE>
365inline
366typename FunctionOutputIterator<FUNCTION>::AssignmentProxy&
367FunctionOutputIterator<FUNCTION>::AssignmentProxy::operator=(const TYPE& rhs)
368{
369 d_function(rhs);
370 return *this;
371}
372 // ----------------------------
373 // class FunctionOutputIterator
374 // ----------------------------
375
376// CREATORS
377template <class FUNCTION>
378inline
379FunctionOutputIterator<FUNCTION>::FunctionOutputIterator()
380 : d_function()
381{
382}
383
384template <class FUNCTION>
385inline
386FunctionOutputIterator<FUNCTION>::FunctionOutputIterator(
387 const FUNCTION& function)
388 : d_function(function)
389{
390}
391
392// MANIPULATORS
393template <class FUNCTION>
394inline
395typename FunctionOutputIterator<FUNCTION>::AssignmentProxy
396FunctionOutputIterator<FUNCTION>::operator*()
397{
398 return AssignmentProxy(d_function);
399}
400
401// FREE OPERATORS
402template <class FUNCTION>
403inline
404FunctionOutputIterator<FUNCTION>&
405operator++(FunctionOutputIterator<FUNCTION>& iterator)
406{
407 return iterator;
408}
409
410template <class FUNCTION>
411inline
412FunctionOutputIterator<FUNCTION>
413operator++(FunctionOutputIterator<FUNCTION>& iterator, int)
414{
415 return iterator;
416}
417
418#undef BDLB_SUNITERATORWORKAROUND
419
420} // close package namespace
421
422
423#endif
424// ----------------------------------------------------------------------------
425// Copyright 2019 Bloomberg Finance L.P.
426//
427// Licensed under the Apache License, Version 2.0 (the "License");
428// you may not use this file except in compliance with the License.
429// You may obtain a copy of the License at
430//
431// http://www.apache.org/licenses/LICENSE-2.0
432//
433// Unless required by applicable law or agreed to in writing, software
434// distributed under the License is distributed on an "AS IS" BASIS,
435// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
436// See the License for the specific language governing permissions and
437// limitations under the License.
438// ----------------------------- END-OF-FILE ----------------------------------
439
440/** @} */
441/** @} */
442/** @} */
Definition bdlb_functionoutputiterator.h:239
FunctionOutputIterator(const FunctionOutputIterator &rhs)=default
void value_type
Definition bdlb_functionoutputiterator.h:281
void difference_type
Definition bdlb_functionoutputiterator.h:280
FunctionOutputIterator & operator=(const FunctionOutputIterator &rhs)=default
bsl::output_iterator_tag iterator_category
Definition bdlb_functionoutputiterator.h:279
FunctionOutputIterator(const FUNCTION &function)
void pointer
Provide type aliases required by C++ standard iterator_traits.
Definition bdlb_functionoutputiterator.h:285
~FunctionOutputIterator()=default
Destroy this object.
void reference
Definition bdlb_functionoutputiterator.h:282
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bdlb_algorithmworkaroundutil.h:74
FunctionOutputIterator< FUNCTION > & operator++(FunctionOutputIterator< FUNCTION > &iterator)
Do nothing and return specified iterator.
Definition bdlb_functionoutputiterator.h:405