Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
algorithm.h
00001 ///\file 00002 00003 /****************************************************************************** 00004 The MIT License(MIT) 00005 00006 Embedded Template Library. 00007 https://github.com/ETLCPP/etl 00008 http://www.etlcpp.com 00009 00010 Copyright(c) 2014 jwellbelove 00011 00012 Permission is hereby granted, free of charge, to any person obtaining a copy 00013 of this software and associated documentation files(the "Software"), to deal 00014 in the Software without restriction, including without limitation the rights 00015 to use, copy, modify, merge, publish, distribute, sublicense, and / or sell 00016 copies of the Software, and to permit persons to whom the Software is 00017 furnished to do so, subject to the following conditions : 00018 00019 The above copyright notice and this permission notice shall be included in all 00020 copies or substantial portions of the Software. 00021 00022 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00023 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00024 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE 00025 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00026 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00027 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 00028 SOFTWARE. 00029 ******************************************************************************/ 00030 00031 #ifndef __ETL_ALGORITHM__ 00032 #define __ETL_ALGORITHM__ 00033 00034 ///\defgroup algorithm algorithm 00035 /// Reverse engineered algorithms from C++ 0x11 00036 /// Additional new variants of certain algorithms. 00037 ///\ingroup utilities 00038 00039 #include <algorithm> 00040 #include <iterator> 00041 #include <utility> 00042 #include <functional> 00043 #include <iterator> 00044 #include <stdint.h> 00045 00046 #include "platform.h " 00047 #include "iterator.h " 00048 #include "type_traits.h " 00049 00050 namespace etl 00051 { 00052 //*************************************************************************** 00053 /// Finds the greatest and the smallest element in the range (begin, end).<br> 00054 ///<a href="http://en.cppreference.com/w/cpp/algorithm/minmax_element"></a> 00055 ///\ingroup algorithm 00056 //*************************************************************************** 00057 template <typename TIterator, 00058 typename TCompare> 00059 std::pair<TIterator, TIterator> minmax_element(TIterator begin, 00060 TIterator end, 00061 TCompare compare) 00062 { 00063 TIterator minimum = begin; 00064 TIterator maximum = begin; 00065 00066 while (begin != end) 00067 { 00068 if (compare(*begin, *minimum)) 00069 { 00070 minimum = begin; 00071 } 00072 00073 if (compare(*maximum, *begin)) 00074 { 00075 maximum = begin; 00076 } 00077 00078 ++begin; 00079 } 00080 00081 return std::pair<TIterator, TIterator>(minimum, maximum); 00082 } 00083 00084 //*************************************************************************** 00085 /// minmax_element 00086 ///\ingroup algorithm 00087 ///<a href="http://en.cppreference.com/w/cpp/algorithm/minmax_element"></a> 00088 //*************************************************************************** 00089 template <typename TIterator> 00090 std::pair<TIterator, TIterator> minmax_element(TIterator begin, 00091 TIterator end) 00092 { 00093 typedef typename std::iterator_traits<TIterator>::value_type value_t; 00094 00095 return etl::minmax_element(begin, end, std::less<value_t>()); 00096 } 00097 00098 //*************************************************************************** 00099 /// minmax 00100 ///\ingroup algorithm 00101 ///<a href="http://en.cppreference.com/w/cpp/algorithm/minmax"></a> 00102 //*************************************************************************** 00103 template <typename T> 00104 std::pair<const T&, const T&> minmax(const T& a, 00105 const T& b) 00106 { 00107 return (b < a) ? std::pair<const T&, const T&>(b, a) : std::pair<const T&, const T&>(a, b); 00108 } 00109 00110 //*************************************************************************** 00111 /// minmax 00112 ///\ingroup algorithm 00113 ///<a href="http://en.cppreference.com/w/cpp/algorithm/minmax"></a> 00114 //*************************************************************************** 00115 template <typename T, 00116 typename TCompare> 00117 std::pair<const T&, const T&> minmax(const T& a, 00118 const T& b, 00119 TCompare compare) 00120 { 00121 return compare(b, a) ? std::pair<const T&, const T&>(b, a) : std::pair<const T&, const T&>(a, b); 00122 } 00123 00124 //*************************************************************************** 00125 /// is_sorted_until 00126 ///\ingroup algorithm 00127 ///<a href="http://en.cppreference.com/w/cpp/algorithm/is_sorted_until"></a> 00128 //*************************************************************************** 00129 template <typename TIterator> 00130 TIterator is_sorted_until(TIterator begin, 00131 TIterator end) 00132 { 00133 if (begin != end) 00134 { 00135 TIterator next = begin; 00136 00137 while (++next != end) 00138 { 00139 if (*next < *begin) 00140 { 00141 return next; 00142 } 00143 00144 ++begin; 00145 } 00146 } 00147 00148 return end; 00149 } 00150 00151 //*************************************************************************** 00152 /// is_sorted_until 00153 ///\ingroup algorithm 00154 ///<a href="http://en.cppreference.com/w/cpp/algorithm/is_sorted_until"></a> 00155 //*************************************************************************** 00156 template <typename TIterator, 00157 typename TCompare> 00158 TIterator is_sorted_until(TIterator begin, 00159 TIterator end, 00160 TCompare compare) 00161 { 00162 if (begin != end) 00163 { 00164 TIterator next = begin; 00165 00166 while (++next != end) 00167 { 00168 if (compare(*next, *begin)) 00169 { 00170 return next; 00171 } 00172 00173 ++begin; 00174 } 00175 } 00176 00177 return end; 00178 } 00179 00180 //*************************************************************************** 00181 /// is_sorted 00182 ///\ingroup algorithm 00183 ///<a href="http://en.cppreference.com/w/cpp/algorithm/is_sorted"></a> 00184 //*************************************************************************** 00185 template<typename TIterator> 00186 bool is_sorted(TIterator begin, 00187 TIterator end) 00188 { 00189 return etl::is_sorted_until(begin, end) == end; 00190 } 00191 00192 //*************************************************************************** 00193 /// is_sorted 00194 ///\ingroup algorithm 00195 ///<a href="http://en.cppreference.com/w/cpp/algorithm/is_sorted"></a> 00196 //*************************************************************************** 00197 template<typename TIterator, 00198 typename TCompare> 00199 bool is_sorted(TIterator begin, 00200 TIterator end, 00201 TCompare compare) 00202 { 00203 return etl::is_sorted_until(begin, end, compare) == end; 00204 } 00205 00206 //*************************************************************************** 00207 /// copy 00208 /// A form of copy where the smallest of the two ranges is used. 00209 /// There is currently no STL equivalent. 00210 /// Specialisation for random access iterators. 00211 ///\param i_begin Beginning of the input range. 00212 ///\param i_end End of the input range. 00213 ///\param o_begin Beginning of the output range. 00214 ///\param o_end End of the output range. 00215 ///\ingroup algorithm 00216 //*************************************************************************** 00217 template <typename TInputIterator, 00218 typename TOutputIterator> 00219 typename etl::enable_if<etl::is_random_iterator<TInputIterator>::value && 00220 etl::is_random_iterator<TOutputIterator>::value, TOutputIterator>::type 00221 copy(TInputIterator i_begin, 00222 TInputIterator i_end, 00223 TOutputIterator o_begin, 00224 TOutputIterator o_end) 00225 { 00226 size_t s_size = std::distance(i_begin, i_end); 00227 size_t d_size = std::distance(o_begin, o_end); 00228 size_t size = (s_size < d_size) ? s_size : d_size; 00229 00230 return std::copy(i_begin, i_begin + size, o_begin); 00231 } 00232 00233 //*************************************************************************** 00234 /// copy 00235 /// A form of copy where the smallest of the two ranges is used. 00236 /// There is currently no STL equivalent. 00237 /// Specialisation for non random access iterators. 00238 ///\param i_begin Beginning of the input range. 00239 ///\param i_end End of the input range. 00240 ///\param o_begin Beginning of the output range. 00241 ///\param o_end End of the output range. 00242 ///\ingroup algorithm 00243 //*************************************************************************** 00244 template <typename TInputIterator, 00245 typename TOutputIterator> 00246 typename etl::enable_if<!etl::is_random_iterator<TInputIterator>::value || 00247 !etl::is_random_iterator<TOutputIterator>::value, TOutputIterator>::type 00248 copy(TInputIterator i_begin, 00249 TInputIterator i_end, 00250 TOutputIterator o_begin, 00251 TOutputIterator o_end) 00252 { 00253 while ((i_begin != i_end) && (o_begin != o_end)) 00254 { 00255 *o_begin++ = *i_begin++; 00256 } 00257 00258 return o_begin; 00259 } 00260 00261 //*************************************************************************** 00262 /// copy_n (Random input iterators) 00263 ///\ingroup algorithm 00264 ///<a href="http://en.cppreference.com/w/cpp/algorithm/copy_n"></a> 00265 //*************************************************************************** 00266 template <typename TInputIterator, 00267 typename TSize, 00268 typename TOutputIterator> 00269 typename etl::enable_if<etl::is_random_iterator<TInputIterator>::value, TOutputIterator>::type 00270 copy_n(TInputIterator i_begin, 00271 TSize n, 00272 TOutputIterator o_begin) 00273 { 00274 return std::copy(i_begin, i_begin + n, o_begin); 00275 } 00276 00277 //*************************************************************************** 00278 /// copy_n (Non-random input iterators) 00279 ///\ingroup algorithm 00280 ///<a href="http://en.cppreference.com/w/cpp/algorithm/copy_n"></a> 00281 //*************************************************************************** 00282 template <typename TInputIterator, 00283 typename TSize, 00284 typename TOutputIterator> 00285 typename etl::enable_if<!etl::is_random_iterator<TInputIterator>::value, TOutputIterator>::type 00286 copy_n(TInputIterator i_begin, 00287 TSize n, 00288 TOutputIterator o_begin) 00289 { 00290 while (n-- > 0) 00291 { 00292 *o_begin++ = *i_begin++; 00293 } 00294 00295 return o_begin; 00296 } 00297 00298 //*************************************************************************** 00299 /// copy_n 00300 /// A form of copy_n where the smallest of the two ranges is used. 00301 ///\ingroup algorithm 00302 //*************************************************************************** 00303 template <typename TInputIterator, 00304 typename TSize, 00305 typename TOutputIterator> 00306 TOutputIterator copy_n(TInputIterator i_begin, 00307 TSize n, 00308 TOutputIterator o_begin, 00309 TOutputIterator o_end) 00310 { 00311 while ((n-- > 0) && (o_begin != o_end)) 00312 { 00313 *o_begin++ = *i_begin++; 00314 } 00315 00316 return o_begin; 00317 } 00318 00319 //*************************************************************************** 00320 /// copy_n 00321 /// A form of copy_n where the smallest of the two ranges is used. 00322 ///\ingroup algorithm 00323 //*************************************************************************** 00324 template <typename TInputIterator, 00325 typename TSize1, 00326 typename TOutputIterator, 00327 typename TSize2> 00328 TOutputIterator copy_n(TInputIterator i_begin, 00329 TSize1 n1, 00330 TOutputIterator o_begin, 00331 TSize2 n2) 00332 { 00333 while ((n1-- > 0) && (n2-- > 0)) 00334 { 00335 *o_begin++ = *i_begin++; 00336 } 00337 00338 return o_begin; 00339 } 00340 00341 //*************************************************************************** 00342 /// copy_if 00343 ///\ingroup algorithm 00344 ///<a href="http://en.cppreference.com/w/cpp/algorithm/copy"></a> 00345 //*************************************************************************** 00346 template <typename TIterator, 00347 typename TOutputIterator, 00348 typename TUnaryPredicate> 00349 TOutputIterator copy_if(TIterator begin, 00350 TIterator end, 00351 TOutputIterator out, 00352 TUnaryPredicate predicate) 00353 { 00354 while (begin != end) 00355 { 00356 if (predicate(*begin)) 00357 { 00358 *out++ = *begin; 00359 } 00360 00361 ++begin; 00362 } 00363 00364 return out; 00365 } 00366 00367 //*************************************************************************** 00368 /// copy_if 00369 /// A form of copy_if where it terminates when the first end iterator is reached. 00370 /// There is currently no STL equivelent. 00371 ///\ingroup algorithm 00372 //*************************************************************************** 00373 template <typename TInputIterator, 00374 typename TOutputIterator, 00375 typename TUnaryPredicate> 00376 TOutputIterator copy_if(TInputIterator i_begin, 00377 TInputIterator i_end, 00378 TOutputIterator o_begin, 00379 TOutputIterator o_end, 00380 TUnaryPredicate predicate) 00381 { 00382 while ((i_begin != i_end) && (o_begin != o_end)) 00383 { 00384 if (predicate(*i_begin)) 00385 { 00386 *o_begin++ = *i_begin; 00387 } 00388 00389 ++i_begin; 00390 } 00391 00392 return o_begin; 00393 } 00394 00395 //*************************************************************************** 00396 /// copy_n_if 00397 /// Combination of copy_n and copy_if. 00398 ///\ingroup algorithm 00399 //*************************************************************************** 00400 template <typename TInputIterator, 00401 typename TSize, 00402 typename TOutputIterator, 00403 typename TUnaryPredicate> 00404 TOutputIterator copy_n_if(TInputIterator i_begin, 00405 TSize n, 00406 TOutputIterator o_begin, 00407 TUnaryPredicate predicate) 00408 { 00409 while (n-- > 0) 00410 { 00411 if (predicate(*i_begin)) 00412 { 00413 *o_begin++ = *i_begin; 00414 } 00415 00416 ++i_begin; 00417 } 00418 00419 return o_begin; 00420 } 00421 00422 //*************************************************************************** 00423 /// binary_find 00424 ///\ingroup algorithm 00425 /// Does a binary search and returns an iterator to the value or end if not found. 00426 //*************************************************************************** 00427 template <typename TIterator, 00428 typename TValue> 00429 TIterator binary_find(TIterator begin, 00430 TIterator end, 00431 const TValue& value) 00432 { 00433 TIterator it = std::lower_bound(begin, end, value); 00434 00435 if ((it == end) || (*it != value)) 00436 { 00437 it = end; 00438 } 00439 00440 return it; 00441 } 00442 00443 //*************************************************************************** 00444 /// binary_find 00445 ///\ingroup algorithm 00446 /// Does a binary search and returns an iterator to the value or end if not found. 00447 //*************************************************************************** 00448 template <typename TIterator, 00449 typename TValue, 00450 typename TBinaryPredicate, 00451 typename TBinaryEquality> 00452 TIterator binary_find(TIterator begin, 00453 TIterator end, 00454 const TValue& value, 00455 TBinaryPredicate predicate, 00456 TBinaryEquality equality) 00457 { 00458 TIterator it = std::lower_bound(begin, end, value, predicate); 00459 00460 if ((it == end) || !equality(*it, value)) 00461 { 00462 it = end; 00463 } 00464 00465 return it; 00466 } 00467 00468 //*************************************************************************** 00469 /// find_if_not 00470 ///\ingroup algorithm 00471 ///<a href="http://en.cppreference.com/w/cpp/algorithm/find"></a> 00472 //*************************************************************************** 00473 template <typename TIterator, 00474 typename TUnaryPredicate> 00475 TIterator find_if_not(TIterator begin, 00476 TIterator end, 00477 TUnaryPredicate predicate) 00478 { 00479 while (begin != end) 00480 { 00481 if (!predicate(*begin)) 00482 { 00483 return begin; 00484 } 00485 00486 ++begin; 00487 } 00488 00489 return end; 00490 } 00491 00492 //*************************************************************************** 00493 /// all_of 00494 ///\ingroup algorithm 00495 ///<a href="http://en.cppreference.com/w/cpp/algorithm/all_any_none_of"></a> 00496 //*************************************************************************** 00497 template <typename TIterator, 00498 typename TUnaryPredicate> 00499 bool all_of(TIterator begin, 00500 TIterator end, 00501 TUnaryPredicate predicate) 00502 { 00503 return etl::find_if_not(begin, end, predicate) == end; 00504 } 00505 00506 //*************************************************************************** 00507 /// any_of 00508 ///\ingroup algorithm 00509 ///<a href="http://en.cppreference.com/w/cpp/algorithm/all_any_none_of"></a> 00510 //*************************************************************************** 00511 template <typename TIterator, 00512 typename TUnaryPredicate> 00513 bool any_of(TIterator begin, 00514 TIterator end, 00515 TUnaryPredicate predicate) 00516 { 00517 return std::find_if(begin, end, predicate) != end; 00518 } 00519 00520 //*************************************************************************** 00521 /// none_of 00522 ///\ingroup algorithm 00523 ///<a href="http://en.cppreference.com/w/cpp/algorithm/all_any_none_of"></a> 00524 //*************************************************************************** 00525 template <typename TIterator, 00526 typename TUnaryPredicate> 00527 bool none_of(TIterator begin, 00528 TIterator end, 00529 TUnaryPredicate predicate) 00530 { 00531 return std::find_if(begin, end, predicate) == end; 00532 } 00533 00534 //*************************************************************************** 00535 /// is_permutation 00536 ///\ingroup algorithm 00537 ///<a href="http://en.cppreference.com/w/cpp/algorithm/is_permutation"></a> 00538 //*************************************************************************** 00539 template <typename TIterator1, 00540 typename TIterator2> 00541 bool is_permutation(TIterator1 begin1, 00542 TIterator1 end1, 00543 TIterator2 begin2) 00544 { 00545 if (begin1 != end1) 00546 { 00547 TIterator2 end2 = begin2; 00548 00549 std::advance(end2, std::distance(begin1, end1)); 00550 00551 for (TIterator1 i = begin1; i != end1; ++i) 00552 { 00553 if (i == std::find(begin1, i, *i)) 00554 { 00555 int32_t n = std::count(begin2, end2, *i); 00556 00557 if (n == 0 || std::count(i, end1, *i) != n) 00558 { 00559 return false; 00560 } 00561 } 00562 } 00563 } 00564 00565 return true; 00566 } 00567 00568 //*************************************************************************** 00569 /// is_permutation 00570 ///\ingroup algorithm 00571 ///<a href="http://en.cppreference.com/w/cpp/algorithm/is_permutation"></a> 00572 //*************************************************************************** 00573 template <typename TIterator1, 00574 typename TIterator2> 00575 bool is_permutation(TIterator1 begin1, 00576 TIterator1 end1, 00577 TIterator2 begin2, 00578 TIterator2 end2) 00579 { 00580 if (begin1 != end1) 00581 { 00582 for (TIterator1 i = begin1; i != end1; ++i) 00583 { 00584 if (i == std::find(begin1, i, *i)) 00585 { 00586 int32_t n = std::count(begin2, end2, *i); 00587 00588 if (n == 0 || std::count(i, end1, *i) != n) 00589 { 00590 return false; 00591 } 00592 } 00593 } 00594 } 00595 00596 return true; 00597 } 00598 00599 //*************************************************************************** 00600 /// is_permutation 00601 ///\ingroup algorithm 00602 ///<a href="http://en.cppreference.com/w/cpp/algorithm/is_permutation"></a> 00603 //*************************************************************************** 00604 template <typename TIterator1, 00605 typename TIterator2, 00606 typename TBinaryPredicate> 00607 bool is_permutation(TIterator1 begin1, 00608 TIterator1 end1, 00609 TIterator2 begin2, 00610 TBinaryPredicate predicate) 00611 { 00612 if (begin1 != end1) 00613 { 00614 TIterator2 end2 = begin2; 00615 00616 std::advance(end2, std::distance(begin1, end1)); 00617 00618 for (TIterator1 i = begin1; i != end1; ++i) 00619 { 00620 if (i == std::find_if(begin1, i, std::bind1st(predicate, *i))) 00621 { 00622 int32_t n = std::count(begin2, end2, *i); 00623 00624 if (n == 0 || std::count(i, end1, *i) != n) 00625 { 00626 return false; 00627 } 00628 } 00629 } 00630 } 00631 00632 return true; 00633 } 00634 00635 //*************************************************************************** 00636 /// is_permutation 00637 ///\ingroup algorithm 00638 ///<a href="http://en.cppreference.com/w/cpp/algorithm/is_permutation"></a> 00639 //*************************************************************************** 00640 template <typename TIterator1, 00641 typename TIterator2, 00642 typename TBinaryPredicate> 00643 bool is_permutation(TIterator1 begin1, 00644 TIterator1 end1, 00645 TIterator2 begin2, 00646 TIterator2 end2, 00647 TBinaryPredicate predicate) 00648 { 00649 if (begin1 != end1) 00650 { 00651 for (TIterator1 i = begin1; i != end1; ++i) 00652 { 00653 if (i == std::find_if(begin1, i, std::bind1st(predicate, *i))) 00654 { 00655 int32_t n = std::count(begin2, end2, *i); 00656 00657 if (n == 0 || std::count(i, end1, *i) != n) 00658 { 00659 return false; 00660 } 00661 } 00662 } 00663 } 00664 00665 return true; 00666 } 00667 00668 //*************************************************************************** 00669 /// is_partitioned 00670 ///\ingroup algorithm 00671 ///<a href="http://en.cppreference.com/w/cpp/algorithm/is_partitioned"></a> 00672 //*************************************************************************** 00673 template <typename TIterator, 00674 typename TUnaryPredicate> 00675 bool is_partitioned(TIterator begin, 00676 TIterator end, 00677 TUnaryPredicate predicate) 00678 { 00679 while (begin != end) 00680 { 00681 if (!predicate(*begin++)) 00682 { 00683 break; 00684 } 00685 } 00686 00687 while (begin != end) 00688 { 00689 if (predicate(*begin++)) 00690 { 00691 return false; 00692 } 00693 } 00694 00695 return true; 00696 } 00697 00698 //*************************************************************************** 00699 /// partition_point 00700 ///<a href="http://en.cppreference.com/w/cpp/algorithm/partition_point"></a> 00701 ///\ingroup algorithm 00702 //*************************************************************************** 00703 template <typename TIterator, 00704 typename TUnaryPredicate> 00705 TIterator partition_point(TIterator begin, 00706 TIterator end, 00707 TUnaryPredicate predicate) 00708 { 00709 while (begin != end) 00710 { 00711 if (!predicate(*begin)) 00712 { 00713 return begin; 00714 } 00715 00716 ++begin; 00717 } 00718 00719 return begin; 00720 } 00721 00722 //*************************************************************************** 00723 /// Copies the elements from the range (begin, end) to two different ranges 00724 /// depending on the value returned by the predicate.<br> 00725 ///<a href="http://en.cppreference.com/w/cpp/algorithm/partition_copy"></a> 00726 ///\ingroup algorithm 00727 //*************************************************************************** 00728 template <typename TSource, 00729 typename TDestinationTrue, 00730 typename TDestinationFalse, 00731 typename TUnaryPredicate> 00732 std::pair<TDestinationTrue, TDestinationFalse> partition_copy(TSource begin, 00733 TSource end, 00734 TDestinationTrue destination_true, 00735 TDestinationFalse destination_false, 00736 TUnaryPredicate predicate) 00737 { 00738 while (begin != end) 00739 { 00740 if (predicate(*begin)) 00741 { 00742 *destination_true++ = *begin++; 00743 } 00744 else 00745 { 00746 *destination_false++ = *begin++; 00747 } 00748 } 00749 00750 return std::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false); 00751 } 00752 00753 //*************************************************************************** 00754 /// Like std::for_each but applies a predicate before calling the function. 00755 ///\ingroup algorithm 00756 //*************************************************************************** 00757 template <typename TIterator, 00758 typename TUnaryFunction, 00759 typename TUnaryPredicate> 00760 TUnaryFunction for_each_if(TIterator begin, 00761 const TIterator end, 00762 TUnaryFunction function, 00763 TUnaryPredicate predicate) 00764 { 00765 while (begin != end) 00766 { 00767 if (predicate(*begin)) 00768 { 00769 function(*begin); 00770 } 00771 00772 ++begin; 00773 } 00774 00775 return function; 00776 } 00777 00778 //*************************************************************************** 00779 /// Like std::for_each but for 'n' iterations. 00780 ///\ingroup algorithm 00781 //*************************************************************************** 00782 template <typename TIterator, 00783 typename TSize, 00784 typename TUnaryFunction> 00785 TIterator for_each_n(TIterator begin, 00786 TSize n, 00787 TUnaryFunction function) 00788 { 00789 while (n-- > 0) 00790 { 00791 function(*begin++); 00792 } 00793 00794 return begin; 00795 } 00796 00797 //*************************************************************************** 00798 /// Like std::for_each but applies a predicate before calling the function, for 'n' iterations 00799 ///\ingroup algorithm 00800 //*************************************************************************** 00801 template <typename TIterator, 00802 typename TSize, 00803 typename TUnaryFunction, 00804 typename TUnaryPredicate> 00805 TIterator for_each_n_if(TIterator begin, 00806 TSize n, 00807 TUnaryFunction function, 00808 TUnaryPredicate predicate) 00809 { 00810 while (n-- > 0) 00811 { 00812 if (predicate(*begin)) 00813 { 00814 function(*begin); 00815 } 00816 00817 ++begin; 00818 } 00819 00820 return begin; 00821 } 00822 00823 //*************************************************************************** 00824 /// A form of std::transform where the transform returns when the first range 00825 /// end is reached. 00826 /// There is currently no STL equivalent. 00827 ///\ingroup algorithm 00828 //*************************************************************************** 00829 template <typename TInputIterator, 00830 typename TOutputIterator, 00831 typename TUnaryFunction> 00832 void transform(TInputIterator i_begin, 00833 TInputIterator i_end, 00834 TOutputIterator o_begin, 00835 TOutputIterator o_end, 00836 TUnaryFunction function) 00837 { 00838 while ((i_begin != i_end) && (o_begin != o_end)) 00839 { 00840 *o_begin++ = function(*i_begin++); 00841 } 00842 } 00843 00844 //*************************************************************************** 00845 /// Transform 'n' items. 00846 /// Random iterators. 00847 /// There is currently no STL equivalent. 00848 ///\ingroup algorithm 00849 //*************************************************************************** 00850 template <typename TInputIterator, 00851 typename TSize, 00852 typename TOutputIterator, 00853 typename TUnaryFunction> 00854 typename etl::enable_if<etl::is_random_iterator<TInputIterator>::value, void>::type 00855 transform_n(TInputIterator i_begin, 00856 TSize n, 00857 TOutputIterator o_begin, 00858 TUnaryFunction function) 00859 { 00860 std::transform(i_begin, i_begin + n, o_begin, function); 00861 } 00862 00863 //*************************************************************************** 00864 /// Transform 'n' items from two ranges. 00865 /// Random iterators. 00866 /// There is currently no STL equivalent. 00867 ///\ingroup algorithm 00868 //*************************************************************************** 00869 template <typename TInputIterator1, 00870 typename TInputIterator2, 00871 typename TSize, 00872 typename TOutputIterator, 00873 typename TBinaryFunction> 00874 typename etl::enable_if<etl::is_random_iterator<TInputIterator1>::value && 00875 etl::is_random_iterator<TInputIterator2>::value, void>::type 00876 transform_n(TInputIterator1 i_begin1, 00877 TInputIterator2 i_begin2, 00878 TSize n, 00879 TOutputIterator o_begin, 00880 TBinaryFunction function) 00881 { 00882 std::transform(i_begin1, i_begin1 + n, i_begin2, o_begin, function); 00883 } 00884 00885 //*************************************************************************** 00886 /// Transform 'n' items. 00887 /// Non-random iterators. 00888 /// There is currently no STL equivalent. 00889 ///\ingroup algorithm 00890 //*************************************************************************** 00891 template <typename TInputIterator, 00892 typename TSize, 00893 typename TOutputIterator, 00894 typename TUnaryFunction> 00895 typename etl::enable_if<!etl::is_random_iterator<TInputIterator>::value, void>::type 00896 transform_n(TInputIterator i_begin, 00897 TSize n, 00898 TOutputIterator o_begin, 00899 TUnaryFunction function) 00900 { 00901 while (n > 0) 00902 { 00903 *o_begin++ = function(*i_begin++); 00904 --n; 00905 } 00906 } 00907 00908 //*************************************************************************** 00909 /// Transform 'n' items from two ranges. 00910 /// Non-random iterators. 00911 /// There is currently no STL equivalent. 00912 ///\ingroup algorithm 00913 //*************************************************************************** 00914 template <typename TInputIterator1, 00915 typename TInputIterator2, 00916 typename TSize, 00917 typename TOutputIterator, 00918 typename TBinaryFunction> 00919 typename etl::enable_if<!etl::is_random_iterator<TInputIterator1>::value || 00920 !etl::is_random_iterator<TInputIterator2>::value, void>::type 00921 transform_n(TInputIterator1 i_begin1, 00922 TInputIterator2 i_begin2, 00923 TSize n, 00924 TOutputIterator o_begin, 00925 TBinaryFunction function) 00926 { 00927 while (n > 0) 00928 { 00929 *o_begin++ = function(*i_begin1++, *i_begin2++); 00930 --n; 00931 } 00932 } 00933 00934 //*************************************************************************** 00935 /// Like std::transform but applies a predicate before calling the function. 00936 ///\ingroup algorithm 00937 //*************************************************************************** 00938 template <typename TInputIterator, 00939 typename TOutputIterator, 00940 typename TUnaryFunction, 00941 typename TUnaryPredicate> 00942 TOutputIterator transform_if(TInputIterator i_begin, 00943 const TInputIterator i_end, 00944 TOutputIterator o_begin, 00945 TUnaryFunction function, 00946 TUnaryPredicate predicate) 00947 { 00948 while (i_begin != i_end) 00949 { 00950 if (predicate(*i_begin)) 00951 { 00952 *o_begin++ = function(*i_begin); 00953 } 00954 00955 ++i_begin; 00956 } 00957 00958 return o_begin; 00959 } 00960 00961 //*************************************************************************** 00962 /// Like etl::transform_if but inputs from two ranges. 00963 ///\ingroup algorithm 00964 //*************************************************************************** 00965 template <typename TInputIterator1, 00966 typename TInputIterator2, 00967 typename TOutputIterator, 00968 typename TBinaryFunction, 00969 typename TBinaryPredicate> 00970 TOutputIterator transform_if(TInputIterator1 i_begin1, 00971 const TInputIterator1 i_end1, 00972 TInputIterator2 i_begin2, 00973 TOutputIterator o_begin, 00974 TBinaryFunction function, 00975 TBinaryPredicate predicate) 00976 { 00977 while (i_begin1 != i_end1) 00978 { 00979 if (predicate(*i_begin1, *i_begin2)) 00980 { 00981 *o_begin++ = function(*i_begin1, *i_begin2); 00982 } 00983 00984 ++i_begin1; 00985 ++i_begin2; 00986 } 00987 00988 return o_begin; 00989 } 00990 00991 //*************************************************************************** 00992 /// Like std::transform_if, for 'n' items. 00993 ///\ingroup algorithm 00994 //*************************************************************************** 00995 template <typename TInputIterator, 00996 typename TSize, 00997 typename TOutputIterator, 00998 typename TUnaryFunction, 00999 typename TUnaryPredicate> 01000 TOutputIterator transform_n_if(TInputIterator i_begin, 01001 TSize n, 01002 TOutputIterator o_begin, 01003 TUnaryFunction function, 01004 TUnaryPredicate predicate) 01005 { 01006 while (n-- > 0) 01007 { 01008 if (predicate(*i_begin)) 01009 { 01010 *o_begin++ = function(*i_begin); 01011 } 01012 01013 ++i_begin; 01014 } 01015 01016 return o_begin; 01017 } 01018 01019 //*************************************************************************** 01020 /// Like etl::transform_if but inputs from two ranges for 'n' items. 01021 ///\ingroup algorithm 01022 //*************************************************************************** 01023 template <typename TInputIterator1, 01024 typename TInputIterator2, 01025 typename TSize, 01026 typename TOutputIterator, 01027 typename TBinaryFunction, 01028 typename TBinaryPredicate> 01029 TOutputIterator transform_n_if(TInputIterator1 i_begin1, 01030 TInputIterator2 i_begin2, 01031 TSize n, 01032 TOutputIterator o_begin, 01033 TBinaryFunction function, 01034 TBinaryPredicate predicate) 01035 { 01036 while (n-- > 0) 01037 { 01038 if (predicate(*i_begin1, *i_begin2)) 01039 { 01040 *o_begin++ = function(*i_begin1, *i_begin2); 01041 } 01042 01043 ++i_begin1; 01044 ++i_begin2; 01045 } 01046 01047 return o_begin; 01048 } 01049 01050 //*************************************************************************** 01051 /// Transforms the elements from the range (begin, end) to two different ranges 01052 /// depending on the value returned by the predicate.<br> 01053 ///\ingroup algorithm 01054 //*************************************************************************** 01055 template <typename TSource, typename TDestinationTrue, typename TDestinationFalse, 01056 typename TUnaryFunctionTrue, typename TUnaryFunctionFalse, 01057 typename TUnaryPredicate> 01058 std::pair<TDestinationTrue, TDestinationFalse> partition_transform(TSource begin, 01059 TSource end, 01060 TDestinationTrue destination_true, 01061 TDestinationFalse destination_false, 01062 TUnaryFunctionTrue function_true, 01063 TUnaryFunctionFalse function_false, 01064 TUnaryPredicate predicate) 01065 { 01066 while (begin != end) 01067 { 01068 if (predicate(*begin)) 01069 { 01070 *destination_true++ = function_true(*begin++); 01071 } 01072 else 01073 { 01074 *destination_false++ = function_false(*begin++); 01075 } 01076 } 01077 01078 return std::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false); 01079 } 01080 01081 //*************************************************************************** 01082 /// Transforms the elements from the ranges (begin1, end1) & (begin2) 01083 /// to two different ranges depending on the value returned by the predicate. 01084 ///\ingroup algorithm 01085 //*************************************************************************** 01086 template <typename TSource1, 01087 typename TSource2, 01088 typename TDestinationTrue, 01089 typename TDestinationFalse, 01090 typename TBinaryFunctionTrue, 01091 typename TBinaryFunctionFalse, 01092 typename TBinaryPredicate> 01093 std::pair<TDestinationTrue, TDestinationFalse> partition_transform(TSource1 begin1, 01094 TSource1 end1, 01095 TSource2 begin2, 01096 TDestinationTrue destination_true, 01097 TDestinationFalse destination_false, 01098 TBinaryFunctionTrue function_true, 01099 TBinaryFunctionFalse function_false, 01100 TBinaryPredicate predicate) 01101 { 01102 while (begin1 != end1) 01103 { 01104 if (predicate(*begin1, *begin2)) 01105 { 01106 *destination_true++ = function_true(*begin1++, *begin2++); 01107 } 01108 else 01109 { 01110 *destination_false++ = function_false(*begin1++, *begin2++); 01111 } 01112 } 01113 01114 return std::pair<TDestinationTrue, TDestinationFalse>(destination_true, destination_false); 01115 } 01116 } 01117 01118 #endif 01119 01120
Generated on Tue Jul 12 2022 14:05:38 by
