]> gcc.gnu.org Git - gcc.git/blob - libstdc++/stl/function.h
Initial revision
[gcc.git] / libstdc++ / stl / function.h
1 /*
2 *
3 * Copyright (c) 1994
4 * Hewlett-Packard Company
5 *
6 * Permission to use, copy, modify, distribute and sell this software
7 * and its documentation for any purpose is hereby granted without fee,
8 * provided that the above copyright notice appear in all copies and
9 * that both that copyright notice and this permission notice appear
10 * in supporting documentation. Hewlett-Packard Company makes no
11 * representations about the suitability of this software for any
12 * purpose. It is provided "as is" without express or implied warranty.
13 *
14 *
15 * Copyright (c) 1996
16 * Silicon Graphics Computer Systems, Inc.
17 *
18 * Permission to use, copy, modify, distribute and sell this software
19 * and its documentation for any purpose is hereby granted without fee,
20 * provided that the above copyright notice appear in all copies and
21 * that both that copyright notice and this permission notice appear
22 * in supporting documentation. Silicon Graphics makes no
23 * representations about the suitability of this software for any
24 * purpose. It is provided "as is" without express or implied warranty.
25 */
26
27 #ifndef __SGI_STL_FUNCTION_H
28 #define __SGI_STL_FUNCTION_H
29
30 #include <stddef.h>
31 #include <stl_config.h>
32
33 template <class T>
34 inline bool operator!=(const T& x, const T& y) {
35 return !(x == y);
36 }
37
38 template <class T>
39 inline bool operator>(const T& x, const T& y) {
40 return y < x;
41 }
42
43 template <class T>
44 inline bool operator<=(const T& x, const T& y) {
45 return !(y < x);
46 }
47
48 template <class T>
49 inline bool operator>=(const T& x, const T& y) {
50 return !(x < y);
51 }
52
53 template <class Arg, class Result>
54 struct unary_function {
55 typedef Arg argument_type;
56 typedef Result result_type;
57 };
58
59 template <class Arg1, class Arg2, class Result>
60 struct binary_function {
61 typedef Arg1 first_argument_type;
62 typedef Arg2 second_argument_type;
63 typedef Result result_type;
64 };
65
66 template <class T>
67 struct plus : public binary_function<T, T, T> {
68 T operator()(const T& x, const T& y) const { return x + y; }
69 };
70
71 template <class T>
72 struct minus : public binary_function<T, T, T> {
73 T operator()(const T& x, const T& y) const { return x - y; }
74 };
75
76 template <class T>
77 struct multiplies : public binary_function<T, T, T> {
78 T operator()(const T& x, const T& y) const { return x * y; }
79 };
80
81 template <class T>
82 struct divides : public binary_function<T, T, T> {
83 T operator()(const T& x, const T& y) const { return x / y; }
84 };
85
86 template <class T> inline T identity_element(plus<T>) { return T(0); }
87
88 template <class T> inline T identity_element(multiplies<T>) { return T(1); }
89
90 template <class T>
91 struct modulus : public binary_function<T, T, T> {
92 T operator()(const T& x, const T& y) const { return x % y; }
93 };
94
95 template <class T>
96 struct negate : public unary_function<T, T> {
97 T operator()(const T& x) const { return -x; }
98 };
99
100 template <class T>
101 struct equal_to : public binary_function<T, T, bool> {
102 bool operator()(const T& x, const T& y) const { return x == y; }
103 };
104
105 template <class T>
106 struct not_equal_to : public binary_function<T, T, bool> {
107 bool operator()(const T& x, const T& y) const { return x != y; }
108 };
109
110 template <class T>
111 struct greater : public binary_function<T, T, bool> {
112 bool operator()(const T& x, const T& y) const { return x > y; }
113 };
114
115 template <class T>
116 struct less : public binary_function<T, T, bool> {
117 bool operator()(const T& x, const T& y) const { return x < y; }
118 };
119
120 template <class T>
121 struct greater_equal : public binary_function<T, T, bool> {
122 bool operator()(const T& x, const T& y) const { return x >= y; }
123 };
124
125 template <class T>
126 struct less_equal : public binary_function<T, T, bool> {
127 bool operator()(const T& x, const T& y) const { return x <= y; }
128 };
129
130 template <class T>
131 struct logical_and : public binary_function<T, T, bool> {
132 bool operator()(const T& x, const T& y) const { return x && y; }
133 };
134
135 template <class T>
136 struct logical_or : public binary_function<T, T, bool> {
137 bool operator()(const T& x, const T& y) const { return x || y; }
138 };
139
140 template <class T>
141 struct logical_not : public unary_function<T, bool> {
142 bool operator()(const T& x) const { return !x; }
143 };
144
145 template <class Predicate>
146 class unary_negate
147 : public unary_function<typename Predicate::argument_type, bool> {
148 protected:
149 Predicate pred;
150 public:
151 explicit unary_negate(const Predicate& x) : pred(x) {}
152 bool operator()(const argument_type& x) const { return !pred(x); }
153 };
154
155 template <class Predicate>
156 inline unary_negate<Predicate> not1(const Predicate& pred) {
157 return unary_negate<Predicate>(pred);
158 }
159
160 template <class Predicate>
161 class binary_negate
162 : public binary_function<typename Predicate::first_argument_type,
163 typename Predicate::second_argument_type,
164 bool> {
165 protected:
166 Predicate pred;
167 public:
168 explicit binary_negate(const Predicate& x) : pred(x) {}
169 bool operator()(const first_argument_type& x,
170 const second_argument_type& y) const {
171 return !pred(x, y);
172 }
173 };
174
175 template <class Predicate>
176 inline binary_negate<Predicate> not2(const Predicate& pred) {
177 return binary_negate<Predicate>(pred);
178 }
179
180 template <class Operation>
181 class binder1st
182 : public unary_function<typename Operation::second_argument_type,
183 typename Operation::result_type> {
184 protected:
185 Operation op;
186 typename Operation::first_argument_type value;
187 public:
188 binder1st(const Operation& x,
189 const typename Operation::first_argument_type& y)
190 : op(x), value(y) {}
191 result_type operator()(const argument_type& x) const {
192 return op(value, x);
193 }
194 };
195
196 template <class Operation, class T>
197 inline binder1st<Operation> bind1st(const Operation& op, const T& x) {
198 typedef typename Operation::first_argument_type arg1_type;
199 return binder1st<Operation>(op, arg1_type(x));
200 }
201
202 template <class Operation>
203 class binder2nd
204 : public unary_function<typename Operation::first_argument_type,
205 typename Operation::result_type> {
206 protected:
207 Operation op;
208 typename Operation::second_argument_type value;
209 public:
210 binder2nd(const Operation& x,
211 const typename Operation::second_argument_type& y)
212 : op(x), value(y) {}
213 result_type operator()(const argument_type& x) const {
214 return op(x, value);
215 }
216 };
217
218 template <class Operation, class T>
219 inline binder2nd<Operation> bind2nd(const Operation& op, const T& x) {
220 typedef typename Operation::second_argument_type arg2_type;
221 return binder2nd<Operation>(op, arg2_type(x));
222 }
223
224 template <class Operation1, class Operation2>
225 class unary_compose : public unary_function<typename Operation2::argument_type,
226 typename Operation1::result_type> {
227 protected:
228 Operation1 op1;
229 Operation2 op2;
230 public:
231 unary_compose(const Operation1& x, const Operation2& y) : op1(x), op2(y) {}
232 result_type operator()(const argument_type& x) const {
233 return op1(op2(x));
234 }
235 };
236
237 template <class Operation1, class Operation2>
238 inline unary_compose<Operation1, Operation2> compose1(const Operation1& op1,
239 const Operation2& op2) {
240 return unary_compose<Operation1, Operation2>(op1, op2);
241 }
242
243 template <class Operation1, class Operation2, class Operation3>
244 class binary_compose
245 : public unary_function<typename Operation2::argument_type,
246 typename Operation1::result_type> {
247 protected:
248 Operation1 op1;
249 Operation2 op2;
250 Operation3 op3;
251 public:
252 binary_compose(const Operation1& x, const Operation2& y,
253 const Operation3& z) : op1(x), op2(y), op3(z) { }
254 result_type operator()(const argument_type& x) const {
255 return op1(op2(x), op3(x));
256 }
257 };
258
259 template <class Operation1, class Operation2, class Operation3>
260 inline binary_compose<Operation1, Operation2, Operation3>
261 compose2(const Operation1& op1, const Operation2& op2, const Operation3& op3) {
262 return binary_compose<Operation1, Operation2, Operation3>(op1, op2, op3);
263 }
264
265 template <class Arg, class Result>
266 class pointer_to_unary_function : public unary_function<Arg, Result> {
267 protected:
268 Result (*ptr)(Arg);
269 public:
270 pointer_to_unary_function() {}
271 explicit pointer_to_unary_function(Result (*x)(Arg)) : ptr(x) {}
272 Result operator()(Arg x) const { return ptr(x); }
273 };
274
275 template <class Arg, class Result>
276 inline pointer_to_unary_function<Arg, Result> ptr_fun(Result (*x)(Arg)) {
277 return pointer_to_unary_function<Arg, Result>(x);
278 }
279
280 template <class Arg1, class Arg2, class Result>
281 class pointer_to_binary_function : public binary_function<Arg1, Arg2, Result> {
282 protected:
283 Result (*ptr)(Arg1, Arg2);
284 public:
285 pointer_to_binary_function() {}
286 explicit pointer_to_binary_function(Result (*x)(Arg1, Arg2)) : ptr(x) {}
287 Result operator()(Arg1 x, Arg2 y) const { return ptr(x, y); }
288 };
289
290 template <class Arg1, class Arg2, class Result>
291 inline pointer_to_binary_function<Arg1, Arg2, Result>
292 ptr_fun(Result (*x)(Arg1, Arg2)) {
293 return pointer_to_binary_function<Arg1, Arg2, Result>(x);
294 }
295
296 template <class T>
297 struct identity : public unary_function<T, T> {
298 const T& operator()(const T& x) const { return x; }
299 };
300
301 template <class Pair>
302 struct select1st : public unary_function<Pair, typename Pair::first_type> {
303 const typename Pair::first_type& operator()(const Pair& x) const
304 {
305 return x.first;
306 }
307 };
308
309 template <class Pair>
310 struct select2nd : public unary_function<Pair, typename Pair::second_type> {
311 const typename Pair::second_type& operator()(const Pair& x) const
312 {
313 return x.second;
314 }
315 };
316
317 template <class Arg1, class Arg2>
318 struct project1st : public binary_function<Arg1, Arg2, Arg1> {
319 Arg1 operator()(const Arg1& x, const Arg2&) const { return x; }
320 };
321
322 template <class Arg1, class Arg2>
323 struct project2nd : public binary_function<Arg1, Arg2, Arg2> {
324 Arg2 operator()(const Arg1&, const Arg2& y) const { return y; }
325 };
326
327 template <class Result>
328 struct constant_void_fun
329 {
330 typedef Result result_type;
331 result_type val;
332 constant_void_fun(const result_type& v) : val(v) {}
333 const result_type& operator()() const { return val; }
334 };
335
336 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
337 template <class Result, class Argument = Result>
338 #else
339 template <class Result, class Argument>
340 #endif
341 struct constant_unary_fun : public unary_function<Argument, Result> {
342 result_type val;
343 constant_unary_fun(const result_type& v) : val(v) {}
344 const result_type& operator()(const argument_type&) const { return val; }
345 };
346
347 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
348 template <class Result, class Arg1 = Result, class Arg2 = Arg1>
349 #else
350 template <class Result, class Arg1, class Arg2>
351 #endif
352 struct constant_binary_fun : public binary_function<Arg1, Arg2, Result> {
353 result_type val;
354 constant_binary_fun(const result_type& v) : val(v) {}
355 const result_type& operator()(const first_argument_type&,
356 const second_argument_type&) const {
357 return val;
358 }
359 };
360
361 template <class Result>
362 inline constant_void_fun<Result> constant0(const Result& val)
363 {
364 return constant_void_fun<Result>(val);
365 }
366
367 template <class Result>
368 inline constant_unary_fun<Result,Result> constant1(const Result& val)
369 {
370 return constant_unary_fun<Result,Result>(val);
371 }
372
373 template <class Result>
374 inline constant_binary_fun<Result,Result,Result> constant2(const Result& val)
375 {
376 return constant_binary_fun<Result,Result,Result>(val);
377 }
378
379 // Note: this code assumes that int is 32 bits.
380 class subtractive_rng : public unary_function<unsigned int, unsigned int> {
381 private:
382 unsigned int table[55];
383 size_t index1;
384 size_t index2;
385 public:
386 unsigned int operator()(unsigned int limit) {
387 index1 = (index1 + 1) % 55;
388 index2 = (index2 + 1) % 55;
389 table[index1] = table[index1] - table[index2];
390 return table[index1] % limit;
391 }
392
393 void initialize(unsigned int seed)
394 {
395 unsigned int k = 1;
396 table[54] = seed;
397 size_t i;
398 for (i = 0; i < 54; i++) {
399 size_t ii = (21 * (i + 1) % 55) - 1;
400 table[ii] = k;
401 k = seed - k;
402 seed = table[ii];
403 }
404 for (int loop = 0; loop < 4; loop++) {
405 for (i = 0; i < 55; i++)
406 table[i] = table[i] - table[(1 + i + 30) % 55];
407 }
408 index1 = 0;
409 index2 = 31;
410 }
411
412 subtractive_rng(unsigned int seed) { initialize(seed); }
413 subtractive_rng() { initialize(161803398u); }
414 };
415
416
417 // Adaptor function objects: pointers to member functions.
418
419 // There are a total of 16 = 2^4 function objects in this family.
420 // (1) Member functions taking no arguments vs member functions taking
421 // one argument.
422 // (2) Call through pointer vs call through reference.
423 // (3) Member function with void return type vs member function with
424 // non-void return type.
425 // (4) Const vs non-const member function.
426
427 // Note that choice (4) is not present in the 8/97 draft C++ standard,
428 // which only allows these adaptors to be used with non-const functions.
429 // This is likely to be recified before the standard becomes final.
430 // Note also that choice (3) is nothing more than a workaround: according
431 // to the draft, compilers should handle void and non-void the same way.
432 // This feature is not yet widely implemented, though. You can only use
433 // member functions returning void if your compiler supports partial
434 // specialization.
435
436 // All of this complexity is in the function objects themselves. You can
437 // ignore it by using the helper function mem_fun, mem_fun_ref,
438 // mem_fun1, and mem_fun1_ref, which create whichever type of adaptor
439 // is appropriate.
440
441
442 template <class S, class T>
443 class mem_fun_t : public unary_function<T*, S> {
444 public:
445 explicit mem_fun_t(S (T::*pf)()) : f(pf) {}
446 S operator()(T* p) const { return (p->*f)(); }
447 private:
448 S (T::*f)();
449 };
450
451 template <class S, class T>
452 class const_mem_fun_t : public unary_function<const T*, S> {
453 public:
454 explicit const_mem_fun_t(S (T::*pf)() const) : f(pf) {}
455 S operator()(const T* p) const { return (p->*f)(); }
456 private:
457 S (T::*f)() const;
458 };
459
460
461 template <class S, class T>
462 class mem_fun_ref_t : public unary_function<T, S> {
463 public:
464 explicit mem_fun_ref_t(S (T::*pf)()) : f(pf) {}
465 S operator()(T& r) const { return (r.*f)(); }
466 private:
467 S (T::*f)();
468 };
469
470 template <class S, class T>
471 class const_mem_fun_ref_t : public unary_function<T, S> {
472 public:
473 explicit const_mem_fun_ref_t(S (T::*pf)() const) : f(pf) {}
474 S operator()(const T& r) const { return (r.*f)(); }
475 private:
476 S (T::*f)() const;
477 };
478
479 template <class S, class T, class A>
480 class mem_fun1_t : public binary_function<T*, A, S> {
481 public:
482 explicit mem_fun1_t(S (T::*pf)(A)) : f(pf) {}
483 S operator()(T* p, A x) const { return (p->*f)(x); }
484 private:
485 S (T::*f)(A);
486 };
487
488 template <class S, class T, class A>
489 class const_mem_fun1_t : public binary_function<const T*, A, S> {
490 public:
491 explicit const_mem_fun1_t(S (T::*pf)(A) const) : f(pf) {}
492 S operator()(const T* p, A x) const { return (p->*f)(x); }
493 private:
494 S (T::*f)(A) const;
495 };
496
497 template <class S, class T, class A>
498 class mem_fun1_ref_t : public binary_function<T, A, S> {
499 public:
500 explicit mem_fun1_ref_t(S (T::*pf)(A)) : f(pf) {}
501 S operator()(T& r, A x) const { return (r.*f)(x); }
502 private:
503 S (T::*f)(A);
504 };
505
506 template <class S, class T, class A>
507 class const_mem_fun1_ref_t : public binary_function<T, A, S> {
508 public:
509 explicit const_mem_fun1_ref_t(S (T::*pf)(A) const) : f(pf) {}
510 S operator()(const T& r, A x) const { return (r.*f)(x); }
511 private:
512 S (T::*f)(A) const;
513 };
514
515 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
516
517 template <class T>
518 class mem_fun_t<void, T> : public unary_function<T*, void> {
519 public:
520 explicit mem_fun_t(void (T::*pf)()) : f(pf) {}
521 void operator()(T* p) const { (p->*f)(); }
522 private:
523 void (T::*f)();
524 };
525
526 template <class T>
527 class const_mem_fun_t<void, T> : public unary_function<const T*, void> {
528 public:
529 explicit const_mem_fun_t(void (T::*pf)() const) : f(pf) {}
530 void operator()(const T* p) const { (p->*f)(); }
531 private:
532 void (T::*f)() const;
533 };
534
535 template <class T>
536 class mem_fun_ref_t<void, T> : public unary_function<T, void> {
537 public:
538 explicit mem_fun_ref_t(void (T::*pf)()) : f(pf) {}
539 void operator()(T& r) const { (r.*f)(); }
540 private:
541 void (T::*f)();
542 };
543
544 template <class T>
545 class const_mem_fun_ref_t<void, T> : public unary_function<T, void> {
546 public:
547 explicit const_mem_fun_ref_t(void (T::*pf)() const) : f(pf) {}
548 void operator()(const T& r) const { (r.*f)(); }
549 private:
550 void (T::*f)() const;
551 };
552
553 template <class T, class A>
554 class mem_fun1_t<void, T, A> : public binary_function<T*, A, void> {
555 public:
556 explicit mem_fun1_t(void (T::*pf)(A)) : f(pf) {}
557 void operator()(T* p, A x) const { (p->*f)(x); }
558 private:
559 void (T::*f)(A);
560 };
561
562 template <class T, class A>
563 class const_mem_fun1_t<void, T, A> : public binary_function<const T*, A, void> {
564 public:
565 explicit const_mem_fun1_t(void (T::*pf)(A) const) : f(pf) {}
566 void operator()(const T* p, A x) const { (p->*f)(x); }
567 private:
568 void (T::*f)(A) const;
569 };
570
571 template <class T, class A>
572 class mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> {
573 public:
574 explicit mem_fun1_ref_t(void (T::*pf)(A)) : f(pf) {}
575 void operator()(T& r, A x) const { (r.*f)(x); }
576 private:
577 void (T::*f)(A);
578 };
579
580 template <class T, class A>
581 class const_mem_fun1_ref_t<void, T, A> : public binary_function<T, A, void> {
582 public:
583 explicit const_mem_fun1_ref_t(void (T::*pf)(A) const) : f(pf) {}
584 void operator()(const T& r, A x) const { (r.*f)(x); }
585 private:
586 void (T::*f)(A) const;
587 };
588
589 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
590
591 // Mem_fun adaptor helper functions. There are only four:
592 // mem_fun, mem_fun_ref, mem_fun1, mem_fun1_ref.
593
594 template <class S, class T>
595 inline mem_fun_t<S,T> mem_fun(S (T::*f)()) {
596 return mem_fun_t<S,T>(f);
597 }
598
599 template <class S, class T>
600 inline const_mem_fun_t<S,T> mem_fun(S (T::*f)() const) {
601 return const_mem_fun_t<S,T>(f);
602 }
603
604 template <class S, class T>
605 inline mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)()) {
606 return mem_fun_ref_t<S,T>(f);
607 }
608
609 template <class S, class T>
610 inline const_mem_fun_ref_t<S,T> mem_fun_ref(S (T::*f)() const) {
611 return const_mem_fun_ref_t<S,T>(f);
612 }
613
614 template <class S, class T, class A>
615 inline mem_fun1_t<S,T,A> mem_fun1(S (T::*f)(A)) {
616 return mem_fun1_t<S,T,A>(f);
617 }
618
619 template <class S, class T, class A>
620 inline const_mem_fun1_t<S,T,A> mem_fun1(S (T::*f)(A) const) {
621 return const_mem_fun1_t<S,T,A>(f);
622 }
623
624 template <class S, class T, class A>
625 inline mem_fun1_ref_t<S,T,A> mem_fun1_ref(S (T::*f)(A)) {
626 return mem_fun1_ref_t<S,T,A>(f);
627 }
628
629 template <class S, class T, class A>
630 inline const_mem_fun1_ref_t<S,T,A> mem_fun1_ref(S (T::*f)(A) const) {
631 return const_mem_fun1_ref_t<S,T,A>(f);
632 }
633
634 #endif /* __SGI_STL_FUNCTION_H */
This page took 0.068943 seconds and 5 git commands to generate.