Added dual input range versions transform algorithm.

This commit is contained in:
jwellbelove 2017-03-03 10:24:02 +00:00
parent 8dbd6904b7
commit 8451bc1e88

View File

@ -53,8 +53,11 @@ namespace etl
///<a href="http://en.cppreference.com/w/cpp/algorithm/minmax_element"></a>
///\ingroup algorithm
//***************************************************************************
template <typename TIterator, typename TCompare>
std::pair<TIterator, TIterator> minmax_element(TIterator begin, TIterator end, TCompare compare)
template <typename TIterator,
typename TCompare>
std::pair<TIterator, TIterator> minmax_element(TIterator begin,
TIterator end,
TCompare compare)
{
TIterator minimum = begin;
TIterator maximum = begin;
@ -83,7 +86,8 @@ namespace etl
///<a href="http://en.cppreference.com/w/cpp/algorithm/minmax_element"></a>
//***************************************************************************
template <typename TIterator>
std::pair<TIterator, TIterator> minmax_element(TIterator begin, TIterator end)
std::pair<TIterator, TIterator> minmax_element(TIterator begin,
TIterator end)
{
typedef typename std::iterator_traits<TIterator>::value_type value_t;
@ -96,7 +100,8 @@ namespace etl
///<a href="http://en.cppreference.com/w/cpp/algorithm/minmax"></a>
//***************************************************************************
template <typename T>
std::pair<const T&, const T&> minmax(const T& a, const T& b)
std::pair<const T&, const T&> minmax(const T& a,
const T& b)
{
return (b < a) ? std::pair<const T&, const T&>(b, a) : std::pair<const T&, const T&>(a, b);
}
@ -106,8 +111,11 @@ namespace etl
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/minmax"></a>
//***************************************************************************
template <typename T, typename TCompare>
std::pair<const T&, const T&> minmax(const T& a, const T& b, TCompare compare)
template <typename T,
typename TCompare>
std::pair<const T&, const T&> minmax(const T& a,
const T& b,
TCompare compare)
{
return compare(b, a) ? std::pair<const T&, const T&>(b, a) : std::pair<const T&, const T&>(a, b);
}
@ -118,7 +126,8 @@ namespace etl
///<a href="http://en.cppreference.com/w/cpp/algorithm/is_sorted_until"></a>
//***************************************************************************
template <typename TIterator>
TIterator is_sorted_until(TIterator begin, TIterator end)
TIterator is_sorted_until(TIterator begin,
TIterator end)
{
if (begin != end)
{
@ -143,8 +152,11 @@ namespace etl
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/is_sorted_until"></a>
//***************************************************************************
template <typename TIterator, typename TCompare>
TIterator is_sorted_until(TIterator begin, TIterator end, TCompare compare)
template <typename TIterator,
typename TCompare>
TIterator is_sorted_until(TIterator begin,
TIterator end,
TCompare compare)
{
if (begin != end)
{
@ -170,7 +182,8 @@ namespace etl
///<a href="http://en.cppreference.com/w/cpp/algorithm/is_sorted"></a>
//***************************************************************************
template<typename TIterator>
bool is_sorted(TIterator begin, TIterator end)
bool is_sorted(TIterator begin,
TIterator end)
{
return etl::is_sorted_until(begin, end) == end;
}
@ -180,8 +193,11 @@ namespace etl
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/is_sorted"></a>
//***************************************************************************
template<typename TIterator, typename TCompare>
bool is_sorted(TIterator begin, TIterator end, TCompare compare)
template<typename TIterator,
typename TCompare>
bool is_sorted(TIterator begin,
TIterator end,
TCompare compare)
{
return etl::is_sorted_until(begin, end, compare) == end;
}
@ -197,11 +213,14 @@ namespace etl
///\param o_end End of the output range.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator, typename TOutputIterator>
template <typename TInputIterator,
typename TOutputIterator>
typename etl::enable_if<etl::is_random_iterator<TInputIterator>::value &&
etl::is_random_iterator<TOutputIterator>::value, TOutputIterator>::type
copy(TInputIterator i_begin, TInputIterator i_end,
TOutputIterator o_begin, TOutputIterator o_end)
copy(TInputIterator i_begin,
TInputIterator i_end,
TOutputIterator o_begin,
TOutputIterator o_end)
{
size_t s_size = std::distance(i_begin, i_end);
size_t d_size = std::distance(o_begin, o_end);
@ -221,11 +240,14 @@ namespace etl
///\param o_end End of the output range.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator, typename TOutputIterator>
template <typename TInputIterator,
typename TOutputIterator>
typename etl::enable_if<!etl::is_random_iterator<TInputIterator>::value ||
!etl::is_random_iterator<TOutputIterator>::value, TOutputIterator>::type
copy(TInputIterator i_begin, TInputIterator i_end,
TOutputIterator o_begin, TOutputIterator o_end)
copy(TInputIterator i_begin,
TInputIterator i_end,
TOutputIterator o_begin,
TOutputIterator o_end)
{
while ((i_begin != i_end) && (o_begin != o_end))
{
@ -240,8 +262,12 @@ namespace etl
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/copy_n"></a>
//***************************************************************************
template <typename TInputIterator, typename Size, typename TOutputIterator>
TOutputIterator copy_n(TInputIterator begin, Size count, TOutputIterator result)
template <typename TInputIterator,
typename TSize,
typename TOutputIterator>
TOutputIterator copy_n(TInputIterator begin,
TSize count,
TOutputIterator result)
{
return std::copy(begin, begin + count, result);
}
@ -251,8 +277,13 @@ namespace etl
/// A form of copy_n where the smallest of the two ranges is used.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator, typename Size, typename TOutputIterator>
TOutputIterator copy_n(TInputIterator i_begin, Size count, TOutputIterator o_begin, TOutputIterator o_end)
template <typename TInputIterator,
typename TSize,
typename TOutputIterator>
TOutputIterator copy_n(TInputIterator i_begin,
TSize count,
TOutputIterator o_begin,
TOutputIterator o_end)
{
return etl::copy(i_begin, i_begin + count, o_begin, o_end);;
}
@ -262,8 +293,13 @@ namespace etl
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/copy"></a>
//***************************************************************************
template <typename TIterator, typename TOutputIterator, typename TUnaryPredicate>
TOutputIterator copy_if(TIterator begin, TIterator end, TOutputIterator out, TUnaryPredicate predicate)
template <typename TIterator,
typename TOutputIterator,
typename TUnaryPredicate>
TOutputIterator copy_if(TIterator begin,
TIterator end,
TOutputIterator out,
TUnaryPredicate predicate)
{
while (begin != end)
{
@ -284,9 +320,13 @@ namespace etl
/// There is currently no STL equivelent.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator, typename TOutputIterator, typename TUnaryPredicate>
TOutputIterator copy_if(TInputIterator i_begin, TInputIterator i_end,
TOutputIterator o_begin, TOutputIterator o_end,
template <typename TInputIterator,
typename TOutputIterator,
typename TUnaryPredicate>
TOutputIterator copy_if(TInputIterator i_begin,
TInputIterator i_end,
TOutputIterator o_begin,
TOutputIterator o_end,
TUnaryPredicate predicate)
{
while ((i_begin != i_end) && (o_begin != o_end))
@ -307,8 +347,11 @@ namespace etl
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/find"></a>
//***************************************************************************
template <typename TIterator, typename TUnaryPredicate>
TIterator find_if_not(TIterator begin, TIterator end, TUnaryPredicate predicate)
template <typename TIterator,
typename TUnaryPredicate>
TIterator find_if_not(TIterator begin,
TIterator end,
TUnaryPredicate predicate)
{
while (begin != end)
{
@ -328,8 +371,11 @@ namespace etl
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/all_any_none_of"></a>
//***************************************************************************
template <typename TIterator, typename TUnaryPredicate >
bool all_of(TIterator begin, TIterator end, TUnaryPredicate predicate)
template <typename TIterator,
typename TUnaryPredicate>
bool all_of(TIterator begin,
TIterator end,
TUnaryPredicate predicate)
{
return etl::find_if_not(begin, end, predicate) == end;
}
@ -339,8 +385,11 @@ namespace etl
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/all_any_none_of"></a>
//***************************************************************************
template <typename TIterator, typename TUnaryPredicate >
bool any_of(TIterator begin, TIterator end, TUnaryPredicate predicate)
template <typename TIterator,
typename TUnaryPredicate>
bool any_of(TIterator begin,
TIterator end,
TUnaryPredicate predicate)
{
return std::find_if(begin, end, predicate) != end;
}
@ -350,8 +399,11 @@ namespace etl
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/all_any_none_of"></a>
//***************************************************************************
template <typename TIterator, typename TUnaryPredicate >
bool none_of(TIterator begin, TIterator end, TUnaryPredicate predicate)
template <typename TIterator,
typename TUnaryPredicate>
bool none_of(TIterator begin,
TIterator end,
TUnaryPredicate predicate)
{
return std::find_if(begin, end, predicate) == end;
}
@ -361,8 +413,11 @@ namespace etl
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/is_permutation"></a>
//***************************************************************************
template <typename TIterator1, typename TIterator2>
bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2)
template <typename TIterator1,
typename TIterator2>
bool is_permutation(TIterator1 begin1,
TIterator1 end1,
TIterator2 begin2)
{
if (begin1 != end1)
{
@ -392,8 +447,12 @@ namespace etl
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/is_permutation"></a>
//***************************************************************************
template <typename TIterator1, typename TIterator2>
bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TIterator2 end2)
template <typename TIterator1,
typename TIterator2>
bool is_permutation(TIterator1 begin1,
TIterator1 end1,
TIterator2 begin2,
TIterator2 end2)
{
if (begin1 != end1)
{
@ -419,8 +478,13 @@ namespace etl
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/is_permutation"></a>
//***************************************************************************
template <typename TIterator1, typename TIterator2, typename TBinaryPredicate>
bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TBinaryPredicate predicate)
template <typename TIterator1,
typename TIterator2,
typename TBinaryPredicate>
bool is_permutation(TIterator1 begin1,
TIterator1 end1,
TIterator2 begin2,
TBinaryPredicate predicate)
{
if (begin1 != end1)
{
@ -450,8 +514,14 @@ namespace etl
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/is_permutation"></a>
//***************************************************************************
template <typename TIterator1, typename TIterator2, typename TBinaryPredicate>
bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TIterator2 end2, TBinaryPredicate predicate)
template <typename TIterator1,
typename TIterator2,
typename TBinaryPredicate>
bool is_permutation(TIterator1 begin1,
TIterator1 end1,
TIterator2 begin2,
TIterator2 end2,
TBinaryPredicate predicate)
{
if (begin1 != end1)
{
@ -477,8 +547,11 @@ namespace etl
///\ingroup algorithm
///<a href="http://en.cppreference.com/w/cpp/algorithm/is_partitioned"></a>
//***************************************************************************
template <typename TIterator, typename TUnaryPredicate>
bool is_partitioned(TIterator begin, TIterator end, TUnaryPredicate predicate)
template <typename TIterator,
typename TUnaryPredicate>
bool is_partitioned(TIterator begin,
TIterator end,
TUnaryPredicate predicate)
{
while (begin != end)
{
@ -504,8 +577,11 @@ namespace etl
///<a href="http://en.cppreference.com/w/cpp/algorithm/partition_point"></a>
///\ingroup algorithm
//***************************************************************************
template <typename TIterator, typename TUnaryPredicate>
TIterator partition_point(TIterator begin, TIterator end, TUnaryPredicate predicate)
template <typename TIterator,
typename TUnaryPredicate>
TIterator partition_point(TIterator begin,
TIterator end,
TUnaryPredicate predicate)
{
while (begin != end)
{
@ -526,7 +602,10 @@ namespace etl
///<a href="http://en.cppreference.com/w/cpp/algorithm/partition_copy"></a>
///\ingroup algorithm
//***************************************************************************
template <typename TSource, typename TDestinationTrue, typename TDestinationFalse, typename TUnaryPredicate>
template <typename TSource,
typename TDestinationTrue,
typename TDestinationFalse,
typename TUnaryPredicate>
std::pair<TDestinationTrue, TDestinationFalse> partition_copy(TSource begin,
TSource end,
TDestinationTrue destination_true,
@ -552,8 +631,13 @@ namespace etl
/// Like std::for_each but applies a predicate before calling the function.
///\ingroup algorithm
//***************************************************************************
template <typename TIterator, typename TUnaryFunction, typename TUnaryPredicate>
TUnaryFunction for_each_if(TIterator begin, const TIterator end, TUnaryFunction function, TUnaryPredicate predicate)
template <typename TIterator,
typename TUnaryFunction,
typename TUnaryPredicate>
TUnaryFunction for_each_if(TIterator begin,
const TIterator end,
TUnaryFunction function,
TUnaryPredicate predicate)
{
while (begin != end)
{
@ -574,7 +658,9 @@ namespace etl
/// There is currently no STL equivalent.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator, typename TOutputIterator, typename TUnaryFunction>
template <typename TInputIterator,
typename TOutputIterator,
typename TUnaryFunction>
void transform(TInputIterator i_begin,
TInputIterator i_end,
TOutputIterator o_begin,
@ -589,10 +675,14 @@ namespace etl
//***************************************************************************
/// Transform 'n' items.
/// Random iterators.
/// There is currently no STL equivalent.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TUnaryFunction>
template <typename TInputIterator,
typename TSize,
typename TOutputIterator,
typename TUnaryFunction>
typename etl::enable_if<etl::is_random_iterator<TInputIterator>::value, void>::type
transform_n(TInputIterator i_begin,
TSize n,
@ -603,11 +693,37 @@ namespace etl
}
//***************************************************************************
/// Transform 'n' items.
/// Transform 'n' items from two ranges.
/// Random iterators.
/// There is currently no STL equivalent.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator, typename TSize, typename TOutputIterator, typename TUnaryFunction>
template <typename TInputIterator1,
typename TInputIterator2,
typename TSize,
typename TOutputIterator,
typename TBinaryFunction>
typename etl::enable_if<etl::is_random_iterator<TInputIterator1>::value &&
etl::is_random_iterator<TInputIterator2>::value, void>::type
transform_n(TInputIterator1 i_begin1,
TInputIterator2 i_begin2,
TSize n,
TOutputIterator o_begin,
TBinaryFunction function)
{
std::transform(i_begin, i_begin + n, i_begin2, o_begin, function);
}
//***************************************************************************
/// Transform 'n' items.
/// Non-random iterators.
/// There is currently no STL equivalent.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator,
typename TSize,
typename TOutputIterator,
typename TUnaryFunction>
typename etl::enable_if<!etl::is_random_iterator<TInputIterator>::value, void>::type
transform_n(TInputIterator i_begin,
TSize n,
@ -621,14 +737,45 @@ namespace etl
}
}
//***************************************************************************
/// Transform 'n' items from two ranges.
/// Non-random iterators.
/// There is currently no STL equivalent.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator1,
typename TInputIterator2,
typename TSize,
typename TOutputIterator,
typename TBinaryFunction>
typename etl::enable_if<!etl::is_random_iterator<TInputIterator1>::value ||
!etl::is_random_iterator<TInputIterator2>::value, void>::type
transform_n(TInputIterator1 i_begin1,
TInputIterator2 i_begin2,
TSize n,
TOutputIterator o_begin,
TBinaryFunction function)
{
while (n > 0)
{
*o_begin++ = function(*i_begin1++, *i_begin2++);
--n;
}
}
//***************************************************************************
/// Like std::transform but applies a predicate before calling the function.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator, typename TOutputIterator, typename TUnaryFunction, typename TUnaryPredicate>
TOutputIterator transform_if(TInputIterator i_begin, const TInputIterator i_end,
TOutputIterator o_begin, TUnaryFunction function,
TUnaryPredicate predicate)
template <typename TInputIterator,
typename TOutputIterator,
typename TUnaryFunction,
typename TUnaryPredicate>
TOutputIterator transform_if(TInputIterator i_begin,
const TInputIterator i_end,
TOutputIterator o_begin,
TUnaryFunction function,
TUnaryPredicate predicate)
{
while (i_begin != i_end)
{
@ -643,16 +790,51 @@ namespace etl
return o_begin;
}
//***************************************************************************
/// Like etl::transform_if but inputs from two ranges.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator1,
typename TInputIterator2,
typename TOutputIterator,
typename TBinaryFunction,
typename TBinaryPredicate>
TOutputIterator transform_if(TInputIterator1 i_begin1,
const TInputIterator1 i_end1,
TInputIterator2 i_begin2,
TOutputIterator o_begin,
TBinaryFunction function,
TBinaryPredicate predicate)
{
while (i_begin1 != i_end1)
{
if (predicate(*i_begin1, *i_begin2))
{
*o_begin++ = function(*i_begin1, *i_begin2);
}
++i_begin1;
++i_begin2;
}
return o_begin;
}
//***************************************************************************
/// Like std::transform but applies a predicate before calling the function.
/// Returns when the first range end is reached.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator, typename TOutputIterator, typename TUnaryFunction, typename TUnaryPredicate>
TOutputIterator transform_if(TInputIterator i_begin, const TInputIterator i_end,
TOutputIterator o_begin, TOutputIterator o_end,
TUnaryFunction function,
TUnaryPredicate predicate)
template <typename TInputIterator,
typename TOutputIterator,
typename TUnaryFunction,
typename TUnaryPredicate>
TOutputIterator transform_if(TInputIterator i_begin,
const TInputIterator i_end,
TOutputIterator o_begin,
TOutputIterator o_end,
TUnaryFunction function,
TUnaryPredicate predicate)
{
while ((i_begin != i_end) && (o_begin != o_end))
{
@ -667,13 +849,47 @@ namespace etl
return o_begin;
}
//***************************************************************************
/// Like etl::transform_if but inputs from two ranges.
/// Returns when the first range end is reached.
///\ingroup algorithm
//***************************************************************************
template <typename TInputIterator1,
typename TInputIterator2,
typename TOutputIterator,
typename TBinaryFunction,
typename TBinaryPredicate>
TOutputIterator transform_if(TInputIterator1 i_begin1,
const TInputIterator1 i_end1,
TInputIterator2 i_begin2,
const TInputIterator1 i_end2,
TOutputIterator o_begin,
const TInputIterator1 o_end,
TBinaryFunction function,
TBinaryPredicate predicate)
{
while ((i_begin1 != i_end1) && (i_begin2 != i_end2) && (o_begin != o_end))
{
if (predicate(*i_begin1, *i_begin2))
{
*o_begin++ = function(*i_begin1, *i_begin2);
}
++i_begin1;
++i_begin2;
}
return o_begin;
}
//***************************************************************************
/// Transforms the elements from the range (begin, end) to two different ranges
/// depending on the value returned by the predicate.<br>
///\ingroup algorithm
//***************************************************************************
template <typename TSource, typename TDestinationTrue, typename TDestinationFalse,
typename TUnaryFunctionTrue, typename TUnaryFunctionFalse, typename TUnaryPredicate>
typename TUnaryFunctionTrue, typename TUnaryFunctionFalse,
typename TUnaryPredicate>
std::pair<TDestinationTrue, TDestinationFalse> partition_transform(TSource begin,
TSource end,
TDestinationTrue destination_true,
@ -698,5 +914,42 @@ namespace etl
}
}
//***************************************************************************
/// Transforms the elements from the ranges (begin1, end1) & (begin2, end2)
/// to two different ranges depending on the value returned by the predicate.
///\ingroup algorithm
//***************************************************************************
template <typename TSource1,
typename TSource2,
typename TDestinationTrue,
typename TDestinationFalse,
typename TBinaryFunctionTrue,
typename TBinaryFunctionFalse,
typename TBinaryPredicate>
std::pair<TDestinationTrue, TDestinationFalse> partition_transform(TSource1 begin1,
TSource1 end1,
TSource2 begin2,
TDestinationTrue destination_true,
TDestinationFalse destination_false,
TBinaryFunctionTrue function_true,
TBinaryFunctionFalse function_false,
TBinaryPredicate predicate)
{
while (begin1 != end1)
{
if (predicate(*begin1, *begin2))
{
*destination_true++ = function_true(*begin1++, *begin2++);
}
else
{
*destination_false++ = function_false(*begin1++, *begin2++);
}
}
return std::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false);
}
}
#endif