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
39 #pragma omp single
40 #pragma omp taskloop
41   for (std::vector<int>::const_iterator i = x; i <= y; i += 6)
42     baz (i);
43 }
44 
45 void
f2(const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)46 f2 (const std::vector<int>::const_iterator &x,
47     const std::vector<int>::const_iterator &y)
48 {
49   std::vector<int>::const_iterator i;
50 #pragma omp parallel
51 #pragma omp single
52 #pragma omp taskloop private(i)
53   for (i = x; i < y - 1; i = 1 - 6 + 7 + i)
54     baz (i);
55 }
56 
57 template <typename T>
58 void
f3(const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)59 f3 (const std::vector<int>::const_iterator &x,
60     const std::vector<int>::const_iterator &y)
61 {
62 #pragma omp parallel
63 #pragma omp single
64 #pragma omp taskloop
65   for (std::vector<int>::const_iterator i = x; i <= y; i = i + 9 - 8)
66     baz (i);
67 }
68 
69 template <typename T>
70 void
f4(const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)71 f4 (const std::vector<int>::const_iterator &x,
72     const std::vector<int>::const_iterator &y)
73 {
74   std::vector<int>::const_iterator i;
75 #pragma omp parallel
76 #pragma omp single
77 #pragma omp taskloop lastprivate(i)
78   for (i = x + 2000 - 64; i > y + 10; --i)
79     baz (i);
80 }
81 
82 void
f5(const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)83 f5 (const std::vector<int>::const_iterator &x,
84     const std::vector<int>::const_iterator &y)
85 {
86 #pragma omp parallel
87 #pragma omp single
88 #pragma omp taskloop
89   for (std::vector<int>::const_iterator i = x + 2000 - 64; i > y + 10; i -= 10)
90     baz (i);
91 }
92 
93 template <int N>
94 void
f6(const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)95 f6 (const std::vector<int>::const_iterator &x,
96     const std::vector<int>::const_iterator &y)
97 {
98 #pragma omp parallel
99 #pragma omp single
100 #pragma omp taskloop
101   for (std::vector<int>::const_iterator i = x + 2000 - 64;
102        i > y + 10; i = i - 12 + 2)
103     {
104       std::vector<int>::const_iterator j = i + N;
105       baz (j);
106     }
107 }
108 
109 template <int N>
110 void
f7(std::vector<int>::const_iterator i,const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)111 f7 (std::vector<int>::const_iterator i,
112     const std::vector<int>::const_iterator &x,
113     const std::vector<int>::const_iterator &y)
114 {
115 #pragma omp parallel
116 #pragma omp single
117 #pragma omp taskloop
118   for (i = x - 10; i <= y + 10; i += N)
119     baz (i);
120 }
121 
122 template <int N>
123 void
f8(J<int> j)124 f8 (J<int> j)
125 {
126   std::vector<int>::const_iterator i;
127 #pragma omp parallel
128 #pragma omp single
129 #pragma omp taskloop
130   for (i = j.begin (); i <= j.end () + N; i += 2)
131     baz (i);
132 }
133 
134 template <typename T, int N>
135 void
f9(const typename std::vector<T>::const_iterator & x,const typename std::vector<T>::const_iterator & y)136 f9 (const typename std::vector<T>::const_iterator &x,
137     const typename std::vector<T>::const_iterator &y)
138 {
139 #pragma omp parallel
140 #pragma omp single
141 #pragma omp taskloop
142   for (typename std::vector<T>::const_iterator i = x; i <= y; i = i + N)
143     baz (i);
144 }
145 
146 template <typename T, int N>
147 void
f10(const typename std::vector<T>::const_iterator & x,const typename std::vector<T>::const_iterator & y)148 f10 (const typename std::vector<T>::const_iterator &x,
149      const typename std::vector<T>::const_iterator &y)
150 {
151   typename std::vector<T>::const_iterator i;
152 #pragma omp parallel
153 #pragma omp single
154 #pragma omp taskloop
155   for (i = x; i > y; i = i + N)
156     baz (i);
157 }
158 
159 template <typename T>
160 void
f11(const T & x,const T & y)161 f11 (const T &x, const T &y)
162 {
163 #pragma omp parallel
164   {
165 #pragma omp single nowait
166 #pragma omp taskloop nogroup
167     for (T i = x; i <= y; i += 3)
168       baz (i);
169 #pragma omp single nowait
170     {
171       T j = y + 3;
172       baz (j);
173     }
174   }
175 }
176 
177 template <typename T>
178 void
f12(const T & x,const T & y)179 f12 (const T &x, const T &y)
180 {
181   T i;
182 #pragma omp parallel
183 #pragma omp single
184 #pragma omp taskloop
185   for (i = x; i > y; --i)
186     baz (i);
187 }
188 
189 template <int N>
190 struct K
191 {
192   template <typename T>
193   static void
f13K194   f13 (const T &x, const T &y)
195   {
196 #pragma omp parallel
197 #pragma omp single
198 #pragma omp taskloop
199     for (T i = x; i <= y + N; i += N)
200       baz (i);
201   }
202 };
203 
204 std::vector<int>::const_iterator
f14(const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)205 f14 (const std::vector<int>::const_iterator &x,
206      const std::vector<int>::const_iterator &y)
207 {
208   std::vector<int>::const_iterator i;
209 #pragma omp parallel
210 #pragma omp single
211 #pragma omp taskloop lastprivate(i)
212   for (i = x; i < y - 1; i = 1 - 6 + 7 + i)
213     baz (i);
214   return i;
215 }
216 
217 template <typename T>
218 std::vector<int>::const_iterator
f15(const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)219 f15 (const std::vector<int>::const_iterator &x,
220      const std::vector<int>::const_iterator &y)
221 {
222   std::vector<int>::const_iterator i;
223 #pragma omp parallel
224 #pragma omp single
225 #pragma omp taskloop lastprivate(i)
226   for (i = x + 2000 - 64; i > y + 10; --i)
227     baz (i);
228   return i;
229 }
230 
231 template <int N>
232 std::vector<int>::const_iterator
f16(std::vector<int>::const_iterator i,const std::vector<int>::const_iterator & x,const std::vector<int>::const_iterator & y)233 f16 (std::vector<int>::const_iterator i,
234      const std::vector<int>::const_iterator &x,
235      const std::vector<int>::const_iterator &y)
236 {
237 #pragma omp parallel
238 #pragma omp single
239 #pragma omp taskloop lastprivate(i)
240   for (i = x - 10; i <= y + 10; i += N)
241     baz (i);
242   return i;
243 }
244 
245 template <int N>
246 std::vector<int>::const_iterator
f17(J<int> j)247 f17 (J<int> j)
248 {
249   static std::vector<int>::const_iterator i;
250 #pragma omp parallel
251 #pragma omp single
252 #pragma omp taskloop lastprivate(i)
253   for (i = j.begin (); i <= j.end () + N; i += 2)
254     baz (i);
255   return i;
256 }
257 
258 template <typename T, int N>
259 typename std::vector<T>::const_iterator
f18(const typename std::vector<T>::const_iterator & x,const typename std::vector<T>::const_iterator & y)260 f18 (const typename std::vector<T>::const_iterator &x,
261      const typename std::vector<T>::const_iterator &y)
262 {
263   static typename std::vector<T>::const_iterator i;
264 #pragma omp parallel
265 #pragma omp single
266 #pragma omp taskloop lastprivate(i)
267   for (i = x; i > y; i = i + N)
268     baz (i);
269   return i;
270 }
271 
272 template <typename T>
273 T
f19(const T & x,const T & y)274 f19 (const T &x, const T &y)
275 {
276   T i;
277 #pragma omp parallel
278   {
279 #pragma omp single nowait
280 #pragma omp taskloop nogroup lastprivate(i)
281     for (i = x; i <= y; i += 3)
282       baz (i);
283 #pragma omp single nowait
284     {
285       T j = y + 3;
286       baz (j);
287     }
288   }
289   return i;
290 }
291 
292 template <typename T>
293 T
f20(const T & x,const T & y)294 f20 (const T &x, const T &y)
295 {
296   T i;
297 #pragma omp parallel
298 #pragma omp single
299 #pragma omp taskloop lastprivate(i)
300   for (i = x; i > y; --i)
301     baz (i);
302   return i;
303 }
304 
305 #define check(expr) \
306   for (int i = 0; i < 2000; i++)			\
307     if (expr)						\
308       {							\
309 	if (results[i] != 1)				\
310 	  std::abort ();				\
311 	results[i] = 0;					\
312       }							\
313     else if (results[i])				\
314       std::abort ()
315 
316 int
main()317 main ()
318 {
319   std::vector<int> a(2000);
320   std::vector<long> b(2000);
321   for (int i = 0; i < 2000; i++)
322     {
323       a[i] = i;
324       b[i] = i;
325     }
326   f1 (a.begin () + 10, a.begin () + 1990);
327   check (i >= 10 && i <= 1990 && (i - 10) % 6 == 0);
328   f2 (a.begin () + 0, a.begin () + 1999);
329   check (i < 1998 && (i & 1) == 0);
330   f3<char> (a.begin () + 20, a.begin () + 1837);
331   check (i >= 20 && i <= 1837);
332   f4<int> (a.begin () + 0, a.begin () + 30);
333   check (i > 40 && i <= 2000 - 64);
334   f5 (a.begin () + 0, a.begin () + 100);
335   check (i >= 116 && i <= 2000 - 64 && (i - 116) % 10 == 0);
336   f6<-10> (a.begin () + 10, a.begin () + 110);
337   check (i >= 116 && i <= 2000 - 64 && (i - 116) % 10 == 0);
338   f7<6> (std::vector<int>::const_iterator (), a.begin () + 12,
339 	 a.begin () + 1800);
340   check (i >= 2 && i <= 1808 && (i - 2) % 6 == 0);
341   f8<121> (J<int> (a.begin () + 14, a.begin () + 1803));
342   check (i >= 14 && i <= 1924 && (i & 1) == 0);
343   f9<int, 7> (a.begin () + 33, a.begin () + 1967);
344   check (i >= 33 && i <= 1967 && (i - 33) % 7 == 0);
345   f10<int, -7> (a.begin () + 1939, a.begin () + 17);
346   check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0);
347   f11<std::vector<int>::const_iterator > (a.begin () + 16, a.begin () + 1981);
348   check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0);
349   f12<std::vector<int>::const_iterator > (a.begin () + 1761, a.begin () + 37);
350   check (i > 37 && i <= 1761);
351   K<5>::f13<std::vector<int>::const_iterator > (a.begin () + 1,
352 						a.begin () + 1935);
353   check (i >= 1 && i <= 1936 && (i - 1) % 5 == 0);
354   if (f14 (a.begin () + 0, a.begin () + 1999) != a.begin () + 1998)
355     std::abort ();
356   check (i < 1998 && (i & 1) == 0);
357   if (f15<int> (a.begin () + 0, a.begin () + 30) != a.begin () + 40)
358     std::abort ();
359   check (i > 40 && i <= 2000 - 64);
360   if (f16<6> (std::vector<int>::const_iterator (), a.begin () + 12,
361 	      a.begin () + 1800) != a.begin () + 1814)
362     std::abort ();
363   check (i >= 2 && i <= 1808 && (i - 2) % 6 == 0);
364   if (f17<121> (J<int> (a.begin () + 14, a.begin () + 1803)) != a.begin () + 1926)
365     std::abort ();
366   check (i >= 14 && i <= 1924 && (i & 1) == 0);
367   if (f18<int, -7> (a.begin () + 1939, a.begin () + 17) != a.begin () + 14)
368     std::abort ();
369   check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0);
370   if (f19<std::vector<int>::const_iterator > (a.begin () + 16, a.begin () + 1981)
371       != a.begin () + 1984)
372     std::abort ();
373   check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0);
374   if (f20<std::vector<int>::const_iterator > (a.begin () + 1761, a.begin () + 37)
375       != a.begin () + 37)
376     std::abort ();
377   check (i > 37 && i <= 1761);
378   f9<long, 7> (b.begin () + 33, b.begin () + 1967);
379   check (i >= 33 && i <= 1967 && (i - 33) % 7 == 0);
380   f10<long, -7> (b.begin () + 1939, b.begin () + 17);
381   check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0);
382   f11<std::vector<long>::const_iterator > (b.begin () + 16, b.begin () + 1981);
383   check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0);
384   f12<std::vector<long>::const_iterator > (b.begin () + 1761, b.begin () + 37);
385   check (i > 37 && i <= 1761);
386   K<5>::f13<std::vector<long>::const_iterator > (b.begin () + 1,
387 						 b.begin () + 1935);
388   check (i >= 1 && i <= 1936 && (i - 1) % 5 == 0);
389   if (f18<long, -7> (b.begin () + 1939, b.begin () + 17) != b.begin () + 14)
390     std::abort ();
391   check (i >= 21 && i <= 1939 && (i - 21) % 7 == 0);
392   if (f19<std::vector<long>::const_iterator > (b.begin () + 16, b.begin () + 1981)
393       != b.begin () + 1984)
394     std::abort ();
395   check (i >= 16 && i <= 1984 && (i - 16) % 3 == 0);
396   if (f20<std::vector<long>::const_iterator > (b.begin () + 1761, b.begin () + 37)
397       != b.begin () + 37)
398     std::abort ();
399   check (i > 37 && i <= 1761);
400 }
401