// // traits.hpp // stream // // Created by Sam Jaffe on 6/24/17. // #pragma once #include #include #include #include #include #include namespace stream::detail { template using begin_t = decltype(std::begin(VAL(C))); template using end_t = decltype(std::end(VAL(C))); template using ref_t = decltype(*VAL(begin_t)); template using value_type = std::remove_reference_t>; template using cref_t = std::add_const_t>; template struct has_size : std::false_type {}; template struct has_empty : std::false_type {}; template struct has_size>> : std::true_type {}; template struct has_empty>> : std::true_type {}; template struct is_comparable : std::false_type {}; template struct is_comparable : std::true_type {}; template struct is_sized_sentinel : std::false_type {}; template struct is_sized_sentinel : std::true_type {}; template constexpr bool has_size_v = has_size{}; template constexpr bool has_empty_v = has_empty{}; template constexpr bool is_comparable_v = is_comparable{}; template constexpr bool has_sentinal_v = !std::is_same_v, end_t>; template class Iter, typename... Ts> using sentinel_iterator = std::conditional_t, detail::end_t, Iter, Ts...>>; template constexpr bool is_sized_sentinel_v = is_sized_sentinel{}; } #include