| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748 |
- //
- // traits.hpp
- // stream
- //
- // Created by Sam Jaffe on 6/24/17.
- //
- #pragma once
- #include <type_traits>
- #include <utility>
- #include <iterator/detail/traits.h>
- #include <iterator/facade.h>
- #include <stream/forward.h>
- #define _val(type) std::declval<type>()
- #define exists(expr) std::void_t<decltype(expr)>
- namespace stream::traits {
- template <typename C> using begin_t = decltype(std::begin(_val(C)));
- template <typename C> using end_t = decltype(std::end(_val(C)));
- template <typename C> using ref_t = decltype(*_val(begin_t<C>));
- template <typename C> using value_type = std::decay_t<ref_t<C>>;
- template <typename C> using cref_t = std::add_const_t<ref_t<C>>;
- template <typename, typename = void> struct has_size : std::false_type {};
- template <typename, typename = void> struct has_empty : std::false_type {};
- template <typename C>
- struct has_size<C, exists(_val(C).size())> : std::true_type {};
- template <typename C>
- struct has_empty<C, exists(_val(C).empty())> : std::true_type {};
- template <typename C> constexpr bool has_size_v = has_size<C>{};
- template <typename C> constexpr bool has_empty_v = has_empty<C>{};
- using iterator::detail::sentinal_type_t;
- template <typename S>
- constexpr bool is_sentinal_v =
- std::is_void_v<sentinal_type_t<ranges::iter<S>>> &&
- !std::is_same_v<begin_t<S>, end_t<S>>;
- }
- #undef _val
- #undef exists
|