# Boost Iterator Traits

Header `boost/iterator_traits.hpp`

The `boost::iterator_traits` class provides access to the associated types of iterators that model the Boost Iterator Concepts, which are a replacement for the iterator requirements in the C++ standard. The main difference between `std::iterator_traits` and `boost::iterator_traits` is that the `iterator_category` type has been removed, and replaced with two new types:

- `traversal_category`: Can the iterator go forward, backward, etc.?
- `return_category`: Is the iterator read or write only? Is the dereferenced type an lvalue?

An important feature of the `boost::iterator_traits` is that it is backwards compatible, i.e., it will automatically work for iterators for which there are valid definitions of `std::iterator_traits`. The old `iterator_category` is mapped to the appropriate traversal and return categories.

When creating a new iterator type that is meant to work with `boost::iterator_traits`, you can either create a specialization of `boost::iterator_traits` for your iterator type, or you can provide all the necessary associated types as nested typedefs. In this case, your iterator class will need to inherit from `new_iterator_base` to let `boost::iterator_traits` know that it will be able to find typedefs for `traversal_category` and `return_category` in you iterator class.

    namespace boost {

      // Inherit from iterator_base if your iterator defines its own
      // return_category and traversal_category. Otherwise, the "old style"
      // iterator category will be mapped to the return_category and
      // traversal_category.
      struct new_iterator_base { };

      template <typename Iterator>
      struct iterator_traits
      {
        if (Iterator inherits from new_iterator_base) {
          typedef typename Iterator::value_type value_type;
          typedef typename Iterator::reference reference;
          typedef typename Iterator::pointer pointer;
          typedef typename Iterator::difference_type difference_type;
          typedef typename Iterator::return_category return_category;
          typedef typename Iterator::traversal_category traversal_category;
        } else {
          typedef std::iterator_traits<Iterator> OldTraits;
          typedef typename OldTraits::value_type value_type;
          typedef typename OldTraits::reference reference;
          typedef typename OldTraits::pointer pointer;
          typedef typename OldTraits::difference_type difference_type;

          typedef typename OldTraits::iterator_category Cat;

          // Determine the traversal_category based on the old iterator_category
          if (Cat inherits from std::random_access_iterator_tag)
            typedef boost::random_access_iterator_tag traversal_category;
          else if (Cat inherits from std::bidirectional_iterator_tag)
            typedef boost::bidirectional_iterator_tag traversal_category;
          else if (Cat inherits from std::forward_iterator_tag)
            typedef boost::forward_iterator_tag traversal_category;
          else
            typedef boost::single_pass_iterator_tag traversal_category;

          // Determine the return_category based on the old iterator_category and value_type
          if (Cat inherits from std::forward_iterator_tag)
            if (is-const(T))
              typedef boost::constant_lvalue_iterator_tag return_category;
            else
              typedef boost::mutable_lvalue_iterator_tag return_category;
          else if (Cat inherits from std::input_iterator_tag)
            typedef boost::readable_iterator_tag return_category;
          else if (Cat inherits from std::output_iterator_tag)
            typedef boost::writable_iterator_tag return_category;
          else
            typedef boost::error_iterator_tag return_category;
        }
      };

      template <typename T>
      struct iterator_traits<T*>
      {
        typedef T value_type;
        typedef T& reference;
        typedef T* pointer;
        typedef std::ptrdiff_t difference_type;
        if (is-const(T))
          typedef boost::constant_lvalue_iterator_tag return_category;
        else
          typedef boost::mutable_lvalue_iterator_tag return_category;
        typedef boost::random_access_iterator_tag traversal_category;
      };

    }

Last modified: Mon Mar 19 12:59:30 EST 2001