1 |
/* |
2 |
* nvmemfun.hpp - Non-virtual member function wrappers |
3 |
* |
4 |
* Kheperix (C) 2003 Gwenole Beauchesne |
5 |
* |
6 |
* This program is free software; you can redistribute it and/or modify |
7 |
* it under the terms of the GNU General Public License as published by |
8 |
* the Free Software Foundation; either version 2 of the License, or |
9 |
* (at your option) any later version. |
10 |
* |
11 |
* This program is distributed in the hope that it will be useful, |
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 |
* GNU General Public License for more details. |
15 |
* |
16 |
* You should have received a copy of the GNU General Public License |
17 |
* along with this program; if not, write to the Free Software |
18 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 |
*/ |
20 |
|
21 |
#ifndef NVMEMFUN_H |
22 |
#define NVMEMFUN_H |
23 |
|
24 |
#include <functional> |
25 |
|
26 |
#if defined __GNUC__ |
27 |
#define HAVE_FAST_NV_MEM_FUN 1 |
28 |
#define MEM_FUN_WORDS 2 |
29 |
#if defined __GXX_ABI_VERSION /* GCC >= 3.0 */ |
30 |
#define MEM_FUN_OFFSET 0 |
31 |
#else |
32 |
#define MEM_FUN_OFFSET 1 |
33 |
#endif |
34 |
#endif |
35 |
|
36 |
#if defined __ICC |
37 |
#define HAVE_FAST_NV_MEM_FUN 1 |
38 |
#define MEM_FUN_WORDS 2 |
39 |
#define MEM_FUN_OFFSET 0 /* GNU C++ ABI v3 */ |
40 |
#endif |
41 |
|
42 |
#if defined __EDG__ && defined __sgi |
43 |
#define HAVE_FAST_NV_MEM_FUN 1 |
44 |
#define MEM_FUN_WORDS 3 |
45 |
#define MEM_FUN_OFFSET 2 |
46 |
#endif |
47 |
|
48 |
#if HAVE_FAST_NV_MEM_FUN |
49 |
|
50 |
template< class PMF, class PF > |
51 |
inline PF nv_mem_fun_of(PMF pmf) { |
52 |
if (pmf == 0) |
53 |
return 0; |
54 |
union { PMF pmf; uintptr p[MEM_FUN_WORDS]; } x; |
55 |
x.pmf = pmf; |
56 |
return (PF)x.p[MEM_FUN_OFFSET]; |
57 |
} |
58 |
|
59 |
template< class R, class T > |
60 |
class nv_mem_fun_t : public std::unary_function<T, R> { |
61 |
typedef R (T::*pmf_t)(); |
62 |
typedef R (*pf_t)(T *); |
63 |
pf_t pf; |
64 |
public: |
65 |
nv_mem_fun_t(pmf_t pmf) : pf(nv_mem_fun_of<pmf_t, pf_t>(pmf)) {} |
66 |
R operator()(T *p) const { return (*pf)(p); } |
67 |
pf_t ptr() const { return pf; } |
68 |
}; |
69 |
|
70 |
template< class R, class T > |
71 |
class const_nv_mem_fun_t : public std::unary_function<T, R> { |
72 |
typedef R (T::*pmf_t)(); |
73 |
typedef R (*pf_t)(T *); |
74 |
pf_t const pf; |
75 |
public: |
76 |
const_nv_mem_fun_t(pmf_t const pmf) : pf(nv_mem_fun_of<pmf_t, pf_t>(pmf)) {} |
77 |
R operator()(const T *p) const { return (*pf)(p); } |
78 |
pf_t ptr() const { return pf; } |
79 |
}; |
80 |
|
81 |
template< class R, class T, class A > |
82 |
class nv_mem_fun1_t : public std::binary_function<T, A, R> { |
83 |
typedef R (T::*pmf_t)(A); |
84 |
typedef R (*pf_t)(T *, A x); |
85 |
pf_t pf; |
86 |
public: |
87 |
nv_mem_fun1_t(pmf_t pmf) : pf(nv_mem_fun_of<pmf_t, pf_t>(pmf)) {} |
88 |
R operator()(T *p, A x) const { return (*pf)(p, x); } |
89 |
pf_t ptr() const { return pf; } |
90 |
}; |
91 |
|
92 |
template< class R, class T, class A > |
93 |
class const_nv_mem_fun1_t : public std::binary_function<T, A, R> { |
94 |
typedef R (T::*pmf_t)(A); |
95 |
typedef R (*pf_t)(T *, A x); |
96 |
pf_t const pf; |
97 |
public: |
98 |
const_nv_mem_fun1_t(pmf_t const pmf) : pf(nv_mem_fun_of<pmf_t, pf_t>(pmf)) {} |
99 |
R operator()(const T *p, A x) const { return (*pf)(p, x); } |
100 |
pf_t ptr() const { return pf; } |
101 |
}; |
102 |
|
103 |
#else |
104 |
|
105 |
template< class R, class T > |
106 |
class nv_mem_fun_t : public std::unary_function<T, R> { |
107 |
typedef R (T::*pmf_t)(); |
108 |
pmf_t pf; |
109 |
public: |
110 |
nv_mem_fun_t(R (T::*pmf)()) : pf(pmf) {} |
111 |
R operator()(T *p) const { return (p->*pf)(); } |
112 |
pmf_t ptr() const { return pf; } |
113 |
}; |
114 |
|
115 |
template< class R, class T > |
116 |
class const_nv_mem_fun_t : public std::unary_function<T, R> { |
117 |
typedef R (T::*pmf_t)() const; |
118 |
pmf_t pf; |
119 |
public: |
120 |
const_nv_mem_fun_t(R (T::*pmf)() const) : pf(pmf) {} |
121 |
R operator()(const T *p) const { return (p->*pf)(); } |
122 |
pmf_t ptr() const { return pf; } |
123 |
}; |
124 |
|
125 |
template< class R, class T, class A > |
126 |
class nv_mem_fun1_t : public std::binary_function<T, A, R> { |
127 |
typedef R (T::*pmf_t)(A); |
128 |
pmf_t pf; |
129 |
public: |
130 |
nv_mem_fun1_t(R (T::*pmf)(A)) : pf(pmf) {} |
131 |
R operator()(T *p, A x) const { return (p->*pf)(x); } |
132 |
pmf_t ptr() const { return pf; } |
133 |
}; |
134 |
|
135 |
template< class R, class T, class A > |
136 |
class const_nv_mem_fun1_t : public std::binary_function<T, A, R> { |
137 |
typedef R (T::*pmf_t)(A) const; |
138 |
pmf_t pf; |
139 |
public: |
140 |
const_nv_mem_fun1_t(R (T::*pmf)(A) const) : pf(pmf) {} |
141 |
R operator()(const T *p, A x) const { return (p->*pf)(x); } |
142 |
pmf_t ptr() const { return pf; } |
143 |
}; |
144 |
|
145 |
#endif |
146 |
|
147 |
template< class R, class T > |
148 |
inline nv_mem_fun_t<R, T> nv_mem_fun(R (T::*pmf)()) { |
149 |
return nv_mem_fun_t<R, T>(pmf); |
150 |
} |
151 |
|
152 |
template< class R, class T > |
153 |
inline const_nv_mem_fun_t<R, T> nv_mem_fun(R (T::*pmf)() const) { |
154 |
return const_nv_mem_fun_t<R, T>(pmf); |
155 |
} |
156 |
|
157 |
template< class R, class T, class A > |
158 |
inline nv_mem_fun1_t<R, T, A> nv_mem_fun(R (T::*pmf)(A)) { |
159 |
return nv_mem_fun1_t<R, T, A>(pmf); |
160 |
} |
161 |
|
162 |
template< class R, class T, class A > |
163 |
inline const_nv_mem_fun1_t<R, T, A> nv_mem_fun(R (T::*pmf)(A) const) { |
164 |
return const_nv_mem_fun1_t<R, T, A>(pmf); |
165 |
} |
166 |
|
167 |
#endif /* NVMEMFUN_H */ |