traits.h 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  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 is_sentinal_v = !std::is_same_v<begin_t<S>, end_t<S>>;
  42. template <typename It, typename S>
  43. constexpr bool is_sized_sentinel_v = is_sized_sentinel<It, S>{};
  44. }
  45. #include <stream/detail/undef.h>