123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- /*
- * Distributed under the Boost Software License, Version 1.0.
- * (See accompanying file LICENSE_1_0.txt or copy at
- * https://www.boost.org/LICENSE_1_0.txt)
- *
- * Copyright (c) 2023 Andrey Semashev
- */
- /*!
- * \file iterator/is_iterator.hpp
- *
- * This header contains definition of the \c is_iterator type trait.
- */
- #ifndef BOOST_ITERATOR_IS_ITERATOR_HPP_INCLUDED_
- #define BOOST_ITERATOR_IS_ITERATOR_HPP_INCLUDED_
- #include <cstddef>
- #include <boost/config.hpp>
- #include <boost/type_traits/integral_constant.hpp>
- #include <boost/type_traits/negation.hpp>
- #include <boost/type_traits/conjunction.hpp>
- #include <boost/type_traits/is_complete.hpp>
- #include <boost/type_traits/is_function.hpp>
- #if !defined(BOOST_NO_CXX17_ITERATOR_TRAITS)
- #include <iterator>
- #endif
- #ifdef BOOST_HAS_PRAGMA_ONCE
- #pragma once
- #endif
- namespace boost {
- namespace iterators {
- namespace detail {
- // The trait attempts to detect if the T type is an iterator class. Class-type iterators are assumed
- // to have the nested type iterator_category. Strictly speaking, this is not required to be the
- // case (e.g. a user can specialize iterator_traits for T without defining T::iterator_category).
- // Still, this is a good heuristic in practice, and we can't do anything better anyway.
- // Since C++17 we can test for iterator_traits<T>::iterator_category presence instead as it is
- // required to be only present for iterators.
- namespace has_iterator_category_detail {
- typedef char yes_type;
- struct no_type { char padding[2]; };
- template< typename T >
- yes_type check(
- #if !defined(BOOST_NO_CXX17_ITERATOR_TRAITS)
- typename std::iterator_traits< T >::iterator_category*
- #else
- typename T::iterator_category*
- #endif
- );
- template< typename >
- no_type check(...);
- } // namespace has_iterator_category_detail
- template< typename T >
- struct is_iterator_impl :
- public boost::integral_constant<
- bool,
- sizeof(has_iterator_category_detail::check< T >(0)) == sizeof(has_iterator_category_detail::yes_type)
- >
- {
- };
- template< typename T >
- struct is_iterator_impl< T* > :
- public boost::conjunction<
- boost::is_complete< T >,
- boost::negation< boost::is_function< T > >
- >::type
- {
- };
- template< typename T, typename U >
- struct is_iterator_impl< T U::* > :
- public boost::false_type
- {
- };
- template< typename T >
- struct is_iterator_impl< T& > :
- public boost::false_type
- {
- };
- template< typename T, std::size_t N >
- struct is_iterator_impl< T[N] > :
- public boost::false_type
- {
- };
- #if !defined(BOOST_TT_HAS_WORKING_IS_COMPLETE)
- template< typename T >
- struct is_iterator_impl< T[] > :
- public boost::false_type
- {
- };
- template< >
- struct is_iterator_impl< void > :
- public boost::false_type
- {
- };
- template< >
- struct is_iterator_impl< void* > :
- public boost::false_type
- {
- };
- #endif // !defined(BOOST_TT_HAS_WORKING_IS_COMPLETE)
- } // namespace detail
- /*!
- * \brief The type trait detects whether the type \c T is an iterator type.
- *
- * The type trait yields \c true if its argument type \c T, after stripping top level
- * cv qualifiers, is one of the following:
- *
- * - A pointer type, other than a pointer to function, a pointer to a class member,
- * or a pointer to an incomplete type, including `void`.
- * - A class type for which an iterator category is obtainable. Prior to C++17,
- * the iterator category must be defined as a public `T::iterator_category` type.
- * Since C++17, the expression `std::iterator_traits< T >::iterator_category` must
- * be valid and produce the iterator category type.
- *
- * Otherwise, the type trait yields \c false.
- */
- template< typename T >
- struct is_iterator : public detail::is_iterator_impl< T >::type {};
- template< typename T >
- struct is_iterator< const T > : public detail::is_iterator_impl< T >::type {};
- template< typename T >
- struct is_iterator< volatile T > : public detail::is_iterator_impl< T >::type {};
- template< typename T >
- struct is_iterator< const volatile T > : public detail::is_iterator_impl< T >::type {};
- } // namespace iterators
- using iterators::is_iterator;
- } // namespace boost
- #endif // BOOST_ITERATOR_IS_ITERATOR_HPP_INCLUDED_
|