remove duplicate code + further simplify

master
Daniel Kolesa 2015-06-07 16:32:32 +01:00
parent 1d47ac26a8
commit f4ca222dbd
1 changed files with 25 additions and 76 deletions

View File

@ -414,59 +414,58 @@ T foldr(R range, T init, F func) {
namespace detail { namespace detail {
template<typename F> template<typename F>
struct MapLambdaTypes: MapLambdaTypes<decltype(&F::operator())> {}; struct HofLambdaTypes: HofLambdaTypes<decltype(&F::operator())> {};
template<typename C, typename R, typename A> template<typename C, typename R, typename A>
struct MapLambdaTypes<R (C::*)(A) const> { struct HofLambdaTypes<R (C::*)(A) const> {
typedef R Result; typedef R Result;
typedef A Arg; typedef A Arg;
}; };
template<typename F> template<typename F>
using MapLambdaRet = typename MapLambdaTypes<F>::Result; using HofLambdaRet = typename HofLambdaTypes<F>::Result;
template<typename F> template<typename F>
using MapLambdaArg = typename MapLambdaTypes<F>::Arg; using HofLambdaArg = typename HofLambdaTypes<F>::Arg;
template<typename F> template<typename F>
struct MapFuncTest { struct HofFuncTest {
template<typename FF> template<typename FF>
static char test(MapLambdaRet<FF> (*)(MapLambdaArg<FF>)); static char test(HofLambdaRet<FF> (*)(HofLambdaArg<FF>));
template<typename FF> template<typename FF>
static int test(...); static int test(...);
static constexpr bool value = (sizeof(test<F>(octa::declval<F>())) == 1); static constexpr bool value = (sizeof(test<F>(octa::declval<F>())) == 1);
}; };
template<typename R, typename F, bool = MapFuncTest<F>::value> template<typename F, bool = HofFuncTest<F>::value>
struct MapFuncTypeObjBase { struct HofFuncTypeObjBase {
typedef octa::Function<R(MapLambdaArg<F>)> Type; typedef octa::Function<HofLambdaRet<F>(HofLambdaArg<F>)> Type;
}; };
template<typename R, typename F> template<typename F>
struct MapFuncTypeObjBase<R, F, true> { struct HofFuncTypeObjBase<F, true> {
typedef MapLambdaRet<F> (*Type)(MapLambdaArg<F>); typedef HofLambdaRet<F> (*Type)(HofLambdaArg<F>);
}; };
template<typename R, typename F, template<typename F, bool = octa::IsDefaultConstructible<F>::value &&
bool = octa::IsDefaultConstructible<F>::value && octa::IsMoveConstructible<F>::value
octa::IsMoveConstructible<F>::value > struct HofFuncTypeObj {
> struct MapFuncTypeObj { typedef typename HofFuncTypeObjBase<F>::Type Type;
typedef typename MapFuncTypeObjBase<R, F>::Type Type;
}; };
template<typename R, typename F> template<typename F>
struct MapFuncTypeObj<R, F, true> { struct HofFuncTypeObj<F, true> {
typedef F Type; typedef F Type;
}; };
template<typename R, typename F, bool = octa::IsClass<F>::value> template<typename F, bool = octa::IsClass<F>::value>
struct MapFuncType { struct HofFuncType {
typedef F Type; typedef F Type;
}; };
template<typename R, typename F> template<typename F>
struct MapFuncType<R, F, true> { struct HofFuncType<F, true> {
typedef typename MapFuncTypeObj<R, F>::Type Type; typedef typename HofFuncTypeObj<F>::Type Type;
}; };
} }
@ -476,7 +475,7 @@ struct MapRange: InputRange<
> { > {
private: private:
T p_range; T p_range;
typename octa::detail::MapFuncType<R, F>::Type p_func; typename octa::detail::HofFuncType<F>::Type p_func;
public: public:
MapRange(): p_range(), p_func() {} MapRange(): p_range(), p_func() {}
@ -560,56 +559,6 @@ MapRange<R, F, octa::detail::MapReturnType<R, F>> map(R range,
func); func);
} }
namespace detail {
template<typename F>
struct FilterLambdaArg: FilterLambdaArg<decltype(&F::operator())> {};
template<typename C, typename A>
struct FilterLambdaArg<bool (C::*)(A) const> {
typedef A Type;
};
template<typename F>
struct FilterPredTest {
template<typename FF>
static char test(bool (*)(typename FilterLambdaArg<FF>::Type));
template<typename FF>
static int test(...);
static constexpr bool value = (sizeof(test<F>(octa::declval<F>())) == 1);
};
template<typename F, bool = FilterPredTest<F>::value>
struct FilterPredTypeObjBase {
typedef octa::Function<bool(typename FilterLambdaArg<F>::Type)> Type;
};
template<typename F>
struct FilterPredTypeObjBase<F, true> {
typedef bool (*Type)(typename FilterLambdaArg<F>::Type);
};
template<typename F, bool = octa::IsDefaultConstructible<F>::value &&
octa::IsMoveConstructible<F>::value
> struct FilterPredTypeObj {
typedef typename FilterPredTypeObjBase<F>::Type Type;
};
template<typename F>
struct FilterPredTypeObj<F, true> {
typedef F Type;
};
template<typename F, bool = octa::IsClass<F>::value>
struct FilterPredType {
typedef F Type;
};
template<typename F>
struct FilterPredType<F, true> {
typedef typename FilterPredTypeObj<F>::Type Type;
};
}
template<typename T, typename F> template<typename T, typename F>
struct FilterRange: InputRange< struct FilterRange: InputRange<
FilterRange<T, F>, octa::CommonType<octa::RangeCategory<T>, FilterRange<T, F>, octa::CommonType<octa::RangeCategory<T>,
@ -618,7 +567,7 @@ struct FilterRange: InputRange<
> { > {
private: private:
T p_range; T p_range;
typename octa::detail::FilterPredType<F>::Type p_pred; typename octa::detail::HofFuncType<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();