Home | History | Annotate | Download | only in unit
      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