// bdlb_nulloutputiterator.h -*-C++-*- #ifndef INCLUDED_BDLB_NULLOUTPUTITERATOR #define INCLUDED_BDLB_NULLOUTPUTITERATOR #include <bsls_ident.h> BSLS_IDENT("$Id: $") //@PURPOSE: Provide an output iterator type that discards output. // //@CLASSES: // bdlb::NullOutputIterator: output iterator template that discards the output // bdlb::NullOutputIterator::AssignmentProxy: proxy for assignment // //@SEE_ALSO: bdlb_nullinputiterator // //@DESCRIPTION: This component provides a mechanism, // 'bdlb::NullOutputIterator', that defines an output iterator with the // following attributes: //: o Meets exactly the requirements for an output iterator according to the //: C++ Standard (C++98, Section 24.1.2 [lib.output.iterators]). //: o De-referencing an iterator and assigning to the returned value has no //: effect. //: o Incrementing an iterator has no effect. // // This iterator type is typically used to call functions purely for their // side-effects, discarding the normal output. It is also useful for testing // whether a template function will compile when presented with a pure output // iterator. This component also provides a template // 'bdlb::NullOutputIterator::AssignmentProxy', that is used as the return type // of 'bdlb::NullOutputIterator::operator*'. The 'AssignmentProxy' provides an // 'operator=' that does nothing, so that the result of the iterator's // 'operator*' can be assigned to even if the value type of the // 'bdlb::NullOutputIterator' does not provide a default constructor: //.. // class ValueType { // // ... data members ... // // public: // ValueType(int value) { ... implementation elided ... } // // // ... rest of class definition elided ... // // }; // // ValueType v(42); // bdlb::NullOutputIterator<ValueType> i; // // // With a non-proxy return type for 'operator*' it would be difficult to // // provide a value for the lefthand side of this expression: // // *i = v; //.. // ///Usage ///----- // This section illustrates intended use of this component. // /// Example 1: Basic Use of 'bdlb::NullOutputIterator' ///- - - - - - - - - - - - - - - - - - - - - - - - - - // In the following example we use a 'bdlb::NullOutputIterator' to enable us to // call a function to capture its return code, while ignoring the output // provided through an iterator. // // First, we define a function 'runningSum' that returns output both through an // output iterator and through a return status code: //.. // template <class IN_ITER, class OUT_ITER> // typename bsl::iterator_traits<OUT_ITER>::value_type // runningSum(IN_ITER first, IN_ITER last, OUT_ITER output) // { // typename bsl::iterator_traits<OUT_ITER>::value_type total = 0; // while (first != last) { // total += *first++; // *output++ = total; // } // return total; // } //.. // Now, we define a function 'average' that captures the total sum returned by // 'runningSum' and uses a 'bdlb::NullOutputIterator' to facilitate calling the // function, and ignoring the output it provides through its output iterator // parameter: //.. // int average(int values[], int numValues) // { // // ... input validation elided ... // return runningSum(values, values + numValues, // bdlb::NullOutputIterator<int>()) / numValues; // } //.. // Finally, we invoke function 'average' on user array and validate result. //.. // void usageExample() // { // const int myArray[5] = { 3, 4, 5, 7, 11 }; // // int averageValue = average(myArray, 5); // assert( averageValue == 6 ); // } //.. #include <bdlscm_version.h> #include <bsls_libraryfeatures.h> #include <bsl_iterator.h> namespace BloombergLP { namespace bdlb { // ======================================= // class NullOutputIteratorAssignmentProxy // ======================================= template <class TYPE> class NullOutputIteratorAssignmentProxy { // Provide an object that can appear on the left side of an assignment // from 'TYPE'. The operation AssignmentProxy() = TYPE() is valid and has // no effect. public: // MANIPULATORS void operator=(const TYPE& rhs); // Assign to this object the value of the specified 'rhs'. The operator // has no effect. }; // ======================== // class NullOutputIterator // ======================== template <class TYPE> class NullOutputIterator #if defined(BSLS_LIBRARYFEATURES_STDCPP_LIBCSTD) // Sun CC workaround: iterators must be derived from 'std::iterator' to work // with the native std library algorithms. However, 'std::iterator' is // deprecated in C++17, so do not rely on derivation unless required, to avoid // deprecation warnings on modern compilers. : public bsl::iterator<bsl::output_iterator_tag, TYPE> #endif { // Provide an output iterator that ignores the output that is provided. // De-referencing an iterator and assigning to the returned value has no // effect. public: // TYPES typedef NullOutputIteratorAssignmentProxy<TYPE> AssignmentProxy; // 'AssignmentProxy' is an alias for an object type returned by // de-referencing operator. typedef bsl::output_iterator_tag iterator_category; typedef TYPE value_type; typedef void difference_type; typedef void pointer; typedef void reference; public: // CREATORS NullOutputIterator(); // Create a 'NullOutputIterator' object. NullOutputIterator(const NullOutputIterator& original); // Create a 'NullOutputIterator' object having the value of the // specified 'original'. ~NullOutputIterator(); // Destroy this object. // MANIPULATORS NullOutputIterator& operator=(const NullOutputIterator& rhs); // Assign to this object the value of the specified 'rhs' iterator, and // return a reference providing modifiable access to this object. AssignmentProxy operator*(); // Return an object that can appear on the left-hand side of an // assignment from 'TYPE'. The assignment to the returned object has // no effect. NullOutputIterator& operator++(); // Set this object to point to the next writable element, and return a // reference providing modifiable access to this object. This // operation has no effect. NullOutputIterator& operator++(int); // Set this object to point to the next writable element, and return a // reference providing modifiable access to this object. This // operation has no effect. }; // ============================================================================ // INLINE DEFINITIONS // ============================================================================ // --------------------------------------- // class NullOutputIteratorAssignmentProxy // --------------------------------------- // MANIPULATORS template <class TYPE> inline void NullOutputIteratorAssignmentProxy<TYPE>::operator=(const TYPE&) { } // ------------------------ // class NullOutputIterator // ------------------------ // CREATORS template <class TYPE> inline NullOutputIterator<TYPE>::NullOutputIterator() { } template <class TYPE> inline NullOutputIterator<TYPE>::NullOutputIterator(const NullOutputIterator&) { } template <class TYPE> inline NullOutputIterator<TYPE>::~NullOutputIterator() { } // MANIPULATORS template <class TYPE> inline NullOutputIterator<TYPE>& NullOutputIterator<TYPE>::operator=(const NullOutputIterator&) { return *this; } template <class TYPE> inline typename NullOutputIterator<TYPE>::AssignmentProxy NullOutputIterator<TYPE>::operator*() { return AssignmentProxy(); } template <class TYPE> inline NullOutputIterator<TYPE>& NullOutputIterator<TYPE>::operator++() { return *this; } template <class TYPE> inline NullOutputIterator<TYPE>& NullOutputIterator<TYPE>::operator++(int) { return *this; } } // close package namespace } // close enterprise namespace #endif // ---------------------------------------------------------------------------- // Copyright 2015 Bloomberg Finance L.P. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // ----------------------------- END-OF-FILE ----------------------------------