-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfunctional_s.h
458 lines (456 loc) · 15.3 KB
/
functional_s.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
/**********************************************************
* File£º functional_s.h
*
* Author£º shenglong ([email protected])
*
* Description£ºthis file contains basic components of functional.
* include: Predict : argument_type, bool.
* first_argument_type, second_argument_type, result_type.
* Operation : argument_type, result_type.
* first_argument_type, second_argument_type, result_type.
* base : unary_function.
* binary_function.
* predefine :
* f : pointer_to_unary_function.
* pointer_to_binary_function.
* mf : mem_fun_t/const_mem_fun_t.
* mem_fun1_t/const_mem_fun1_t.
* mem_fun_ref/const_mem_fun_ref.
* mem_fun1_ref/const_mem_fun1_ref.
* FO : binder1st/binder2nd.
* unary_compose/binary_compose.
*
*/
#ifndef FUNCTIONAL_S_H
#define FUNCTIONAL_S_H
#include "include_s.h"
namespace safe {
////////////////////////////// base ////////////////////////////////////////////
template<typename Result>
struct generate_function {
typedef Result result_type;
};
template<typename Arg,typename Result>
struct unary_function {
typedef Arg arugment_type;
typedef Result result_type;
};
template<typename Arg1,typename Arg2,typename Result>
struct binary_function {
typedef Arg1 first_argument_type;
typedef Arg2 second_argument_type;
typedef Result result_type;
};
////////////////////////////// pre-difine ////////////////////////////////////////////
// calculate : negate, plus, minus, multiples, divides, modulus
template<typename Type>
struct negate : public unary_function<Type,Type> {
Type& operator ()( Type& _Left ) const {
return -_Left;
}
};
template<typename Type>
struct plus : public binary_function<Type,Type,Type> {
Type operator()( const Type& _Left,const Type& _Right ) const {
return _Left + _Right;
}
};
template<class Type>
struct minus : public binary_function<Type, Type, Type>
{
Type operator()( const Type& _Left,const Type& _Right ) const {
return _Left - _Right;
};
};
template<typename Type>
struct multiples : public binary_function<Type,Type,Type> {
Type operator()( const Type& _Left,const Type& _Right ) const {
return _Left * _Right;
}
};
template<typename Type>
struct divides : public binary_function<Type,Type,Type> {
Type operator()( const Type& _Left,const Type& _Right ) const {
return _Left / _Right;
}
};
template<typename Type>
struct modulus : public binary_function<Type,Type,Type> {
Type operator()( const Type& _Left,const Type& _Right ) const {
return _Left % _Right;
}
};
// logic : not, and, or
template<typename Type>
struct logic_not : public unary_function<Type,Type> {
bool operator()(Type& _Left) const {
return !_Left;
}
};
template<typename Type>
struct logic_and : public binary_function<Type,Type,Type> {
bool operator()(const Type& _Left,const Type& _Right) const {
return _Left && _Right;
}
};
template<typename Type>
struct logic_or : public binary_function<Type,Type,Type> {
bool operator()(const Type& _Left,const Type& _Right) const {
return _Left || _Right;
}
};
// equal_to , greater_equal, greater, less_equal, less, not_equal_to
template<typename Type>
struct equal_to : public binary_function<Type,Type,bool> {
bool operator()( const Type& _Left,const Type& _Right ) {
return _Left == _Right;
}
};
template<typename Type>
struct greater_equal : public binary_function<Type,Type,bool> {
bool operator()( const Type& _Left,const Type& _Right ) {
return _Left >= _Right;
}
};
template<typename Type>
struct greater : public binary_function<Type,Type,bool> {
bool operator()( const Type& _Left,const Type& _Right ) {
return _Left > _Right;
}
};
template<typename Type>
struct less_equal : public binary_function<Type,Type,bool> {
bool operator()( const Type& _Left,const Type& _Right ) {
return _Left <= _Right;
}
};
template<typename Type>
struct less : public binary_function<Type,Type,bool> {
bool operator()( const Type& _Left,const Type& _Right ) {
return _Left < _Right;
}
};
template<typename Type>
struct not_equal_to : public binary_function<Type,Type,bool> {
bool operator()( const Type& _Left,const Type& _Right ) {
return _Left != _Right;
}
};
////////////////////////////// f ////////////////////////////////////////////
template<typename Result>
class generator : public generate_function<Result> {
public:
explicit generator() {}
Result operator()() {
return rand();
}
};
template<typename Arg,typename Result>
class pointer_to_unary_function : public unary_function<Arg,Result> {
public:
explicit pointer_to_unary_function(Result (*_pfunc)(Arg)){
_f = _pfunc;
}
Result operator()(const Arg _Left) const {
return _f(_Left);
}
private:
Result (*_f)(Arg);
};
template<typename Arg1,typename Arg2,typename Result>
class pointer_to_binary_function : public binary_function<Arg1,Arg2,Result> {
public:
explicit pointer_to_binary_function(Result (*_pfunc)(Arg1,Arg2)) {
_f = _pfunc;
}
Result operator()(const Arg1 _Left,const Arg2 _Right) const {
return _f(_Left,_Right);
}
private:
Result (*_f)(Arg1,Arg2);
};
template<typename Arg,typename Result>
pointer_to_unary_function<Arg,Result> ptr_fun(Result (*_pfunc)(Arg)) {
return pointer_to_unary_function<Arg,Result>(_pfunc);
}
template<typename Arg1,typename Arg2,typename Result>
pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun(Result (*_pfunc)(Arg1,Arg2)) {
return pointer_to_binary_function<Arg1,Arg2,Result>(_pfunc);
}
////////////////////////////// mf ////////////////////////////////////////////
// unary mf
template<typename Type,typename Result>
class men_fun_t : public unary_function<Type*,Result> {
public:
explicit men_fun_t(Result (Type::*_pfunc)()) {
_f = _pfunc;
}
Result operator()(Type* _pLeft) const {
return _pLeft->_f();
}
private:
Result (Type::*_f)();
};
template<typename Type,typename Result>
class men_fun_ref_t : public unary_function<Type,Result> {
public:
explicit men_fun_ref_t(Result (Type::*_pfunc)()) {
_f = _pfunc;
}
Result operator()(Type& _Left) const {
return _Left._f();
}
private:
Result (Type::*_f)();
};
template<typename Type,typename Result>
class const_men_fun_t : public unary_function<Type*,Result> {
public:
explicit const_men_fun_t(Result (Type::*_pfunc)() const) {
_f = _pfunc;
}
Result operator()(const Type* _pLeft) const {
return _pLeft->_f();
}
private:
Result (Type::*_f)() const;
};
template<typename Type,typename Result>
class const_men_fun_ref_t : public unary_function<Type,Result> {
public:
explicit const_men_fun_ref_t(Result (Type::*_pfunc)() const) {
_f = _pfunc;
}
Result operator()(const Type& _Left) const {
return _Left._f();
}
private:
Result (Type::*_f)() const;
};
// binary mf
template<typename Type,typename Arg,typename Result>
class men_fun1_t : public binary_function<Type*,Arg,Result> {
public:
explicit men_fun1_t(Result (Type::*_pfunc)(Arg)) {
_f = _pfunc;
}
Result operator()(Type* _pLeft,Arg _Right) const {
return _Left->_f(_Right);
}
private:
Result (Type::*_f)(Arg);
};
template<typename Type,typename Arg,typename Result>
class men_fun1_ref_t : public binary_function<Type,Arg,Result> {
public:
explicit men_fun1_ref_t(Result (Type::*_pfunc)(Arg)) {
_f = _pfunc;x
}
Result operator()(Type& _Left,Arg _Right) const {
return _Left._f(_Right);
}
private:
Result (Type::*_f)(Arg);
};
template<typename Type,typename Arg,typename Result>
class const_men_fun1_t : public binary_function<Type*,Arg,Result> {
public:
explicit const_men_fun1_t(Result (Type::*_pfunc)(Arg) const) {
_f = _pfunc;
}
Result operator()(const Type* _pLeft,Arg _Right) {
return _pLeft->_f(_Right);
}
private:
Result (Type::*_f)(Arg) const;
};
template<typename Type,typename Arg,typename Result>
class const_men_fun1_ref_t : public binary_function<Type,Arg,Result> {
public:
explicit const_men_fun1_ref_t(Result (Type::*_pfunc)(Arg) const) {
_f = _pfunc;
}
Result operator()(const Type& _Left,Arg _Right) const {
return _Left._f(_Right);
}
private:
Result (Type::*_f)(Arg) const;
};
// men_fun for pointer.
template<typename Type,typename Result>
men_fun_t<Type,Result> men_fun(Result (Type::*_Pm)()) {
return men_fun_t<Type,Result>(_Pm);
}
template<typename Type,typename Result>
const_men_fun_t<Type,Result> men_fun(Result (Type::*_Pm)() const) {
return const_men_fun_t<Type,Result>(_Pm);
}
template<typename Type,typename Arg,typename Result>
men_fun1_t<Type,Arg,Result> men_fun(Result (Type::*_Pm)(Arg)) {
return men_fun1_t<Type,Arg,Result>(_Pm);
}
template<typename Type,typename Arg,typename Result>
const_men_fun1_t<Type,Arg,Result> men_fun(Result (Type::*_Pm)(Arg) const) {
return const_men_fun1_t<Type,Arg,Result>(_Pm);
}
// men_fun_ref for reference.
template<typename Type,typename Result>
men_fun_ref_t<Type,Result> men_fun_ref(Result (Type::*_Pm)()) {
return men_fun_ref_t<Type,Result>(_Pm);
}
template<typename Type,typename Result>
const_men_fun_ref_t<Type,Result> men_fun_ref(Result (Type::*_Pm)() const) {
return const_men_fun_ref_t<Type,Result>(_Pm);
}
template<typename Type,typename Arg,typename Result>
men_fun1_ref_t<Type,Arg,Result> men_fun_ref(Result (Type::*_Pm)(Arg)) {
return men_fun1_ref_t<Type,Arg,Result>(_Pm);
}
template<typename Type,typename Arg,typename Result>
const_men_fun1_ref_t<Type,Arg,Result> men_fun_ref(Result (Type::*_Pm)(Arg) const) {
return const_men_fun1_ref_t<Type,Arg,Result>(_Pm);
}
////////////////////////////// FO ////////////////////////////////////////////
//binder1st //binder2nd
template<typename Operation>
class binder1st : public unary_function<typename Operation::second_argument_type,
typename Operation::result_type>
{
public:
typedef typename Operation::second_argument_type argument_type;
typedef typename Operation::result_type result_type;
explicit binder1st(const Operation& _Func,
const typename Operation::first_argument_type& _Left ) {
_op = _Func;
_value = _Left;
}
result_type operator()(const argument_type& _Right) const {
return _op(_value,_Right);
}
private:
Operation _op;
typename Operation::first_argument_type _value;
};
template<typename Operation>
class binder2nd : public unary_function<typename Operation::first_argument_type,
typename Operation::result_type>
{
public:
typedef typename Operation::first_argument_type argument_type;
typedef typename Operation::result_type result_type;
explicit binder2nd(const Operation& _Func,
const typename Operation::second_argument_type& _Right) {
_op = _Func;
_value = _Right;
}
result_type operator()(const argument_type& _Left) const {
return _op(_Left,_value);
}
private:
Operation _op;
typename Operation::second_argument_type _value;
};
template<typename Operation>
inline binder1st<Operation> bind1st(const Operation& Func,const typename Operation::first_argument_type& Left) {
return binder1st<Operation>(Func,Left);
}
template<typename Operation>
inline binder2nd<Operation> bind2nd(const Operation& Func,const typename Operation::second_argument_type& Right) {
return binder2nd<Operation>(Func,Right);
}
// compose
template<typename Unary_Operation1, typename Unary_Operation2>
class unary_compose : unary_function<typename Unary_Operation2::argument_type,
typename Unary_Operation1::result_type> {
Unary_Operation1 Op1;
Unary_Operation2 Op2;
public:
typedef typename Unary_Operation1::result_type result_type;
typedef typename Unary_Operation2::argument_type argument_type;
public:
explicit unary_compose( const Unary_Operation1& x, const Unary_Operation2& y ) : Op1( x ), Op2( y ) { }
result_type operator( )( const argument_type& x ) { return Op1( Op2( x ) ); }
};
template<typename Binary_Operation1, typename Unary_Operation1, typename Unary_Operation2>
class binary_compose : unary_function<typename Unary_Operation1::argument_type,
typename Binary_Operation1::result_type> {
Binary_Operation1 Op1;
Unary_Operation1 Op2;
Unary_Operation2 Op3;
public:
typedef typename Unary_Operation1::argument_type argument_type;
typedef typename Binary_Operation1::result_type result_type;
public:
explicit binary_compose( const Binary_Operation1& x, const Unary_Operation1& y, const Unary_Operation2& z ) :
Op1( x ), Op2( y ), Op3( z ) { }
result_type operator( )( const argument_type& x ) { return Op1( Op2( x ), Op3( x ) ); }
};
template<typename Unary_Operation1, typename Unary_Operation2>
inline unary_compose<Unary_Operation1, Unary_Operation2>
compose1( const Unary_Operation1& x, const Unary_Operation2& y ) {
return unary_compose<Unary_Operation1, Unary_Operation2>( x, y );
}
template<typename Binary_Operation1, typename Unary_Operation1, typename Unary_Operation2>
inline binary_compose<Binary_Operation1, Unary_Operation1, Unary_Operation2>
compose2( const Binary_Operation1& x,
const Unary_Operation1& y,
const Unary_Operation2& z ) {
return binary_compose<Binary_Operation1, Unary_Operation1, Unary_Operation2>( x, y, z );
}
//unary_negate //binary_negate
template<typename Predict>
class unary_negate : public unary_function<typename Predict::argument_type,bool> {
Predict _pre;
public:
typedef typename Predict::argument_type argument_type;
explicit unary_negate( const Predict& p ) : _pre( p ) {}
bool operator()( const argument_type& pm ) {
return !_pre( pm );
}
};
template<typename Operation>
class binary_negate : public binary_function<typename Operation::first_argument_type,
typename Operation::second_argument_type,
bool>
{
Operation _op;
public:
typedef typename Operation::first_argument_type first_argument_type;
typedef typename Operation::second_argument_type second_argument_type;
explicit binary_negate( const Operation& p ) : _op( p ) {}
bool operator()( const first_argument_type& Left,
const second_argument_type& Right ) {
return !_op( Left,Right );
}
};
template<typename Predict>
bool not1( const Predict& p ) {
return unary_negate<Predict>( p );
}
template<typename Operation>
bool not2( const Operation& op ) {
return binary_negate<Operation>( op );
}
// identity.
template<typename T>
struct identity : public unary_function<T,T> {
const T& operator( )( const T& x ) { return x; }
};
template<typename Pair>
struct select1st : public unary_function<Pair, typename Pair::first_type> {
const typename Pair::first_type operator( )( const Pair& x ) const { return x.first; }
};
template<typename Pair>
struct select2nd : public unary_function<Pair, typename Pair::second_type> {
const typename Pair::second_type operator( )( const Pair& x ) const { return x.second; }
};
template<typename Arg1, typename Arg2>
struct project1st : public binary_function<Arg1, Arg2, Arg1> {
Arg1 operator( )( const Arg1& x, const Arg2& ) const { return x; }
};
template<typename Arg1, typename Arg2>
struct project2nd : public binary_function<Arg1, Arg2, Arg2> {
Arg2 operator( )( const Arg1&, const Arg2& x ) const { return x; }
};
} // namespace safe.
#endif // FUNCTIONAL_S_H