
/* 1. A standard covnersion sequence is better than a user-defined sequence
      which is better than an elipses conversion sequence.  */

class A{};
class B: public A {public: operator int (){ return 1;}};

// standard vs user-defined
int foo0  (int) { return 10; }
int foo1  (int) { return 11; } // B -> int   : user defined
int foo1  (A)   { return 12; } // B -> A     : standard
int test1 () {
  B b;
  return foo1(b); // 12
}

// user-defined vs ellipsis
int foo2 (int) { return 13;} // B -> int   : user defined
int foo2 (...) { return 14;} // B -> ...   : ellipsis
int test2(){
  B b;
  return foo2(b); // 13
}

/* 2. Standard Conversion squence S1 is better than standard Conversion
      S2 if:  */

//      - S1 has a better rank than S2
//        see overload.exp for more comprehensive testing of this.
int foo3 (double) { return 21; } // float->double is 'promotion rank'
int foo3 (int)    { return 22; } // float->int is 'conversion rank'
int test3(){
  return foo3 (1.0f); // 21
}

//      - S1 and S2 are both 'qualification conversions' but S1 cv-qualification
//        is a subset of S2 cv-qualification.
int foo4 (const volatile int*) { return 23; }
int foo4 (      volatile int*) { return 24; }
int test4 () {
  volatile int a = 5;
  return foo4(&a); // 24
}

//      - S1 and S2 have the same rank but:
//        - S2 is a conversion of pointer or memeber-pointer to bool
int foo5 (bool)  { return 25; }
int foo5 (void*) { return 26; }
int test5 () {
  char *a;
  return foo5(a); // 26
}

//        - Class B publicly extends class A and S1 is a conversion of
//          B* to A* and S2 is a conversion B* to void*
int foo6 (void*) { return 27; }
int foo6 (A*)    { return 28; }
int test6 () {
  B *bp;
  return foo6(bp); // 28
}

//        - Class C publicly extends Class B which publicly extends
//          class A and S1 is a conversion of C* to B* and S2 is a
//          conversion C* to A*.
class C: public B {};
int foo7 (A*)    { return 29; }
int foo7 (B*) { return 210; }
int test7 () {
  C *cp;
  return foo7(cp); // 210
}

//        - Same as above but for references.
int foo8 (A&) { return 211; }
int foo8 (B&) { return 212; }
int test8 () {
  C c;
  return foo8(c); // 212
}

//        - Same as above but passing by copy.
int foo9 (A) { return 213; }
int foo9 (B) { return 214; }
int test9 () {
  C c;
  return foo9(c); // 212
}

//        - S1 is a conversion of A::* to B::* and S2 is a conversion of
//          A::* to C::8.
int foo10 (void (C::*)()) { return 215; }
int foo10 (void (B::*)()) { return 216; }
int test10 () {
  void (A::*amp)();
  return foo10(amp); // 216
}

//      - S1 is a subsequence of S2
int foo101 (volatile const char*) { return 217; } // array-to-pointer conversion
                                                 // plus qualification conversion
int foo101 (         const char*) { return 218; } // array-to-pointer conversion

int test101 () {
  return foo101("abc"); // 216
}

/* 3. User defined conversion U1 is better than user defined Conversion U2,
      if U1 and U2 are using the same conversion function but U1 has a better
      second standard conversion sequence than U2.  */
class D {public: operator short(){ return 0;}};
int foo11 (float) { return 31; }
int foo11 (int)   { return 32; }
int test11 () {
  D d;
  return foo11(d); // 32
}

/* 4. Function Level Ranking.
      All else being equal some functions are preferred by overload resolution.
      Function F1 is better than function F2 if: */
//    - F1 is a non-template function and F2 is a template function
template<class T> int foo12(T)   { return 41; }
                  int foo12(int) { return 42; }
int test12 (){
  return foo12(1); //42
}

//    - F1 is a more specialized template instance
template<class T> int foo13(T)  { return 43; }
template<class T> int foo13(T*) { return 44; }
int test13 (){
  char *c;
  return foo13(c); // 44
}

//    - The context is user defined conversion and F1 has
//      a better return type than F2
class E {
  public:
    operator double () {return 45; }
    operator int    () {return 46; }
};
int foo14 (int a) {return a;}
int test14 (){
  E e;
  return foo14(e); // 46
}

int main() {
  B b;
  foo0(b);
  foo1(b);
  test1();

  foo2(b);
  test2();

  foo3(1.0f);
  test3();

  volatile int a;
  foo4(&a);
  test4();

  char *c;
  foo5(c);
  test5();

  B *bp;
  foo6(bp);
  test6();

  C *cp;
  foo7(cp);
  test7();

  C co;
  foo8(co);
  test8();

  foo9(co);
  test9();

  void (A::*amp)();
  foo10(amp);
  test10();

  foo101("abc");
  test101();

  D d;
  foo11(d);
  test11();

  foo12(1);
  test12();

  foo13(c);
  test13();

  E e;
  foo14(e);
  test14();

  return 0; // end of main
}
