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/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 c6f09ec05..00f54248b 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,117 @@ 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; + } + +#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 + //*************************************************************************** + 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_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 //*************************************************************************** /// exchange (const) diff --git a/test/test_utility.cpp b/test/test_utility.cpp index 3261a2943..aa4c66c9b 100644 --- a/test/test_utility.cpp +++ b/test/test_utility.cpp @@ -30,6 +30,10 @@ SOFTWARE. #include "etl/utility.h" +#include +#include +#include + #include "data.h" namespace @@ -330,6 +334,106 @@ 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_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 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_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 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) {