traits.h 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  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. #define _val(type) std::declval<type>()
  14. #define exists(expr) std::void_t<decltype(expr)>
  15. namespace stream::traits {
  16. template <typename C> using begin_t = decltype(std::begin(_val(C)));
  17. template <typename C> using end_t = decltype(std::end(_val(C)));
  18. template <typename C> using ref_t = decltype(*_val(begin_t<C>));
  19. template <typename C> using value_type = std::remove_reference_t<ref_t<C>>;
  20. template <typename C> using cref_t = std::add_const_t<ref_t<C>>;
  21. template <typename, typename = void> struct has_size : std::false_type {};
  22. template <typename, typename = void> struct has_empty : std::false_type {};
  23. template <typename C>
  24. struct has_size<C, std::enable_if_t<std::is_integral_v<decltype(_val(C).size())>>> : std::true_type {};
  25. template <typename C>
  26. struct has_empty<C, std::enable_if_t<std::is_same_v<decltype(_val(C).empty()), bool>>> : std::true_type {};
  27. template <typename It, typename S, typename = void>
  28. struct is_comparable : std::false_type {};
  29. template <typename It, typename S>
  30. struct is_comparable<It, S, exists(_val(It) == _val(S))> : std::true_type {};
  31. template <typename C> constexpr bool has_size_v = has_size<C>{};
  32. template <typename C> constexpr bool has_empty_v = has_empty<C>{};
  33. template <typename It, typename S>
  34. constexpr bool is_comparable_v = is_comparable<It, S>{};
  35. template <typename S>
  36. constexpr bool is_sentinal_v = !std::is_same_v<begin_t<S>, end_t<S>>;
  37. }
  38. #undef _val
  39. #undef exists