mirror of
https://github.com/ETLCPP/etl.git
synced 2026-06-16 00:46:03 +08:00
Additional algorithms.
This commit is contained in:
parent
6e04c8b190
commit
14074ade05
@ -258,21 +258,40 @@ namespace etl
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// copy_n
|
||||
/// copy_n (Random input iterators)
|
||||
///\ingroup algorithm
|
||||
///<a href="http://en.cppreference.com/w/cpp/algorithm/copy_n"></a>
|
||||
//***************************************************************************
|
||||
template <typename TInputIterator,
|
||||
typename TSize,
|
||||
typename TOutputIterator>
|
||||
TOutputIterator copy_n(TInputIterator i_begin,
|
||||
TSize n,
|
||||
TOutputIterator o_begin)
|
||||
typename etl::enable_if<etl::is_random_iterator<TInputIterator>::value, TOutputIterator>::type
|
||||
copy_n(TInputIterator i_begin,
|
||||
TSize n,
|
||||
TOutputIterator o_begin)
|
||||
{
|
||||
TInputIterator i_end(i_begin);
|
||||
std::advance(i_end, n);
|
||||
return std::copy(i_begin, i_begin + n, o_begin);
|
||||
}
|
||||
|
||||
return std::copy(i_begin, i_end, o_begin);
|
||||
//***************************************************************************
|
||||
/// copy_n (Non-random input iterators)
|
||||
///\ingroup algorithm
|
||||
///<a href="http://en.cppreference.com/w/cpp/algorithm/copy_n"></a>
|
||||
//***************************************************************************
|
||||
template <typename TInputIterator,
|
||||
typename TSize,
|
||||
typename TOutputIterator>
|
||||
typename etl::enable_if<!etl::is_random_iterator<TInputIterator>::value, TOutputIterator>::type
|
||||
copy_n(TInputIterator i_begin,
|
||||
TSize n,
|
||||
TOutputIterator o_begin)
|
||||
{
|
||||
while (n-- > 0)
|
||||
{
|
||||
*o_begin++ = *i_begin++;
|
||||
}
|
||||
|
||||
return o_begin;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -288,10 +307,34 @@ namespace etl
|
||||
TOutputIterator o_begin,
|
||||
TOutputIterator o_end)
|
||||
{
|
||||
TInputIterator i_end(i_begin);
|
||||
std::advance(i_end, n);
|
||||
while ((n-- > 0) && (o_begin != o_end))
|
||||
{
|
||||
*o_begin++ = *i_begin++;
|
||||
}
|
||||
|
||||
return etl::copy(i_begin, i_end, o_begin, o_end);;
|
||||
return o_begin;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
/// copy_n
|
||||
/// A form of copy_n where the smallest of the two ranges is used.
|
||||
///\ingroup algorithm
|
||||
//***************************************************************************
|
||||
template <typename TInputIterator,
|
||||
typename TSize1,
|
||||
typename TOutputIterator,
|
||||
typename TSize2>
|
||||
TOutputIterator copy_n(TInputIterator i_begin,
|
||||
TSize1 n1,
|
||||
TOutputIterator o_begin,
|
||||
TSize2 n2)
|
||||
{
|
||||
while ((n1-- > 0) && (n2-- > 0))
|
||||
{
|
||||
*o_begin++ = *i_begin++;
|
||||
}
|
||||
|
||||
return o_begin;
|
||||
}
|
||||
|
||||
//***************************************************************************
|
||||
@ -357,12 +400,12 @@ namespace etl
|
||||
typename TSize,
|
||||
typename TOutputIterator,
|
||||
typename TUnaryPredicate>
|
||||
TOutputIterator copy_n_if(TInputIterator begin,
|
||||
TOutputIterator copy_n_if(TInputIterator i_begin,
|
||||
TSize n,
|
||||
TOutputIterator result,
|
||||
TOutputIterator o_begin,
|
||||
TUnaryPredicate predicate)
|
||||
{
|
||||
while (n > 0)
|
||||
while (n-- > 0)
|
||||
{
|
||||
if (predicate(*i_begin))
|
||||
{
|
||||
@ -370,7 +413,6 @@ namespace etl
|
||||
}
|
||||
|
||||
++i_begin;
|
||||
--n;
|
||||
}
|
||||
|
||||
return o_begin;
|
||||
@ -697,10 +739,9 @@ namespace etl
|
||||
TSize n,
|
||||
TUnaryFunction function)
|
||||
{
|
||||
while (n > 0)
|
||||
while (n-- > 0)
|
||||
{
|
||||
function(*begin++);
|
||||
--n;
|
||||
}
|
||||
|
||||
return begin;
|
||||
@ -719,7 +760,7 @@ namespace etl
|
||||
TUnaryFunction function,
|
||||
TUnaryPredicate predicate)
|
||||
{
|
||||
while (n > 0)
|
||||
while (n-- > 0)
|
||||
{
|
||||
if (predicate(*begin))
|
||||
{
|
||||
@ -727,7 +768,6 @@ namespace etl
|
||||
}
|
||||
|
||||
++begin;
|
||||
--n;
|
||||
}
|
||||
|
||||
return begin;
|
||||
|
||||
@ -219,7 +219,7 @@ namespace
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(copy_n)
|
||||
TEST(copy_n_random_iterator)
|
||||
{
|
||||
int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
int data2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
@ -236,6 +236,24 @@ namespace
|
||||
CHECK(is_same);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(copy_n_non_random_iterator)
|
||||
{
|
||||
std::list<int> data1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
int data2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
int data3[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
int* result;
|
||||
|
||||
std::copy_n(std::begin(data1), 4, std::begin(data2));
|
||||
result = etl::copy_n(std::begin(data1), 4, std::begin(data3));
|
||||
|
||||
CHECK_EQUAL(std::begin(data3) + 4, result);
|
||||
|
||||
bool is_same = std::equal(std::begin(data2), std::end(data2), std::begin(data3));
|
||||
CHECK(is_same);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(copy_n_4_parameter)
|
||||
{
|
||||
@ -272,6 +290,42 @@ namespace
|
||||
CHECK(is_same);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(copy_2n_4_parameter)
|
||||
{
|
||||
int data1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
|
||||
int out1[10];
|
||||
int out2[5];
|
||||
|
||||
int check1[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
|
||||
int check2[] = { 1, 2, 3, 4, 5 };
|
||||
int check3[] = { 1, 2, 3, 4, 5, 0, 0, 0, 0, 0 };
|
||||
|
||||
int* result;
|
||||
|
||||
// Same size.
|
||||
std::fill(std::begin(out1), std::end(out1), 0);
|
||||
result = etl::copy_n(std::begin(data1), 10, std::begin(out1), 10);
|
||||
CHECK_EQUAL(std::end(out1), result);
|
||||
bool is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check1));
|
||||
CHECK(is_same);
|
||||
|
||||
// Destination smaller.
|
||||
std::fill(std::begin(out2), std::end(out2), 0);
|
||||
result = etl::copy_n(std::begin(data1), 10, std::begin(out2), 5);
|
||||
CHECK_EQUAL(std::end(out2), result);
|
||||
is_same = std::equal(std::begin(out2), std::end(out2), std::begin(check2));
|
||||
CHECK(is_same);
|
||||
|
||||
// Source smaller.
|
||||
std::fill(std::begin(out1), std::end(out1), 0);
|
||||
result = etl::copy_n(std::begin(data1), 5, std::begin(out1), 10);
|
||||
CHECK_EQUAL(std::begin(out1) + 5, result);
|
||||
is_same = std::equal(std::begin(out1), std::end(out1), std::begin(check3));
|
||||
CHECK(is_same);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(copy_if)
|
||||
{
|
||||
@ -287,6 +341,28 @@ namespace
|
||||
CHECK(is_same);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(copy_n_if)
|
||||
{
|
||||
int data1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 };
|
||||
int data2[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
int data3[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
|
||||
// Copy everything less than 5.
|
||||
int *pout = data2;
|
||||
for (int* pin = std::begin(data1); pin != std::begin(data1) + 6; ++pin)
|
||||
{
|
||||
if (*pin < 5)
|
||||
{
|
||||
*pout++ = *pin;
|
||||
}
|
||||
}
|
||||
etl::copy_n_if(std::begin(data1), 6, std::begin(data3), std::bind2nd(std::less<int>(), 5));
|
||||
|
||||
bool is_same = std::equal(std::begin(data2), std::end(data2), std::begin(data3));
|
||||
CHECK(is_same);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(copy_if_4_parameter)
|
||||
{
|
||||
@ -499,6 +575,46 @@ namespace
|
||||
CHECK_EQUAL(10, accumulator.sum);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(for_each_n)
|
||||
{
|
||||
int data1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 };
|
||||
int data2[] = { 2, 16, 4, 14, 6, 6, 4, 5, 10, 9 };
|
||||
|
||||
struct Multiply
|
||||
{
|
||||
void operator()(int& i)
|
||||
{
|
||||
i *= 2;
|
||||
}
|
||||
} multiplier;
|
||||
|
||||
etl::for_each_n(std::begin(data1), 5, multiplier);
|
||||
|
||||
bool are_equal = std::equal(std::begin(data1), std::end(data1), std::begin(data2));
|
||||
CHECK(are_equal);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(for_each_n_if)
|
||||
{
|
||||
int data1[] = { 1, 8, 2, 7, 3, 6, 4, 5, 10, 9 };
|
||||
int data2[] = { 2, 8, 4, 7, 6, 6, 4, 5, 10, 9 };
|
||||
|
||||
struct Multiply
|
||||
{
|
||||
void operator()(int& i)
|
||||
{
|
||||
i *= 2;
|
||||
}
|
||||
} multiplier;
|
||||
|
||||
etl::for_each_n_if(std::begin(data1), 5, multiplier, std::bind2nd(std::less<int>(), 5));
|
||||
|
||||
bool are_equal = std::equal(std::begin(data1), std::end(data1), std::begin(data2));
|
||||
CHECK(are_equal);
|
||||
}
|
||||
|
||||
//=========================================================================
|
||||
TEST(transform_4_parameter)
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user