diff --git a/include/etl/utility.h b/include/etl/utility.h index 52cf0d37..b98ca3d7 100644 --- a/include/etl/utility.h +++ b/include/etl/utility.h @@ -496,7 +496,7 @@ namespace etl ETL_STATIC_ASSERT(etl::is_integral::value, "Integral types only"); - typedef T value_type; + using value_type = T; static ETL_CONSTEXPR size_t size() ETL_NOEXCEPT { @@ -504,7 +504,7 @@ namespace etl } }; - namespace private_integer_sequence + namespace private_index_sequence { template struct make_index_sequence; @@ -512,19 +512,19 @@ namespace etl template struct make_index_sequence> { - typedef typename make_index_sequence>::type type; + using type = typename make_index_sequence>::type; }; template struct make_index_sequence<0, etl::integer_sequence> { - typedef etl::integer_sequence type; + using type = etl::integer_sequence; }; } //*********************************** template - using make_index_sequence = typename private_integer_sequence::make_index_sequence>::type; + using make_index_sequence = typename private_index_sequence::make_index_sequence>::type; //*********************************** template @@ -601,10 +601,13 @@ namespace etl #if ETL_USING_CPP11 //************************************************************************* - /// A function wrapper for free/global functions. + // A function wrapper for free/global functions. + // Deprecated. + // See etl::function_ptr_as_functor for a runtime time wrapper option. + // See etl::function_as_functor for a compile time wrapper option. //************************************************************************* template - class functor + class ETL_DEPRECATED functor { public: @@ -618,7 +621,7 @@ namespace etl //********************************* /// Const function operator. - //********************************* + //********************************* constexpr TReturn operator()(TParams... args) const { return ptr(etl::forward(args)...); @@ -629,18 +632,18 @@ namespace etl /// The pointer to the function. TReturn(*ptr)(TParams...); }; -#endif -#if ETL_USING_CPP11 //***************************************************************************** - // A wrapper for a member function + // Wrap a member function with a static free function. // Creates a static member function that calls the specified member function. + // Deprecated + // See etl::member_function_as_static //***************************************************************************** template - class member_function_wrapper; + class ETL_DEPRECATED member_function_wrapper; template - class member_function_wrapper + class ETL_DEPRECATED member_function_wrapper { public: @@ -650,12 +653,12 @@ namespace etl return (Instance.*Method)(etl::forward(params)...); } }; -#endif -#if ETL_USING_CPP11 //***************************************************************************** - // A wrapper for a functor + // Wrap a functor with a static free function. // Creates a static member function that calls the specified functor. + // Deprecated + // See etl::functor_as_static //***************************************************************************** template class functor_wrapper; @@ -672,6 +675,104 @@ namespace etl } }; #endif + +#if ETL_USING_CPP17 + //***************************************************************************** + // Wraps a functor with a static free function at compile time. + // Creates a static member 'function' that calls the specified functor. + //***************************************************************************** + template + struct functor_as_static + { + template + static constexpr auto call(TArgs&&... args) + { + return (Instance.operator())(etl::forward(args)...); + } + }; + + //***************************************************************************** + // Wraps a member function with a static free function at compile time. + // Creates a static member function that calls the specified member function. + //***************************************************************************** + template + struct member_function_as_static + { + template + static constexpr auto call(TArgs&&... args) + { + return (Instance.*Method)(etl::forward(args)...); + } + }; + + //***************************************************************************** + // Wraps a member function with a functor at compile time. + // Creates a functor that calls the specified member function. + //***************************************************************************** + template + class member_function_as_functor + { + public: + + template + constexpr auto operator()(TArgs&&... args) const -> decltype((Instance.*Method)(etl::forward(args)...)) + { + return (Instance.*Method)(etl::forward(args)...); + } + }; + + //***************************************************************************** + // Wraps a function with a functor at compile time. + // Creates a functor that calls the specified free function. + //***************************************************************************** + template + class function_as_functor + { + public: + + template + constexpr auto operator()(TArgs&&... args) const -> decltype(Function(etl::forward(args)...)) + { + return Function(etl::forward(args)...); + } + }; +#endif + +#if ETL_USING_CPP11 + //***************************************************************************** + // Wraps a function pointer with a functor at run time. + // Creates a functor that calls the specified free function. + //***************************************************************************** + template + class function_ptr_as_functor; + + template + class function_ptr_as_functor + { + public: + + //********************************* + /// Constructor. + //********************************* + constexpr function_ptr_as_functor(TReturn(*ptr_)(TArgs...)) + : ptr(ptr_) + { + } + + //********************************* + /// Const function operator. + //********************************* + constexpr TReturn operator()(TArgs... args) const + { + return ptr(etl::forward(args)...); + } + + private: + + /// The pointer to the function. + TReturn(*ptr)(TArgs...); + }; +#endif } #endif diff --git a/test/test_utility.cpp b/test/test_utility.cpp index a1f28e95..07a2818e 100644 --- a/test/test_utility.cpp +++ b/test/test_utility.cpp @@ -412,14 +412,14 @@ namespace } //************************************************************************* - TEST(test_functor) + TEST(test_functor_deprecated) { constexpr etl::functor fw1(TestGlobal); CHECK_EQUAL(2, fw1(1)); } //************************************************************************* - TEST(test_member_function_wrapper) + TEST(test_member_function_wrapper_deprecated) { constexpr int(*pf)(int) = &etl::member_function_wrapper::function; @@ -427,13 +427,63 @@ namespace } //************************************************************************* - TEST(test_functor_wrapper) + TEST(test_functor_wrapper_deprecated) { constexpr int(*pf)(int) = &etl::functor_wrapper::function; CHECK_EQUAL(2, pf(1)); } + //************************************************************************* +#if ETL_USING_CPP17 + TEST(test_function_as_functor) + { + constexpr etl::function_as_functor faf; + + CHECK_EQUAL(2, faf(1)); + } +#endif + + //************************************************************************* + TEST(test_function_ptr_as_functor) + { + constexpr decltype(TestGlobal)* fptr = TestGlobal; + + constexpr etl::function_ptr_as_functor fpaf(fptr); + + CHECK_EQUAL(2, fpaf(1)); + } + + //************************************************************************* +#if ETL_USING_CPP17 + TEST(test_functor_as_static) + { + using fas_t = etl::functor_as_static; + + CHECK_EQUAL(2, fas_t::call(1)); + } +#endif + + //************************************************************************* +#if ETL_USING_CPP17 + TEST(test_member_function_as_static) + { + using mfas_t = etl::member_function_as_static<&TestClass::MemberFunction, test>; + + CHECK_EQUAL(2, mfas_t::call(1)); + } +#endif + +#if ETL_USING_CPP17 + //************************************************************************* + TEST(test_member_function_as_functor) + { + constexpr etl::member_function_as_functor<&TestClass::MemberFunction, test> mfaf; + + CHECK_EQUAL(2, mfaf(1)); + } +#endif + //************************************************************************* struct SF {