From 20485936c50afd5b69152550441a36809db3a675 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sat, 18 Aug 2018 12:04:11 +0100 Subject: [PATCH] Added bind1st & bind2nd to alternate STL implementations. Added additional conditional compilation to algorithms using 'bind'. --- include/etl/algorithm.h | 4 +- include/etl/stl/alternate/functional.h | 84 ++++++++++++++++++++++++++ test/test_no_stl_functional.cpp | 22 +++++++ 3 files changed, 108 insertions(+), 2 deletions(-) diff --git a/include/etl/algorithm.h b/include/etl/algorithm.h index f808db86..a705f986 100644 --- a/include/etl/algorithm.h +++ b/include/etl/algorithm.h @@ -617,7 +617,7 @@ namespace etl for (TIterator1 i = begin1; i != end1; ++i) { -#if ETL_CPP11_SUPPORTED +#if ETL_CPP11_SUPPORTED && !defined(ETL_NO_STL) if (i == std::find_if(begin1, i, std::bind(predicate, *i, std::placeholders::_1))) #else if (i == std::find_if(begin1, i, std::bind1st(predicate, *i))) @@ -654,7 +654,7 @@ namespace etl { for (TIterator1 i = begin1; i != end1; ++i) { -#if ETL_CPP11_SUPPORTED +#if ETL_CPP11_SUPPORTED && !defined(ETL_NO_STL) if (i == std::find_if(begin1, i, std::bind(predicate, *i, std::placeholders::_1))) #else if (i == std::find_if(begin1, i, std::bind1st(predicate, *i))) diff --git a/include/etl/stl/alternate/functional.h b/include/etl/stl/alternate/functional.h index 5dd58506..5ba390a3 100644 --- a/include/etl/stl/alternate/functional.h +++ b/include/etl/stl/alternate/functional.h @@ -49,6 +49,90 @@ namespace std return lhs != rhs; } }; + + //*************************************************************************** + + template + struct unary_function + { + typedef TArgumentType aurgument_type; + typedef TResultType result_type; + }; + + //*************************************************************************** + + template + struct binary_function + { + typedef TFirstArgumentType first_aurgument_type; + typedef TSecondArgumentType second_aurgument_type; + typedef TResultType result_type; + }; + + //*************************************************************************** + + template + class binder1st : public etlstd::unary_function + { + protected: + + TFunction operation; + typename TFunction::first_argument_type value; + + public: + + binder1st(const TFunction& f, const typename TFunction::first_argument_type& v) + : operation (f), value(v) + { + } + + typename TFunction::result_type operator()(typename TFunction::second_argument_type& x) const + { + return operation(value, x); + } + + typename TFunction::result_type operator()(const typename TFunction::second_argument_type& x) const + { + return operation(value, x); + } + }; + + template + binder1st bind1st(const F& f, const T& x) + { + return binder1st(f, x); + } + + //*************************************************************************** + + template + class binder2nd : public etlstd::unary_function + { + protected: + TFunction operation; + typename TFunction::second_argument_type value; + public: + binder2nd(const TFunction& f, const typename TFunction::second_argument_type& v) + : operation (f), value(v) + { + } + + typename TFunction::result_type operator()(typename TFunction::first_argument_type& x) const + { + return operation(x, value); + } + + typename TFunction::result_type operator()(const typename TFunction::first_argument_type& x) const + { + return operation(x, value); + } + }; + + template + binder2nd bind2nd(const F& f, const T& x) + { + return binder2nd(f, x); + } } #endif \ No newline at end of file diff --git a/test/test_no_stl_functional.cpp b/test/test_no_stl_functional.cpp index 90eb26e1..18f253d1 100644 --- a/test/test_no_stl_functional.cpp +++ b/test/test_no_stl_functional.cpp @@ -41,6 +41,14 @@ namespace return TCompare()(a, b); } + struct test : std::binary_function + { + bool operator()(int a, int b) const + { + return a < b; + } + }; + SUITE(test_no_stl_functional) { //************************************************************************* @@ -74,5 +82,19 @@ namespace CHECK((compare>(1, 2))); CHECK((compare>(2, 1))); } + + //************************************************************************* + TEST(test_bind1st) + { + CHECK((etlstd::bind1st(test(), 1)(2))); + CHECK(!(etlstd::bind1st(test(), 2)(1))); + } + + //************************************************************************* + TEST(test_bind2nd) + { + CHECK(!(etlstd::bind2nd(test(), 1)(2))); + CHECK((etlstd::bind2nd(test(), 2)(1))); + } }; }