From 8b52ad62dd0f1bb299aaa10a0ec8584aef7441e9 Mon Sep 17 00:00:00 2001 From: Eric Vantillard Date: Sat, 1 Oct 2022 12:40:18 +0200 Subject: [PATCH 1/2] Feature/add pair functors (#610) * Move __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS before `#include `. (#601) Macros must be defined before first include of stdint.h. Else they have no effect. * Replace ETL_COMPILER_ICCAVR by ETL_COMPILER_IAR. (#602) The current definition mechanism for ETL_COMPILER_ICCAVR does not work. Both IAR compilers, for ARM and AVR define `__IAR_SYSTEMS_ICC__`. Thus `ETL_COMPILER_TYPE_DETECTED` will be defined in line before ETL_COMPILER_ICCAVR is defined. This switch will never be entered. Currently I see no reason for differentiating both compilers (`__ICCARM__` and `__ICCAVR__`). The condition for the IAR compiler platform (`__IAR_SYSTEMS_ICC__`) is sufficient (combined with --- .gitignore | 23 +--- Doxyfile | 2 +- include/etl/platform.h | 26 ++-- include/etl/private/minmax_pop.h | 2 +- include/etl/private/minmax_push.h | 2 +- include/etl/profiles/determine_compiler.h | 13 -- .../etl/profiles/determine_compiler_version.h | 3 - include/etl/utility.h | 121 ++++++++++++++++-- test/test_fixed_iterator.cpp | 16 +-- test/test_hash.cpp | 6 +- test/test_multi_array.cpp | 2 +- test/test_utility.cpp | 77 +++++++++++ 12 files changed, 218 insertions(+), 75 deletions(-) diff --git a/.gitignore b/.gitignore index db038001b..dd68c7525 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ ## Personal ################# docs/html +include/etl/html/ +include/etl/latex/ test/vs2013/Debug test/vs2013/Release test/keil/Debug @@ -91,14 +93,12 @@ build/ *.tlb *.tli *.tlh -*.tmp *.tmp_proj *.log *.vspscc *.vssscc .builds *.pidb -*.log *.scc # Visual C++ cache files @@ -219,7 +219,6 @@ $RECYCLE.BIN/ *.egg *.egg-info dist/ -build/ eggs/ parts/ var/ @@ -241,7 +240,6 @@ pip-log.txt #Mr Developer .mr.developer.cfg *.depend -*.depend *.layout *.session *.tags @@ -270,13 +268,9 @@ test/kdevelopbuild/unittest++ test/random_clcg.csv test/random_hash.csv test/random_lcg.csv -test/random_lcg.csv -test/random_lcg.csv -test/random_lsfr.csv test/random_lsfr.csv test/random_mwc.csv test/random_pcg.csv -test/random_pcg.csv test/random_xorshift.csv test/cmake_install.cmake test/Makefile @@ -331,21 +325,16 @@ test/vs2019/Test2 test/vs2019/Debug MSVC - Force C++03 test/vs2019/Debug LLVM - No STL test/vs2019/Debug - No STL -test/meson-info test/etl_unit_tests.p -test/meson-logs -test/meson-private test/.ninja_deps test/.ninja_log test/build.ninja test/compile_commands.json test/etl_unit_tests test/build-make -test/build-make test/meson-info test/meson-logs test/meson-private -test/build-make test/build-ninja test/vs2019/Debug MSVC C++20 test/vs2019/Debug MSVC C++20 - No STL @@ -370,12 +359,4 @@ test/etl_error_handler/build-log_errors-GCC-Debug test/etl_error_handler/build-exceptions_and_log_errors-GCC-Debug test/etl_error_handler/build-exceptions-GCC-Debug test/etl_error_handler/exceptions_and_log_errors/.vs -test/etl_error_handler/exceptions/build-make -test/etl_error_handler/log_errors/build-make -test/etl_error_handler/log_errors_and_exceptions/build-make -test/etl_error_handler/log_errors_and_exceptions/.vs -test/etl_error_handler/exceptions/build-make -test/etl_error_handler/log_errors/build-make -test/etl_error_handler/log_errors_and_exceptions/.vs -test/etl_error_handler/log_errors_and_exceptions/build-make examples/ArmTimerCallbacks - C++/ArmTimerCallbacks.uvoptx diff --git a/Doxyfile b/Doxyfile index 0d1448340..437a911ef 100644 --- a/Doxyfile +++ b/Doxyfile @@ -872,7 +872,7 @@ EXCLUDE_SYMBOLS = # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = +EXAMPLE_PATH = ./test # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and diff --git a/include/etl/platform.h b/include/etl/platform.h index 6c21e285c..b108027e1 100644 --- a/include/etl/platform.h +++ b/include/etl/platform.h @@ -31,6 +31,20 @@ SOFTWARE. #ifndef ETL_PLATFORM_INCLUDED #define ETL_PLATFORM_INCLUDED +//************************************* +// Enable all limit macros +// Note: This macro must be defined before the first include of stdint.h +#if !defined(__STDC_LIMIT_MACROS) + #define __STDC_LIMIT_MACROS +#endif + +//************************************* +// Enable all constant macros +// Note: This macro must be defined before the first include of stdint.h +#if !defined(__STDC_CONSTANT_MACROS) + #define __STDC_CONSTANT_MACROS +#endif + #include #include #include @@ -382,18 +396,6 @@ SOFTWARE. #define ETL_HAS_INITIALIZER_LIST 0 #endif -//************************************* -// Enable all limit macros -#if !defined(__STDC_LIMIT_MACROS) - #define __STDC_LIMIT_MACROS -#endif - -//************************************* -// Enable all constant macros -#if !defined(__STDC_CONSTANT_MACROS) - #define __STDC_CONSTANT_MACROS -#endif - //************************************* // Check for availability of certain builtins #include "profiles/determine_builtin_support.h" diff --git a/include/etl/private/minmax_pop.h b/include/etl/private/minmax_pop.h index bf8ac02e4..ea66ebbb4 100644 --- a/include/etl/private/minmax_pop.h +++ b/include/etl/private/minmax_pop.h @@ -32,7 +32,7 @@ SOFTWARE. * The header include guard has been intentionally omitted. * This file is intended to evaluated multiple times by design. */ -#if !defined(ETL_COMPILER_GREEN_HILLS) && !defined(ETL_COMPILER_ICCAVR) +#if !defined(ETL_COMPILER_GREEN_HILLS) && !defined(ETL_COMPILER_IAR) #if !defined(ETL_COMPILER_ARM5) #pragma pop_macro("min") #pragma pop_macro("max") diff --git a/include/etl/private/minmax_push.h b/include/etl/private/minmax_push.h index e1db69810..1e41bd6d4 100644 --- a/include/etl/private/minmax_push.h +++ b/include/etl/private/minmax_push.h @@ -33,7 +33,7 @@ SOFTWARE. * This file is intended to evaluated multiple times by design. */ -#if !defined(ETL_COMPILER_GREEN_HILLS) && !defined(ETL_COMPILER_ICCAVR) +#if !defined(ETL_COMPILER_GREEN_HILLS) && !defined(ETL_COMPILER_IAR) #if !defined(ETL_COMPILER_ARM5) #pragma push_macro("min") #pragma push_macro("max") diff --git a/include/etl/profiles/determine_compiler.h b/include/etl/profiles/determine_compiler.h index d21271578..feb11de88 100644 --- a/include/etl/profiles/determine_compiler.h +++ b/include/etl/profiles/determine_compiler.h @@ -112,13 +112,6 @@ SOFTWARE. #endif #endif - #if !defined(ETL_COMPILER_TYPE_DETECTED) && !defined(ETL_COMPILER_ICCAVR) - #if defined(__ICCAVR__) - #define ETL_COMPILER_ICCAVR - #define ETL_COMPILER_TYPE_DETECTED - #endif - #endif - #if !defined(ETL_COMPILER_TYPE_DETECTED) && !defined(ETL_COMPILER_MICROSOFT) #if defined(_MSC_VER) #define ETL_COMPILER_MICROSOFT @@ -140,12 +133,6 @@ SOFTWARE. #define ETL_USING_GCC_COMPILER 0 #endif -#if defined(ETL_COMPILER_ICCAVR) - #define ETL_USING_ICCAVR_COMPILER 1 -#else - #define ETL_USING_ICCAVR_COMPILER 0 -#endif - #if defined(ETL_COMPILER_MICROSOFT) #define ETL_USING_MICROSOFT_COMPILER 1 #else diff --git a/include/etl/profiles/determine_compiler_version.h b/include/etl/profiles/determine_compiler_version.h index 2a5f9761e..6835a75e3 100644 --- a/include/etl/profiles/determine_compiler_version.h +++ b/include/etl/profiles/determine_compiler_version.h @@ -37,9 +37,6 @@ SOFTWARE. #if defined(ETL_COMPILER_GCC) #define ETL_COMPILER_VERSION __GNUC__ #define ETL_COMPILER_FULL_VERSION ((__GNUC__ * 10000) + (__GNUC_MINOR__ * 100) + __GNUC_PATCHLEVEL__) - #elif defined(ETL_COMPILER_ICCAVR) - #define ETL_COMPILER_VERSION __VER__ - #define ETL_COMPILER_FULL_VERSION __VER__ #elif defined(ETL_COMPILER_MICROSOFT) #define ETL_COMPILER_VERSION _MSC_VER #define ETL_COMPILER_FULL_VERSION _MSC_FULL_VER diff --git a/include/etl/utility.h b/include/etl/utility.h index c6f09ec05..509896ded 100644 --- a/include/etl/utility.h +++ b/include/etl/utility.h @@ -93,24 +93,36 @@ namespace etl } #endif - //****************************************************************************** + /** + * @brief pair holds two objects of arbitrary type + * + * @tparam T1, T2 The types of the elements that the pair stores + */ template struct pair { - typedef T1 first_type; - typedef T2 second_type; + typedef T1 first_type; ///< @c first_type is the first bound type + typedef T2 second_type; ///< @c second_type is the second bound type - T1 first; - T2 second; + T1 first; ///< @c first is a copy of the first object + T2 second; ///< @c second is a copy of the second object - /// Default constructor + /** + * @brief Default constructor + * + * The default constructor creates @c first and @c second using their respective default constructors. + */ ETL_CONSTEXPR pair() : first(T1()) , second(T2()) { } - /// Constructor from parameters + /** + * @brief Constructor from parameters + * + * Two objects may be passed to a @c pair constructor to be copied. + */ ETL_CONSTEXPR14 pair(const T1& a, const T2& b) : first(a) , second(b) @@ -118,7 +130,9 @@ namespace etl } #if ETL_USING_CPP11 - /// Move constructor from parameters + /** + * @brief Move constructor from parameters. + */ template ETL_CONSTEXPR14 pair(U1&& a, U2&& b) : first(etl::forward(a)) @@ -127,7 +141,11 @@ namespace etl } #endif - /// Copy constructor + /** + * @brief Copy constructor + * + * There is also a templated copy constructor for the @c pair class itself. + */ template ETL_CONSTEXPR14 pair(const pair& other) : first(other.first) @@ -224,7 +242,14 @@ namespace etl #endif }; - //****************************************************************************** + /** + * @brief A convenience wrapper for creating a @ref pair from two objects. + * + * @param a The first object. + * @param b The second object. + * + * @return A newly-constructed @ref pair object of the appropriate type. + */ #if ETL_USING_CPP11 template inline pair make_pair(T1&& a, T2&& b) @@ -246,13 +271,14 @@ namespace etl a.swap(b); } - //****************************************************************************** + /// Two pairs of the same type are equal iff their members are equal. template inline bool operator ==(const pair& a, const pair& b) { return (a.first == b.first) && (a.second == b.second); } + /// Uses @c operator== to find the result. template inline bool operator !=(const pair& a, const pair& b) { @@ -266,24 +292,97 @@ namespace etl (!(b.first < a.first) && (a.second < b.second)); } + /// Uses @c operator< to find the result. template inline bool operator >(const pair& a, const pair& b) { return (b < a); } + /// Uses @c operator< to find the result. template inline bool operator <=(const pair& a, const pair& b) { return !(b < a); } + /// Uses @c operator< to find the result. template inline bool operator >=(const pair& a, const pair& b) { return !(a < b); } + /** + * @brief Functor to select @ref pair::first + * + * @ref select1st is a functor object that takes a single argument, a @ref pair, and returns the @ref pair::first element. + * + * @b Example + * @snippet test_utility.cpp test_select1st_example + * + * @tparam TPair The function object's argument type. + * + * @see select2nd + */ + template + struct select1st + { + typedef typename TPair::first_type type; ///< type of member @ref pair::first. + + /** + * @brief Function call that return @c p.first. + * @return a reference to member @ref pair::first of the @c pair `p` + */ + type& operator()(TPair& p) const + { + return p.first; + } + + /** + * @copydoc operator()(TPair&)const + */ + const type& operator()(const TPair& p) const + { + return p.first; + } + }; + + /** + * @brief Functor to select @ref pair::second + * + * @ref select2nd is a functor object that takes a single argument, a @ref pair, and returns the @ref pair::second element. + * + * @b Example + * @snippet test_utility.cpp test_select2nd_example + * + * @tparam TPair The function object's argument type. + * + * @see select1st + */ + template + struct select2nd + { + typedef typename TPair::second_type type; ///< type of member @ref pair::second. + + /** + * @brief Function call. The return value is `p.second`. + * @return a reference to member `second` of the pair `p`. + */ + type& operator()(TPair& p) const + { + return p.second; + } + + /** + * @copydoc operator()(TPair&)const + */ + const type& operator()(const TPair& p) const + { + return p.second; + } + }; + #if ETL_NOT_USING_STL || ETL_CPP14_NOT_SUPPORTED //*************************************************************************** /// exchange (const) diff --git a/test/test_fixed_iterator.cpp b/test/test_fixed_iterator.cpp index 3c6925c17..d8cde6722 100644 --- a/test/test_fixed_iterator.cpp +++ b/test/test_fixed_iterator.cpp @@ -55,7 +55,7 @@ namespace //************************************************************************* TEST(test_copy_constructor) { - int a; + int a{}; etl::fixed_iterator fi1(&a); etl::fixed_iterator fi2(fi1); @@ -66,7 +66,7 @@ namespace //************************************************************************* TEST(test_constructor) { - int a; + int a{}; etl::fixed_iterator fi(&a); @@ -76,7 +76,7 @@ namespace //************************************************************************* TEST(test_make) { - int a; + int a{}; etl::fixed_iterator fi = &a; @@ -121,7 +121,7 @@ namespace //************************************************************************* TEST(test_conversion_operator) { - int a; + int a{}; etl::fixed_iterator fi(&a); @@ -202,8 +202,8 @@ namespace //************************************************************************* TEST(test_assignment) { - int a; - int b; + int a{}; + int b{}; etl::fixed_iterator fi = &a; fi = &b; @@ -218,8 +218,8 @@ namespace //************************************************************************* TEST(test_equality) { - int a; - int b; + int a{}; + int b{}; etl::fixed_iterator fi1 = &a; etl::fixed_iterator fi2 = &a; diff --git a/test/test_hash.cpp b/test/test_hash.cpp index 19c1fc476..8a1bd8a49 100644 --- a/test/test_hash.cpp +++ b/test/test_hash.cpp @@ -202,7 +202,7 @@ namespace //************************************************************************* TEST(test_hash_pointer) { - int i; + int i{}; size_t hash = etl::hash()(&i); CHECK_EQUAL(size_t(&i), hash); @@ -211,7 +211,7 @@ namespace //************************************************************************* TEST(test_hash_const_pointer) { - int i; + int i{}; size_t hash = etl::hash()(&i); CHECK_EQUAL(size_t(&i), hash); @@ -220,7 +220,7 @@ namespace //************************************************************************* TEST(test_hash_const_pointer_const) { - int i; + int i{}; const int * const pi = &i; size_t hash = etl::hash()(pi); diff --git a/test/test_multi_array.cpp b/test/test_multi_array.cpp index 5d0af28a7..78ba585cb 100644 --- a/test/test_multi_array.cpp +++ b/test/test_multi_array.cpp @@ -298,7 +298,7 @@ namespace //************************************************************************* TEST(test_empty) { - Data data; + Data data{}; CHECK(!data.empty()); CHECK(!data[0].empty()); diff --git a/test/test_utility.cpp b/test/test_utility.cpp index 3261a2943..b686092d6 100644 --- a/test/test_utility.cpp +++ b/test/test_utility.cpp @@ -30,6 +30,9 @@ SOFTWARE. #include "etl/utility.h" +#include +#include + #include "data.h" namespace @@ -330,6 +333,80 @@ namespace CHECK(constCalled); } + //************************************************************************* + TEST(test_select1st) + { + typedef etl::pair EtlPair; + typedef std::pair StdPair; + + EtlPair ep1(1, "Hello"); + StdPair sp2(2, "World"); + + auto selector = etl::select1st(); + + CHECK_EQUAL(1, selector(ep1)); + CHECK_EQUAL(2, selector(sp2)); + } + + //************************************************************************* + TEST(test_select1st_example) + { + //! [test_select1st_example] + using Map = std::map; + using Vector = std::vector; + + const Map map = {{1, 0.3}, + {47, 0.8}, + {33, 0.1}}; + Vector result{}; + + // extract the map keys into a vector + std::transform(map.begin(), map.end(), std::back_inserter(result), etl::select1st()); + //! [test_select1st_example] + + CHECK_EQUAL(3, result.size()); + + const Vector expected{1, 33, 47}; + CHECK_ARRAY_EQUAL(expected, result, 3); + } + + //************************************************************************* + TEST(test_select2nd) + { + typedef etl::pair EtlPair; + typedef std::pair StdPair; + + EtlPair ep1(1, "Hello"); + StdPair sp2(2, "World"); + + auto selector = etl::select2nd(); + CHECK_EQUAL(std::string("Hello"), selector(ep1)); + CHECK_EQUAL(std::string("World"), selector(sp2)); + } + + //************************************************************************* + TEST(test_select2nd_example) + { + //! [test_select2nd_example] + using Map = std::map; + using Vector = std::vector; + + const Map map = {{1, 0.3}, + {47, 0.8}, + {33, 0.1}}; + Vector result{}; + + // extract the map values into a vector + std::transform(map.begin(), map.end(), std::back_inserter(result), etl::select2nd()); + //! [test_select2nd_example] + + CHECK_EQUAL(3, result.size()); + + const Vector expected{0.1, 0.3, 0.8}; + sort(result.begin(), result.end()); // sort for comparison + CHECK_ARRAY_CLOSE(expected, result, 3, 0.0001); + } + //************************************************************************* TEST(test_functor) { From 7dd3e3bcbb3b1583e5dd88d9b526c6b54a448411 Mon Sep 17 00:00:00 2001 From: John Wellbelove Date: Sun, 2 Oct 2022 12:55:55 +0100 Subject: [PATCH 2/2] Added select1st and select2nd --- include/etl/unaligned_type.h | 3 + include/etl/utility.h | 158 ++++++++++++++++++++--------------- test/test_utility.cpp | 35 +++++++- 3 files changed, 123 insertions(+), 73 deletions(-) diff --git a/include/etl/unaligned_type.h b/include/etl/unaligned_type.h index 54b722054..4e5cb5dce 100644 --- a/include/etl/unaligned_type.h +++ b/include/etl/unaligned_type.h @@ -217,6 +217,9 @@ namespace etl //************************************************************************* /// unaligned_type + ///\brief Allows an arithmetic type to be stored at an unaligned address. + ///\tparam T The arithmetic type. + ///\tparam Endian The endianness of the arithmetic type. //************************************************************************* template class unaligned_type : public private_unaligned_type::unaligned_type_common diff --git a/include/etl/utility.h b/include/etl/utility.h index 509896ded..00f54248b 100644 --- a/include/etl/utility.h +++ b/include/etl/utility.h @@ -93,11 +93,11 @@ namespace etl } #endif - /** - * @brief pair holds two objects of arbitrary type - * - * @tparam T1, T2 The types of the elements that the pair stores - */ + //*************************************************************************** + ///\brief pair holds two objects of arbitrary type + /// + ///\tparam T1, T2 The types of the elements that the pair stores + //*************************************************************************** template struct pair { @@ -107,22 +107,22 @@ namespace etl T1 first; ///< @c first is a copy of the first object T2 second; ///< @c second is a copy of the second object - /** - * @brief Default constructor - * - * The default constructor creates @c first and @c second using their respective default constructors. - */ + //*************************************************************************** + ///\brief Default constructor + /// + /// The default constructor creates @c first and @c second using their respective default constructors. + //*************************************************************************** ETL_CONSTEXPR pair() : first(T1()) , second(T2()) { } - /** - * @brief Constructor from parameters - * - * Two objects may be passed to a @c pair constructor to be copied. - */ + //*************************************************************************** + ///\brief Constructor from parameters + /// + /// Two objects may be passed to a @c pair constructor to be copied. + //*************************************************************************** ETL_CONSTEXPR14 pair(const T1& a, const T2& b) : first(a) , second(b) @@ -130,9 +130,9 @@ namespace etl } #if ETL_USING_CPP11 - /** - * @brief Move constructor from parameters. - */ + //*************************************************************************** + ///\brief Move constructor from parameters. + //*************************************************************************** template ETL_CONSTEXPR14 pair(U1&& a, U2&& b) : first(etl::forward(a)) @@ -141,11 +141,11 @@ namespace etl } #endif - /** - * @brief Copy constructor - * - * There is also a templated copy constructor for the @c pair class itself. - */ + //*************************************************************************** + ///\brief Copy constructor + /// + /// There is also a templated copy constructor for the @c pair class itself. + //*************************************************************************** template ETL_CONSTEXPR14 pair(const pair& other) : first(other.first) @@ -242,14 +242,14 @@ namespace etl #endif }; - /** - * @brief A convenience wrapper for creating a @ref pair from two objects. - * - * @param a The first object. - * @param b The second object. - * - * @return A newly-constructed @ref pair object of the appropriate type. - */ + //*************************************************************************** + ///\brief A convenience wrapper for creating a @ref pair from two objects. + /// + ///\param a The first object. + ///\param b The second object. + /// + ///\return A newly-constructed @ref pair object of the appropriate type. + //*************************************************************************** #if ETL_USING_CPP11 template inline pair make_pair(T1&& a, T2&& b) @@ -313,74 +313,94 @@ namespace etl return !(a < b); } - /** - * @brief Functor to select @ref pair::first - * - * @ref select1st is a functor object that takes a single argument, a @ref pair, and returns the @ref pair::first element. - * - * @b Example - * @snippet test_utility.cpp test_select1st_example - * - * @tparam TPair The function object's argument type. - * - * @see select2nd - */ + //*************************************************************************** + ///\brief Functor to select @ref pair::first + /// + ///\ref select1st is a functor object that takes a single argument, a @ref pair, and returns the @ref pair::first element. + /// + ///\b Example + ///\snippet test_utility.cpp test_select1st_example + /// + ///\tparam TPair The function object's argument type. + /// + ///\see select2nd + //*************************************************************************** template struct select1st { typedef typename TPair::first_type type; ///< type of member @ref pair::first. - /** - * @brief Function call that return @c p.first. - * @return a reference to member @ref pair::first of the @c pair `p` - */ + //*************************************************************************** + ///\brief Function call that return @c p.first. + ///\return a reference to member @ref pair::first of the @c pair `p` + //*************************************************************************** type& operator()(TPair& p) const { return p.first; } - /** - * @copydoc operator()(TPair&)const - */ + //*************************************************************************** + ///\copydoc operator()(TPair&)const + // const type& operator()(const TPair& p) const { return p.first; } + +#if ETL_CPP11_SUPPORTED + //*************************************************************************** + ///\copydoc operator()(TPair&)const + //*************************************************************************** + type&& operator()(TPair&& p) const + { + return etl::move(p.first); + } +#endif }; - /** - * @brief Functor to select @ref pair::second - * - * @ref select2nd is a functor object that takes a single argument, a @ref pair, and returns the @ref pair::second element. - * - * @b Example - * @snippet test_utility.cpp test_select2nd_example - * - * @tparam TPair The function object's argument type. - * - * @see select1st - */ + //*************************************************************************** + ///\brief Functor to select @ref pair::second + /// + ///\ref select2nd is a functor object that takes a single argument, a @ref pair, and returns the @ref pair::second element. + /// + ///\b Example + ///\snippet test_utility.cpp test_select2nd_example + /// + ///\tparam TPair The function object's argument type. + /// + ///\see select1st + //*************************************************************************** template struct select2nd { typedef typename TPair::second_type type; ///< type of member @ref pair::second. - /** - * @brief Function call. The return value is `p.second`. - * @return a reference to member `second` of the pair `p`. - */ + //*************************************************************************** + ///\brief Function call. The return value is `p.second`. + ///\return a reference to member `second` of the pair `p`. + //*************************************************************************** type& operator()(TPair& p) const { return p.second; } - /** - * @copydoc operator()(TPair&)const - */ + //*************************************************************************** + ///\copydoc operator()(TPair&)const + //*************************************************************************** const type& operator()(const TPair& p) const { return p.second; } + +#if ETL_CPP11_SUPPORTED + //*************************************************************************** + ///\copydoc operator()(TPair&)const + //*************************************************************************** + type&& operator()(TPair&& p) const + { + return etl::move(p.second); + } +#endif }; #if ETL_NOT_USING_STL || ETL_CPP14_NOT_SUPPORTED diff --git a/test/test_utility.cpp b/test/test_utility.cpp index b686092d6..aa4c66c9b 100644 --- a/test/test_utility.cpp +++ b/test/test_utility.cpp @@ -32,6 +32,7 @@ SOFTWARE. #include #include +#include #include "data.h" @@ -348,11 +349,23 @@ namespace CHECK_EQUAL(2, selector(sp2)); } + //************************************************************************* + TEST(test_select1st_move) + { + typedef etl::pair EtlPair; + typedef std::pair StdPair; + + auto selector = etl::select1st(); + + CHECK_EQUAL(1, selector(std::move(EtlPair(1, "Hello")))); + CHECK_EQUAL(2, selector(std::move(StdPair(2, "Hello")))); + } + //************************************************************************* TEST(test_select1st_example) { //! [test_select1st_example] - using Map = std::map; + using Map = std::map; using Vector = std::vector; const Map map = {{1, 0.3}, @@ -360,7 +373,7 @@ namespace {33, 0.1}}; Vector result{}; - // extract the map keys into a vector + // Extract the map keys into a vector std::transform(map.begin(), map.end(), std::back_inserter(result), etl::select1st()); //! [test_select1st_example] @@ -384,11 +397,25 @@ namespace CHECK_EQUAL(std::string("World"), selector(sp2)); } + //************************************************************************* + TEST(test_select2nd_move) + { + typedef etl::pair EtlPair; + typedef std::pair StdPair; + + EtlPair ep1(1, "Hello"); + StdPair sp2(2, "World"); + + auto selector = etl::select2nd(); + CHECK_EQUAL(std::string("Hello"), selector(std::move(EtlPair(1, "Hello")))); + CHECK_EQUAL(std::string("World"), selector(std::move(StdPair(1, "World")))); + } + //************************************************************************* TEST(test_select2nd_example) { //! [test_select2nd_example] - using Map = std::map; + using Map = std::map; using Vector = std::vector; const Map map = {{1, 0.3}, @@ -396,7 +423,7 @@ namespace {33, 0.1}}; Vector result{}; - // extract the map values into a vector + // Extract the map values into a vector std::transform(map.begin(), map.end(), std::back_inserter(result), etl::select2nd()); //! [test_select2nd_example]