From 804ed0616dbe4e07eeada8ba2c847ab375678ac2 Mon Sep 17 00:00:00 2001 From: jwellbelove Date: Mon, 8 Dec 2014 20:08:55 +0000 Subject: [PATCH] Added C++ 11 algorithms --- algorithm.h | 471 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 471 insertions(+) create mode 100644 algorithm.h diff --git a/algorithm.h b/algorithm.h new file mode 100644 index 00000000..1f103491 --- /dev/null +++ b/algorithm.h @@ -0,0 +1,471 @@ +///\file + +/****************************************************************************** +The MIT License(MIT) + +Embedded Template Library. + +Copyright(c) 2014 jwellbelove + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files(the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and / or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions : + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +******************************************************************************/ + +#ifndef __ETL_ALGORITHM__ +#define __ETL_ALGORITHM__ + +///\defgroup algorithm algorithm +/// Reverse engineered algorithms from C++ 0x11 +///\ingroup utilities + +#include +#include +#include +#include + +#include "type_traits.h" + +namespace etl +{ + //*************************************************************************** + /// Finds the greatest and the smallest element in the range (begin, end).
+ /// + ///\ingroup algorithm + //*************************************************************************** + template + std::pair minmax_element(TIterator begin, TIterator end, TCompare compare) + { + TIterator minimum = begin; + TIterator maximum = begin; + + while (begin != end) + { + if (compare(*begin, *minimum)) + { + minimum = begin; + } + + if (compare(*maximum, *begin)) + { + maximum = begin; + } + + ++begin; + } + + return std::pair(minimum, maximum); + } + + //*************************************************************************** + /// minmax_element + ///\ingroup algorithm + /// + //*************************************************************************** + template + std::pair minmax_element(TIterator begin, TIterator end) + { + typedef typename std::iterator_traits::value_type value_t; + + return etl::minmax_element(begin, end, std::less()); + } + + //*************************************************************************** + /// minmax + ///\ingroup algorithm + /// + //*************************************************************************** + template + std::pair minmax(const T& a, const T& b) + { + return (b < a) ? std::pair(b, a) : std::pair(a, b); + } + + //*************************************************************************** + /// minmax + ///\ingroup algorithm + /// + //*************************************************************************** + template + std::pair minmax(const T& a, const T& b, TCompare compare) + { + return compare(b, a) ? std::pair(b, a) : std::pair(a, b); + } + + //*************************************************************************** + /// is_sorted_until + ///\ingroup algorithm + /// + //*************************************************************************** + template + TIterator is_sorted_until(TIterator begin, TIterator end) + { + if (begin != end) + { + TIterator next = begin; + + while (++next != end) + { + if (*next < *begin) + { + return next; + } + + ++begin; + } + } + + return end; + } + + //*************************************************************************** + /// is_sorted_until + ///\ingroup algorithm + /// + //*************************************************************************** + template + TIterator is_sorted_until(TIterator begin, TIterator end, TCompare compare) + { + if (begin != end) + { + TIterator next = begin; + + while (++next != end) + { + if (compare(*next, *begin)) + { + return next; + } + + ++begin; + } + } + + return end; + } + + //*************************************************************************** + /// is_sorted + ///\ingroup algorithm + /// + //*************************************************************************** + template + bool is_sorted(TIterator begin, TIterator end) + { + return etl::is_sorted_until(begin, end) == end; + } + + //*************************************************************************** + /// is_sorted + ///\ingroup algorithm + /// + //*************************************************************************** + template + bool is_sorted(TIterator begin, TIterator end, TCompare compare) + { + return etl::is_sorted_until(begin, end, compare) == end; + } + + //*************************************************************************** + /// copy_n + ///\ingroup algorithm + /// + //*************************************************************************** + template + TOutputIterator copy_n(TInputIterator begin, Size count, TOutputIterator result) + { + if (count > 0) + { + for (Size i = 0; i < count; ++i) + { + *result++ = *begin++; + } + } + + return result; + } + + //*************************************************************************** + /// copy_if + ///\ingroup algorithm + /// + //*************************************************************************** + template + TOutputIterator copy_if(TIterator begin, TIterator end, TOutputIterator out, TUnaryPredicate predicate) + { + while (begin != end) + { + if (predicate(*begin)) + { + *out++ = *begin; + } + + ++begin; + } + + return out; + } + + //*************************************************************************** + /// find_if_not + ///\ingroup algorithm + /// + //*************************************************************************** + template + TIterator find_if_not(TIterator begin, TIterator end, TUnaryPredicate predicate) + { + while (begin != end) + { + if (!predicate(*begin)) + { + return begin; + } + + ++begin; + } + + return end; + } + + //*************************************************************************** + /// all_of + ///\ingroup algorithm + /// + //*************************************************************************** + template + bool all_of(TIterator begin, TIterator end, TUnaryPredicate predicate) + { + return etl::find_if_not(begin, end, predicate) == end; + } + + //*************************************************************************** + /// any_of + ///\ingroup algorithm + /// + //*************************************************************************** + template + bool any_of(TIterator begin, TIterator end, TUnaryPredicate predicate) + { + return std::find_if(begin, end, predicate) != end; + } + + //*************************************************************************** + /// none_of + ///\ingroup algorithm + /// + //*************************************************************************** + template + bool none_of(TIterator begin, TIterator end, TUnaryPredicate predicate) + { + return std::find_if(begin, end, predicate) == end; + } + + //*************************************************************************** + /// is_permutation + ///\ingroup algorithm + /// + //*************************************************************************** + template + bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2) + { + if (begin1 != end1) + { + TIterator2 end2 = begin2; + + std::advance(end2, std::distance(begin1, end1)); + + for (TIterator1 i = begin1; i != end1; ++i) + { + if (i == std::find(begin1, i, *i)) + { + size_t n = std::count(begin2, end2, *i); + + if (n == 0 || std::count(i, end1, *i) != n) + { + return false; + } + } + } + } + + return true; + } + + //*************************************************************************** + /// is_permutation + ///\ingroup algorithm + /// + //*************************************************************************** + template + bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TIterator2 end2) + { + if (begin1 != end1) + { + for (TIterator1 i = begin1; i != end1; ++i) + { + if (i == std::find(begin1, i, *i)) + { + size_t n = std::count(begin2, end2, *i); + + if (n == 0 || std::count(i, end1, *i) != n) + { + return false; + } + } + } + } + + return true; + } + + //*************************************************************************** + /// is_permutation + ///\ingroup algorithm + /// + //*************************************************************************** + template + bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TBinaryPredicate predicate) + { + if (begin1 != end1) + { + TIterator2 end2 = begin2; + + std::advance(end2, std::distance(begin1, end1)); + + for (TIterator1 i = begin1; i != end1; ++i) + { + if (i == std::find_if(begin1, i, std::bind1st(predicate, *i))) + { + size_t n = std::count(begin2, end2, *i); + + if (n == 0 || std::count(i, end1, *i) != n) + { + return false; + } + } + } + } + + return true; + } + + //*************************************************************************** + /// is_permutation + ///\ingroup algorithm + /// + //*************************************************************************** + template + bool is_permutation(TIterator1 begin1, TIterator1 end1, TIterator2 begin2, TIterator2 end2, TBinaryPredicate predicate) + { + if (begin1 != end1) + { + for (TIterator1 i = begin1; i != end1; ++i) + { + if (i == std::find_if(begin1, i, std::bind1st(predicate, *i))) + { + size_t n = std::count(begin2, end2, *i); + + if (n == 0 || std::count(i, end1, *i) != n) + { + return false; + } + } + } + } + + return true; + } + + //*************************************************************************** + /// is_partitioned + ///\ingroup algorithm + /// + //*************************************************************************** + template + bool is_partitioned(TIterator begin, TIterator end, TUnaryPredicate predicate) + { + while (begin != end) + { + if (!predicate(*begin++)) + { + break; + } + } + + while (begin != end) + { + if (predicate(*begin++)) + { + return false; + } + } + + return true; + } + + //*************************************************************************** + /// partition_point + /// + ///\ingroup algorithm + //*************************************************************************** + template + TIterator partition_point(TIterator begin, TIterator end, TUnaryPredicate predicate) + { + while (begin != end) + { + if (!predicate(*begin)) + { + return begin; + } + + ++begin; + } + + return begin; + } + + //*************************************************************************** + /// Copies the elements from the range (begin, end) to two different ranges + /// depending on the value returned by the predicate.
+ /// + ///\ingroup algorithm + //*************************************************************************** + template + std::pair partition_copy(TSource begin, + TSource end, + TDestinationTrue destination_true, + TDestinationFalse destination_false, + TUnaryPredicate predicate) + { + while (begin != end) + { + if (predicate(*begin)) + { + *destination_true++ = *begin++; + } + else + { + *destination_false++ = *begin++; + } + } + + return std::pair(destination_true, destination_false); + } +} + +#endif +