BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bdlt_calendarreverseiteratoradapter

Detailed Description

Outline

Purpose

Provide reverse iterator adapter for calendar iterators.

Classes

See also
bdlt_calendar, bdlt_packedcalendar

Description

This component provides a template, bdlt::CalendarReverseIteratorAdapter, that can be used to adapt a calendar iterator to be a reverse iterator (see bdlt_calendar and bdlt_packedcalendar ). Calendar iterators cannot return a reference to an underlying element of the calendar and hence cannot be used with bsl::reverse_iterator. The reverse iterator adapter defined in this component provides a subset of the bsl::reverse_iterator interface that can be used with the calendar iterators defined in bdlt. Specifically, the types value_type, difference_type , pointer, and reference are defined but iterator_category is not defined (since this is not a fully-compliant iterator). Furthermore, the methods appropriate for random-access iterators are not included (e.g., operator+=).

Limitation

bdlt::CalendarReverseIteratorAdapter is not a fully-compliant implementation of std::reverse_iterator according to the C++ standard. It is an implementation of the minimum functionality needed to support the public iterators in the bdlt_calendar and bdlt_packedcalendar components. Within that limitation, it is a subset implementation of bsl::reverse_iterator. Specifically, iterator_category is not defined for this adapter and the methods of a bsl::reverse_iterator relevant only to random-access compliant ITERATOR types are omitted.

Usage

This section illustrates intended use of this component.

Example 1: Basic Use of bdlt::CalendarReverseIteratorAdapter

In this example, we will use the bdlt::CalendarReverseIteratorAdapter to traverse an iterable container type. Specifically, we will create an array of struct values, implement a bidirectional iterator class that is a forward iterator for this array, and then use bdlt::CalendarReverseIteratorAdapter to provide a reverse iterator that will be used to traverse the array.

First, we define a bidirectional iterator class:

// This `class` basically behaves as a pointer to the (template
// parameter) `TYPE` with 4 types defined to allow the use of
// `bdlt::CalendarReverseIteratorAdapter` with this `class`. Note that
// this `class` supports only a subset of the functionality that a
// pointer would, but this subset covers all the functionality that a
// `bdlt::CalendarReverseIteratorAdapter` needs.
template <class TYPE>
class Iterator {
// DATA
TYPE *d_ptr; // pointer to the element referred to by this iterator
// FRIENDS
template <class OTHER>
friend bool operator==(const Iterator<OTHER>&, const Iterator<OTHER>&);
public:
// PUBLIC TYPES
typedef TYPE value_type;
typedef int difference_type;
typedef TYPE *pointer;
typedef TYPE& reference;
// CREATORS
/// Create an `Iterator` object having the default value.
Iterator()
: d_ptr(0)
{
}
/// Create an `Iterator` object from the specified `value`.
Iterator(TYPE *value) // IMPLICIT
: d_ptr(value)
{
}
// Iterator(const Iterator&) = default;
// ~Iterator() = default;
// MANIPULATORS
// Iterator& operator=(const Iterator&) = default;
/// Increment to the next element in the iteration sequence, and
/// return a reference providing modifiable access to this iterator.
/// The behavior is undefined if, on entry, this iterator has the
/// past-the-end value for an iterator over the underlying sequence.
Iterator& operator++()
{
++d_ptr;
return *this;
}
/// Decrement to the previous element in the iteration sequence, and
/// return a reference providing modifiable access to this iterator.
/// The behavior is undefined if, on entry, this iterator has the
/// same value as an iterator at the start of the underlying
/// sequence.
Iterator& operator--()
{
--d_ptr;
return *this;
}
// ACCESSORS
/// Return a reference to the element referred to by this iterator.
/// The behavior is undefined unless this iterator is within the
/// bounds of the underlying sequence.
reference operator*() const
{
return *d_ptr;
}
/// Return a pointer to the element referred to by this iterator.
/// The behavior is undefined unless this iterator is within the
/// bounds of the underlying sequence.
pointer operator->() const
{
return d_ptr;
}
// Return an iterator referencing the location at the specified
// `offset` from the element referenced by this iterator. The
// behavior is undefined unless the resultant iterator is within
// the bounds of the underlying sequence.
Iterator operator+(bsl::ptrdiff_t offset) const
{
return Iterator(d_ptr + offset);
}
};
// FREE OPERATORS
/// Return `true` if the specified `lhs` iterator has the same value as
/// the specified `rhs` iterator, and `false` otherwise. Two iterators
/// have the same value if they refer to the same element, or both have
/// the past-the-end value for am iterator over the underlying iteration
/// sequence. The behavior is undefined unless `lhs` and `rhs` refer to
/// the same underlying sequence.
template <class TYPE>
inline
bool operator==(const Iterator<TYPE>& lhs, const Iterator<TYPE>& rhs)
{
return lhs.d_ptr == rhs.d_ptr;
}
/// Return `true` if the specified `lhs` iterator does not have the same
/// value as the specified `rhs` iterator, and `false` otherwise. Two
/// iterators do not have the same value if (1) they do not refer to the
/// same element and (2) both do not have the past-the-end value for an
/// iterator over the underlying iteration sequence. The behavior is
/// undefined unless `lhs` and `rhs` refer to the same underlying
/// sequence.
template <class TYPE>
inline
bool operator!=(const Iterator<TYPE>& lhs, const Iterator<TYPE>& rhs)
{
return !(lhs == rhs);
}
bool operator!=(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
bool operator==(const FileCleanerConfiguration &lhs, const FileCleanerConfiguration &rhs)
TransformIterator< FUNCTOR, ITERATOR > operator--(TransformIterator< FUNCTOR, ITERATOR > &iterator, int)
FunctionOutputIterator< FUNCTION > & operator++(FunctionOutputIterator< FUNCTION > &iterator)
Do nothing and return specified iterator.
Definition bdlb_functionoutputiterator.h:405
TransformIterator< FUNCTOR, ITERATOR > operator+(const TransformIterator< FUNCTOR, ITERATOR > &iterator, typename TransformIterator< FUNCTOR, ITERATOR >::difference_type offset)
Decimal32 operator*(Decimal32 lhs, Decimal32 rhs)

Then, we define struct S, the type that will be referred to by the Iterator type:

struct S {
char d_c;
int d_i;
};

The struct S has two data members. By creating an array of distinct S values, the state of an iterator referring to an element of this array can be easily verified by inspecting these two members.

Next, we define four (distinct) S values:

const S s0 = { 'A', 3 };
const S s1 = { 'B', 5 };
const S s2 = { 'C', 7 };
const S s3 = { 'D', 9 };

Then, we define s, an array of S values:

S s[] = { s0, s1, s2, s3 };
enum { NUM_S = sizeof s / sizeof *s };

Next, we define an iterator, sfBegin, referring to the first element of s and an iterator, sfEnd, having the past-the-end value for an iterator over s:

Iterator<S> sfBegin(s + 0), sfEnd(s + NUM_S);

Then, for convenience we declare our reverse iterator type that will be used to traverse s in the reverse direction:

Definition bdlt_calendarreverseiteratoradapter.h:298

Next, we declare begin and end reverse iterators to our range of S values:

const Reverse rBegin(sfEnd), rEnd(sfBegin);

Now, we traverse our range in the reverse direction, from rBegin to rEnd, streaming out the contents of the S values as we go:

for (Reverse it = rBegin; rEnd != it; ++it) {
stream << (rBegin == it ? "" : ", ")
<< "{ "
<< it->d_c
<< ", "
<< it->d_i
<< " }";
}
stream << bsl::flush;
Definition bslstl_ostringstream.h:175

Finally, we verify the contents of the range output:

assert(stream.str() == "{ D, 9 }, { C, 7 }, { B, 5 }, { A, 3 }");
void str(const StringType &value)
Definition bslstl_ostringstream.h:581