simplify func checks

master
Daniel Kolesa 2015-06-07 16:17:03 +01:00
parent ee8d565203
commit 1d47ac26a8
1 changed files with 31 additions and 34 deletions

View File

@ -428,7 +428,7 @@ namespace detail {
template<typename F> template<typename F>
using MapLambdaArg = typename MapLambdaTypes<F>::Arg; using MapLambdaArg = typename MapLambdaTypes<F>::Arg;
template<typename T, typename F> template<typename F>
struct MapFuncTest { struct MapFuncTest {
template<typename FF> template<typename FF>
static char test(MapLambdaRet<FF> (*)(MapLambdaArg<FF>)); static char test(MapLambdaRet<FF> (*)(MapLambdaArg<FF>));
@ -437,37 +437,36 @@ namespace detail {
static constexpr bool value = (sizeof(test<F>(octa::declval<F>())) == 1); static constexpr bool value = (sizeof(test<F>(octa::declval<F>())) == 1);
}; };
template<typename T, typename R, typename F, template<typename R, typename F, bool = MapFuncTest<F>::value>
bool = MapFuncTest<T, F>::value struct MapFuncTypeObjBase {
> struct MapFuncTypeObjBase { typedef octa::Function<R(MapLambdaArg<F>)> Type;
typedef octa::Function<R(octa::RangeReference<T>)> Type;
}; };
template<typename T, typename R, typename F> template<typename R, typename F>
struct MapFuncTypeObjBase<T, R, F, true> { struct MapFuncTypeObjBase<R, F, true> {
typedef MapLambdaRet<F> (*Type)(MapLambdaArg<F>); typedef MapLambdaRet<F> (*Type)(MapLambdaArg<F>);
}; };
template<typename T, typename R, typename F, template<typename R, typename F,
bool = octa::IsDefaultConstructible<F>::value && bool = octa::IsDefaultConstructible<F>::value &&
octa::IsMoveConstructible<F>::value octa::IsMoveConstructible<F>::value
> struct MapFuncTypeObj { > struct MapFuncTypeObj {
typedef typename MapFuncTypeObjBase<T, R, F>::Type Type; typedef typename MapFuncTypeObjBase<R, F>::Type Type;
}; };
template<typename T, typename R, typename F> template<typename R, typename F>
struct MapFuncTypeObj<T, R, F, true> { struct MapFuncTypeObj<R, F, true> {
typedef F Type; typedef F Type;
}; };
template<typename T, typename R, typename F, bool = octa::IsClass<F>::value> template<typename R, typename F, bool = octa::IsClass<F>::value>
struct MapFuncType { struct MapFuncType {
typedef F Type; typedef F Type;
}; };
template<typename T, typename R, typename F> template<typename R, typename F>
struct MapFuncType<T, R, F, true> { struct MapFuncType<R, F, true> {
typedef typename MapFuncTypeObj<T, R, F>::Type Type; typedef typename MapFuncTypeObj<R, F>::Type Type;
}; };
} }
@ -477,7 +476,7 @@ struct MapRange: InputRange<
> { > {
private: private:
T p_range; T p_range;
typename octa::detail::MapFuncType<T, R, F>::Type p_func; typename octa::detail::MapFuncType<R, F>::Type p_func;
public: public:
MapRange(): p_range(), p_func() {} MapRange(): p_range(), p_func() {}
@ -570,7 +569,7 @@ namespace detail {
typedef A Type; typedef A Type;
}; };
template<typename T, typename F> template<typename F>
struct FilterPredTest { struct FilterPredTest {
template<typename FF> template<typename FF>
static char test(bool (*)(typename FilterLambdaArg<FF>::Type)); static char test(bool (*)(typename FilterLambdaArg<FF>::Type));
@ -579,37 +578,35 @@ namespace detail {
static constexpr bool value = (sizeof(test<F>(octa::declval<F>())) == 1); static constexpr bool value = (sizeof(test<F>(octa::declval<F>())) == 1);
}; };
template<typename T, typename F, template<typename F, bool = FilterPredTest<F>::value>
bool = FilterPredTest<T, F>::value struct FilterPredTypeObjBase {
> struct FilterPredTypeObjBase { typedef octa::Function<bool(typename FilterLambdaArg<F>::Type)> Type;
typedef octa::Function<bool(octa::RangeReference<T>)> Type;
}; };
template<typename T, typename F> template<typename F>
struct FilterPredTypeObjBase<T, F, true> { struct FilterPredTypeObjBase<F, true> {
typedef bool (*Type)(typename FilterLambdaArg<F>::Type); typedef bool (*Type)(typename FilterLambdaArg<F>::Type);
}; };
template<typename T, typename F, template<typename F, bool = octa::IsDefaultConstructible<F>::value &&
bool = octa::IsDefaultConstructible<F>::value && octa::IsMoveConstructible<F>::value
octa::IsMoveConstructible<F>::value
> struct FilterPredTypeObj { > struct FilterPredTypeObj {
typedef typename FilterPredTypeObjBase<T, F>::Type Type; typedef typename FilterPredTypeObjBase<F>::Type Type;
}; };
template<typename T, typename F> template<typename F>
struct FilterPredTypeObj<T, F, true> { struct FilterPredTypeObj<F, true> {
typedef F Type; typedef F Type;
}; };
template<typename T, typename F, bool = octa::IsClass<F>::value> template<typename F, bool = octa::IsClass<F>::value>
struct FilterPredType { struct FilterPredType {
typedef F Type; typedef F Type;
}; };
template<typename T, typename F> template<typename F>
struct FilterPredType<T, F, true> { struct FilterPredType<F, true> {
typedef typename FilterPredTypeObj<T, F>::Type Type; typedef typename FilterPredTypeObj<F>::Type Type;
}; };
} }
@ -621,7 +618,7 @@ struct FilterRange: InputRange<
> { > {
private: private:
T p_range; T p_range;
typename octa::detail::FilterPredType<T, F>::Type p_pred; typename octa::detail::FilterPredType<F>::Type p_pred;
void advance_valid() { void advance_valid() {
while (!p_range.empty() && !p_pred(front())) p_range.pop_front(); while (!p_range.empty() && !p_pred(front())) p_range.pop_front();