traits.h 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  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::decay_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, exists(_val(C).size())> : std::true_type {};
  25. template <typename C>
  26. struct has_empty<C, exists(_val(C).empty())> : std::true_type {};
  27. template <typename C> constexpr bool has_size_v = has_size<C>{};
  28. template <typename C> constexpr bool has_empty_v = has_empty<C>{};
  29. using iterator::detail::sentinal_type_t;
  30. template <typename S>
  31. constexpr bool is_sentinal_v =
  32. std::is_void_v<sentinal_type_t<ranges::iter<S>>> &&
  33. !std::is_same_v<begin_t<S>, end_t<S>>;
  34. }
  35. #undef _val
  36. #undef exists