Home | History | Annotate | Download | only in test
      1 //===------------------------- dynamic_cast_stress.cpp --------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 // UNSUPPORTED: c++98, c++03
     11 
     12 #include <cassert>
     13 #include <tuple>
     14 #include "support/timer.hpp"
     15 
     16 template <std::size_t Indx, std::size_t Depth>
     17 struct C
     18     : public virtual C<Indx, Depth-1>,
     19       public virtual C<Indx+1, Depth-1>
     20 {
     21     virtual ~C() {}
     22 };
     23 
     24 template <std::size_t Indx>
     25 struct C<Indx, 0>
     26 {
     27     virtual ~C() {}
     28 };
     29 
     30 template <std::size_t Indx, std::size_t Depth>
     31 struct B
     32     : public virtual C<Indx, Depth-1>,
     33       public virtual C<Indx+1, Depth-1>
     34 {
     35 };
     36 
     37 template <class Indx, std::size_t Depth>
     38 struct makeB;
     39 
     40 template <std::size_t ...Indx, std::size_t Depth>
     41 struct makeB<std::__tuple_indices<Indx...>, Depth>
     42     : public B<Indx, Depth>...
     43 {
     44 };
     45 
     46 template <std::size_t Width, std::size_t Depth>
     47 struct A
     48     : public makeB<typename std::__make_tuple_indices<Width>::type, Depth>
     49 {
     50 };
     51 
     52 void test()
     53 {
     54     const std::size_t Width = 10;
     55     const std::size_t Depth = 5;
     56     A<Width, Depth> a;
     57     typedef B<Width/2, Depth> Destination;
     58 //    typedef A<Width, Depth> Destination;
     59     Destination *b = nullptr;
     60     {
     61         timer t;
     62         b = dynamic_cast<Destination*>((C<Width/2, 0>*)&a);
     63     }
     64     assert(b != 0);
     65 }
     66 
     67 int main()
     68 {
     69     test();
     70 }
     71 
     72 /*
     73 Timing results I'm seeing (median of 3 microseconds):
     74 
     75                           libc++abi    gcc's dynamic_cast
     76 B<Width/2, Depth> -O3      48.334         93.190           libc++abi 93% faster
     77 B<Width/2, Depth> -Os      58.535         94.103           libc++abi 61% faster
     78 A<Width, Depth>   -O3      11.515         33.134           libc++abi 188% faster
     79 A<Width, Depth>   -Os      12.631         31.553           libc++abi 150% faster
     80 
     81 */
     82