traits.h 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. //
  2. // traits.hpp
  3. // stream
  4. //
  5. // Created by Sam Jaffe on 6/24/17.
  6. //
  7. #pragma once
  8. #include <type_traits>
  9. #include <utility>
  10. #include <iterator/detail/traits.h>
  11. #include <iterator/facade.h>
  12. #include <stream/forward.h>
  13. #include <stream/detail/macro.h>
  14. namespace stream::detail {
  15. template <typename C> using begin_t = decltype(std::begin(VAL(C)));
  16. template <typename C> using end_t = decltype(std::end(VAL(C)));
  17. template <typename C> using ref_t = decltype(*VAL(begin_t<C>));
  18. template <typename C> using value_type = std::remove_reference_t<ref_t<C>>;
  19. template <typename C> using cref_t = std::add_const_t<ref_t<C>>;
  20. template <typename, typename = void> struct has_size : std::false_type {};
  21. template <typename, typename = void> struct has_empty : std::false_type {};
  22. template <typename C>
  23. struct has_size<C, std::enable_if_t<std::is_integral_v<TYPE(C, size())>>>
  24. : std::true_type {};
  25. template <typename C>
  26. struct has_empty<C, std::enable_if_t<std::is_same_v<TYPE(C, empty()), bool>>>
  27. : std::true_type {};
  28. template <typename It, typename S, typename = void>
  29. struct is_comparable : std::false_type {};
  30. template <typename It, typename S>
  31. struct is_comparable<It, S, EXISTS(VAL(It) == VAL(S))> : std::true_type {};
  32. template <typename It, typename S, typename = void>
  33. struct is_sized_sentinel : std::false_type {};
  34. template <typename It, typename S>
  35. struct is_sized_sentinel<It, S, EXISTS(VAL(S) - VAL(It))> : std::true_type {};
  36. template <typename C> constexpr bool has_size_v = has_size<C>{};
  37. template <typename C> constexpr bool has_empty_v = has_empty<C>{};
  38. template <typename It, typename S>
  39. constexpr bool is_comparable_v = is_comparable<It, S>{};
  40. template <typename S>
  41. constexpr bool has_sentinal_v = !std::is_same_v<begin_t<S>, end_t<S>>;
  42. template <typename S, template <typename...> class Iter, typename... Ts>
  43. using sentinel_iterator =
  44. std::conditional_t<detail::has_sentinal_v<S>, detail::end_t<S>,
  45. Iter<detail::begin_t<S>, Ts...>>;
  46. template <typename It, typename S>
  47. constexpr bool is_sized_sentinel_v = is_sized_sentinel<It, S>{};
  48. }
  49. #include <stream/detail/undef.h>