blob: 5d3c341fc93ef9ecb98376393eb096c4eaf095be [file] [log] [blame]
Howard Hinnanta39c1042012-01-13 01:22:31 +00001//===------------------------- 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#include <cassert>
11#include <tuple>
12#include <chrono>
13#include <iostream>
14
15template <std::size_t Indx, std::size_t Depth>
16struct C
17 : public virtual C<Indx, Depth-1>,
18 public virtual C<Indx+1, Depth-1>
19{
20 virtual ~C() {}
21};
22
23template <std::size_t Indx>
24struct C<Indx, 0>
25{
26 virtual ~C() {}
27};
28
29template <std::size_t Indx, std::size_t Depth>
30struct B
31 : public virtual C<Indx, Depth-1>,
32 public virtual C<Indx+1, Depth-1>
33{
34};
35
36template <class Indx, std::size_t Depth>
37struct makeB;
38
39template <std::size_t ...Indx, std::size_t Depth>
40struct makeB<std::__tuple_indices<Indx...>, Depth>
41 : public B<Indx, Depth>...
42{
43};
44
45template <std::size_t Width, std::size_t Depth>
46struct A
47 : public makeB<typename std::__make_tuple_indices<Width>::type, Depth>
48{
49};
50
51void test()
52{
53 typedef std::chrono::high_resolution_clock Clock;
54 typedef std::chrono::duration<double, std::micro> US;
55 const std::size_t Width = 20;
56 const std::size_t Depth = 7;
57 A<Width, Depth> a;
58 typedef B<Width/2, Depth> Destination;
59// typedef A<Width, Depth> Destination;
60 auto t0 = Clock::now();
61 Destination* b = dynamic_cast<Destination*>((C<Width/2, 0>*)&a);
62 auto t1 = Clock::now();
63 std::cout << US(t1-t0).count() << " microseconds\n";
64 assert(b != 0);
65}
66
67int main()
68{
69 test();
70}
71
72/*
73Timing results I'm seeing (median of 3 microseconds):
74
75 libc++abi gcc's dynamic_cast
76B<Width/2, Depth> -O3 64.214 93.190 libc++abi 45% faster
77B<Width/2, Depth> -Os 79.520 94.103 libc++abi 18% faster
78A<Width, Depth> -O3 11.833 33.134 libc++abi 180% faster
79A<Width, Depth> -Os 14.663 31.553 libc++abi 115% faster
80
81*/