1 // { dg-do run }
2 
3 #include <vector>
4 #include <cstdlib>
5 
6 template <typename T>
7 class J
8 {
9 public:
10   typedef typename std::vector<T>::const_iterator const_iterator;
J(const const_iterator & x,const const_iterator & y)11   J(const const_iterator &x, const const_iterator &y) : b (x), e (y) {}
12   const const_iterator &begin ();
13   const const_iterator &end ();
14 private:
15   const_iterator b, e;
16 };
17 
18 template <typename T>
begin()19 const typename std::vector<T>::const_iterator &J<T>::begin () { return b; }
20 template <typename T>
end()21 const typename std::vector<T>::const_iterator &J<T>::end () { return e; }
22 
23 int results[2000];
24 
25 template <typename T>
26 void
baz(T & i)27 baz (T &i)
28 {
29   if (*i < 0 || *i >= 2000)
30     std::abort ();
31   results[*i]++;
32 }
33 
34 void
f1(const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)35 f1 (const std::vector<int>::const_iterator &x,
36     const std::vector<int>::const_iterator &y)
37 {
38 #pragma omp parallel for
39   for (std::vector<int>::const_iterator i = x; i <= y; i += 6)
40     baz (i);
41 }
42 
43 void
f2(const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)44 f2 (const std::vector<int>::const_iterator &x,
45     const std::vector<int>::const_iterator &y)
46 {
47   std::vector<int>::const_iterator i;
48 #pragma omp parallel for private(i)
49   for (i = x; i < y - 1; i = 1 - 6 + 7 + i)
50     baz (i);
51 }
52 
53 template <typename T>
54 void
f3(const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)55 f3 (const std::vector<int>::const_iterator &x,
56     const std::vector<int>::const_iterator &y)
57 {
58 #pragma omp parallel for schedule (dynamic, 6)
59   for (std::vector<int>::const_iterator i = x; i <= y; i = i + 9 - 8)
60     baz (i);
61 }
62 
63 template <typename T>
64 void
f4(const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)65 f4 (const std::vector<int>::const_iterator &x,
66     const std::vector<int>::const_iterator &y)
67 {
68   std::vector<int>::const_iterator i;
69 #pragma omp parallel for lastprivate(i)
70   for (i = x + 2000 - 64; i > y + 10; --i)
71     baz (i);
72 }
73 
74 void
f5(const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)75 f5 (const std::vector<int>::const_iterator &x,
76     const std::vector<int>::const_iterator &y)
77 {
78 #pragma omp parallel for schedule (static, 10)
79   for (std::vector<int>::const_iterator i = x + 2000 - 64; i > y + 10; i -= 10)
80     baz (i);
81 }
82 
83 template <int N>
84 void
f6(const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)85 f6 (const std::vector<int>::const_iterator &x,
86     const std::vector<int>::const_iterator &y)
87 {
88 #pragma omp parallel for schedule (runtime)
89   for (std::vector<int>::const_iterator i = x + 2000 - 64;
90        i > y + 10; i = i - 12 + 2)
91     {
92       std::vector<int>::const_iterator j = i + N;
93       baz (j);
94     }
95 }
96 
97 template <int N>
98 void
f7(std::vector<int>::const_iterator i,const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)99 f7 (std::vector<int>::const_iterator i,
100     const std::vector<int>::const_iterator &x,
101     const std::vector<int>::const_iterator &y)
102 {
103 #pragma omp parallel for schedule (dynamic, 6)
104   for (i = x - 10; i <= y + 10; i += N)
105     baz (i);
106 }
107 
108 template <int N>
109 void
f8(J<int> j)110 f8 (J<int> j)
111 {
112   std::vector<int>::const_iterator i;
113 #pragma omp parallel for schedule (dynamic, 40)
114   for (i = j.begin (); i <= j.end () + N; i += 2)
115     baz (i);
116 }
117 
118 template <typename T, int N>
119 void
f9(const typename std::vector<T>::const_iterator & x,const typename std::vector<T>::const_iterator & y)120 f9 (const typename std::vector<T>::const_iterator &x,
121     const typename std::vector<T>::const_iterator &y)
122 {
123 #pragma omp parallel for schedule (static, 25)
124   for (typename std::vector<T>::const_iterator i = x; i <= y; i = i + N)
125     baz (i);
126 }
127 
128 template <typename T, int N>
129 void
f10(const typename std::vector<T>::const_iterator & x,const typename std::vector<T>::const_iterator & y)130 f10 (const typename std::vector<T>::const_iterator &x,
131      const typename std::vector<T>::const_iterator &y)
132 {
133   typename std::vector<T>::const_iterator i;
134 #pragma omp parallel for
135   for (i = x; i > y; i = i + N)
136     baz (i);
137 }
138 
139 template <typename T>
140 void
f11(const T & x,const T & y)141 f11 (const T &x, const T &y)
142 {
143 #pragma omp parallel
144   {
145 #pragma omp for nowait schedule (static, 2)
146     for (T i = x; i <= y; i += 3)
147       baz (i);
148 #pragma omp single
149     {
150       T j = y + 3;
151       baz (j);
152     }
153   }
154 }
155 
156 template <typename T>
157 void
f12(const T & x,const T & y)158 f12 (const T &x, const T &y)
159 {
160   T i;
161 #pragma omp parallel for schedule (dynamic, 130)
162   for (i = x; i > y; --i)
163     baz (i);
164 }
165 
166 template <int N>
167 struct K
168 {
169   template <typename T>
170   static void
f13K171   f13 (const T &x, const T &y)
172   {
173 #pragma omp parallel for schedule (runtime)
174     for (T i = x; i <= y + N; i += N)
175       baz (i);
176   }
177 };
178 
179 #define check(expr) \
180   for (int i = 0; i < 2000; i++)			\
181     if (expr)						\
182       {							\
183 	if (results[i] != 1)				\
184 	  std::abort ();				\
185 	results[i] = 0;					\
186       }							\
187     else if (results[i])				\
188       std::abort ()
189 
190 int
main()191 main ()
192 {
193   std::vector<int> a(2000);
194   std::vector<long> b(2000);
195   for (int i = 0; i < 2000; i++)
196     {
197       a[i] = i;
198       b[i] = i;
199     }
200   f1 (a.begin () + 10, a.begin () + 1990);
201   check (i >= 10 && i <= 1990 && (i - 10) % 6 == 0);
202   f2 (a.begin () + 0, a.begin () + 1999);
203   check (i < 1998 && (i & 1) == 0);
204   f3<char> (a.begin () + 20, a.begin () + 1837);
205   check (i >= 20 && i <= 1837);
206   f4<int> (a.begin () + 0, a.begin () + 30);
207   check (i > 40 && i <= 2000 - 64);
208   f5 (a.begin () + 0, a.begin () + 100);
209   check (i >= 116 && i <= 2000 - 64 && (i - 116) % 10 == 0);
210   f6<-10> (a.begin () + 10, a.begin () + 110);
211   check (i >= 116 && i <= 2000 - 64 && (i - 116) % 10 == 0);
212   f7<6> (std::vector<int>::const_iterator (), a.begin () + 12,
213 	 a.begin () + 1800);
214   check (i >= 2 && i <= 1808 && (i - 2) % 6 == 0);
215   f8<121> (J<int> (a.begin () + 14, a.begin () + 1803));
216   check (i >= 14 && i <= 1924 && (i & 1) == 0);
217   f9<int, 7> (a.begin () + 33, a.begin () + 1967);
218   check (i >= 33 && i <= 1967 && (i - 33) % 7 == 0);
219   f10<int, -7> (a.begin () + 1939, a.begin () + 17);
220   check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0);
221   f11<std::vector<int>::const_iterator > (a.begin () + 16, a.begin () + 1981);
222   check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0);
223   f12<std::vector<int>::const_iterator > (a.begin () + 1761, a.begin () + 37);
224   check (i > 37 && i <= 1761);
225   K<5>::f13<std::vector<int>::const_iterator > (a.begin () + 1,
226 						a.begin () + 1935);
227   check (i >= 1 && i <= 1936 && (i - 1) % 5 == 0);
228   f9<long, 7> (b.begin () + 33, b.begin () + 1967);
229   check (i >= 33 && i <= 1967 && (i - 33) % 7 == 0);
230   f10<long, -7> (b.begin () + 1939, b.begin () + 17);
231   check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0);
232   f11<std::vector<long>::const_iterator > (b.begin () + 16, b.begin () + 1981);
233   check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0);
234   f12<std::vector<long>::const_iterator > (b.begin () + 1761, b.begin () + 37);
235   check (i > 37 && i <= 1761);
236   K<5>::f13<std::vector<long>::const_iterator > (b.begin () + 1,
237 						 b.begin () + 1935);
238   check (i >= 1 && i <= 1936 && (i - 1) % 5 == 0);
239 }
240