reduce_init_op.pass.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. //===----------------------------------------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is dual licensed under the MIT and the University of Illinois Open
  6. // Source Licenses. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. // <numeric>
  10. // UNSUPPORTED: c++98, c++03, c++11, c++14
  11. // template<class InputIterator, class T, class BinaryOperation>
  12. // T reduce(InputIterator first, InputIterator last, T init, BinaryOperation op);
  13. #include <numeric>
  14. #include <cassert>
  15. #include "test_iterators.h"
  16. template <class Iter, class T, class Op>
  17. void
  18. test(Iter first, Iter last, T init, Op op, T x)
  19. {
  20. static_assert( std::is_same_v<T, decltype(std::reduce(first, last, init, op))>, "" );
  21. assert(std::reduce(first, last, init, op) == x);
  22. }
  23. template <class Iter>
  24. void
  25. test()
  26. {
  27. int ia[] = {1, 2, 3, 4, 5, 6};
  28. unsigned sa = sizeof(ia) / sizeof(ia[0]);
  29. test(Iter(ia), Iter(ia), 0, std::plus<>(), 0);
  30. test(Iter(ia), Iter(ia), 1, std::multiplies<>(), 1);
  31. test(Iter(ia), Iter(ia+1), 0, std::plus<>(), 1);
  32. test(Iter(ia), Iter(ia+1), 2, std::multiplies<>(), 2);
  33. test(Iter(ia), Iter(ia+2), 0, std::plus<>(), 3);
  34. test(Iter(ia), Iter(ia+2), 3, std::multiplies<>(), 6);
  35. test(Iter(ia), Iter(ia+sa), 0, std::plus<>(), 21);
  36. test(Iter(ia), Iter(ia+sa), 4, std::multiplies<>(), 2880);
  37. }
  38. template <typename T, typename Init>
  39. void test_return_type()
  40. {
  41. T *p = nullptr;
  42. static_assert( std::is_same_v<Init, decltype(std::reduce(p, p, Init{}, std::plus<>()))>, "" );
  43. }
  44. int main()
  45. {
  46. test_return_type<char, int>();
  47. test_return_type<int, int>();
  48. test_return_type<int, unsigned long>();
  49. test_return_type<float, int>();
  50. test_return_type<short, float>();
  51. test_return_type<double, char>();
  52. test_return_type<char, double>();
  53. test<input_iterator<const int*> >();
  54. test<forward_iterator<const int*> >();
  55. test<bidirectional_iterator<const int*> >();
  56. test<random_access_iterator<const int*> >();
  57. test<const int*>();
  58. // Make sure the math is done using the correct type
  59. {
  60. auto v = {1, 2, 3, 4, 5, 6, 7, 8};
  61. unsigned res = std::reduce(v.begin(), v.end(), 1U, std::multiplies<>());
  62. assert(res == 40320); // 8! will not fit into a char
  63. }
  64. }