1/*
2 * Distributed under the Boost Software License, Version 1.0.
3 * (See accompanying file LICENSE_1_0.txt or copy at
4 * https://www.boost.org/LICENSE_1_0.txt)
5 *
6 * Copyright (c) 2023 Andrey Semashev
7 */
8/*!
9 * \file iterator/is_iterator.hpp
10 *
11 * This header contains definition of the \c is_iterator type trait.
12 */
13
14#ifndef BOOST_ITERATOR_IS_ITERATOR_HPP_INCLUDED_
15#define BOOST_ITERATOR_IS_ITERATOR_HPP_INCLUDED_
16
17#include <cstddef>
18#include <boost/config.hpp>
19#include <boost/type_traits/integral_constant.hpp>
20#include <boost/type_traits/negation.hpp>
21#include <boost/type_traits/conjunction.hpp>
22#include <boost/type_traits/is_complete.hpp>
23#include <boost/type_traits/is_function.hpp>
24#if !defined(BOOST_NO_CXX17_ITERATOR_TRAITS)
25#include <iterator>
26#endif
27
28#ifdef BOOST_HAS_PRAGMA_ONCE
29#pragma once
30#endif
31
32namespace boost {
33namespace iterators {
34namespace detail {
35
36// The trait attempts to detect if the T type is an iterator class. Class-type iterators are assumed
37// to have the nested type iterator_category. Strictly speaking, this is not required to be the
38// case (e.g. a user can specialize iterator_traits for T without defining T::iterator_category).
39// Still, this is a good heuristic in practice, and we can't do anything better anyway.
40// Since C++17 we can test for iterator_traits<T>::iterator_category presence instead as it is
41// required to be only present for iterators.
42namespace has_iterator_category_detail {
43
44typedef char yes_type;
45struct no_type { char padding[2]; };
46
47template< typename T >
48yes_type check(
49#if !defined(BOOST_NO_CXX17_ITERATOR_TRAITS)
50 typename std::iterator_traits< T >::iterator_category*
51#else
52 typename T::iterator_category*
53#endif
54);
55template< typename >
56no_type check(...);
57
58} // namespace has_iterator_category_detail
59
60template< typename T >
61struct is_iterator_impl :
62 public boost::integral_constant<
63 bool,
64 sizeof(has_iterator_category_detail::check< T >(0)) == sizeof(has_iterator_category_detail::yes_type)
65 >
66{
67};
68
69template< typename T >
70struct is_iterator_impl< T* > :
71 public boost::conjunction<
72 boost::is_complete< T >,
73 boost::negation< boost::is_function< T > >
74 >::type
75{
76};
77
78template< typename T, typename U >
79struct is_iterator_impl< T U::* > :
80 public boost::false_type
81{
82};
83
84template< typename T >
85struct is_iterator_impl< T& > :
86 public boost::false_type
87{
88};
89
90template< typename T, std::size_t N >
91struct is_iterator_impl< T[N] > :
92 public boost::false_type
93{
94};
95
96#if !defined(BOOST_TT_HAS_WORKING_IS_COMPLETE)
97template< typename T >
98struct is_iterator_impl< T[] > :
99 public boost::false_type
100{
101};
102
103template< >
104struct is_iterator_impl< void > :
105 public boost::false_type
106{
107};
108
109template< >
110struct is_iterator_impl< void* > :
111 public boost::false_type
112{
113};
114#endif // !defined(BOOST_TT_HAS_WORKING_IS_COMPLETE)
115
116} // namespace detail
117
118/*!
119 * \brief The type trait detects whether the type \c T is an iterator type.
120 *
121 * The type trait yields \c true if its argument type \c T, after stripping top level
122 * cv qualifiers, is one of the following:
123 *
124 * - A pointer type, other than a pointer to function, a pointer to a class member,
125 * or a pointer to an incomplete type, including `void`.
126 * - A class type for which an iterator category is obtainable. Prior to C++17,
127 * the iterator category must be defined as a public `T::iterator_category` type.
128 * Since C++17, the expression `std::iterator_traits< T >::iterator_category` must
129 * be valid and produce the iterator category type.
130 *
131 * Otherwise, the type trait yields \c false.
132 */
133template< typename T >
134struct is_iterator : public detail::is_iterator_impl< T >::type {};
135template< typename T >
136struct is_iterator< const T > : public detail::is_iterator_impl< T >::type {};
137template< typename T >
138struct is_iterator< volatile T > : public detail::is_iterator_impl< T >::type {};
139template< typename T >
140struct is_iterator< const volatile T > : public detail::is_iterator_impl< T >::type {};
141
142} // namespace iterators
143
144using iterators::is_iterator;
145
146} // namespace boost
147
148#endif // BOOST_ITERATOR_IS_ITERATOR_HPP_INCLUDED_
149

source code of boost/libs/iterator/include/boost/iterator/is_iterator.hpp