thor-os/tstl/include/algorithms.hpp
2016-08-14 12:41:49 +02:00

181 lines
4.3 KiB
C++

//=======================================================================
// 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 <type_traits.hpp>
#include <utility.hpp>
#include <types.hpp>
#include <enable_if.hpp>
namespace std {
template<typename InputIterator, typename OutputIterator>
void copy(OutputIterator out, InputIterator it, InputIterator end){
if(it != end){
*out = *it;
while(++it != end){
*++out = *it;
}
}
}
template<typename InputIterator, typename OutputIterator, std::enable_if_t<!std::has_trivial_assign<typename std::iterator_traits<OutputIterator>::value_type>::value, int> = 42>
void copy_n(OutputIterator out, InputIterator in, size_t n){
if(n > 0){
*out = *in;
while(--n){
*++out = *++in;
}
}
}
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<uint64_t*>(out);
auto* in64 = reinterpret_cast<const uint64_t*>(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;
}
}
template<typename InputIterator, typename OutputIterator, std::enable_if_t<std::has_trivial_assign<typename std::iterator_traits<OutputIterator>::value_type>::value, int> = 42>
void copy_n(OutputIterator out, InputIterator in, size_t n){
memcpy(reinterpret_cast<char*>(out), reinterpret_cast<const char*>(in), n * sizeof(decltype(*out)));
}
template<typename InputIterator, typename OutputIterator>
void move_n(OutputIterator out, InputIterator in, size_t n){
if(n > 0){
*out = std::move(*in);
while(--n){
*++out = std::move(*++in);
}
}
}
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<uint64_t*>(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;
}
}
template<typename ForwardIterator, typename T>
void fill(ForwardIterator it, ForwardIterator end, const T& value){
if(it != end){
*it = value;
while(++it != end){
*it = value;
}
}
}
template<typename ForwardIterator, typename T, std::enable_if_t<!std::has_trivial_assign<typename std::iterator_traits<ForwardIterator>::value_type>::value, int> = 42>
void fill_n(ForwardIterator it, size_t n, const T& value){
if(n > 0){
*it = value;
while(--n){
*++it = value;
}
}
}
template<typename ForwardIterator, typename T, std::enable_if_t<std::has_trivial_assign<typename std::iterator_traits<ForwardIterator>::value_type>::value, int> = 42>
void fill_n(ForwardIterator it, size_t n, const T& value){
if(!value){
memclr(reinterpret_cast<char*>(it), n * sizeof(decltype(*it)));
} else {
if(n > 0){
*it = value;
while(--n){
*++it = value;
}
}
}
}
template<typename Iterator1, typename Iterator2>
size_t compare_n(Iterator1 it1, Iterator2 it2, size_t n){
if(n > 0){
while(n--){
if(*it1 != *it2){
return *it1- *it2;
} else {
++it1;
++it2;
}
}
}
return 0;
}
template<typename Iterator1, typename Iterator2>
bool equal_n(Iterator1 it1, Iterator2 it2, size_t n){
return compare_n(it1, it2, n) == 0;
}
template<typename T>
constexpr const T& min(const T& a, const T& b){
return a <= b ? a : b;
}
template<typename T>
constexpr const T& max(const T& a, const T& b){
return a >= b ? a : b;
}
} //end of namespace std
#endif