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