Boost C++ Libraries

...one of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards

This is the documentation for an old version of Boost. Click here to view this page for the latest version.
PrevUpHomeNext

Type Traits

Overview

Have you ever wanted to write a generic function that can operate on any kind of dereferenceable object? If you have, you've probably run into the problem of how to determine the type that the object "points at":

template <class Dereferenceable>
void f(Dereferenceable p)
{
    *what-goes-here?* value = \*p;
    ...
}

pointee

It turns out to be impossible to come up with a fully-general algorithm to do determine what-goes-here directly, but it is possible to require that pointee<Dereferenceable>::type is correct. Naturally, pointee has the same difficulty: it can't determine the appropriate ::type reliably for all Dereferenceables, but it makes very good guesses (it works for all pointers, standard and boost smart pointers, and iterators), and when it guesses wrongly, it can be specialized as necessary:

namespace boost
{
  template <class T>
  struct pointee<third_party_lib::smart_pointer<T> >
  {
      typedef T type;
  };
}

indirect_reference

indirect_reference<T>::type is rather more specialized than pointee, and is meant to be used to forward the result of dereferencing an object of its argument type. Most dereferenceable types just return a reference to their pointee, but some return proxy references or return the pointee by value. When that information is needed, call on indirect_reference.

Both of these templates are essential to the correct functioning of indirect_iterator.

minimum_category

minimum_category takes two iterator categories or two iterator traversal tags and returns the one that is the weakest (i.e. least advanced). For example:

static_assert(
    is_same<
        minimum_category<
            std::forward_iterator_tag,
            std::random_access_iterator_tag
        >::type,
        std::forward_iterator_tag
    >::value,
    "Unexpected minimum_category result"
);

Iterator category and traversal tags manipulation

The library provides several utilities to simplify conversions between iterator categories and traversal tags:

Reference

pointee

template <class Dereferenceable>
struct pointee
{
    typedef /* see below */ type;
};

Requires: For an object x of type Dereferenceable, *x is well-formed. If ++x is ill-formed it shall neither be ambiguous nor shall it violate access control, and Dereferenceable::element_type shall be an accessible type. Otherwise iterator_traits<Dereferenceable>::value_type shall be well formed. [Note: These requirements need not apply to explicit or partial specializations of pointee]

type is determined according to the following algorithm, where x is an object of type Dereferenceable:

if ( ++x is ill-formed )
{
    return Dereferenceable::element_type
}
else if (*x is a mutable reference to
         std::iterator_traits<Dereferenceable>::value_type)
{
    return iterator_traits<Dereferenceable>::value_type
}
else
{
    return iterator_traits<Dereferenceable>::value_type const
}

indirect_reference

template <class Dereferenceable>
struct indirect_reference
{
    typedef /* see below */ type;
};

Requires: For an object x of type Dereferenceable, *x is well-formed. If ++x is ill-formed it shall neither be ambiguous nor shall it violate access control, and pointee<Dereferenceable>::type& shall be well-formed. Otherwise iterator_traits<Dereferenceable>::reference shall be well formed. [Note: These requirements need not apply to explicit or partial specializations of indirect_reference]

type is determined according to the following algorithm, where x is an object of type Dereferenceable:

if ( ++x is ill-formed )
    return pointee<Dereferenceable>::type&
else
    std::iterator_traits<Dereferenceable>::reference

minimum_category

template <typename C1, typename C2>
struct minimum_category
{
    typedef /* see below */ type;
};

Requires: Both C1 and C2 shall be standard iterator categories or iterator traversal tags.

type is determined according to the following algorithm, where c1 is an object of type C1 and c2 is an object of type C2:

if (c1 is convertible to c2)
    return C2;
else
    return C1;
[Note] Note

The above definition relies on the fact that the more restricting categories and traversal tags are convertible to the less restricting ones.

iterator_category_to_traversal

template <typename C>
struct iterator_category_to_traversal
{
    typedef /* see below */ type;
};

Requires: C shall be a standard iterator category or an iterator traversal tag.

If C is an iterator traversal tag or convertible to one, type equivalent to C. Otherwise, type is defined to the closest iterator traversal tag matching C.

iterator_traversal

template <typename Iterator>
struct iterator_traversal
{
    typedef typename iterator_category_to_traversal<
        typename iterator_category<Iterator>::type
    >::type type;
};

Requires: Iterator shall be an iterator.

pure_traversal_tag

template <typename T>
struct pure_traversal_tag
{
    typedef /* see below */ type;
};

Requires: T shall be convertible to an iterator traversal tag.

type is defined to be the most advanced traversal tag Tag so that T is convertible to Tag.

pure_iterator_traversal

template <typename Iterator>
struct pure_iterator_traversal
{
    typedef typename pure_traversal_tag<
        typename iterator_traversal<Iterator>::type
    >::type type;
};

Requires: Iterator shall be an iterator.


PrevUpHomeNext