From 548de69102f741f9a5f7feb66704a0db2ed18b45 Mon Sep 17 00:00:00 2001 From: q66 Date: Sun, 7 Jun 2015 18:06:29 +0100 Subject: [PATCH] add octa::FunctionMakeDefaultConstructible, use in MapRange and FilterRange This turns any callable object into a primitive default constructible type. That is, for regular function objects, the type represents the object type itself, for function pointers, the type represents the function pointer, for simple lambdas the type represents a function pointer they map to (only when the lambda doesn't capture) and for closures it represents the right octa::Function type. --- octa/algorithm.h | 61 ++--------------------------------------------- octa/functional.h | 54 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 59 deletions(-) diff --git a/octa/algorithm.h b/octa/algorithm.h index 392efbd..c62bb47 100644 --- a/octa/algorithm.h +++ b/octa/algorithm.h @@ -412,70 +412,13 @@ T foldr(R range, T init, F func) { return init; } -namespace detail { - template - struct HofLambdaTypes: HofLambdaTypes {}; - - template - struct HofLambdaTypes { - typedef R Result; - typedef A Arg; - }; - - template - using HofLambdaRet = typename HofLambdaTypes::Result; - - template - using HofLambdaArg = typename HofLambdaTypes::Arg; - - template - struct HofFuncTest { - template - static char test(HofLambdaRet (*)(HofLambdaArg)); - template - static int test(...); - static constexpr bool value = (sizeof(test(octa::declval())) == 1); - }; - - template::value> - struct HofFuncTypeObjBase { - typedef octa::Function(HofLambdaArg)> Type; - }; - - template - struct HofFuncTypeObjBase { - typedef HofLambdaRet (*Type)(HofLambdaArg); - }; - - template::value && - octa::IsMoveConstructible::value - > struct HofFuncTypeObj { - typedef typename HofFuncTypeObjBase::Type Type; - }; - - template - struct HofFuncTypeObj { - typedef F Type; - }; - - template::value> - struct HofFuncType { - typedef F Type; - }; - - template - struct HofFuncType { - typedef typename HofFuncTypeObj::Type Type; - }; -} - template struct MapRange: InputRange< MapRange, octa::RangeCategory, R, R, octa::RangeSize > { private: T p_range; - typename octa::detail::HofFuncType::Type p_func; + typename octa::FunctionMakeDefaultConstructible p_func; public: MapRange(): p_range(), p_func() {} @@ -567,7 +510,7 @@ struct FilterRange: InputRange< > { private: T p_range; - typename octa::detail::HofFuncType::Type p_pred; + typename octa::FunctionMakeDefaultConstructible p_pred; void advance_valid() { while (!p_range.empty() && !p_pred(front())) p_range.pop_front(); diff --git a/octa/functional.h b/octa/functional.h index ad251bf..4c49920 100644 --- a/octa/functional.h +++ b/octa/functional.h @@ -735,6 +735,60 @@ bool operator!=(nullptr_t, const Function &rhs) { return rhs; } template bool operator!=(const Function &lhs, nullptr_t) { return lhs; } +namespace detail { + template + struct DcLambdaTypes: DcLambdaTypes {}; + + template + struct DcLambdaTypes { + typedef R (*Ptr)(A...); + typedef octa::Function Obj; + }; + + template + struct DcFuncTest { + template + static char test(typename DcLambdaTypes::Ptr); + template + static int test(...); + static constexpr bool value = (sizeof(test(octa::declval())) == 1); + }; + + template::value> + struct DcFuncTypeObjBase { + typedef typename DcLambdaTypes::Obj Type; + }; + + template + struct DcFuncTypeObjBase { + typedef typename DcLambdaTypes::Ptr Type; + }; + + template::value && + octa::IsMoveConstructible::value + > struct DcFuncTypeObj { + typedef typename DcFuncTypeObjBase::Type Type; + }; + + template + struct DcFuncTypeObj { + typedef F Type; + }; + + template::value> + struct DcFuncType { + typedef F Type; + }; + + template + struct DcFuncType { + typedef typename DcFuncTypeObj::Type Type; + }; +} + +template using FunctionMakeDefaultConstructible + = typename octa::detail::DcFuncType::Type; + } /* namespace octa */ #endif \ No newline at end of file