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) 9using namespace std; 10#endif 11 12// 13// TestCase class 14// 15class 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 27protected: 28 // compile test not neccessary to run but... 29 void mem_ptr_fun(); 30 void find(); 31}; 32 33CPPUNIT_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 40struct S1 { } s1; 41struct S2 { } s2; 42 43int f1(S1&); 44int f2(S1&, S2&); 45int f1c(const S1&); 46int f2c(const S1&, const S2&); 47 48void vf1(S1&); 49void vf2(S1&, S2&); 50void vf1c(const S1&); 51void vf2c(const S1&, const S2&); 52 53class Class { 54public: 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// 71void 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} 131int f1(S1&) 132{return 1;} 133 134int f2(S1&, S2&) 135{return 2;} 136 137int f1c(const S1&) 138{return 1;} 139 140int f2c(const S1&, const S2&) 141{return 2;} 142 143void vf1(S1&) 144{} 145 146void vf2(S1&, S2&) 147{} 148 149void vf1c(const S1&) 150{} 151 152void vf2c(const S1&, const S2&) 153{} 154 155int Class::f0() 156{return 0;} 157 158int Class::f1(const S1&) 159{return 1;} 160 161void Class::vf0() 162{} 163 164void Class::vf1(const S1&) 165{} 166 167int Class::f0c() const 168{return 0;} 169 170int Class::f1c(const S1&) const 171{return 1;} 172 173void Class::vf0c() const 174{} 175 176void Class::vf1c(const S1&) const 177{} 178 179struct 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 193void 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