141 lines · cpp
1//===----------------------------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9// <numeric>10 11// Became constexpr in C++2012// template<InputIterator InIter,13// OutputIterator<auto, const InIter::value_type&> OutIter,14// Callable<auto, const InIter::value_type&, InIter::reference> BinaryOperation>15// requires HasAssign<InIter::value_type, BinaryOperation::result_type>16// && Constructible<InIter::value_type, InIter::reference>17// && CopyConstructible<BinaryOperation>18// OutIter19// partial_sum(InIter first, InIter last, OutIter result, BinaryOperation binary_op);20 21#include <numeric>22#include <functional>23#include <string>24#include <cassert>25 26#include "test_macros.h"27#include "test_iterators.h"28 29#if TEST_STD_VER > 1730struct rvalue_addable31{32 bool correctOperatorUsed = false;33 34 // make sure the predicate is passed an rvalue and an lvalue (so check that the first argument was moved)35 constexpr rvalue_addable operator()(rvalue_addable&& r, rvalue_addable const&) {36 r.correctOperatorUsed = true;37 return std::move(r);38 }39};40 41constexpr rvalue_addable operator+(rvalue_addable& lhs, rvalue_addable const&)42{43 lhs.correctOperatorUsed = false;44 return lhs;45}46 47constexpr rvalue_addable operator+(rvalue_addable&& lhs, rvalue_addable const&)48{49 lhs.correctOperatorUsed = true;50 return std::move(lhs);51}52 53constexpr void54test_use_move()55{56 const std::size_t size = 100;57 rvalue_addable arr[size];58 rvalue_addable res1[size];59 rvalue_addable res2[size];60 std::partial_sum(arr, arr + size, res1);61 std::partial_sum(arr, arr + size, res2, /*predicate=*/rvalue_addable());62 // start at 1 because the first element is not moved63 for (unsigned i = 1; i < size; ++i) assert(res1[i].correctOperatorUsed);64 for (unsigned i = 1; i < size; ++i) assert(res2[i].correctOperatorUsed);65}66#endif // TEST_STD_VER > 1767 68TEST_CONSTEXPR_CXX20 void test_string() {69 std::string sa[] = {"a", "b", "c"};70 std::string sr[] = {"a", "ba", "cb"};71 std::string output[3];72 std::adjacent_difference(sa, sa + 3, output, std::plus<std::string>());73 for (unsigned i = 0; i < 3; ++i) assert(output[i] == sr[i]);74}75 76template <class InIter, class OutIter>77TEST_CONSTEXPR_CXX20 void78test()79{80 int ia[] = {1, 2, 3, 4, 5};81 int ir[] = {1, -1, -4, -8, -13};82 const unsigned s = sizeof(ia) / sizeof(ia[0]);83 int ib[s] = {0};84 OutIter r = std::partial_sum(InIter(ia), InIter(ia+s), OutIter(ib), std::minus<int>());85 assert(base(r) == ib + s);86 for (unsigned i = 0; i < s; ++i)87 assert(ib[i] == ir[i]);88}89 90TEST_CONSTEXPR_CXX20 bool91test()92{93 test<cpp17_input_iterator<const int*>, cpp17_output_iterator<int*> >();94 test<cpp17_input_iterator<const int*>, forward_iterator<int*> >();95 test<cpp17_input_iterator<const int*>, bidirectional_iterator<int*> >();96 test<cpp17_input_iterator<const int*>, random_access_iterator<int*> >();97 test<cpp17_input_iterator<const int*>, int*>();98 99 test<forward_iterator<const int*>, cpp17_output_iterator<int*> >();100 test<forward_iterator<const int*>, forward_iterator<int*> >();101 test<forward_iterator<const int*>, bidirectional_iterator<int*> >();102 test<forward_iterator<const int*>, random_access_iterator<int*> >();103 test<forward_iterator<const int*>, int*>();104 105 test<bidirectional_iterator<const int*>, cpp17_output_iterator<int*> >();106 test<bidirectional_iterator<const int*>, forward_iterator<int*> >();107 test<bidirectional_iterator<const int*>, bidirectional_iterator<int*> >();108 test<bidirectional_iterator<const int*>, random_access_iterator<int*> >();109 test<bidirectional_iterator<const int*>, int*>();110 111 test<random_access_iterator<const int*>, cpp17_output_iterator<int*> >();112 test<random_access_iterator<const int*>, forward_iterator<int*> >();113 test<random_access_iterator<const int*>, bidirectional_iterator<int*> >();114 test<random_access_iterator<const int*>, random_access_iterator<int*> >();115 test<random_access_iterator<const int*>, int*>();116 117 test<const int*, cpp17_output_iterator<int*> >();118 test<const int*, forward_iterator<int*> >();119 test<const int*, bidirectional_iterator<int*> >();120 test<const int*, random_access_iterator<int*> >();121 test<const int*, int*>();122 123#if TEST_STD_VER > 17124 test_use_move();125#endif // TEST_STD_VER > 17126 127 test_string();128 129 return true;130}131 132int main(int, char**)133{134 test();135#if TEST_STD_VER > 17136 static_assert(test());137#endif138 139 return 0;140}141