Next : Iterator Operations, Previous : Examples of using iterator tags, Top : Table of Contents


Library defined primitives

input_iterator Iterator
output_iterator Iterator
forward_iterator Iterator
bidirectional_iterator Iterator
random_access_iterator Iterator

To simplify the task of defining the iterator_category, value_type and distance_type for user definable iterators, the library provides the following predefined classes and functions:

// iterator tags
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag {};
struct bidirectional_iterator_tag {};
struct random_access_iterator_tag {};

// iterator bases
template  struct input_iterator {};
struct output_iterator {};
// output_iterator is not a template because output iterators
// do not have either value type or distance type defined.
template  struct forward_iterator {};
template  struct bidirectional_iterator {};
template  struct random_access_iterator {};

// iterator_category
template 
inline input_iterator_tag
iterator_category(const input_iterator&) {
    return input_iterator_tag();
}

inline output_iterator_tag iterator_category(const output_iterator&) {
    return output_iterator_tag();
}

template 
inline forward_iterator_tag
iterator_category(const forward_iterator&) {
    return forward_iterator_tag();
}

template 
inline bidirectional_iterator_tag
iterator_category(const bidirectional_iterator&) {
    return bidirectional_iterator_tag();
}

template 
inline random_access_iterator_tag
iterator_category(const random_access_iterator&) {
    return random_access_iterator_tag();
}

template 
inline random_access_iterator_tag iterator_category(const T*) {
    return random_access_iterator_tag();}
}

// value_type of iterator
template 
inline T* value_type(const input_iterator&) {
    return (T*)(0);
}

template 
inline T* value_type(const forward_iterator&) {
    return (T*)(0);
}

template 
inline T* value_type(const bidirectional_iterator&) {
    return (T*)(0);
}

template 
inline T* value_type(const random_access_iterator&) {
    return (T*)(0);
}

template  inline T* value_type(const T*) { return (T*)(0); }

// distance_type of iterator
template 
inline Distance* distance_type(const input_iterator&) {
    return (Distance*)(0);
}

template 
inline Distance* distance_type(const forward_iterator&) {
    return (Distance*)(0);
}

template 
inline Distance* distance_type(const bidirectional_iterator&) {
    return (Distance*)(0);
}

template 
inline Distance* distance_type(const random_access_iterator&) {
    return (Distance*)(0);
}

template 
inline ptrdiff_t* distance_type(const T*) { return (ptrdiff_t*)(0); }

If a user wants to define a bidirectional iterator for some data structure containing double and such that it works on a large memory model of a computer, it can be done by defining:

class MyIterator : public bidirectional_iterator {
    // code implementing ++, etc.
};

Then there is no need to define iterator_category, value_type, and distance_type on MyIterator.


 

Top