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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 // <valarray>
10 
11 // template<class T> class valarray;
12 
13 // valarray& operator+=(const valarray& v);
14 
15 // [valarray.syn]/3
16 //   Any function returning a valarray<T> is permitted to return an object of
17 //   another type, provided all the const member functions of valarray<T> are
18 //   also applicable to this type.
19 //
20 // Libc++ uses this and returns __val_expr<_Expr> for several operations.
21 //
22 // The const overloads of
23 //   valarray::operator[](...) const
24 // return propxy objects. These proxies are implicitly convertible to
25 // std::valarray.
26 //
27 // Validate the function works for valarray, the proxies, and __val_expr.
28 
29 #include <valarray>
30 #include <cassert>
31 #include <cstddef>
32 
33 #include "test_macros.h"
34 
35 template <class A>
test(const A & rhs)36 void test(const A& rhs) {
37   int input[]      = {1, 2, 3, 4, 5};
38   int expected[]   = {7, 9, 11, 13, 15};
39   const unsigned N = sizeof(input) / sizeof(input[0]);
40   std::valarray<int> value(input, N);
41 
42   value += rhs;
43 
44   assert(value.size() == N);
45   for (std::size_t i = 0; i < value.size(); ++i)
46     assert(value[i] == expected[i]);
47 }
48 
main(int,char **)49 int main(int, char**) {
50   int input[]      = {6, 7, 8, 9, 10};
51   const unsigned N = sizeof(input) / sizeof(input[0]);
52 
53   std::valarray<bool> mask(true, N);
54   std::size_t indices[] = {0, 1, 2, 3, 4};
55   std::valarray<std::size_t> indirect(indices, N);
56 
57   std::valarray<int> zero(0, N);
58 
59   {
60     std::valarray<int> value(input, N);
61 
62     test(value);
63     test(value[std::slice(0, N, 1)]);
64     test(value[std::gslice(0, std::valarray<std::size_t>(N, 1), std::valarray<std::size_t>(1, 1))]);
65     test(value[mask]);
66     test(value[indirect]);
67     test(value + zero);
68   }
69 
70   {
71     const std::valarray<int> value(input, N);
72 
73     test(value);
74     test(value[std::slice(0, N, 1)]);
75     test(value[std::gslice(0, std::valarray<std::size_t>(N, 1), std::valarray<std::size_t>(1, 1))]);
76     test(value[mask]);
77     test(value[indirect]);
78     test(value + zero);
79   }
80 
81   return 0;
82 }
83