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