IsOutputRange will now test for presence of the right 'put' method, enabling IsOutputRange tests on hybrid ranges (i.e. input ranges that satisfy output requirements)

master
Daniel Kolesa 2015-05-23 22:24:12 +01:00
parent 7589a93539
commit 329aefdecd
1 changed files with 13 additions and 3 deletions

View File

@ -79,9 +79,19 @@ namespace octa {
// is output range
template<typename T, bool = IsConvertible<
RangeCategory<T>, OutputRangeTag
>::value> struct IsOutputRange: False {};
template<typename T, typename P>
struct __OctaOutputRangeTest {
template<typename U, void (U::*)(P)> struct __OctaTest {};
template<typename U> static char __octa_test(__OctaTest<U, &U::put> *);
template<typename U> static int __octa_test(...);
static constexpr bool value = (sizeof(__octa_test<T>(0)) == sizeof(char));
};
template<typename T, bool
= (IsConvertible<RangeCategory<T>, OutputRangeTag>::value ||
__OctaOutputRangeTest<T, const RangeValue<T> &>::value ||
__OctaOutputRangeTest<T, RangeValue<T> &&>::value)
> struct IsOutputRange: False {};
template<typename T>
struct IsOutputRange<T, true>: True {};