Provide reverse iterator adapter for calendar iterators.
More...
Namespaces |
namespace | bdlt |
Detailed Description
- Outline
-
-
- Purpose:
- Provide reverse iterator adapter for calendar iterators.
-
- Classes:
-
- See also:
- Component bdlt_calendar, Component 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:
template <class TYPE>
class Iterator {
TYPE *d_ptr;
template <class OTHER>
friend bool operator==(const Iterator<OTHER>&, const Iterator<OTHER>&);
public:
typedef TYPE value_type;
typedef int difference_type;
typedef TYPE *pointer;
typedef TYPE& reference;
Iterator()
: d_ptr(0)
{
}
Iterator(TYPE *value)
: d_ptr(value)
{
}
Iterator& operator++()
{
++d_ptr;
return *this;
}
Iterator& operator--()
{
--d_ptr;
return *this;
}
reference operator*() const
{
return *d_ptr;
}
pointer operator->() const
{
return d_ptr;
}
Iterator operator+(bsl::ptrdiff_t offset) const
{
return Iterator(d_ptr + offset);
}
};
template <class TYPE>
inline
bool operator==(const Iterator<TYPE>& lhs, const Iterator<TYPE>& rhs)
{
return lhs.d_ptr == rhs.d_ptr;
}
template <class TYPE>
inline
bool operator!=(const Iterator<TYPE>& lhs, const Iterator<TYPE>& rhs)
{
return !(lhs == 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: 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: bsl::ostringstream stream;
for (Reverse it = rBegin; rEnd != it; ++it) {
stream << (rBegin == it ? "" : ", ")
<< "{ "
<< it->d_c
<< ", "
<< it->d_i
<< " }";
}
stream << bsl::flush;
Finally, we verify the contents of the range output: assert(stream.str() == "{ D, 9 }, { C, 7 }, { B, 5 }, { A, 3 }");