1 // (C) Copyright Jeremy Siek 2000-2002.
2 // Distributed under the Boost Software License, Version 1.0. (See
3 // accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5 
6 // This file doesn't work on other compilers.
7 #if defined(__GNUC__) || defined(__KCC)
8 
9 #include <algorithm>
10 #include <numeric>
11 #include <boost/config.hpp>
12 #include <boost/concept_check.hpp>
13 #include <boost/concept_archetype.hpp>
14 
15 /*
16 
17  This file uses the archetype classes to find out which concepts
18  actually *cover* the STL algorithms true requirements. The
19  archetypes/concepts chosen do not necessarily match the C++ standard
20  or the SGI STL documentation, but instead were chosen based on the
21  minimal concepts that current STL implementations require, which in
22  many cases is less stringent than the standard. In some places there
23  was significant differences in the implementations' requirements and
24  in those places macros were used to select different requirements,
25  the purpose being to document what the requirements of various
26  implementations are.  It is an open issue as to whether the C++
27  standard should be changed to reflect these weaker requirements.
28 
29 */
30 
31 boost::detail::dummy_constructor dummy_cons;
32 
33 // This is a special concept needed for std::swap_ranges.
34 // It is mutually convertible, and also SGIAssignable
35 template <class T>
36 class mutually_convertible_archetype
37 {
38 private:
mutually_convertible_archetype()39   mutually_convertible_archetype() { }
40 public:
mutually_convertible_archetype(const mutually_convertible_archetype &)41   mutually_convertible_archetype(const mutually_convertible_archetype&) { }
42   mutually_convertible_archetype&
operator =(const mutually_convertible_archetype &)43   operator=(const mutually_convertible_archetype&)
44     { return *this; }
mutually_convertible_archetype(boost::detail::dummy_constructor)45   mutually_convertible_archetype(boost::detail::dummy_constructor) { }
46 
47   template <class U>
48   mutually_convertible_archetype&
operator =(const mutually_convertible_archetype<U> &)49   operator=(const mutually_convertible_archetype<U>&)
50     { return *this; }
51 
52 };
53 
54 
55 // for std::accumulate
56 namespace accum
57 {
58   typedef boost::sgi_assignable_archetype<> Ret;
59   struct T {
Taccum::T60     T(const Ret&) { }
Taccum::T61     T(boost::detail::dummy_constructor x) { }
62   };
63   typedef boost::null_archetype<> Tin;
operator +(const T &,const Tin &)64   Ret operator+(const T&, const Tin&) {
65     return Ret(dummy_cons);
66   }
67 }
68 
69 // for std::inner_product
70 namespace inner_prod
71 {
72   typedef boost::sgi_assignable_archetype<> RetAdd;
73   typedef boost::sgi_assignable_archetype<> RetMult;
74   struct T {
Tinner_prod::T75     T(const RetAdd&) { }
Tinner_prod::T76     T(boost::detail::dummy_constructor x) { }
77   };
78   typedef boost::null_archetype<int> Tin1;
79   typedef boost::null_archetype<char> Tin2;
80 }
81 
82 namespace boost { // so Koenig lookup will find
83 
84   inner_prod::RetMult
operator *(const inner_prod::Tin1 &,const inner_prod::Tin2 &)85   operator*(const inner_prod::Tin1&, const inner_prod::Tin2&) {
86     return inner_prod::RetMult(dummy_cons);
87   }
88   inner_prod::RetAdd
operator +(const inner_prod::T &,const inner_prod::RetMult &)89   operator+(const inner_prod::T&,
90             const inner_prod::RetMult&) {
91     return inner_prod::RetAdd(dummy_cons);
92   }
93 }
94 
95 
96 // for std::partial_sum and adj_diff
97 namespace part_sum
98 {
99   class T {
100   public:
101     typedef boost::sgi_assignable_archetype<> Ret;
T(const Ret &)102     T(const Ret&) { }
T(boost::detail::dummy_constructor x)103     T(boost::detail::dummy_constructor x) { }
104   private:
T()105     T() { }
106   };
operator +(const T &,const T &)107   T::Ret operator+(const T&, const T&) {
108     return T::Ret(dummy_cons);
109   }
operator -(const T &,const T &)110   T::Ret operator-(const T&, const T&) {
111     return T::Ret(dummy_cons);
112   }
113 }
114 
115 // for std::power
116 
117 namespace power_stuff {
118   struct monoid_archetype {
monoid_archetypepower_stuff::monoid_archetype119     monoid_archetype(boost::detail::dummy_constructor x) { }
120   };
121 
122   boost::multipliable_archetype<monoid_archetype>
identity_element(std::multiplies<boost::multipliable_archetype<monoid_archetype>>)123   identity_element
124   (std::multiplies< boost::multipliable_archetype<monoid_archetype> >)
125   {
126     return boost::multipliable_archetype<monoid_archetype>(dummy_cons);
127   }
128 }
129 
130 struct tag1 { };
131 struct tag2 { };
132 
133 
134 int
main()135 main()
136 {
137   using namespace boost;
138 
139   //===========================================================================
140   // Non-mutating Algorithms
141   {
142     input_iterator_archetype< null_archetype<> > in;
143     unary_function_archetype< null_archetype<> , null_archetype<> >
144       f(dummy_cons);
145     std::for_each(in, in, f);
146   }
147   // gcc bug
148   {
149     typedef equality_comparable2_first_archetype<> Left;
150     input_iterator_archetype< Left > in;
151     equality_comparable2_second_archetype<> value(dummy_cons);
152     in = std::find(in, in, value);
153   }
154   {
155     typedef null_archetype<> T;
156     input_iterator_archetype<T> in;
157     unary_predicate_archetype<T> pred(dummy_cons);
158     in = std::find_if(in, in, pred);
159   }
160   {
161     forward_iterator_archetype< equality_comparable_archetype<> > fo;
162     fo = std::adjacent_find(fo, fo);
163   }
164   {
165     forward_iterator_archetype<
166       convertible_to_archetype< null_archetype<>  > > fo;
167     binary_predicate_archetype<null_archetype<> , null_archetype<> >
168       pred(dummy_cons);
169     fo = std::adjacent_find(fo, fo, pred);
170   }
171   // gcc bug
172   {
173     typedef equal_op_first_archetype<> Left;
174     input_iterator_archetype<Left> in;
175     typedef equal_op_second_archetype<> Right;
176     forward_iterator_archetype<Right> fo;
177     in = std::find_first_of(in, in, fo, fo);
178   }
179   {
180     typedef equal_op_first_archetype<> Left;
181     typedef input_iterator_archetype<Left> InIter;
182     InIter in;
183     function_requires< InputIterator<InIter> >();
184     equal_op_second_archetype<> value(dummy_cons);
185     std::iterator_traits<InIter>::difference_type
186       n = std::count(in, in, value);
187     ignore_unused_variable_warning(n);
188   }
189   {
190     typedef input_iterator_archetype< null_archetype<> > InIter;
191     InIter in;
192     unary_predicate_archetype<null_archetype<> > pred(dummy_cons);
193     std::iterator_traits<InIter>::difference_type
194       n = std::count_if(in, in, pred);
195     ignore_unused_variable_warning(n);
196   }
197   // gcc bug
198   {
199     typedef equal_op_first_archetype<> Left;
200     typedef input_iterator_archetype<Left> InIter1;
201     InIter1 in1;
202     typedef equal_op_second_archetype<> Right;
203     typedef input_iterator_archetype<Right> InIter2;
204     InIter2 in2;
205     std::pair<InIter1, InIter2> p = std::mismatch(in1, in1, in2);
206     ignore_unused_variable_warning(p);
207   }
208   {
209     typedef input_iterator_archetype<null_archetype<> > InIter;
210     InIter in1, in2;
211     binary_predicate_archetype<null_archetype<> , null_archetype<> >
212       pred(dummy_cons);
213     std::pair<InIter, InIter> p = std::mismatch(in1, in1, in2, pred);
214     ignore_unused_variable_warning(p);
215   }
216   // gcc bug
217   {
218     typedef equality_comparable2_first_archetype<> Left;
219     input_iterator_archetype<Left> in1;
220     typedef equality_comparable2_second_archetype<> Right;
221     input_iterator_archetype<Right> in2;
222     bool b = std::equal(in1, in1, in2);
223     ignore_unused_variable_warning(b);
224   }
225   {
226     input_iterator_archetype< null_archetype<> >
227       in1, in2;
228     binary_predicate_archetype<null_archetype<> , null_archetype<> >
229       pred(dummy_cons);
230     bool b = std::equal(in1, in1, in2, pred);
231     ignore_unused_variable_warning(b);
232   }
233   {
234     typedef equality_comparable2_first_archetype<> Left;
235     forward_iterator_archetype<Left> fo1;
236     typedef equality_comparable2_second_archetype<> Right;
237     forward_iterator_archetype<Right> fo2;
238     fo1 = std::search(fo1, fo1, fo2, fo2);
239   }
240   {
241     typedef equality_comparable2_first_archetype<
242       convertible_to_archetype<null_archetype<> > > Left;
243     forward_iterator_archetype<Left> fo1;
244     typedef equality_comparable2_second_archetype<
245       convertible_to_archetype<null_archetype<> > > Right;
246     forward_iterator_archetype<Right> fo2;
247     binary_predicate_archetype<null_archetype<> , null_archetype<> >
248       pred(dummy_cons);
249     fo1 = std::search(fo1, fo1, fo2, fo2, pred);
250   }
251   {
252     typedef equality_comparable2_first_archetype<> Left;
253     forward_iterator_archetype<Left> fo;
254     equality_comparable2_second_archetype<> value(dummy_cons);
255     int n = 1;
256     fo = std::search_n(fo, fo, n, value);
257   }
258   {
259     forward_iterator_archetype<
260       convertible_to_archetype<null_archetype<> > > fo;
261     convertible_to_archetype<null_archetype<> > value(dummy_cons);
262     binary_predicate_archetype<null_archetype<> , null_archetype<> >
263       pred(dummy_cons);
264     int n = 1;
265     fo = std::search_n(fo, fo, n, value, pred);
266   }
267   {
268     typedef equality_comparable2_first_archetype<> Left;
269     forward_iterator_archetype<Left> fo1;
270     typedef equality_comparable2_second_archetype<null_archetype<> > Right;
271     forward_iterator_archetype<Right> fo2;
272     fo1 = std::find_end(fo1, fo1, fo2, fo2);
273   }
274   {
275     // equality comparable required because find_end() calls search
276     typedef equality_comparable2_first_archetype<
277       convertible_to_archetype<null_archetype<> > > Left;
278     forward_iterator_archetype<Left> fo1;
279     typedef equality_comparable2_second_archetype<
280       convertible_to_archetype<null_archetype<> > > Right;
281     forward_iterator_archetype<Right> fo2;
282     binary_predicate_archetype<null_archetype<> , null_archetype<> >
283       pred(dummy_cons);
284     fo1 = std::find_end(fo1, fo1, fo2, fo2, pred);
285   }
286 
287   //===========================================================================
288   // Mutating Algorithms
289 
290   {
291     typedef null_archetype<> T;
292     input_iterator_archetype<T> in;
293     output_iterator_archetype<T> out(dummy_cons);
294     out = std::copy(in, in, out);
295   }
296   {
297     typedef assignable_archetype<> OutT;
298     typedef convertible_to_archetype<OutT> InT;
299     bidirectional_iterator_archetype<InT> bid_in;
300     mutable_bidirectional_iterator_archetype<OutT> bid_out;
301     bid_out = std::copy_backward(bid_in, bid_in, bid_out);
302   }
303   {
304     sgi_assignable_archetype<> a(dummy_cons), b(dummy_cons);
305     std::swap(a, b);
306   }
307   {
308     typedef sgi_assignable_archetype<> T;
309     mutable_forward_iterator_archetype<T> a, b;
310     std::iter_swap(a, b);
311   }
312   {
313     typedef mutually_convertible_archetype<int> Tin;
314     typedef mutually_convertible_archetype<char> Tout;
315     mutable_forward_iterator_archetype<Tin> fi1;
316     mutable_forward_iterator_archetype<Tout> fi2;
317     fi2 = std::swap_ranges(fi1, fi1, fi2);
318   }
319   {
320     typedef null_archetype<int> Tin;
321     typedef null_archetype<char> Tout;
322     input_iterator_archetype<Tin> in;
323     output_iterator_archetype<Tout> out(dummy_cons);
324     unary_function_archetype<null_archetype<> ,
325       convertible_to_archetype<Tout> > op(dummy_cons);
326     out = std::transform(in, in, out, op);
327   }
328   {
329     typedef null_archetype<int> Tin1;
330     typedef null_archetype<char> Tin2;
331     typedef null_archetype<double> Tout;
332     input_iterator_archetype<Tin1> in1;
333     input_iterator_archetype<Tin2> in2;
334     output_iterator_archetype<Tout> out(dummy_cons);
335     binary_function_archetype<Tin1, Tin2,
336       convertible_to_archetype<Tout> > op(dummy_cons);
337     out = std::transform(in1, in1, in2, out, op);
338   }
339   {
340     typedef equality_comparable2_first_archetype<
341       assignable_archetype<> > FT;
342     mutable_forward_iterator_archetype<FT> fi;
343     equality_comparable2_second_archetype<
344       convertible_to_archetype<FT> > value(dummy_cons);
345     std::replace(fi, fi, value, value);
346   }
347   {
348     typedef null_archetype<> PredArg;
349     typedef assignable_archetype<
350       convertible_to_archetype<PredArg> > FT;
351     mutable_forward_iterator_archetype<FT> fi;
352     unary_predicate_archetype<PredArg> pred(dummy_cons);
353     convertible_to_archetype<FT> value(dummy_cons);
354     std::replace_if(fi, fi, pred, value);
355   }
356   // gcc bug
357   {
358     // Issue, the use of ?: inside replace_copy() complicates things
359     typedef equal_op_first_archetype<> Tin;
360     typedef null_archetype<> Tout;
361     typedef equal_op_second_archetype< convertible_to_archetype<Tout> > T;
362     input_iterator_archetype<Tin> in;
363     output_iterator_archetype<Tout> out(dummy_cons);
364     T value(dummy_cons);
365     out = std::replace_copy(in, in, out, value, value);
366   }
367   {
368     // The issue of ?: also affects this function
369     typedef null_archetype<> Tout;
370     typedef assignable_archetype< convertible_to_archetype<Tout> > Tin;
371     input_iterator_archetype<Tin> in;
372     output_iterator_archetype<Tout> out(dummy_cons);
373     unary_predicate_archetype<Tin> pred(dummy_cons);
374     Tin value(dummy_cons);
375     out = std::replace_copy_if(in, in, out, pred, value);
376   }
377   {
378     typedef assignable_archetype<> FT;
379     mutable_forward_iterator_archetype<FT> fi;
380     typedef convertible_to_archetype<FT> T;
381     T value(dummy_cons);
382     std::fill(fi, fi, value);
383   }
384   {
385     typedef null_archetype<> Tout;
386     typedef convertible_to_archetype<Tout> T;
387     output_iterator_archetype<Tout> out(dummy_cons);
388     T value(dummy_cons);
389     int n = 1;
390     out = std::fill_n(out, n, value);
391   }
392   {
393     typedef assignable_archetype<> FT;
394     typedef convertible_to_archetype<FT> Ret;
395     mutable_forward_iterator_archetype<FT> fi;
396     generator_archetype<Ret> gen;
397     std::generate(fi, fi, gen);
398   }
399   {
400     typedef assignable_archetype<> FT;
401     typedef convertible_to_archetype<FT> Ret;
402     mutable_forward_iterator_archetype<FT> fi;
403     generator_archetype<Ret> gen;
404     int n = 1;
405     std::generate_n(fi, n, gen);
406   }
407   {
408     typedef assignable_archetype< equality_comparable2_first_archetype<> > FT;
409     typedef equality_comparable2_second_archetype<> T;
410     mutable_forward_iterator_archetype<FT> fi;
411     T value(dummy_cons);
412     fi = std::remove(fi, fi, value);
413   }
414   {
415     typedef assignable_archetype<> FT;
416     mutable_forward_iterator_archetype<FT> fi;
417     typedef null_archetype<> PredArg;
418     unary_predicate_archetype<PredArg> pred(dummy_cons);
419     fi = std::remove_if(fi, fi, pred);
420   }
421   // gcc bug
422   {
423     typedef null_archetype<> Tout;
424     typedef equality_comparable2_first_archetype<
425       convertible_to_archetype<Tout> > Tin;
426     typedef equality_comparable2_second_archetype<> T;
427     input_iterator_archetype<Tin> in;
428     output_iterator_archetype<Tout> out(dummy_cons);
429     T value(dummy_cons);
430     out = std::remove_copy(in, in, out, value);
431   }
432   {
433     typedef null_archetype<> T;
434     input_iterator_archetype<T> in;
435     output_iterator_archetype<T> out(dummy_cons);
436     unary_predicate_archetype<T> pred(dummy_cons);
437     out = std::remove_copy_if(in, in, out, pred);
438   }
439   {
440     typedef sgi_assignable_archetype< equality_comparable_archetype<> > T;
441     mutable_forward_iterator_archetype<T> fi;
442     fi = std::unique(fi, fi);
443   }
444   {
445     typedef null_archetype<int> Arg1;
446     typedef null_archetype<char> Arg2;
447     typedef sgi_assignable_archetype<
448       convertible_to_archetype<Arg1,
449       convertible_to_archetype<Arg2> > > FT;
450     mutable_forward_iterator_archetype<FT> fi;
451     binary_predicate_archetype<Arg1, Arg2> pred(dummy_cons);
452     fi = std::unique(fi, fi, pred);
453   }
454   // gcc bug
455   {
456     typedef equality_comparable_archetype< sgi_assignable_archetype<> > T;
457     input_iterator_archetype<T> in;
458     output_iterator_archetype<T> out(dummy_cons);
459     out = std::unique_copy(in, in, out);
460   }
461   {
462     typedef sgi_assignable_archetype<> T;
463     input_iterator_archetype<T> in;
464     output_iterator_archetype<T> out(dummy_cons);
465     binary_predicate_archetype<T, T> pred(dummy_cons);
466     out = std::unique_copy(in, in, out, pred);
467   }
468   {
469     typedef sgi_assignable_archetype<> T;
470     mutable_bidirectional_iterator_archetype<T> bi;
471     std::reverse(bi, bi);
472   }
473   {
474     typedef null_archetype<> Tout;
475     typedef convertible_to_archetype<Tout> Tin;
476     bidirectional_iterator_archetype<Tin> bi;
477     output_iterator_archetype<Tout> out(dummy_cons);
478     out = std::reverse_copy(bi, bi, out);
479   }
480   {
481     typedef sgi_assignable_archetype<> T;
482     mutable_forward_iterator_archetype<T> fi;
483     // Issue, SGI STL is not have void return type, C++ standard does
484     std::rotate(fi, fi, fi);
485   }
486   {
487     typedef null_archetype<> Tout;
488     typedef convertible_to_archetype<Tout> FT;
489     forward_iterator_archetype<FT> fi;
490     output_iterator_archetype<Tout> out(dummy_cons);
491     out = std::rotate_copy(fi, fi, fi, out);
492   }
493   {
494     typedef sgi_assignable_archetype<> T;
495     mutable_random_access_iterator_archetype<T> ri;
496     std::random_shuffle(ri, ri);
497   }
498   {
499     typedef sgi_assignable_archetype<> T;
500     mutable_random_access_iterator_archetype<T> ri;
501     unary_function_archetype<std::ptrdiff_t, std::ptrdiff_t> ran(dummy_cons);
502     std::random_shuffle(ri, ri, ran);
503   }
504   {
505     typedef null_archetype<> PredArg;
506     typedef sgi_assignable_archetype<convertible_to_archetype<PredArg> > FT;
507     mutable_bidirectional_iterator_archetype<FT> bi;
508     unary_predicate_archetype<PredArg> pred(dummy_cons);
509     bi = std::partition(bi, bi, pred);
510   }
511   {
512     typedef null_archetype<> PredArg;
513     typedef sgi_assignable_archetype<convertible_to_archetype<PredArg> > FT;
514     mutable_forward_iterator_archetype<FT> fi;
515     unary_predicate_archetype<PredArg> pred(dummy_cons);
516     fi = std::stable_partition(fi, fi, pred);
517   }
518 
519   //===========================================================================
520   // Sorting Algorithms
521   {
522     typedef sgi_assignable_archetype<
523       less_than_comparable_archetype<> > T;
524     mutable_random_access_iterator_archetype<T> ri;
525     std::sort(ri, ri);
526   }
527   {
528     typedef null_archetype<> Arg;
529     typedef sgi_assignable_archetype<
530       convertible_to_archetype<Arg> > T;
531     mutable_random_access_iterator_archetype<T> ri;
532     binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
533     std::sort(ri, ri, comp);
534   }
535   {
536     typedef less_than_comparable_archetype<
537         sgi_assignable_archetype<> > ValueType;
538     mutable_random_access_iterator_archetype<ValueType> ri;
539     std::stable_sort(ri, ri);
540   }
541   {
542     typedef null_archetype<> Arg;
543     typedef sgi_assignable_archetype<
544       convertible_to_archetype<Arg> > ValueType;
545     mutable_random_access_iterator_archetype<ValueType> ri;
546     binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
547     std::stable_sort(ri, ri, comp);
548   }
549   {
550     typedef sgi_assignable_archetype<
551       less_than_comparable_archetype<> > T;
552     mutable_random_access_iterator_archetype<T> ri;
553     std::partial_sort(ri, ri, ri);
554   }
555 
556   {
557     typedef null_archetype<> Arg;
558     typedef sgi_assignable_archetype<
559       convertible_to_archetype<Arg> > T;
560     mutable_random_access_iterator_archetype<T> ri;
561     binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
562     std::partial_sort(ri, ri, ri, comp);
563   }
564   // gcc bug
565   {
566     // This could be formulated so that the two iterators are not
567     // required to have the same value type, but it is messy.
568     typedef sgi_assignable_archetype<
569       less_than_comparable_archetype<> > T;
570     input_iterator_archetype<T> in;
571     mutable_random_access_iterator_archetype<T> ri_out;
572     ri_out = std::partial_sort_copy(in, in , ri_out, ri_out);
573   }
574   {
575     typedef sgi_assignable_archetype<> T;
576     input_iterator_archetype<T> in;
577     mutable_random_access_iterator_archetype<T> ri_out;
578     binary_predicate_archetype<T, T> comp(dummy_cons);
579     ri_out = std::partial_sort_copy(in, in , ri_out, ri_out, comp);
580   }
581   {
582     typedef sgi_assignable_archetype< less_than_comparable_archetype<> > T;
583     mutable_random_access_iterator_archetype<T> ri;
584     std::nth_element(ri, ri, ri);
585   }
586   {
587     typedef null_archetype<int> Arg1;
588     typedef null_archetype<char> Arg2;
589     typedef sgi_assignable_archetype<
590       convertible_to_archetype<Arg1,
591       convertible_to_archetype<Arg2> > > T;
592     mutable_random_access_iterator_archetype<T> ri;
593     binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
594     std::nth_element(ri, ri, ri, comp);
595   }
596   {
597 #if defined(__GNUC__)
598     typedef less_than_op_first_archetype<> FT;
599     typedef less_than_op_second_archetype<> T;
600 #elif defined(__KCC)
601     // The KAI version of this uses a one-argument less-than function
602     // object.
603     typedef less_than_comparable_archetype<> T;
604     typedef convertible_to_archetype<T> FT;
605 #endif
606     forward_iterator_archetype<FT> fi;
607     T value(dummy_cons);
608     fi = std::lower_bound(fi, fi, value);
609   }
610   {
611     typedef null_archetype<int> Arg1;
612     typedef null_archetype<char> Arg2;
613     typedef convertible_to_archetype<Arg1> FT;
614     typedef convertible_to_archetype<Arg2> T;
615     forward_iterator_archetype<FT> fi;
616     T value(dummy_cons);
617     binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
618     fi = std::lower_bound(fi, fi, value, comp);
619   }
620   {
621 #if defined(__GNUC__)
622     // Note, order of T,FT is flipped from lower_bound
623     typedef less_than_op_second_archetype<> FT;
624     typedef less_than_op_first_archetype<> T;
625 #elif defined(__KCC)
626     typedef less_than_comparable_archetype<> T;
627     typedef convertible_to_archetype<T> FT;
628 #endif
629     forward_iterator_archetype<FT> fi;
630     T value(dummy_cons);
631     fi = std::upper_bound(fi, fi, value);
632   }
633   {
634     typedef null_archetype<int> Arg1;
635     typedef null_archetype<char> Arg2;
636     // Note, order of T,FT is flipped from lower_bound
637     typedef convertible_to_archetype<Arg1> T;
638     typedef convertible_to_archetype<Arg2> FT;
639     forward_iterator_archetype<FT> fi;
640     T value(dummy_cons);
641     binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
642     fi = std::upper_bound(fi, fi, value, comp);
643   }
644   {
645 #if defined(__GNUC__)
646     typedef less_than_op_first_archetype<
647       less_than_op_second_archetype< null_archetype<>, optag2>, optag1> FT;
648     typedef less_than_op_second_archetype<
649       less_than_op_first_archetype< null_archetype<>, optag2>, optag1> T;
650 #elif defined(__KCC)
651     typedef less_than_comparable_archetype<> T;
652     typedef convertible_to_archetype<T> FT;
653 #endif
654     typedef forward_iterator_archetype<FT> FIter;
655     FIter fi;
656     T value(dummy_cons);
657     std::pair<FIter,FIter> p = std::equal_range(fi, fi, value);
658     ignore_unused_variable_warning(p);
659   }
660   {
661     typedef null_archetype<int> Arg1;
662     typedef null_archetype<char> Arg2;
663     typedef convertible_to_archetype<Arg1,
664       convertible_to_archetype<Arg2> > FT;
665     typedef convertible_to_archetype<Arg2,
666       convertible_to_archetype<Arg1> > T;
667     typedef forward_iterator_archetype<FT> FIter;
668     FIter fi;
669     T value(dummy_cons);
670     binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
671     std::pair<FIter,FIter> p = std::equal_range(fi, fi, value, comp);
672     ignore_unused_variable_warning(p);
673   }
674   {
675 #if defined(__GNUC__)
676     typedef less_than_op_first_archetype<
677       less_than_op_second_archetype<null_archetype<>, optag2>, optag1> FT;
678     typedef less_than_op_second_archetype<
679       less_than_op_first_archetype<null_archetype<>, optag2>, optag1> T;
680 #elif defined(__KCC)
681     typedef less_than_op_first_archetype< less_than_comparable_archetype<> > T;
682     typedef less_than_op_second_archetype< convertible_to_archetype<T> > FT;
683 #endif
684     forward_iterator_archetype<FT> fi;
685     T value(dummy_cons);
686     bool b = std::binary_search(fi, fi, value);
687     ignore_unused_variable_warning(b);
688   }
689   {
690     typedef null_archetype<int> Arg1;
691     typedef null_archetype<char> Arg2;
692 #if defined(__GNUC__) || defined(__KCC)
693     typedef convertible_to_archetype<Arg1,
694       convertible_to_archetype<Arg2> > FT;
695     typedef convertible_to_archetype<Arg2,
696       convertible_to_archetype<Arg1> > T;
697 #endif
698     typedef forward_iterator_archetype<FT> FIter;
699     FIter fi;
700     T value(dummy_cons);
701     binary_predicate_archetype<Arg1, Arg2> comp(dummy_cons);
702     bool b = std::binary_search(fi, fi, value, comp);
703     ignore_unused_variable_warning(b);
704   }
705   {
706     typedef null_archetype<> Tout;
707 #if defined(__GNUC__) || defined(__KCC)
708     typedef less_than_op_first_archetype<
709       less_than_op_second_archetype<
710       convertible_to_archetype<Tout>, optag2>, optag1 > Tin1;
711     typedef less_than_op_second_archetype<
712       less_than_op_first_archetype<
713       convertible_to_archetype<Tout>, optag2> ,optag1> Tin2;
714 #endif
715     // gcc bug
716     input_iterator_archetype<Tin1> in1;
717     input_iterator_archetype<Tin2> in2;
718     output_iterator_archetype<Tout> out(dummy_cons);
719     out = std::merge(in1, in1, in2, in2, out);
720     out = std::set_union(in1, in1, in2, in2, out);
721     out = std::set_intersection(in1, in1, in2, in2, out);
722     out = std::set_difference(in1, in1, in2, in2, out);
723     out = std::set_symmetric_difference(in1, in1, in2, in2, out);
724   }
725   {
726     typedef null_archetype<> T;
727     input_iterator_archetype<T> in1;
728     input_iterator_archetype<T,2> in2;
729     typedef convertible_from_archetype<T> Tout;
730     output_iterator_archetype<T> out(dummy_cons);
731     binary_predicate_archetype<T, T> comp(dummy_cons);
732     out = std::merge(in1, in1, in2, in2, out, comp);
733     out = std::set_union(in1, in1, in2, in2, out, comp);
734     out = std::set_intersection(in1, in1, in2, in2, out, comp);
735     out = std::set_difference(in1, in1, in2, in2, out, comp);
736     out = std::set_symmetric_difference(in1, in1, in2, in2, out, comp);
737   }
738   {
739     typedef sgi_assignable_archetype<
740       less_than_comparable_archetype<> > T;
741     mutable_bidirectional_iterator_archetype<T> bi;
742     std::inplace_merge(bi, bi, bi);
743   }
744   {
745     typedef null_archetype<> Arg;
746     typedef sgi_assignable_archetype<
747       convertible_to_archetype<Arg> > T;
748     mutable_bidirectional_iterator_archetype<T> bi;
749     binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
750     std::inplace_merge(bi, bi, bi, comp);
751   }
752   // gcc bug
753   {
754     typedef less_than_op_first_archetype<
755       less_than_op_second_archetype<null_archetype<>, optag1>, optag2> Tin1;
756     typedef less_than_op_second_archetype<
757       less_than_op_first_archetype<null_archetype<>, optag1>, optag2> Tin2;
758     input_iterator_archetype<Tin1> in1;
759     input_iterator_archetype<Tin2> in2;
760     bool b = std::includes(in1, in1, in2, in2);
761     b = std::lexicographical_compare(in1, in1, in2, in2);
762     ignore_unused_variable_warning(b);
763   }
764   {
765     typedef null_archetype<int> Tin;
766     input_iterator_archetype<Tin> in1;
767     input_iterator_archetype<Tin,1> in2;
768     binary_predicate_archetype<Tin, Tin> comp(dummy_cons);
769     bool b = std::includes(in1, in1, in2, in2, comp);
770     b = std::lexicographical_compare(in1, in1, in2, in2, comp);
771     ignore_unused_variable_warning(b);
772   }
773   {
774     typedef sgi_assignable_archetype<
775       less_than_comparable_archetype<> > T;
776     mutable_random_access_iterator_archetype<T> ri;
777     std::push_heap(ri, ri);
778     std::pop_heap(ri, ri);
779     std::make_heap(ri, ri);
780     std::sort_heap(ri, ri);
781   }
782   {
783     typedef null_archetype<> Arg;
784     typedef sgi_assignable_archetype<
785       convertible_to_archetype<Arg> > T;
786     mutable_random_access_iterator_archetype<T> ri;
787     binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
788     std::push_heap(ri, ri, comp);
789     std::pop_heap(ri, ri, comp);
790     std::make_heap(ri, ri, comp);
791     std::sort_heap(ri, ri, comp);
792   }
793   {
794     typedef less_than_comparable_archetype<> T;
795     T a(dummy_cons), b(dummy_cons);
796     BOOST_USING_STD_MIN();
797     BOOST_USING_STD_MAX();
798     const T& c = min BOOST_PREVENT_MACRO_SUBSTITUTION(a, b);
799     const T& d = max BOOST_PREVENT_MACRO_SUBSTITUTION(a, b);
800     ignore_unused_variable_warning(c);
801     ignore_unused_variable_warning(d);
802   }
803   {
804     typedef null_archetype<> Arg;
805     binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
806     typedef convertible_to_archetype<Arg> T;
807     T a(dummy_cons), b(dummy_cons);
808     BOOST_USING_STD_MIN();
809     BOOST_USING_STD_MAX();
810     const T& c = min BOOST_PREVENT_MACRO_SUBSTITUTION(a, b, comp);
811     const T& d = max BOOST_PREVENT_MACRO_SUBSTITUTION(a, b, comp);
812     ignore_unused_variable_warning(c);
813     ignore_unused_variable_warning(d);
814   }
815   {
816     typedef less_than_comparable_archetype<> T;
817     forward_iterator_archetype<T> fi;
818     fi = std::min_element(fi, fi);
819     fi = std::max_element(fi, fi);
820   }
821   {
822     typedef null_archetype<> Arg;
823     binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
824     typedef convertible_to_archetype<Arg> T;
825     forward_iterator_archetype<T> fi;
826     fi = std::min_element(fi, fi, comp);
827     fi = std::max_element(fi, fi, comp);
828   }
829   {
830     typedef sgi_assignable_archetype<
831       less_than_comparable_archetype<> > T;
832     mutable_bidirectional_iterator_archetype<T> bi;
833     bool b = std::next_permutation(bi, bi);
834     b = std::prev_permutation(bi, bi);
835     ignore_unused_variable_warning(b);
836   }
837   {
838     typedef null_archetype<> Arg;
839     binary_predicate_archetype<Arg, Arg> comp(dummy_cons);
840     typedef sgi_assignable_archetype<
841       convertible_to_archetype<Arg> > T;
842     mutable_bidirectional_iterator_archetype<T> bi;
843     bool b = std::next_permutation(bi, bi, comp);
844     b = std::prev_permutation(bi, bi, comp);
845     ignore_unused_variable_warning(b);
846   }
847   //===========================================================================
848   // Generalized Numeric Algorithms
849 
850   {
851     // Bummer, couldn't use plus_op because of a problem with
852     // mutually recursive types.
853     input_iterator_archetype<accum::Tin> in;
854     accum::T init(dummy_cons);
855     init = std::accumulate(in, in, init);
856   }
857   {
858     typedef null_archetype<int> Arg1;
859     typedef null_archetype<char> Arg2;
860     typedef sgi_assignable_archetype<
861       convertible_to_archetype<Arg1> > T;
862     typedef convertible_to_archetype<T> Ret;
863     input_iterator_archetype<Arg2> in;
864     T init(dummy_cons);
865     binary_function_archetype<Arg1, Arg2, Ret> op(dummy_cons);
866     init = std::accumulate(in, in, init, op);
867   }
868   {
869     input_iterator_archetype<inner_prod::Tin1> in1;
870     input_iterator_archetype<inner_prod::Tin2> in2;
871     inner_prod::T init(dummy_cons);
872     init = std::inner_product(in1, in1, in2, init);
873   }
874   {
875     typedef null_archetype<int> MultArg1;
876     typedef null_archetype<char> MultArg2;
877     typedef null_archetype<short> AddArg1;
878     typedef null_archetype<long> AddArg2;
879     typedef sgi_assignable_archetype<
880       convertible_to_archetype<AddArg1> > T;
881     typedef convertible_to_archetype<AddArg2> RetMult;
882     typedef convertible_to_archetype<T> RetAdd;
883     input_iterator_archetype<MultArg1> in1;
884     input_iterator_archetype<MultArg2> in2;
885     T init(dummy_cons);
886     binary_function_archetype<MultArg1, MultArg2, RetMult> mult_op(dummy_cons);
887     binary_function_archetype<AddArg1, AddArg2, RetAdd> add_op(dummy_cons);
888     init = std::inner_product(in1, in1, in2, init, add_op, mult_op);
889   }
890   {
891     input_iterator_archetype<part_sum::T> in;
892     output_iterator_archetype<part_sum::T> out(dummy_cons);
893     out = std::partial_sum(in, in, out);
894   }
895   {
896     typedef sgi_assignable_archetype<> T;
897     input_iterator_archetype<T> in;
898     output_iterator_archetype<T> out(dummy_cons);
899     binary_function_archetype<T, T, T> add_op(dummy_cons);
900     out = std::partial_sum(in, in, out, add_op);
901     binary_function_archetype<T, T, T> subtract_op(dummy_cons);
902     out = std::adjacent_difference(in, in, out, subtract_op);
903   }
904   {
905     input_iterator_archetype<part_sum::T> in;
906     output_iterator_archetype<part_sum::T> out(dummy_cons);
907     out = std::adjacent_difference(in, in, out);
908   }
909   return 0;
910 }
911 
912 #else
913 
main()914 int main() {}
915 
916 #endif
917