1 #include <functional> 2 #include <memory> 3 #include <vector> 4 #include <algorithm> 5 6 #include "cppunit/cppunit_proxy.h" 7 8 #if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) 9 using namespace std; 10 #endif 11 12 // 13 // TestCase class 14 // 15 class MemFunPtrTest : public CPPUNIT_NS::TestCase 16 { 17 CPPUNIT_TEST_SUITE(MemFunPtrTest); 18 CPPUNIT_TEST(mem_ptr_fun); 19 #if defined (STLPORT) && !defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) 20 //This test require partial template specialization feature to avoid the 21 //reference to reference problem. No workaround yet for limited compilers. 22 CPPUNIT_IGNORE; 23 #endif 24 CPPUNIT_TEST(find); 25 CPPUNIT_TEST_SUITE_END(); 26 27 protected: 28 // compile test not neccessary to run but... 29 void mem_ptr_fun(); 30 void find(); 31 }; 32 33 CPPUNIT_TEST_SUITE_REGISTRATION(MemFunPtrTest); 34 35 #if defined(_STLP_DONT_RETURN_VOID) && (defined(_STLP_NO_MEMBER_TEMPLATE_CLASSES) && defined(_STLP_NO_CLASS_PARTIAL_SPECIALIZATION)) 36 # define _STLP_DONT_TEST_RETURN_VOID 37 #endif 38 //else there is no workaround for the return void bug 39 40 struct S1 { } s1; 41 struct S2 { } s2; 42 43 int f1(S1&); 44 int f2(S1&, S2&); 45 int f1c(const S1&); 46 int f2c(const S1&, const S2&); 47 48 void vf1(S1&); 49 void vf2(S1&, S2&); 50 void vf1c(const S1&); 51 void vf2c(const S1&, const S2&); 52 53 class Class { 54 public: 55 int f0(); 56 int f1(const S1&); 57 58 void vf0(); 59 void vf1(const S1&); 60 61 int f0c() const; 62 int f1c(const S1&) const; 63 64 void vf0c() const; 65 void vf1c(const S1&) const; 66 }; 67 68 // 69 // tests implementation 70 // 71 void MemFunPtrTest::mem_ptr_fun() 72 { 73 Class obj; 74 const Class& objc = obj; 75 76 // ptr_fun 77 78 ptr_fun(f1)(s1); 79 ptr_fun(f2)(s1, s2); 80 81 ptr_fun(f1c)(s1); 82 ptr_fun(f2c)(s1, s2); 83 84 #ifndef _STLP_DONT_TEST_RETURN_VOID 85 ptr_fun(vf1)(s1); 86 ptr_fun(vf2)(s1, s2); 87 88 ptr_fun(vf1c)(s1); 89 ptr_fun(vf2c)(s1, s2); 90 #endif /* _STLP_DONT_TEST_RETURN_VOID */ 91 92 // mem_fun 93 94 mem_fun(&Class::f0)(&obj); 95 mem_fun(&Class::f1)(&obj, s1); 96 97 #ifndef _STLP_DONT_TEST_RETURN_VOID 98 mem_fun(&Class::vf0)(&obj); 99 mem_fun(&Class::vf1)(&obj, s1); 100 #endif /* _STLP_DONT_TEST_RETURN_VOID */ 101 102 // mem_fun (const) 103 104 mem_fun(&Class::f0c)(&objc); 105 mem_fun(&Class::f1c)(&objc, s1); 106 107 #ifndef _STLP_DONT_TEST_RETURN_VOID 108 mem_fun(&Class::vf0c)(&objc); 109 mem_fun(&Class::vf1c)(&objc, s1); 110 #endif /* _STLP_DONT_TEST_RETURN_VOID */ 111 112 // mem_fun_ref 113 114 mem_fun_ref(&Class::f0)(obj); 115 mem_fun_ref(&Class::f1)(obj, s1); 116 117 #ifndef _STLP_DONT_TEST_RETURN_VOID 118 mem_fun_ref(&Class::vf0)(obj); 119 mem_fun_ref(&Class::vf1)(obj, s1); 120 #endif /* _STLP_DONT_TEST_RETURN_VOID */ 121 122 // mem_fun_ref (const) 123 mem_fun_ref(&Class::f0c)(objc); 124 mem_fun_ref(&Class::f1c)(objc, s1); 125 126 #ifndef _STLP_DONT_TEST_RETURN_VOID 127 mem_fun_ref(&Class::vf0c)(objc); 128 mem_fun_ref(&Class::vf1c)(objc, s1); 129 #endif /* _STLP_DONT_TEST_RETURN_VOID */ 130 } 131 int f1(S1&) 132 {return 1;} 133 134 int f2(S1&, S2&) 135 {return 2;} 136 137 int f1c(const S1&) 138 {return 1;} 139 140 int f2c(const S1&, const S2&) 141 {return 2;} 142 143 void vf1(S1&) 144 {} 145 146 void vf2(S1&, S2&) 147 {} 148 149 void vf1c(const S1&) 150 {} 151 152 void vf2c(const S1&, const S2&) 153 {} 154 155 int Class::f0() 156 {return 0;} 157 158 int Class::f1(const S1&) 159 {return 1;} 160 161 void Class::vf0() 162 {} 163 164 void Class::vf1(const S1&) 165 {} 166 167 int Class::f0c() const 168 {return 0;} 169 170 int Class::f1c(const S1&) const 171 {return 1;} 172 173 void Class::vf0c() const 174 {} 175 176 void Class::vf1c(const S1&) const 177 {} 178 179 struct V { 180 public: 181 V(int _v) : 182 v(_v) 183 { } 184 185 bool f( int _v ) const { return (v == _v); } 186 187 int v; 188 #if defined (__DMC__) 189 V(){} 190 #endif 191 }; 192 193 void MemFunPtrTest::find() 194 { 195 #if !defined (STLPORT) || defined (_STLP_CLASS_PARTIAL_SPECIALIZATION) 196 vector<V> v; 197 198 v.push_back( V(1) ); 199 v.push_back( V(2) ); 200 v.push_back( V(3) ); 201 202 // step-by-step complication of work for compiler: 203 204 // step 1: 205 const_mem_fun1_ref_t<bool,V,int> pmf = mem_fun_ref( &V::f ); 206 binder2nd<const_mem_fun1_ref_t<bool,V,int> > b(pmf, 2); 207 vector<V>::iterator i = find_if( v.begin(), v.end(), b ); 208 CPPUNIT_ASSERT(i != v.end()); 209 CPPUNIT_ASSERT(i->v == 2); 210 211 // step 2, just check that compiler understand what pass to bind2nd: 212 binder2nd<const_mem_fun1_ref_t<bool,V,int> > b2 = bind2nd( pmf, 2 ); 213 214 // step 3, the same as step 1, but more intellect from compiler required: 215 binder2nd<const_mem_fun1_ref_t<bool,V,int> > b3 = bind2nd( mem_fun_ref( &V::f ), 2 ); 216 217 vector<V>::iterator j = find_if( v.begin(), v.end(), b3 ); 218 CPPUNIT_ASSERT(j != v.end()); 219 CPPUNIT_ASSERT(j->v == 2); 220 221 // step 4, more brief, more complex: 222 vector<V>::iterator k = find_if( v.begin(), v.end(), bind2nd( mem_fun_ref( &V::f ), 2 ) ); 223 CPPUNIT_ASSERT(k != v.end()); 224 CPPUNIT_ASSERT(k->v == 2); 225 #endif 226 } 227 228 #ifdef _STLP_DONT_TEST_RETURN_VOID 229 # undef _STLP_DONT_TEST_RETURN_VOID 230 #endif 231