iterator 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. // -*-c++-*-
  2. // vim: set ft=cpp:
  3. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  4. file Copyright.txt or https://cmake.org/licensing for details. */
  5. #ifndef cmext_iterator
  6. #define cmext_iterator
  7. #include <iterator>
  8. #include <cm/type_traits>
  9. namespace cm {
  10. // checks if a type is an iterator type
  11. template <typename I>
  12. using is_iterator =
  13. std::is_integral<typename std::iterator_traits<I>::difference_type>;
  14. // checks if a type is an input iterator type
  15. template <typename I>
  16. using is_input_iterator =
  17. std::is_base_of<std::input_iterator_tag,
  18. typename std::iterator_traits<I>::iterator_category>;
  19. // checks if a type is a range type: must have a difference_type type
  20. template <typename Range>
  21. using is_range = cm::bool_constant<
  22. cm::is_iterator<decltype(std::declval<const Range>().begin())>::value &&
  23. cm::is_iterator<decltype(std::declval<const Range>().end())>::value>;
  24. // checks if a type is an input range type: must have methods begin() and end()
  25. // returning an input iterator
  26. template <typename Range>
  27. using is_input_range =
  28. #if defined(_MSC_VER) && _MSC_VER < 1920
  29. // MS C++ is not able to evaluate complex type introspection,
  30. // so use a simplified version
  31. cm::is_input_iterator<typename Range::const_iterator>;
  32. #else
  33. cm::bool_constant<
  34. cm::is_input_iterator<decltype(
  35. std::declval<const Range>().begin())>::value &&
  36. cm::is_input_iterator<decltype(std::declval<const Range>().end())>::value>;
  37. #endif
  38. } // namespace cm
  39. #endif