#ifndef ABSL_BASE_INTERNAL_ITERATOR_TRAITS_H_
#define ABSL_BASE_INTERNAL_ITERATOR_TRAITS_H_
#include <iterator>
#include <type_traits>
#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {
template <typename Iterator, typename = void>
struct IteratorCategory {};
template <typename Iterator>
struct IteratorCategory<
Iterator,
absl::void_t<typename std::iterator_traits<Iterator>::iterator_category>> {
using type = typename std::iterator_traits<Iterator>::iterator_category;
};
template <typename Iterator, typename = void>
struct IteratorConceptImpl : IteratorCategory<Iterator> {};
template <typename Iterator>
struct IteratorConceptImpl<
Iterator,
absl::void_t<typename std::iterator_traits<Iterator>::iterator_concept>> {
using type = typename std::iterator_traits<Iterator>::iterator_concept;
};
template <typename Iterator>
using IteratorConcept = typename IteratorConceptImpl<Iterator>::type;
template <typename IteratorTag, typename Iterator>
using IsAtLeastIterator =
std::is_convertible<IteratorConcept<Iterator>, IteratorTag>;
template <typename Iterator>
using IsAtLeastInputIterator =
IsAtLeastIterator<std::input_iterator_tag, Iterator>;
template <typename Iterator>
using IsAtLeastForwardIterator =
IsAtLeastIterator<std::forward_iterator_tag, Iterator>;
} ABSL_NAMESPACE_END
}
#endif