diff --git a/.gitignore b/.gitignore index db038001..dd68c752 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 0d144834..437a911e 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/utility.h b/include/etl/utility.h index c6f09ec0..509896de 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_utility.cpp b/test/test_utility.cpp index 3261a294..b686092d 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) {