OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [language/] [cxx/] [ustl/] [current/] [include/] [ustl/] [ufunction.h] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
// This file is part of the uSTL library, an STL implementation.
2
//
3
// Copyright (c) 2005-2009 by Mike Sharov <msharov@users.sourceforge.net>
4
// This file is free software, distributed under the MIT License.
5
 
6
#ifndef UFUNCTION_H_221ABA8551801799263C927234C085F3
7
#define UFUNCTION_H_221ABA8551801799263C927234C085F3
8
 
9
namespace ustl {
10
 
11
//----------------------------------------------------------------------
12
// Standard functors
13
//----------------------------------------------------------------------
14
 
15
/// \brief void-returning function abstract interface.
16
/// \ingroup FunctorObjects
17
template <typename Result>
18
struct void_function {
19
    typedef Result      result_type;
20
};
21
 
22
/// \brief \p Result f (\p Arg) function abstract interface.
23
/// \ingroup FunctorObjects
24
template <typename Arg, typename Result>
25
struct unary_function {
26
    typedef Arg         argument_type;
27
    typedef Result      result_type;
28
};
29
 
30
/// \brief \p Result f (\p Arg1, \p Arg2) function abstract interface.
31
/// \ingroup FunctorObjects
32
template <typename Arg1, typename Arg2, typename Result>
33
struct binary_function {
34
    typedef Arg1        first_argument_type;
35
    typedef Arg2        second_argument_type;
36
    typedef Result      result_type;
37
};
38
 
39
#ifndef DOXYGEN_SHOULD_SKIP_THIS
40
 
41
#define STD_BINARY_FUNCTOR(name, rv, func)      \
42
template <class T> struct name : public binary_function<T,T,rv> \
43
{ inline rv operator()(const T& a, const T& b) const { return func; } };
44
#define STD_UNARY_FUNCTOR(name, rv, func)       \
45
template <class T> struct name : public unary_function<T,rv> \
46
{ inline rv operator()(const T& a) const { return func; } };
47
#define STD_CONVERSION_FUNCTOR(name, func)      \
48
template <class S, class D> struct name : public unary_function<S,D> \
49
{ inline D operator()(const S& a) const { return func; } };
50
 
51
STD_BINARY_FUNCTOR (plus,               T,      (a + b))
52
STD_BINARY_FUNCTOR (minus,              T,      (a - b))
53
STD_BINARY_FUNCTOR (divides,            T,      (a / b))
54
STD_BINARY_FUNCTOR (modulus,            T,      (a % b))
55
STD_BINARY_FUNCTOR (multiplies,         T,      (a * b))
56
STD_BINARY_FUNCTOR (logical_and,        T,      (a && b))
57
STD_BINARY_FUNCTOR (logical_or,         T,      (a || b))
58
STD_UNARY_FUNCTOR  (logical_not,        T,      (!a))
59
STD_BINARY_FUNCTOR (bitwise_or,         T,      (a | b))
60
STD_BINARY_FUNCTOR (bitwise_and,        T,      (a & b))
61
STD_BINARY_FUNCTOR (bitwise_xor,        T,      (a ^ b))
62
STD_UNARY_FUNCTOR  (bitwise_not,        T,      (~a))
63
STD_UNARY_FUNCTOR  (negate,             T,      (-a))
64
STD_BINARY_FUNCTOR (equal_to,           bool,   (a == b))
65
STD_BINARY_FUNCTOR (not_equal_to,       bool,   (!(a == b)))
66
STD_BINARY_FUNCTOR (greater,            bool,   (b < a))
67
STD_BINARY_FUNCTOR (less,               bool,   (a < b))
68
STD_BINARY_FUNCTOR (greater_equal,      bool,   (!(a < b)))
69
STD_BINARY_FUNCTOR (less_equal,         bool,   (!(b < a)))
70
STD_BINARY_FUNCTOR (compare,            int,    (a < b ? -1 : (b < a)))
71
STD_UNARY_FUNCTOR  (identity,           T,      (a))
72
 
73
#endif // DOXYGEN_SHOULD_SKIP_THIS
74
 
75
/// \brief Selects and returns the first argument.
76
/// \ingroup FunctorObjects
77
template <class T1, class T2> struct project1st : public binary_function<T1,T2,T1>    { inline const T1& operator()(const T1& a, const T2&) const { return (a); } };
78
/// \brief Selects and returns the second argument.
79
/// \ingroup FunctorObjects
80
template <class T1, class T2> struct project2nd : public binary_function<T1,T2,T2>    { inline const T2& operator()(const T1&, const T2& a) const { return (a); } };
81
 
82
//----------------------------------------------------------------------
83
// Generic function to functor converters.
84
//----------------------------------------------------------------------
85
 
86
/// \brief Wrapper object for unary function pointers.
87
/// Use the ptr_fun accessor to create this object.
88
/// \ingroup FunctorObjects
89
template <typename Arg, typename Result>
90
class pointer_to_unary_function : public unary_function<Arg,Result> {
91
public:
92
    typedef Arg         argument_type;
93
    typedef Result      result_type;
94
    typedef Result      (*pfunc_t)(Arg);
95
public:
96
    explicit inline     pointer_to_unary_function (pfunc_t pfn) : m_pfn (pfn) {}
97
    inline result_type  operator() (argument_type v) const { return (m_pfn(v)); }
98
private:
99
    pfunc_t             m_pfn;  ///< Pointer to the wrapped function.
100
};
101
 
102
/// \brief Wrapper object for binary function pointers.
103
/// Use the ptr_fun accessor to create this object.
104
/// \ingroup FunctorObjects
105
template <typename Arg1, typename Arg2, typename Result>
106
class pointer_to_binary_function : public binary_function<Arg1,Arg2,Result> {
107
public:
108
    typedef Arg1        first_argument_type;
109
    typedef Arg2        second_argument_type;
110
    typedef Result      result_type;
111
    typedef Result      (*pfunc_t)(Arg1, Arg2);
112
public:
113
    explicit inline     pointer_to_binary_function (pfunc_t pfn) : m_pfn (pfn) {}
114
    inline result_type  operator() (first_argument_type v1, second_argument_type v2) const { return (m_pfn(v1, v2)); }
115
private:
116
    pfunc_t             m_pfn;  ///< Pointer to the wrapped function.
117
};
118
 
119
/// ptr_fun(pfn) wraps function pointer pfn into a functor class that calls it.
120
/// \ingroup FunctorAccessors
121
template <typename Arg, typename Result>
122
inline pointer_to_unary_function<Arg,Result> ptr_fun (Result (*pfn)(Arg))
123
{
124
    return (pointer_to_unary_function<Arg,Result> (pfn));
125
}
126
 
127
/// ptr_fun(pfn) wraps function pointer pfn into a functor class that calls it.
128
/// \ingroup FunctorAccessors
129
template <typename Arg1, typename Arg2, typename Result>
130
inline pointer_to_binary_function<Arg1,Arg2,Result> ptr_fun (Result (*pfn)(Arg1,Arg2))
131
{
132
    return (pointer_to_binary_function<Arg1,Arg2,Result> (pfn));
133
}
134
 
135
//----------------------------------------------------------------------
136
// Negators.
137
//----------------------------------------------------------------------
138
 
139
/// \brief Wraps a unary function to return its logical negative.
140
/// Use the unary_negator accessor to create this object.
141
/// \ingroup FunctorObjects
142
template <class UnaryFunction>
143
class unary_negate : public unary_function<typename UnaryFunction::argument_type,
144
                                           typename UnaryFunction::result_type> {
145
public:
146
    typedef typename UnaryFunction::argument_type       argument_type;
147
    typedef typename UnaryFunction::result_type         result_type;
148
public:
149
    explicit inline unary_negate (UnaryFunction pfn) : m_pfn (pfn) {}
150
    inline result_type operator() (argument_type v) const { return (!m_pfn(v)); }
151
private:
152
    UnaryFunction       m_pfn;
153
};
154
 
155
/// Returns the functor that negates the result of *pfn().
156
/// \ingroup FunctorAccessors
157
template <class UnaryFunction>
158
inline unary_negate<UnaryFunction> unary_negator (UnaryFunction pfn)
159
{
160
    return (unary_negate<UnaryFunction>(pfn));
161
}
162
 
163
//----------------------------------------------------------------------
164
// Argument binders
165
//----------------------------------------------------------------------
166
 
167
/// \brief Converts a binary function to a unary function
168
/// by binding a constant value to the first argument.
169
/// Use the bind1st accessor to create this object.
170
/// \ingroup FunctorObjects
171
template <class BinaryFunction>
172
class binder1st : public unary_function<typename BinaryFunction::second_argument_type,
173
                                        typename BinaryFunction::result_type> {
174
public:
175
    typedef typename BinaryFunction::first_argument_type        arg1_t;
176
    typedef typename BinaryFunction::second_argument_type       arg2_t;
177
    typedef typename BinaryFunction::result_type                result_t;
178
public:
179
    inline binder1st (const BinaryFunction& pfn, const arg1_t& v) : m_pfn (pfn), m_Value(v) {}
180
    inline result_t operator()(arg2_t v2) const { return (m_pfn (m_Value, v2)); }
181
protected:
182
    BinaryFunction      m_pfn;
183
    arg1_t              m_Value;
184
};
185
 
186
/// \brief Converts a binary function to a unary function
187
/// by binding a constant value to the second argument.
188
/// Use the bind2nd accessor to create this object.
189
/// \ingroup FunctorObjects
190
template <class BinaryFunction>
191
class binder2nd : public unary_function<typename BinaryFunction::first_argument_type,
192
                                        typename BinaryFunction::result_type> {
193
public:
194
    typedef typename BinaryFunction::first_argument_type        arg1_t;
195
    typedef typename BinaryFunction::second_argument_type       arg2_t;
196
    typedef typename BinaryFunction::result_type                result_t;
197
public:
198
    inline binder2nd (const BinaryFunction& pfn, const arg2_t& v) : m_pfn (pfn), m_Value(v) {}
199
    inline result_t operator()(arg1_t v1) const { return (m_pfn (v1, m_Value)); }
200
protected:
201
    BinaryFunction      m_pfn;
202
    arg2_t              m_Value;
203
};
204
 
205
/// Converts \p pfn into a unary function by binding the first argument to \p v.
206
/// \ingroup FunctorAccessors
207
template <typename BinaryFunction>
208
inline binder1st<BinaryFunction>
209
bind1st (BinaryFunction pfn, typename BinaryFunction::first_argument_type v)
210
{
211
    return (binder1st<BinaryFunction> (pfn, v));
212
}
213
 
214
/// Converts \p pfn into a unary function by binding the second argument to \p v.
215
/// \ingroup FunctorAccessors
216
template <typename BinaryFunction>
217
inline binder2nd<BinaryFunction>
218
bind2nd (BinaryFunction pfn, typename BinaryFunction::second_argument_type v)
219
{
220
    return (binder2nd<BinaryFunction> (pfn, v));
221
}
222
 
223
//----------------------------------------------------------------------
224
// Composition adapters
225
//----------------------------------------------------------------------
226
 
227
/// \brief Chains two unary functions together.
228
///
229
/// When f(x) and g(x) are composed, the result is function c(x)=f(g(x)).
230
/// Use the \ref compose1 accessor to create this object.
231
/// This template is an extension, implemented by SGI STL and uSTL.
232
/// \ingroup FunctorObjects
233
///
234
template <typename Operation1, typename Operation2>
235
class unary_compose : public unary_function<typename Operation2::argument_type,
236
                                            typename Operation1::result_type> {
237
public:
238
    typedef typename Operation2::argument_type  arg_t;
239
    typedef const arg_t&                        rcarg_t;
240
    typedef typename Operation1::result_type    result_t;
241
public:
242
    inline unary_compose (const Operation1& f, const Operation2& g) : m_f(f), m_g(g) {}
243
    inline result_t operator() (rcarg_t x) const { return m_f(m_g(x)); }
244
protected:
245
    Operation1  m_f;    ///< f(x), if c(x) = f(g(x))
246
    Operation2  m_g;    ///< g(x), if c(x) = f(g(x))
247
};
248
 
249
/// Creates a \ref unary_compose object whose function c(x)=f(g(x))
250
/// \ingroup FunctorAccessors
251
template <typename Operation1, typename Operation2>
252
inline unary_compose<Operation1, Operation2>
253
compose1 (const Operation1& f, const Operation2& g)
254
{ return unary_compose<Operation1,Operation2>(f, g); }
255
 
256
/// \brief Chains two unary functions through a binary function.
257
///
258
/// When f(x,y), g(x), and h(x) are composed, the result is function
259
/// c(x)=f(g(x),h(x)). Use the \ref compose2 accessor to create this
260
/// object. This template is an extension, implemented by SGI STL and uSTL.
261
/// \ingroup FunctorObjects
262
///
263
template <typename Operation1, typename Operation2, typename Operation3>
264
class binary_compose : public unary_function<typename Operation2::argument_type,
265
                                            typename Operation1::result_type> {
266
public:
267
    typedef typename Operation2::argument_type  arg_t;
268
    typedef const arg_t&                        rcarg_t;
269
    typedef typename Operation1::result_type    result_t;
270
public:
271
    inline binary_compose (const Operation1& f, const Operation2& g, const Operation3& h) : m_f(f), m_g(g), m_h(h) {}
272
    inline result_t operator() (rcarg_t x) const { return m_f(m_g(x), m_h(x)); }
273
protected:
274
    Operation1  m_f;    ///< f(x,y), if c(x) = f(g(x),h(x))
275
    Operation2  m_g;    ///< g(x), if c(x) = f(g(x),h(x))
276
    Operation3  m_h;    ///< h(x), if c(x) = f(g(x),h(x))
277
};
278
 
279
/// Creates a \ref binary_compose object whose function c(x)=f(g(x),h(x))
280
/// \ingroup FunctorAccessors
281
template <typename Operation1, typename Operation2, typename Operation3>
282
inline binary_compose<Operation1, Operation2, Operation3>
283
compose2 (const Operation1& f, const Operation2& g, const Operation3& h)
284
{ return binary_compose<Operation1, Operation2, Operation3> (f, g, h); }
285
 
286
//----------------------------------------------------------------------
287
// Member function adaptors
288
//----------------------------------------------------------------------
289
 
290
#ifndef DOXYGEN_SHOULD_SKIP_THIS
291
 
292
#define MEM_FUN_T(WrapperName, ClassName, ArgType, FuncType, CallType)                          \
293
    template <typename Ret, class T>                                                            \
294
    class ClassName : public unary_function<ArgType,Ret> {                                      \
295
    public:                                                                                     \
296
        typedef Ret (T::*func_t) FuncType;                                                      \
297
    public:                                                                                     \
298
        explicit inline ClassName (func_t pf) : m_pf (pf) {}                                    \
299
        inline Ret      operator() (ArgType p) const { return ((p CallType m_pf)()); }          \
300
    private:                                                                                    \
301
        func_t  m_pf;                                                                           \
302
    };  \
303
        \
304
    template <class Ret, typename T>            \
305
    inline ClassName<Ret,T> WrapperName (Ret (T::*pf) FuncType) \
306
    {                                           \
307
        return (ClassName<Ret,T> (pf));         \
308
    }
309
 
310
MEM_FUN_T(mem_fun,      mem_fun_t,              T*,             (void),         ->*)
311
MEM_FUN_T(mem_fun,      const_mem_fun_t,        const T*,       (void) const,   ->*)
312
MEM_FUN_T(mem_fun_ref,  mem_fun_ref_t,          T&,             (void),         .*)
313
MEM_FUN_T(mem_fun_ref,  const_mem_fun_ref_t,    const T&,       (void) const,   .*)
314
 
315
#define EXT_MEM_FUN_T(ClassName, HostType, FuncType) \
316
    template <class T, typename Ret, typename V> \
317
    class ClassName : public unary_function<V,void> { \
318
    public: \
319
        typedef Ret (T::*func_t)(V) FuncType; \
320
    public: \
321
        inline          ClassName (HostType t, func_t pf) : m_t (t), m_pf (pf) {} \
322
        inline Ret      operator() (V v) const { return ((m_t->*m_pf)(v)); } \
323
    private: \
324
        HostType        m_t; \
325
        func_t          m_pf; \
326
    };  \
327
        \
328
    template <class T, typename Ret, typename V>                                        \
329
    inline ClassName<T,Ret,V> mem_fun (HostType p, Ret (T::*pf)(V) FuncType)    \
330
    {                                                                                   \
331
        return (ClassName<T,Ret,V> (p, pf));                                            \
332
    }
333
 
334
EXT_MEM_FUN_T(ext_mem_fun_t,            T*,             )
335
EXT_MEM_FUN_T(const_ext_mem_fun_t,      const T*,       const)
336
 
337
#endif // DOXYGEN_SHOULD_SKIP_THIS
338
 
339
//----------------------------------------------------------------------
340
// Member variable adaptors (uSTL extension)
341
//----------------------------------------------------------------------
342
 
343
#ifndef DOXYGEN_SHOULD_SKIP_THIS
344
 
345
#define MEM_VAR_T(FunctorName, ArgType, VarType, BaseClass, CallImpl)                   \
346
    template <typename Function, class T, typename VT>                                  \
347
    class FunctorName##_t : public BaseClass {                                          \
348
    public:                                                                             \
349
        typedef ArgType                         argument_type;                          \
350
        typedef typename Function::result_type  result_type;                            \
351
        typedef VarType                         mem_var_ptr_t;                          \
352
    public:                                                                             \
353
        inline FunctorName##_t (mem_var_ptr_t pv, Function pfn) : m_pv(pv), m_pfn(pfn) {}       \
354
        inline result_type operator() CallImpl                                          \
355
    private:                                                                            \
356
        mem_var_ptr_t   m_pv;                                                           \
357
        Function        m_pfn;                                                          \
358
    };                                                                                  \
359
                                                                                        \
360
    template <typename Function, class T, typename VT>                                  \
361
    inline FunctorName##_t<Function, T, VT>                                             \
362
    FunctorName (VT T::*mvp, Function pfn)                                              \
363
    {                                                                                   \
364
        return (FunctorName##_t<Function,T,VT> (mvp, pfn));                             \
365
    }
366
 
367
#define FUNCTOR_UNARY_BASE(ArgType)     unary_function<ArgType, typename Function::result_type>
368
#define FUNCTOR_BINARY_BASE(ArgType)    binary_function<ArgType, ArgType, typename Function::result_type>
369
 
370
#define MEM_VAR_UNARY_ARGS              (argument_type p) const \
371
                                        { return (m_pfn(p.*m_pv)); }
372
#define MEM_VAR_BINARY_ARGS             (argument_type p1, argument_type p2) const \
373
                                        { return (m_pfn(p1.*m_pv, p2.*m_pv)); }
374
 
375
MEM_VAR_T(mem_var1,             T&, VT T::*,            FUNCTOR_UNARY_BASE(T&),  MEM_VAR_UNARY_ARGS)
376
MEM_VAR_T(const_mem_var1, const T&, const VT T::*,      FUNCTOR_UNARY_BASE(T&),  MEM_VAR_UNARY_ARGS)
377
MEM_VAR_T(mem_var2,             T&, VT T::*,            FUNCTOR_BINARY_BASE(T&), MEM_VAR_BINARY_ARGS)
378
MEM_VAR_T(const_mem_var2, const T&, const VT T::*,      FUNCTOR_BINARY_BASE(T&), MEM_VAR_BINARY_ARGS)
379
 
380
#undef MEM_VAR_UNARY_ARGS
381
#undef MEM_VAR_BINARY_ARGS
382
 
383
#endif // DOXYGEN_SHOULD_SKIP_THIS
384
 
385
/// Returned functor passes member variable \p mvp reference of given object to equal\<VT\>.
386
/// \ingroup FunctorAccessors
387
template <class T, typename VT>
388
inline const_mem_var1_t<binder2nd<equal_to<VT> >, T, VT>
389
mem_var_equal_to (const VT T::*mvp, const VT& v)
390
{
391
    return (const_mem_var1_t<binder2nd<equal_to<VT> >,T,VT> (mvp, bind2nd(equal_to<VT>(), v)));
392
}
393
 
394
/// Returned functor passes member variable \p mvp reference of given object to less\<VT\>.
395
/// \ingroup FunctorAccessors
396
template <class T, typename VT>
397
inline const_mem_var1_t<binder2nd<less<VT> >, T, VT>
398
mem_var_less (const VT T::*mvp, const VT& v)
399
{
400
    return (const_mem_var1_t<binder2nd<less<VT> >,T,VT> (mvp, bind2nd(less<VT>(), v)));
401
}
402
 
403
/// Returned functor passes member variable \p mvp reference of given object to equal\<VT\>.
404
/// \ingroup FunctorAccessors
405
template <class T, typename VT>
406
inline const_mem_var2_t<equal_to<VT>, T, VT>
407
mem_var_equal_to (const VT T::*mvp)
408
{
409
    return (const_mem_var2_t<equal_to<VT>,T,VT> (mvp, equal_to<VT>()));
410
}
411
 
412
/// Returned functor passes member variable \p mvp reference of given object to less\<VT\>.
413
/// \ingroup FunctorAccessors
414
template <class T, typename VT>
415
inline const_mem_var2_t<less<VT>, T, VT>
416
mem_var_less (const VT T::*mvp)
417
{
418
    return (const_mem_var2_t<less<VT>,T,VT> (mvp, less<VT>()));
419
}
420
 
421
//----------------------------------------------------------------------
422
// Dereference adaptors (uSTL extension)
423
//----------------------------------------------------------------------
424
 
425
#ifndef DOXYGEN_SHOULD_SKIP_THIS
426
 
427
#define DEREFERENCER_T(ClassName, ArgType, BaseClass, CallImpl, FunctorKey)     \
428
    template <typename T, typename Function>                                    \
429
    class ClassName : public BaseClass {                                        \
430
    public:                                                                     \
431
        typedef ArgType*                        argument_type;                  \
432
        typedef typename Function::result_type  result_type;                    \
433
    public:                                                                     \
434
        inline                  ClassName (Function pfn) : m_pfn (pfn) {}       \
435
        inline result_type      operator() CallImpl                             \
436
    private:                                                                    \
437
        Function                m_pfn;                                          \
438
    };                                                                          \
439
                                                                                \
440
    template <typename T, typename Function>                                    \
441
    inline ClassName<T,Function> _dereference (Function pfn, FunctorKey)        \
442
    {                                                                           \
443
        return (ClassName<T,Function> (pfn));                                   \
444
    }
445
 
446
#define DEREF_UNARY_ARGS                (argument_type p) const \
447
                                        { return (m_pfn(*p)); }
448
#define DEREF_BINARY_ARGS               (argument_type p1, argument_type p2) const \
449
                                        { return (m_pfn(*p1, *p2)); }
450
 
451
DEREFERENCER_T(deref1_t,        T,              FUNCTOR_UNARY_BASE(T*),         DEREF_UNARY_ARGS,       FUNCTOR_UNARY_BASE(T))
452
DEREFERENCER_T(const_deref1_t,  const T,        FUNCTOR_UNARY_BASE(const T*),   DEREF_UNARY_ARGS,       FUNCTOR_UNARY_BASE(const T))
453
DEREFERENCER_T(deref2_t,        T,              FUNCTOR_BINARY_BASE(T*),        DEREF_BINARY_ARGS,      FUNCTOR_BINARY_BASE(T))
454
DEREFERENCER_T(const_deref2_t,  const T,        FUNCTOR_BINARY_BASE(const T*),  DEREF_BINARY_ARGS,      FUNCTOR_BINARY_BASE(const T))
455
 
456
#define dereference(f) _dereference(f,f)
457
 
458
#undef DEREF_UNARY_ARGS
459
#undef DEREF_BINARY_ARGS
460
 
461
#endif
462
 
463
} // namespace ustl
464
 
465
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.