111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/*
211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Copyright (C) 2010 The Android Open Source Project
311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Licensed under the Apache License, Version 2.0 (the "License");
511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * you may not use this file except in compliance with the License.
611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * You may obtain a copy of the License at
711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *      http://www.apache.org/licenses/LICENSE-2.0
911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * Unless required by applicable law or agreed to in writing, software
1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * distributed under the License is distributed on an "AS IS" BASIS,
1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * See the License for the specific language governing permissions and
1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert * limitations under the License.
1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <typeinfo>
1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <cstdio>
1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertusing namespace std;
2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass Foo
2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertpublic:
2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  virtual ~Foo() { }
2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  virtual void print()
2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::printf("in Foo!\n");
2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass Bar: public Foo
3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  public:
3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  void print()
3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::printf("in Bar!\n");
3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct Base {};
4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct Derived : Base {};
4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct Poly_Base {virtual void Member(){}};
4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstruct Poly_Derived: Poly_Base {};
4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define CHECK(cond)  \
4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    do { \
4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        if (!(cond)) { \
4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            fprintf(stderr, "KO: Assertion failure: %s\n", #cond); \
4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert            fail++;\
5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        }\
5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    } while (0)
5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertint main()
5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    int  fail = 0;
5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    Foo* foo = new Bar();
5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    Bar* bar;
5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // built-in types:
6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    int i;
6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    int * pi;
6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    CHECK(typeid(int) == typeid(i));
6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    CHECK(typeid(int*) == typeid(pi));
6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    CHECK(typeid(int) == typeid(*pi));
6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    printf("int is: %s\n", typeid(int).name());
6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    printf("  i is: %s\n", typeid(i).name());
6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    printf(" pi is: %s\n", typeid(pi).name());
7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    printf("*pi is: %s\n", typeid(*pi).name());
7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // non-polymorphic types:
7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    Derived derived;
7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    Base* pbase = &derived;
7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    CHECK(typeid(derived) == typeid(Derived));
7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    CHECK(typeid(pbase) == typeid(Base*));
7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    CHECK(typeid(&derived) == typeid(Derived*));
7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    printf("derived is: %s\n", typeid(derived).name());
8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    printf(" *pbase is: %s\n", typeid(*pbase).name());
8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // polymorphic types:
8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    Poly_Derived polyderived;
8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    Poly_Base* ppolybase = &polyderived;
8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    CHECK(typeid(polyderived) == typeid(Poly_Derived));
8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    CHECK(typeid(ppolybase) == typeid(Poly_Base*));
8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    CHECK(typeid(polyderived) == typeid(*ppolybase));
9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    printf("polyderived is: %s\n", typeid(polyderived).name());
9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    printf(" *ppolybase is: %s\n", typeid(*ppolybase).name());
9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    bar = dynamic_cast<Bar*>(foo);
9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (bar != NULL) {
9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        printf("OK: 'foo' is pointing to a Bar class instance.\n");
9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    } else {
9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        fprintf(stderr, "KO: Could not dynamically cast 'foo' to a 'Bar*'\n");
9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        fail++;
10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    delete foo;
10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return (fail > 0);
10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
106