From 755429f90149743308c70ccf22319161cbc6e71f Mon Sep 17 00:00:00 2001 From: q66 Date: Sat, 18 Feb 2017 15:05:42 +0100 Subject: [PATCH] ravamped range traits --- ostd/range.hh | 77 +++++++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 27 deletions(-) diff --git a/ostd/range.hh b/ostd/range.hh index 49c01fc..2063121 100644 --- a/ostd/range.hh +++ b/ostd/range.hh @@ -28,36 +28,59 @@ struct random_access_range_tag: bidirectional_range_tag {}; struct finite_random_access_range_tag: random_access_range_tag {}; struct contiguous_range_tag: finite_random_access_range_tag {}; -template -struct range_half; +namespace detail { + template + struct range_category_test { + template + static char test(typename RR::range_category *); + template + static int test(...); + static constexpr bool value = (sizeof(test(0)) == sizeof(char)); + }; -#define OSTD_RANGE_TRAIT(Name, Member) \ -namespace detail { \ - template \ - struct range_##Name##_test { \ - template \ - static char test(std::remove_reference_t *); \ - template \ - static int test(...); \ - static constexpr bool value = (sizeof(test(0)) == sizeof(char)); \ - }; \ - template::value> \ - struct range_##Name##_base {}; \ - template \ - struct range_##Name##_base { \ - using type = typename T::Member; \ - }; \ -} \ -template \ -using range_##Name##_t = typename detail::range_##Name##_base::type; + template + constexpr bool test_range_category = range_category_test::value; -OSTD_RANGE_TRAIT(category, range_category) -OSTD_RANGE_TRAIT(size, size_type) -OSTD_RANGE_TRAIT(value, value_type) -OSTD_RANGE_TRAIT(reference, reference) -OSTD_RANGE_TRAIT(difference, difference_type) + template + struct range_traits_base {}; -#undef OSTD_RANGE_TRAIT + template + struct range_traits_base { + using range_category = typename R::range_category; + using size_type = typename R::size_type; + using value_type = typename R::value_type; + using reference = typename R::reference; + using difference_type = typename R::difference_type; + }; + + template + struct range_traits_impl {}; + + template + struct range_traits_impl: range_traits_base< + R, + std::is_convertible_v || + std::is_convertible_v + > {}; +} + +template +struct range_traits: detail::range_traits_impl> {}; + +template +using range_category_t = typename range_traits::range_category; + +template +using range_size_t = typename range_traits::size_type; + +template +using range_value_t = typename range_traits::value_type; + +template +using range_reference_t = typename range_traits::reference; + +template +using range_difference_t = typename range_traits::difference_type; namespace detail { template