type_traits.qbk 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211
  1. [section:traits Type Traits]
  2. [h2 Overview]
  3. Have you ever wanted to write a generic function that can operate
  4. on any kind of dereferenceable object? If you have, you've
  5. probably run into the problem of how to determine the type that the
  6. object "points at":
  7. template <class Dereferenceable>
  8. void f(Dereferenceable p)
  9. {
  10. *what-goes-here?* value = \*p;
  11. ...
  12. }
  13. [h2 `pointee`]
  14. It turns out to be impossible to come up with a fully-general
  15. algorithm to do determine *what-goes-here* directly, but it is
  16. possible to require that `pointee<Dereferenceable>::type` is
  17. correct. Naturally, `pointee` has the same difficulty: it can't
  18. determine the appropriate `::type` reliably for all
  19. `Dereferenceable`\ s, but it makes very good guesses (it works
  20. for all pointers, standard and boost smart pointers, and
  21. iterators), and when it guesses wrongly, it can be specialized as
  22. necessary:
  23. namespace boost
  24. {
  25. template <class T>
  26. struct pointee<third_party_lib::smart_pointer<T> >
  27. {
  28. typedef T type;
  29. };
  30. }
  31. [h2 `indirect_reference`]
  32. `indirect_reference<T>::type` is rather more specialized than
  33. `pointee`, and is meant to be used to forward the result of
  34. dereferencing an object of its argument type. Most dereferenceable
  35. types just return a reference to their pointee, but some return
  36. proxy references or return the pointee by value. When that
  37. information is needed, call on `indirect_reference`.
  38. Both of these templates are essential to the correct functioning of
  39. [link iterator.specialized.indirect `indirect_iterator`].
  40. [h2 `minimum_category`]
  41. `minimum_category` takes two iterator categories or two iterator traversal tags
  42. and returns the one that is the weakest (i.e. least advanced). For example:
  43. static_assert(
  44. is_same<
  45. minimum_category<
  46. std::forward_iterator_tag,
  47. std::random_access_iterator_tag
  48. >::type,
  49. std::forward_iterator_tag
  50. >::value,
  51. "Unexpected minimum_category result"
  52. );
  53. [h2 Iterator category and traversal tags manipulation]
  54. The library provides several utilities to simplify conversions between iterator categories
  55. and traversal tags:
  56. * `iterator_category_to_traversal<C>::type` - the metafunction takes an iterator category `C` and returns
  57. the corresponding traversal tag.
  58. * `iterator_traversal<T>::type` - a shorthand for `iterator_category_to_traversal<iterator_category<T>::type>::type`.
  59. * `pure_traversal_tag<T>::type` - the metafunction takes a tag `T` which derives from one of the iterator traversal tags
  60. and returns that traversal tag. `T` may also derive from other tags describing the iterator (e.g. whether this is a `const`-iterator
  61. or not), these additional tags are not considered.
  62. * `pure_iterator_traversal<T>::type` - a shorthand for `pure_traversal_tag<iterator_traversal<T>::type>::type`.
  63. [h2 Reference]
  64. [h3 `pointee`]
  65. template <class Dereferenceable>
  66. struct pointee
  67. {
  68. typedef /* see below */ type;
  69. };
  70. [*Requires:] For an object `x` of type `Dereferenceable`, `*x`
  71. is well-formed. If `++x` is ill-formed it shall neither be
  72. ambiguous nor shall it violate access control, and
  73. `Dereferenceable::element_type` shall be an accessible type.
  74. Otherwise `iterator_traits<Dereferenceable>::value_type` shall
  75. be well formed. \[Note: These requirements need not apply to
  76. explicit or partial specializations of `pointee`\]
  77. `type` is determined according to the following algorithm, where
  78. `x` is an object of type `Dereferenceable`:
  79. if ( ++x is ill-formed )
  80. {
  81. return Dereferenceable::element_type
  82. }
  83. else if (*x is a mutable reference to
  84. std::iterator_traits<Dereferenceable>::value_type)
  85. {
  86. return iterator_traits<Dereferenceable>::value_type
  87. }
  88. else
  89. {
  90. return iterator_traits<Dereferenceable>::value_type const
  91. }
  92. [h3 `indirect_reference`]
  93. template <class Dereferenceable>
  94. struct indirect_reference
  95. {
  96. typedef /* see below */ type;
  97. };
  98. [*Requires:] For an object `x` of type `Dereferenceable`, `*x`
  99. is well-formed. If `++x` is ill-formed it shall neither be
  100. ambiguous nor shall it violate access control, and
  101. `pointee<Dereferenceable>::type&` shall be well-formed.
  102. Otherwise `iterator_traits<Dereferenceable>::reference` shall
  103. be well formed. \[Note: These requirements need not apply to
  104. explicit or partial specializations of `indirect_reference`\]
  105. `type` is determined according to the following algorithm, where
  106. `x` is an object of type `Dereferenceable`:
  107. if ( ++x is ill-formed )
  108. return pointee<Dereferenceable>::type&
  109. else
  110. std::iterator_traits<Dereferenceable>::reference
  111. [h3 `minimum_category`]
  112. template <typename C1, typename C2>
  113. struct minimum_category
  114. {
  115. typedef /* see below */ type;
  116. };
  117. [*Requires:] Both `C1` and `C2` shall be standard iterator categories or
  118. iterator traversal tags.
  119. `type` is determined according to the following algorithm, where `c1` is an
  120. object of type `C1` and `c2` is an object of type `C2`:
  121. if (c1 is convertible to c2)
  122. return C2;
  123. else
  124. return C1;
  125. [note The above definition relies on the fact that the more restricting categories
  126. and traversal tags are convertible to the less restricting ones.]
  127. [h3 `iterator_category_to_traversal`]
  128. template <typename C>
  129. struct iterator_category_to_traversal
  130. {
  131. typedef /* see below */ type;
  132. };
  133. [*Requires:] `C` shall be a standard iterator category or an
  134. iterator traversal tag.
  135. If `C` is an iterator traversal tag or convertible to one, `type` equivalent to `C`.
  136. Otherwise, `type` is defined to the closest iterator traversal tag matching `C`.
  137. [h3 `iterator_traversal`]
  138. template <typename Iterator>
  139. struct iterator_traversal
  140. {
  141. typedef typename iterator_category_to_traversal<
  142. typename iterator_category<Iterator>::type
  143. >::type type;
  144. };
  145. [*Requires:] `Iterator` shall be an iterator.
  146. [h3 `pure_traversal_tag`]
  147. template <typename T>
  148. struct pure_traversal_tag
  149. {
  150. typedef /* see below */ type;
  151. };
  152. [*Requires:] `T` shall be convertible to an iterator traversal tag.
  153. `type` is defined to be the most advanced traversal tag `Tag` so that `T` is convertible to `Tag`.
  154. [h3 `pure_iterator_traversal`]
  155. template <typename Iterator>
  156. struct pure_iterator_traversal
  157. {
  158. typedef typename pure_traversal_tag<
  159. typename iterator_traversal<Iterator>::type
  160. >::type type;
  161. };
  162. [*Requires:] `Iterator` shall be an iterator.
  163. [endsect]