4 * Hewlett-Packard Company
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.
16 * Silicon Graphics Computer Systems, Inc.
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.
27 #ifndef __SGI_STL_FUNCTION_H
28 #define __SGI_STL_FUNCTION_H
31 #include <stl_config.h>
34 inline bool operator!=(const T
& x
, const T
& y
) {
39 inline bool operator>(const T
& x
, const T
& y
) {
44 inline bool operator<=(const T
& x
, const T
& y
) {
49 inline bool operator>=(const T
& x
, const T
& y
) {
53 template <class Arg
, class Result
>
54 struct unary_function
{
55 typedef Arg argument_type
;
56 typedef Result result_type
;
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
;
67 struct plus
: public binary_function
<T
, T
, T
> {
68 T
operator()(const T
& x
, const T
& y
) const { return x
+ y
; }
72 struct minus
: public binary_function
<T
, T
, T
> {
73 T
operator()(const T
& x
, const T
& y
) const { return x
- y
; }
77 struct multiplies
: public binary_function
<T
, T
, T
> {
78 T
operator()(const T
& x
, const T
& y
) const { return x
* y
; }
82 struct divides
: public binary_function
<T
, T
, T
> {
83 T
operator()(const T
& x
, const T
& y
) const { return x
/ y
; }
86 template <class T
> inline T
identity_element(plus
<T
>) { return T(0); }
88 template <class T
> inline T
identity_element(multiplies
<T
>) { return T(1); }
91 struct modulus
: public binary_function
<T
, T
, T
> {
92 T
operator()(const T
& x
, const T
& y
) const { return x
% y
; }
96 struct negate
: public unary_function
<T
, T
> {
97 T
operator()(const T
& x
) const { return -x
; }
101 struct equal_to
: public binary_function
<T
, T
, bool> {
102 bool operator()(const T
& x
, const T
& y
) const { return x
== y
; }
106 struct not_equal_to
: public binary_function
<T
, T
, bool> {
107 bool operator()(const T
& x
, const T
& y
) const { return x
!= y
; }
111 struct greater
: public binary_function
<T
, T
, bool> {
112 bool operator()(const T
& x
, const T
& y
) const { return x
> y
; }
116 struct less
: public binary_function
<T
, T
, bool> {
117 bool operator()(const T
& x
, const T
& y
) const { return x
< y
; }
121 struct greater_equal
: public binary_function
<T
, T
, bool> {
122 bool operator()(const T
& x
, const T
& y
) const { return x
>= y
; }
126 struct less_equal
: public binary_function
<T
, T
, bool> {
127 bool operator()(const T
& x
, const T
& y
) const { return x
<= y
; }
131 struct logical_and
: public binary_function
<T
, T
, bool> {
132 bool operator()(const T
& x
, const T
& y
) const { return x
&& y
; }
136 struct logical_or
: public binary_function
<T
, T
, bool> {
137 bool operator()(const T
& x
, const T
& y
) const { return x
|| y
; }
141 struct logical_not
: public unary_function
<T
, bool> {
142 bool operator()(const T
& x
) const { return !x
; }
145 template <class Predicate
>
147 : public unary_function
<typename
Predicate::argument_type
, bool> {
151 explicit unary_negate(const Predicate
& x
) : pred(x
) {}
152 bool operator()(const argument_type
& x
) const { return !pred(x
); }
155 template <class Predicate
>
156 inline unary_negate
<Predicate
> not1(const Predicate
& pred
) {
157 return unary_negate
<Predicate
>(pred
);
160 template <class Predicate
>
162 : public binary_function
<typename
Predicate::first_argument_type
,
163 typename
Predicate::second_argument_type
,
168 explicit binary_negate(const Predicate
& x
) : pred(x
) {}
169 bool operator()(const first_argument_type
& x
,
170 const second_argument_type
& y
) const {
175 template <class Predicate
>
176 inline binary_negate
<Predicate
> not2(const Predicate
& pred
) {
177 return binary_negate
<Predicate
>(pred
);
180 template <class Operation
>
182 : public unary_function
<typename
Operation::second_argument_type
,
183 typename
Operation::result_type
> {
186 typename
Operation::first_argument_type value
;
188 binder1st(const Operation
& x
,
189 const typename
Operation::first_argument_type
& y
)
191 result_type
operator()(const argument_type
& x
) const {
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
));
202 template <class Operation
>
204 : public unary_function
<typename
Operation::first_argument_type
,
205 typename
Operation::result_type
> {
208 typename
Operation::second_argument_type value
;
210 binder2nd(const Operation
& x
,
211 const typename
Operation::second_argument_type
& y
)
213 result_type
operator()(const argument_type
& x
) const {
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
));
224 template <class Operation1
, class Operation2
>
225 class unary_compose
: public unary_function
<typename
Operation2::argument_type
,
226 typename
Operation1::result_type
> {
231 unary_compose(const Operation1
& x
, const Operation2
& y
) : op1(x
), op2(y
) {}
232 result_type
operator()(const argument_type
& x
) const {
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
);
243 template <class Operation1
, class Operation2
, class Operation3
>
245 : public unary_function
<typename
Operation2::argument_type
,
246 typename
Operation1::result_type
> {
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
));
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
);
265 template <class Arg
, class Result
>
266 class pointer_to_unary_function
: public unary_function
<Arg
, Result
> {
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
); }
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
);
280 template <class Arg1
, class Arg2
, class Result
>
281 class pointer_to_binary_function
: public binary_function
<Arg1
, Arg2
, Result
> {
283 Result (*ptr
)(Arg1
, Arg2
);
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
); }
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
);
297 struct identity
: public unary_function
<T
, T
> {
298 const T
& operator()(const T
& x
) const { return x
; }
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
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
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
; }
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
; }
327 template <class Result
>
328 struct constant_void_fun
330 typedef Result result_type
;
332 constant_void_fun(const result_type
& v
) : val(v
) {}
333 const result_type
& operator()() const { return val
; }
336 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
337 template <class Result
, class Argument
= Result
>
339 template <class Result
, class Argument
>
341 struct constant_unary_fun
: public unary_function
<Argument
, Result
> {
343 constant_unary_fun(const result_type
& v
) : val(v
) {}
344 const result_type
& operator()(const argument_type
&) const { return val
; }
347 #ifndef __STL_LIMITED_DEFAULT_TEMPLATES
348 template <class Result
, class Arg1
= Result
, class Arg2
= Arg1
>
350 template <class Result
, class Arg1
, class Arg2
>
352 struct constant_binary_fun
: public binary_function
<Arg1
, Arg2
, Result
> {
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 {
361 template <class Result
>
362 inline constant_void_fun
<Result
> constant0(const Result
& val
)
364 return constant_void_fun
<Result
>(val
);
367 template <class Result
>
368 inline constant_unary_fun
<Result
,Result
> constant1(const Result
& val
)
370 return constant_unary_fun
<Result
,Result
>(val
);
373 template <class Result
>
374 inline constant_binary_fun
<Result
,Result
,Result
> constant2(const Result
& val
)
376 return constant_binary_fun
<Result
,Result
,Result
>(val
);
379 // Note: this code assumes that int is 32 bits.
380 class subtractive_rng
: public unary_function
<unsigned int, unsigned int> {
382 unsigned int table
[55];
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
;
393 void initialize(unsigned int seed
)
398 for (i
= 0; i
< 54; i
++) {
399 size_t ii
= (21 * (i
+ 1) % 55) - 1;
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];
412 subtractive_rng(unsigned int seed
) { initialize(seed
); }
413 subtractive_rng() { initialize(161803398u); }
417 // Adaptor function objects: pointers to member functions.
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
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.
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
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
442 template <class S
, class T
>
443 class mem_fun_t
: public unary_function
<T
*, S
> {
445 explicit mem_fun_t(S (T::*pf
)()) : f(pf
) {}
446 S
operator()(T
* p
) const { return (p
->*f
)(); }
451 template <class S
, class T
>
452 class const_mem_fun_t
: public unary_function
<const T
*, S
> {
454 explicit const_mem_fun_t(S (T::*pf
)() const) : f(pf
) {}
455 S
operator()(const T
* p
) const { return (p
->*f
)(); }
461 template <class S
, class T
>
462 class mem_fun_ref_t
: public unary_function
<T
, S
> {
464 explicit mem_fun_ref_t(S (T::*pf
)()) : f(pf
) {}
465 S
operator()(T
& r
) const { return (r
.*f
)(); }
470 template <class S
, class T
>
471 class const_mem_fun_ref_t
: public unary_function
<T
, S
> {
473 explicit const_mem_fun_ref_t(S (T::*pf
)() const) : f(pf
) {}
474 S
operator()(const T
& r
) const { return (r
.*f
)(); }
479 template <class S
, class T
, class A
>
480 class mem_fun1_t
: public binary_function
<T
*, A
, S
> {
482 explicit mem_fun1_t(S (T::*pf
)(A
)) : f(pf
) {}
483 S
operator()(T
* p
, A x
) const { return (p
->*f
)(x
); }
488 template <class S
, class T
, class A
>
489 class const_mem_fun1_t
: public binary_function
<const T
*, A
, S
> {
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
); }
497 template <class S
, class T
, class A
>
498 class mem_fun1_ref_t
: public binary_function
<T
, A
, S
> {
500 explicit mem_fun1_ref_t(S (T::*pf
)(A
)) : f(pf
) {}
501 S
operator()(T
& r
, A x
) const { return (r
.*f
)(x
); }
506 template <class S
, class T
, class A
>
507 class const_mem_fun1_ref_t
: public binary_function
<T
, A
, S
> {
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
); }
515 #ifdef __STL_CLASS_PARTIAL_SPECIALIZATION
518 class mem_fun_t
<void, T
> : public unary_function
<T
*, void> {
520 explicit mem_fun_t(void (T::*pf
)()) : f(pf
) {}
521 void operator()(T
* p
) const { (p
->*f
)(); }
527 class const_mem_fun_t
<void, T
> : public unary_function
<const T
*, void> {
529 explicit const_mem_fun_t(void (T::*pf
)() const) : f(pf
) {}
530 void operator()(const T
* p
) const { (p
->*f
)(); }
532 void (T::*f
)() const;
536 class mem_fun_ref_t
<void, T
> : public unary_function
<T
, void> {
538 explicit mem_fun_ref_t(void (T::*pf
)()) : f(pf
) {}
539 void operator()(T
& r
) const { (r
.*f
)(); }
545 class const_mem_fun_ref_t
<void, T
> : public unary_function
<T
, void> {
547 explicit const_mem_fun_ref_t(void (T::*pf
)() const) : f(pf
) {}
548 void operator()(const T
& r
) const { (r
.*f
)(); }
550 void (T::*f
)() const;
553 template <class T
, class A
>
554 class mem_fun1_t
<void, T
, A
> : public binary_function
<T
*, A
, void> {
556 explicit mem_fun1_t(void (T::*pf
)(A
)) : f(pf
) {}
557 void operator()(T
* p
, A x
) const { (p
->*f
)(x
); }
562 template <class T
, class A
>
563 class const_mem_fun1_t
<void, T
, A
> : public binary_function
<const T
*, A
, void> {
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
); }
568 void (T::*f
)(A
) const;
571 template <class T
, class A
>
572 class mem_fun1_ref_t
<void, T
, A
> : public binary_function
<T
, A
, void> {
574 explicit mem_fun1_ref_t(void (T::*pf
)(A
)) : f(pf
) {}
575 void operator()(T
& r
, A x
) const { (r
.*f
)(x
); }
580 template <class T
, class A
>
581 class const_mem_fun1_ref_t
<void, T
, A
> : public binary_function
<T
, A
, void> {
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
); }
586 void (T::*f
)(A
) const;
589 #endif /* __STL_CLASS_PARTIAL_SPECIALIZATION */
591 // Mem_fun adaptor helper functions. There are only four:
592 // mem_fun, mem_fun_ref, mem_fun1, mem_fun1_ref.
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
634 #endif /* __SGI_STL_FUNCTION_H */