From 8451bc1e888f09d2d7313168cfe5c2eeddbe2941 Mon Sep 17 00:00:00 2001 From: jwellbelove Date: Fri, 3 Mar 2017 10:24:02 +0000 Subject: [PATCH] Added dual input range versions transform algorithm. --- src/algorithm.h | 381 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 317 insertions(+), 64 deletions(-) diff --git a/src/algorithm.h b/src/algorithm.h index 58e05eb1..7698dee4 100644 --- a/src/algorithm.h +++ b/src/algorithm.h @@ -53,8 +53,11 @@ namespace etl /// ///\ingroup algorithm //*************************************************************************** - template - std::pair minmax_element(TIterator begin, TIterator end, TCompare compare) + template + std::pair minmax_element(TIterator begin, + TIterator end, + TCompare compare) { TIterator minimum = begin; TIterator maximum = begin; @@ -83,7 +86,8 @@ namespace etl /// //*************************************************************************** template - std::pair minmax_element(TIterator begin, TIterator end) + std::pair minmax_element(TIterator begin, + TIterator end) { typedef typename std::iterator_traits::value_type value_t; @@ -96,7 +100,8 @@ namespace etl /// //*************************************************************************** template - std::pair minmax(const T& a, const T& b) + std::pair minmax(const T& a, + const T& b) { return (b < a) ? std::pair(b, a) : std::pair(a, b); } @@ -106,8 +111,11 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - std::pair minmax(const T& a, const T& b, TCompare compare) + template + std::pair minmax(const T& a, + const T& b, + TCompare compare) { return compare(b, a) ? std::pair(b, a) : std::pair(a, b); } @@ -118,7 +126,8 @@ namespace etl /// //*************************************************************************** template - 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 /// //*************************************************************************** - template - TIterator is_sorted_until(TIterator begin, TIterator end, TCompare compare) + template + TIterator is_sorted_until(TIterator begin, + TIterator end, + TCompare compare) { if (begin != end) { @@ -170,7 +182,8 @@ namespace etl /// //*************************************************************************** template - 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 /// //*************************************************************************** - template - bool is_sorted(TIterator begin, TIterator end, TCompare compare) + template + 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 + template typename etl::enable_if::value && etl::is_random_iterator::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 + template typename etl::enable_if::value || !etl::is_random_iterator::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 /// //*************************************************************************** - template - TOutputIterator copy_n(TInputIterator begin, Size count, TOutputIterator result) + template + 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 - TOutputIterator copy_n(TInputIterator i_begin, Size count, TOutputIterator o_begin, TOutputIterator o_end) + template + 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 /// //*************************************************************************** - template - TOutputIterator copy_if(TIterator begin, TIterator end, TOutputIterator out, TUnaryPredicate predicate) + template + 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 - TOutputIterator copy_if(TInputIterator i_begin, TInputIterator i_end, - TOutputIterator o_begin, TOutputIterator o_end, + template + 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 /// //*************************************************************************** - template - TIterator find_if_not(TIterator begin, TIterator end, TUnaryPredicate predicate) + template + TIterator find_if_not(TIterator begin, + TIterator end, + TUnaryPredicate predicate) { while (begin != end) { @@ -328,8 +371,11 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - bool all_of(TIterator begin, TIterator end, TUnaryPredicate predicate) + template + 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 /// //*************************************************************************** - template - bool any_of(TIterator begin, TIterator end, TUnaryPredicate predicate) + template + 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 /// //*************************************************************************** - template - bool none_of(TIterator begin, TIterator end, TUnaryPredicate predicate) + template + 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 /// //*************************************************************************** - template - bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2) + template + bool is_permutation(TIterator1 begin1, + TIterator1 end1, + TIterator2 begin2) { if (begin1 != end1) { @@ -392,8 +447,12 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TIterator2 end2) + template + bool is_permutation(TIterator1 begin1, + TIterator1 end1, + TIterator2 begin2, + TIterator2 end2) { if (begin1 != end1) { @@ -419,8 +478,13 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TBinaryPredicate predicate) + template + bool is_permutation(TIterator1 begin1, + TIterator1 end1, + TIterator2 begin2, + TBinaryPredicate predicate) { if (begin1 != end1) { @@ -450,8 +514,14 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TIterator2 end2, TBinaryPredicate predicate) + template + bool is_permutation(TIterator1 begin1, + TIterator1 end1, + TIterator2 begin2, + TIterator2 end2, + TBinaryPredicate predicate) { if (begin1 != end1) { @@ -477,8 +547,11 @@ namespace etl ///\ingroup algorithm /// //*************************************************************************** - template - bool is_partitioned(TIterator begin, TIterator end, TUnaryPredicate predicate) + template + bool is_partitioned(TIterator begin, + TIterator end, + TUnaryPredicate predicate) { while (begin != end) { @@ -504,8 +577,11 @@ namespace etl /// ///\ingroup algorithm //*************************************************************************** - template - TIterator partition_point(TIterator begin, TIterator end, TUnaryPredicate predicate) + template + TIterator partition_point(TIterator begin, + TIterator end, + TUnaryPredicate predicate) { while (begin != end) { @@ -526,7 +602,10 @@ namespace etl /// ///\ingroup algorithm //*************************************************************************** - template + template std::pair 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 - TUnaryFunction for_each_if(TIterator begin, const TIterator end, TUnaryFunction function, TUnaryPredicate predicate) + template + 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 + template 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 + template typename etl::enable_if::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 + template + typename etl::enable_if::value && + etl::is_random_iterator::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 etl::enable_if::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 etl::enable_if::value || + !etl::is_random_iterator::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 - TOutputIterator transform_if(TInputIterator i_begin, const TInputIterator i_end, - TOutputIterator o_begin, TUnaryFunction function, - TUnaryPredicate predicate) + template + 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 + 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 - TOutputIterator transform_if(TInputIterator i_begin, const TInputIterator i_end, - TOutputIterator o_begin, TOutputIterator o_end, - TUnaryFunction function, - TUnaryPredicate predicate) + template + 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 + 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.
///\ingroup algorithm //*************************************************************************** template + typename TUnaryFunctionTrue, typename TUnaryFunctionFalse, + typename TUnaryPredicate> std::pair 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 + std::pair 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(destination_true, destination_false); + } +} + #endif