//======================================================================= // Copyright Baptiste Wicht 2013-2016. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= #ifndef ALGORITHMS_H #define ALGORITHMS_H #include #include #include #include namespace std { /*! * \brief Copies all elements in the range [first, last). * * The behavior is undefined if d_first is within the range [first, last) * * \param first The beginning of the range * \param last The end of the range * \param d_first The output iterator */ template void copy(InputIterator first, InputIterator last, OutputIterator d_first){ if(first != last){ *d_first = *first; while(++first != last){ *++d_first = *first; } } } /*! * \brief Copy bytes bytes of memory from in to out * \param out Pointer to the output * \param in Pointer to the input * \param bytes The number of bytes */ inline void memcpy(char* out, const char* in, size_t bytes){ if(!bytes){ return; } // Copy as much as possible 64 bits at at time if(bytes >= 8){ auto* out64 = reinterpret_cast(out); auto* in64 = reinterpret_cast(in); const size_t l = bytes / 8; for(size_t i = 0; i < l; ++i){ out64[i] = in64[i]; } bytes -= l * 8; out += l * 8; in += l * 8; } // Finish up byte by byte while(bytes >= 1){ *out++ = *in++; --bytes; } } /*! * \brief Copies exactly count values from the range beginning at first to the range beginning at result, if count>0. Does nothing otherwise. * \param first The beginning of the input range * \param count The number fo elements to copy * \param out The output iterator */ template::value_type>::value, int> = 42> void copy_n(InputIterator first, size_t count, OutputIterator out){ if(count > 0){ *out = *first; while(--count){ *++out = *++first; } } } /*! * \brief Copies exactly count values from the range beginning at first to the range beginning at result, if count>0. Does nothing otherwise. * \param first The beginning of the input range * \param count The number fo elements to copy * \param out The output iterator */ template::value_type>::value, int> = 42> void copy_n(InputIterator first, size_t count, OutputIterator out){ memcpy(reinterpret_cast(out), reinterpret_cast(first), count * sizeof(decltype(*out))); } /*! * \brief Moves exactly count values from the range beginning at first to the range beginning at result, if count>0. Does nothing otherwise. * \param first The beginning of the input range * \param count The number fo elements to move * \param out The output iterator */ template void move_n(InputIterator in, size_t n, OutputIterator out){ if(n > 0){ *out = std::move(*in); while(--n){ *++out = std::move(*++in); } } } /*! * \brief Clear bytes bytes of memory from out * \param out Pointer to the output * \param bytes The number of bytes */ inline void memclr(char* out, size_t bytes){ if(!bytes){ return; } // Copy as much as possible 64 bits at at time if(bytes >= 8){ auto* out64 = reinterpret_cast(out); const size_t l = bytes / 8; for(size_t i = 0; i < l; ++i){ out64[i] = 0; } bytes -= l * 8; out += l * 8; } // Finish up byte by byte while(bytes >= 1){ *out++ = 0; --bytes; } } /*! * \brief Assigns the given value to the elements in the range [first, last). * \param first The beginning of the range * \param last The end of the range * \param value The value to write */ template void fill(ForwardIterator first, ForwardIterator last, const T& value){ if(first != last){ *first = value; while(++first != last){ *first = value; } } } /*! * \brief Assigns the given value to the first count elements in the range beginning at * first if count > 0. Does nothing otherwise. * \param first The beginning of the range * \param count The number of elements * \param value The value to write */ template::value_type>::value, int> = 42> void fill_n(ForwardIterator first, size_t count, const T& value){ if(count > 0){ *first = value; while(--count){ *++first = value; } } } /*! * \brief Assigns the given value to the first count elements in the range beginning at * first if count > 0. Does nothing otherwise. * \param first The beginning of the range * \param count The number of elements * \param value The value to write */ template::value_type>::value, int> = 42> void fill_n(ForwardIterator first, size_t count, const T& value){ if(!value){ memclr(reinterpret_cast(first), count * sizeof(decltype(*first))); } else { if(count > 0){ *first = value; while(--count){ *++first = value; } } } } template size_t compare_n(Iterator1 it1, Iterator2 it2, size_t count){ if(count > 0){ while(count--){ if(*it1 != *it2){ return *it1- *it2; } else { ++it1; ++it2; } } } return 0; } template bool equal_n(Iterator1 it1, Iterator2 it2, size_t n){ return compare_n(it1, it2, n) == 0; } template void for_each(Iterator it, Iterator end, Functor func){ while(it != end){ func(*it); ++it; } } template T accumulate(Iterator it, Iterator end, T init){ while(it != end){ init = init + *it; ++it; } return init; } template Iterator find(Iterator first, Iterator last, const T& value){ for (; first != last; ++first) { if (*first == value) { return first; } } return last; } template Iterator find_if(Iterator first, Iterator last, Pred pred) { for (; first != last; ++first) { if (pred(*first)) { return first; } } return last; } template< typename Iterator, typename T > Iterator remove(Iterator first, Iterator last, const T& value){ first = std::find(first, last, value); if (first != last){ for(auto it = first; ++it != last; ){ if (!(*it == value)){ *first++ = std::move(*it); } } } return first; } template Iterator remove_if(Iterator first, Iterator last, Pred pred) { first = std::find_if(first, last, pred); if (first != last) { for (auto it = first; ++it != last;) { if (!pred(*it)) { *first++ = std::move(*it); } } } return first; } template constexpr const T& min(const T& a, const T& b){ return a <= b ? a : b; } template constexpr const T& max(const T& a, const T& b){ return a >= b ? a : b; } } //end of namespace std #endif