iterator 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. // -*-c++-*-
  2. // vim: set ft=cpp:
  3. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  4. file LICENSE.rst 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 =
  21. #if defined(_MSC_VER) && _MSC_VER < 1920
  22. // MS C++ is not able to evaluate complex type introspection,
  23. // so use a simplified version
  24. cm::bool_constant<std::is_class<Range>::value ||
  25. std::is_array<Range>::value>;
  26. #else
  27. cm::bool_constant<
  28. cm::is_iterator<decltype(std::begin(
  29. std::declval<Range const>()))>::value &&
  30. cm::is_iterator<decltype(std::end(std::declval<Range const>()))>::value>;
  31. #endif
  32. // checks if a type is an input range type: std::begin() and std::end() are
  33. // returning an input iterator
  34. template <typename Range>
  35. using is_input_range =
  36. #if defined(_MSC_VER) && _MSC_VER < 1920
  37. // MS C++ is not able to evaluate complex type introspection,
  38. // so use a simplified version
  39. cm::bool_constant<std::is_class<Range>::value ||
  40. std::is_pointer<Range>::value ||
  41. std::is_array<Range>::value>;
  42. #else
  43. cm::bool_constant<cm::is_input_iterator<decltype(std::begin(
  44. std::declval<Range const>()))>::value &&
  45. cm::is_input_iterator<decltype(std::end(
  46. std::declval<Range const>()))>::value>;
  47. #endif
  48. } // namespace cm