iterator 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  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. #pragma once
  6. #include <iterator>
  7. #include <cm/type_traits>
  8. namespace cm {
  9. // checks if a type is an iterator type
  10. template <typename I>
  11. using is_iterator =
  12. std::is_integral<typename std::iterator_traits<I>::difference_type>;
  13. // checks if a type is an input iterator type
  14. template <typename I>
  15. using is_input_iterator =
  16. std::is_base_of<std::input_iterator_tag,
  17. typename std::iterator_traits<I>::iterator_category>;
  18. // checks if a type is a range type: std::begin() and std::end() are supported
  19. template <typename Range>
  20. using is_range = cm::bool_constant<
  21. cm::is_iterator<decltype(std::begin(std::declval<const Range>()))>::value &&
  22. cm::is_iterator<decltype(std::end(std::declval<const Range>()))>::value>;
  23. // checks if a type is an input range type: std::begin() and std::end() are
  24. // returning an input iterator
  25. template <typename Range>
  26. using is_input_range =
  27. #if defined(_MSC_VER) && _MSC_VER < 1920
  28. // MS C++ is not able to evaluate complex type introspection,
  29. // so use a simplified version
  30. cm::bool_constant<std::is_class<Range>::value ||
  31. std::is_pointer<Range>::value ||
  32. std::is_array<Range>::value>;
  33. #else
  34. cm::bool_constant<cm::is_input_iterator<decltype(
  35. std::begin(std::declval<const Range>()))>::value &&
  36. cm::is_input_iterator<decltype(
  37. std::end(std::declval<const Range>()))>::value>;
  38. #endif
  39. } // namespace cm