Skip to content

Commit

Permalink
Added select1st and select2nd
Browse files Browse the repository at this point in the history
  • Loading branch information
jwellbelove committed Oct 2, 2022
1 parent 8b52ad6 commit 7dd3e3b
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 73 deletions.
3 changes: 3 additions & 0 deletions include/etl/unaligned_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename T, int Endian_>
class unaligned_type : public private_unaligned_type::unaligned_type_common<sizeof(T)>
Expand Down
158 changes: 89 additions & 69 deletions include/etl/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 <typename T1, typename T2>
struct pair
{
Expand All @@ -107,32 +107,32 @@ 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)
{
}

#if ETL_USING_CPP11
/**
* @brief Move constructor from parameters.
*/
//***************************************************************************
///\brief Move constructor from parameters.
//***************************************************************************
template <typename U1, typename U2>
ETL_CONSTEXPR14 pair(U1&& a, U2&& b)
: first(etl::forward<U1>(a))
Expand All @@ -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 <typename U1, typename U2>
ETL_CONSTEXPR14 pair(const pair<U1, U2>& other)
: first(other.first)
Expand Down Expand Up @@ -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 <typename T1, typename T2>
inline pair<T1, T2> make_pair(T1&& a, T2&& b)
Expand Down Expand Up @@ -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 <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`
*/
//***************************************************************************
///\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 <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`.
*/
//***************************************************************************
///\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
Expand Down
35 changes: 31 additions & 4 deletions test/test_utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ SOFTWARE.

#include <map>
#include <vector>
#include <algorithm>

#include "data.h"

Expand Down Expand Up @@ -348,19 +349,31 @@ namespace
CHECK_EQUAL(2, selector(sp2));
}

//*************************************************************************
TEST(test_select1st_move)
{
typedef etl::pair<int, std::string> EtlPair;
typedef std::pair<int, std::string> StdPair;

auto selector = etl::select1st<EtlPair>();

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<int, double>;
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
// 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]

Expand All @@ -384,19 +397,33 @@ namespace
CHECK_EQUAL(std::string("World"), selector(sp2));
}

//*************************************************************************
TEST(test_select2nd_move)
{
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(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<int, double>;
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
// 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]

Expand Down

0 comments on commit 7dd3e3b

Please sign in to comment.