-
Notifications
You must be signed in to change notification settings - Fork 10.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement the non-parallel versions of exclusive_scan and transform_e…
…xclusive_scan. Reviewed as https://reviews.llvm.org/D34038. llvm-svn: 305136
- Loading branch information
Showing
4 changed files
with
409 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
libcxx/test/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_iter_iter_iter.pass.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is dual licensed under the MIT and the University of Illinois Open | ||
// Source Licenses. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
// <numeric> | ||
// UNSUPPORTED: c++98, c++03, c++11, c++14 | ||
|
||
// template<class InputIterator, class OutputIterator, class T> | ||
// OutputIterator exclusive_scan(InputIterator first, InputIterator last, | ||
// OutputIterator result, T init); | ||
// | ||
|
||
#include <numeric> | ||
#include <vector> | ||
#include <cassert> | ||
|
||
#include "test_iterators.h" | ||
|
||
template <class Iter1, class T, class Iter2> | ||
void | ||
test(Iter1 first, Iter1 last, T init, Iter2 rFirst, Iter2 rLast) | ||
{ | ||
std::vector<typename std::iterator_traits<Iter1>::value_type> v; | ||
|
||
// Not in place | ||
std::exclusive_scan(first, last, std::back_inserter(v), init); | ||
assert(std::equal(v.begin(), v.end(), rFirst, rLast)); | ||
|
||
// In place | ||
v.clear(); | ||
v.assign(first, last); | ||
std::exclusive_scan(v.begin(), v.end(), v.begin(), init); | ||
assert(std::equal(v.begin(), v.end(), rFirst, rLast)); | ||
} | ||
|
||
|
||
template <class Iter> | ||
void | ||
test() | ||
{ | ||
int ia[] = {1, 3, 5, 7, 9}; | ||
const int pRes[] = {0, 1, 4, 9, 16}; | ||
const unsigned sa = sizeof(ia) / sizeof(ia[0]); | ||
static_assert(sa == sizeof(pRes) / sizeof(pRes[0])); // just to be sure | ||
|
||
for (unsigned int i = 0; i < sa; ++i ) | ||
test(Iter(ia), Iter(ia + i), 0, pRes, pRes + i); | ||
} | ||
|
||
int triangle(int n) { return n*(n+1)/2; } | ||
|
||
// Basic sanity | ||
void basic_tests() | ||
{ | ||
{ | ||
std::vector<int> v(10); | ||
std::fill(v.begin(), v.end(), 3); | ||
std::exclusive_scan(v.begin(), v.end(), v.begin(), 50); | ||
for (size_t i = 0; i < v.size(); ++i) | ||
assert(v[i] == 50 + (int) i * 3); | ||
} | ||
|
||
{ | ||
std::vector<int> v(10); | ||
std::iota(v.begin(), v.end(), 0); | ||
std::exclusive_scan(v.begin(), v.end(), v.begin(), 30); | ||
for (size_t i = 0; i < v.size(); ++i) | ||
assert(v[i] == 30 + triangle(i-1)); | ||
} | ||
|
||
{ | ||
std::vector<int> v(10); | ||
std::iota(v.begin(), v.end(), 1); | ||
std::exclusive_scan(v.begin(), v.end(), v.begin(), 40); | ||
for (size_t i = 0; i < v.size(); ++i) | ||
assert(v[i] == 40 + triangle(i)); | ||
} | ||
|
||
} | ||
|
||
int main() | ||
{ | ||
basic_tests(); | ||
|
||
// All the iterator categories | ||
test<input_iterator <const int*> >(); | ||
test<forward_iterator <const int*> >(); | ||
test<bidirectional_iterator<const int*> >(); | ||
test<random_access_iterator<const int*> >(); | ||
test<const int*>(); | ||
test< int*>(); | ||
} |
87 changes: 87 additions & 0 deletions
87
...st/std/numerics/numeric.ops/exclusive.scan/exclusive_scan_iter_iter_iter_init_op.pass.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,87 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is dual licensed under the MIT and the University of Illinois Open | ||
// Source Licenses. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
// <numeric> | ||
// UNSUPPORTED: c++98, c++03, c++11, c++14 | ||
|
||
// template<class InputIterator, class OutputIterator, class T, class BinaryOperation> | ||
// OutputIterator | ||
// exclusive_scan(InputIterator first, InputIterator last, | ||
// OutputIterator result, | ||
// T init, BinaryOperation binary_op); // C++17 | ||
|
||
#include <numeric> | ||
#include <vector> | ||
#include <cassert> | ||
|
||
#include "test_iterators.h" | ||
|
||
template <class Iter1, class T, class Op, class Iter2> | ||
void | ||
test(Iter1 first, Iter1 last, T init, Op op, Iter2 rFirst, Iter2 rLast) | ||
{ | ||
std::vector<typename std::iterator_traits<Iter1>::value_type> v; | ||
|
||
// Not in place | ||
std::exclusive_scan(first, last, std::back_inserter(v), init, op); | ||
assert(std::equal(v.begin(), v.end(), rFirst, rLast)); | ||
|
||
// In place | ||
v.clear(); | ||
v.assign(first, last); | ||
std::exclusive_scan(v.begin(), v.end(), v.begin(), init, op); | ||
assert(std::equal(v.begin(), v.end(), rFirst, rLast)); | ||
} | ||
|
||
|
||
template <class Iter> | ||
void | ||
test() | ||
{ | ||
int ia[] = {1, 3, 5, 7, 9}; | ||
const int pRes[] = {0, 1, 4, 9, 16}; | ||
const int mRes[] = {1, 1, 3, 15, 105}; | ||
const unsigned sa = sizeof(ia) / sizeof(ia[0]); | ||
static_assert(sa == sizeof(pRes) / sizeof(pRes[0])); // just to be sure | ||
static_assert(sa == sizeof(mRes) / sizeof(mRes[0])); // just to be sure | ||
|
||
for (unsigned int i = 0; i < sa; ++i ) { | ||
test(Iter(ia), Iter(ia + i), 0, std::plus<>(), pRes, pRes + i); | ||
test(Iter(ia), Iter(ia + i), 1, std::multiplies<>(), mRes, mRes + i); | ||
} | ||
} | ||
|
||
int main() | ||
{ | ||
// All the iterator categories | ||
test<input_iterator <const int*> >(); | ||
test<forward_iterator <const int*> >(); | ||
test<bidirectional_iterator<const int*> >(); | ||
test<random_access_iterator<const int*> >(); | ||
test<const int*>(); | ||
test< int*>(); | ||
|
||
// Make sure that the calculations are done using the init typedef | ||
{ | ||
std::vector<unsigned char> v(10); | ||
std::iota(v.begin(), v.end(), 1); | ||
std::vector<int> res; | ||
std::exclusive_scan(v.begin(), v.end(), std::back_inserter(res), 1, std::multiplies<>()); | ||
|
||
assert(res.size() == 10); | ||
int j = 1; | ||
assert(res[0] == 1); | ||
for (size_t i = 1; i < v.size(); ++i) | ||
{ | ||
j *= i; | ||
assert(res[i] == j); | ||
} | ||
} | ||
} | ||
|
Oops, something went wrong.