mirror of
https://github.com/ETLCPP/etl.git
synced 2026-04-30 19:09:10 +08:00
Feature/add pair functors (#610)
* Move __STDC_LIMIT_MACROS and __STDC_CONSTANT_MACROS before `#include <stdint.h>`. (#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 <C++11 detection). At the moment ETL_COMPILER_ICCAVR is used as a switch condition for using `#pragma push_macro`. But actually IAR ARM and IAR AVR have no such macro defined. ETL_COMPILER_IAR is defined for both compilers. Thus the switch condition is replaced with ETL_COMPILER_IAR. * Fix 'maybe-uninitialized' g++ error on macos (#600) * Add documentation to the pair class * Add test directory to the EXAMPLE_PATH * Update .gitignore - Remove duplicate entries - Add doxygen output directories * Add Select1st and Select2nd functors * Merge select1st and select2nd into utility.h Co-authored-by: David Hebbeker <dhebbeker@users.noreply.github.com>
This commit is contained in:
parent
92d8739db4
commit
b5182dd83e
23
.gitignore
vendored
23
.gitignore
vendored
@ -3,6 +3,8 @@
|
|||||||
## Personal
|
## Personal
|
||||||
#################
|
#################
|
||||||
docs/html
|
docs/html
|
||||||
|
include/etl/html/
|
||||||
|
include/etl/latex/
|
||||||
test/vs2013/Debug
|
test/vs2013/Debug
|
||||||
test/vs2013/Release
|
test/vs2013/Release
|
||||||
test/keil/Debug
|
test/keil/Debug
|
||||||
@ -91,14 +93,12 @@ build/
|
|||||||
*.tlb
|
*.tlb
|
||||||
*.tli
|
*.tli
|
||||||
*.tlh
|
*.tlh
|
||||||
*.tmp
|
|
||||||
*.tmp_proj
|
*.tmp_proj
|
||||||
*.log
|
*.log
|
||||||
*.vspscc
|
*.vspscc
|
||||||
*.vssscc
|
*.vssscc
|
||||||
.builds
|
.builds
|
||||||
*.pidb
|
*.pidb
|
||||||
*.log
|
|
||||||
*.scc
|
*.scc
|
||||||
|
|
||||||
# Visual C++ cache files
|
# Visual C++ cache files
|
||||||
@ -219,7 +219,6 @@ $RECYCLE.BIN/
|
|||||||
*.egg
|
*.egg
|
||||||
*.egg-info
|
*.egg-info
|
||||||
dist/
|
dist/
|
||||||
build/
|
|
||||||
eggs/
|
eggs/
|
||||||
parts/
|
parts/
|
||||||
var/
|
var/
|
||||||
@ -241,7 +240,6 @@ pip-log.txt
|
|||||||
#Mr Developer
|
#Mr Developer
|
||||||
.mr.developer.cfg
|
.mr.developer.cfg
|
||||||
*.depend
|
*.depend
|
||||||
*.depend
|
|
||||||
*.layout
|
*.layout
|
||||||
*.session
|
*.session
|
||||||
*.tags
|
*.tags
|
||||||
@ -270,13 +268,9 @@ test/kdevelopbuild/unittest++
|
|||||||
test/random_clcg.csv
|
test/random_clcg.csv
|
||||||
test/random_hash.csv
|
test/random_hash.csv
|
||||||
test/random_lcg.csv
|
test/random_lcg.csv
|
||||||
test/random_lcg.csv
|
|
||||||
test/random_lcg.csv
|
|
||||||
test/random_lsfr.csv
|
|
||||||
test/random_lsfr.csv
|
test/random_lsfr.csv
|
||||||
test/random_mwc.csv
|
test/random_mwc.csv
|
||||||
test/random_pcg.csv
|
test/random_pcg.csv
|
||||||
test/random_pcg.csv
|
|
||||||
test/random_xorshift.csv
|
test/random_xorshift.csv
|
||||||
test/cmake_install.cmake
|
test/cmake_install.cmake
|
||||||
test/Makefile
|
test/Makefile
|
||||||
@ -331,21 +325,16 @@ test/vs2019/Test2
|
|||||||
test/vs2019/Debug MSVC - Force C++03
|
test/vs2019/Debug MSVC - Force C++03
|
||||||
test/vs2019/Debug LLVM - No STL
|
test/vs2019/Debug LLVM - No STL
|
||||||
test/vs2019/Debug - No STL
|
test/vs2019/Debug - No STL
|
||||||
test/meson-info
|
|
||||||
test/etl_unit_tests.p
|
test/etl_unit_tests.p
|
||||||
test/meson-logs
|
|
||||||
test/meson-private
|
|
||||||
test/.ninja_deps
|
test/.ninja_deps
|
||||||
test/.ninja_log
|
test/.ninja_log
|
||||||
test/build.ninja
|
test/build.ninja
|
||||||
test/compile_commands.json
|
test/compile_commands.json
|
||||||
test/etl_unit_tests
|
test/etl_unit_tests
|
||||||
test/build-make
|
test/build-make
|
||||||
test/build-make
|
|
||||||
test/meson-info
|
test/meson-info
|
||||||
test/meson-logs
|
test/meson-logs
|
||||||
test/meson-private
|
test/meson-private
|
||||||
test/build-make
|
|
||||||
test/build-ninja
|
test/build-ninja
|
||||||
test/vs2019/Debug MSVC C++20
|
test/vs2019/Debug MSVC C++20
|
||||||
test/vs2019/Debug MSVC C++20 - No STL
|
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_and_log_errors-GCC-Debug
|
||||||
test/etl_error_handler/build-exceptions-GCC-Debug
|
test/etl_error_handler/build-exceptions-GCC-Debug
|
||||||
test/etl_error_handler/exceptions_and_log_errors/.vs
|
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
|
examples/ArmTimerCallbacks - C++/ArmTimerCallbacks.uvoptx
|
||||||
|
|||||||
2
Doxyfile
2
Doxyfile
@ -872,7 +872,7 @@ EXCLUDE_SYMBOLS =
|
|||||||
# that contain example code fragments that are included (see the \include
|
# that contain example code fragments that are included (see the \include
|
||||||
# command).
|
# command).
|
||||||
|
|
||||||
EXAMPLE_PATH =
|
EXAMPLE_PATH = ./test
|
||||||
|
|
||||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
# 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
|
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
|
||||||
|
|||||||
@ -93,24 +93,36 @@ namespace etl
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//******************************************************************************
|
/**
|
||||||
|
* @brief pair holds two objects of arbitrary type
|
||||||
|
*
|
||||||
|
* @tparam T1, T2 The types of the elements that the pair stores
|
||||||
|
*/
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
struct pair
|
struct pair
|
||||||
{
|
{
|
||||||
typedef T1 first_type;
|
typedef T1 first_type; ///< @c first_type is the first bound type
|
||||||
typedef T2 second_type;
|
typedef T2 second_type; ///< @c second_type is the second bound type
|
||||||
|
|
||||||
T1 first;
|
T1 first; ///< @c first is a copy of the first object
|
||||||
T2 second;
|
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()
|
ETL_CONSTEXPR pair()
|
||||||
: first(T1())
|
: first(T1())
|
||||||
, second(T2())
|
, 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)
|
ETL_CONSTEXPR14 pair(const T1& a, const T2& b)
|
||||||
: first(a)
|
: first(a)
|
||||||
, second(b)
|
, second(b)
|
||||||
@ -118,7 +130,9 @@ namespace etl
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if ETL_USING_CPP11
|
#if ETL_USING_CPP11
|
||||||
/// Move constructor from parameters
|
/**
|
||||||
|
* @brief Move constructor from parameters.
|
||||||
|
*/
|
||||||
template <typename U1, typename U2>
|
template <typename U1, typename U2>
|
||||||
ETL_CONSTEXPR14 pair(U1&& a, U2&& b)
|
ETL_CONSTEXPR14 pair(U1&& a, U2&& b)
|
||||||
: first(etl::forward<U1>(a))
|
: first(etl::forward<U1>(a))
|
||||||
@ -127,7 +141,11 @@ namespace etl
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/// Copy constructor
|
/**
|
||||||
|
* @brief Copy constructor
|
||||||
|
*
|
||||||
|
* There is also a templated copy constructor for the @c pair class itself.
|
||||||
|
*/
|
||||||
template <typename U1, typename U2>
|
template <typename U1, typename U2>
|
||||||
ETL_CONSTEXPR14 pair(const pair<U1, U2>& other)
|
ETL_CONSTEXPR14 pair(const pair<U1, U2>& other)
|
||||||
: first(other.first)
|
: first(other.first)
|
||||||
@ -224,7 +242,14 @@ namespace etl
|
|||||||
#endif
|
#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
|
#if ETL_USING_CPP11
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
inline pair<T1, T2> make_pair(T1&& a, T2&& b)
|
inline pair<T1, T2> make_pair(T1&& a, T2&& b)
|
||||||
@ -246,13 +271,14 @@ namespace etl
|
|||||||
a.swap(b);
|
a.swap(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
//******************************************************************************
|
/// Two pairs of the same type are equal iff their members are equal.
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
inline bool operator ==(const pair<T1, T2>& a, const pair<T1, T2>& b)
|
inline bool operator ==(const pair<T1, T2>& a, const pair<T1, T2>& b)
|
||||||
{
|
{
|
||||||
return (a.first == b.first) && (a.second == b.second);
|
return (a.first == b.first) && (a.second == b.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Uses @c operator== to find the result.
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
inline bool operator !=(const pair<T1, T2>& a, const pair<T1, T2>& b)
|
inline bool operator !=(const pair<T1, T2>& a, const pair<T1, T2>& b)
|
||||||
{
|
{
|
||||||
@ -266,24 +292,97 @@ namespace etl
|
|||||||
(!(b.first < a.first) && (a.second < b.second));
|
(!(b.first < a.first) && (a.second < b.second));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Uses @c operator< to find the result.
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
inline bool operator >(const pair<T1, T2>& a, const pair<T1, T2>& b)
|
inline bool operator >(const pair<T1, T2>& a, const pair<T1, T2>& b)
|
||||||
{
|
{
|
||||||
return (b < a);
|
return (b < a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Uses @c operator< to find the result.
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
inline bool operator <=(const pair<T1, T2>& a, const pair<T1, T2>& b)
|
inline bool operator <=(const pair<T1, T2>& a, const pair<T1, T2>& b)
|
||||||
{
|
{
|
||||||
return !(b < a);
|
return !(b < a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Uses @c operator< to find the result.
|
||||||
template <typename T1, typename T2>
|
template <typename T1, typename T2>
|
||||||
inline bool operator >=(const pair<T1, T2>& a, const pair<T1, T2>& b)
|
inline bool operator >=(const pair<T1, T2>& a, const pair<T1, T2>& b)
|
||||||
{
|
{
|
||||||
return !(a < 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 <typename TPair>
|
||||||
|
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 <typename TPair>
|
||||||
|
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
|
#if ETL_NOT_USING_STL || ETL_CPP14_NOT_SUPPORTED
|
||||||
//***************************************************************************
|
//***************************************************************************
|
||||||
/// exchange (const)
|
/// exchange (const)
|
||||||
|
|||||||
@ -30,6 +30,9 @@ SOFTWARE.
|
|||||||
|
|
||||||
#include "etl/utility.h"
|
#include "etl/utility.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "data.h"
|
#include "data.h"
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
@ -330,6 +333,80 @@ namespace
|
|||||||
CHECK(constCalled);
|
CHECK(constCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST(test_select1st)
|
||||||
|
{
|
||||||
|
typedef etl::pair<int, std::string> EtlPair;
|
||||||
|
typedef std::pair<int, std::string> StdPair;
|
||||||
|
|
||||||
|
EtlPair ep1(1, "Hello");
|
||||||
|
StdPair sp2(2, "World");
|
||||||
|
|
||||||
|
auto selector = etl::select1st<EtlPair>();
|
||||||
|
|
||||||
|
CHECK_EQUAL(1, selector(ep1));
|
||||||
|
CHECK_EQUAL(2, selector(sp2));
|
||||||
|
}
|
||||||
|
|
||||||
|
//*************************************************************************
|
||||||
|
TEST(test_select1st_example)
|
||||||
|
{
|
||||||
|
//! [test_select1st_example]
|
||||||
|
using Map = std::map<int, double>;
|
||||||
|
using Vector = std::vector<int>;
|
||||||
|
|
||||||
|
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<Map::value_type>());
|
||||||
|
//! [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<int, std::string> EtlPair;
|
||||||
|
typedef std::pair<int, std::string> StdPair;
|
||||||
|
|
||||||
|
EtlPair ep1(1, "Hello");
|
||||||
|
StdPair sp2(2, "World");
|
||||||
|
|
||||||
|
auto selector = etl::select2nd<EtlPair>();
|
||||||
|
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<int, double>;
|
||||||
|
using Vector = std::vector<double>;
|
||||||
|
|
||||||
|
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<Map::value_type>());
|
||||||
|
//! [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)
|
TEST(test_functor)
|
||||||
{
|
{
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user