#include #include #include #include #include #include #include #include struct A { virtual int MemberFn() { return 0;} virtual ~A() {} }; struct AB : A {}; struct AC : A {}; struct AD : A {}; struct ACD : AC {}; struct ABE : AB {}; template< class T, int N> struct array /* Simple fixed-size STL-style container. */ { inline explicit array( unsigned int i) { assert( i==N); i=i; } inline explicit array() {} inline T& operator [] ( unsigned int i) { return this->m_items[i]; } inline const T& operator [] ( unsigned int i) const { return this->m_items[i]; } inline unsigned int size() const { return N; } private: T m_items[N]; }; template< class T, int N> bool operator < ( const array< T, N>& lhs, const array< T, N>& rhs) { for ( unsigned int i=0; i struct vmap /* Simple associative map, for use with key types that look like arrays with operator[] - see the static cmp() function. Underlying implementation is a sorted std::vector. */ { typedef Key key_type; typedef Value mapped_type; typedef std::pair< key_type, mapped_type> value_type; vmap() : m_cached( -1) {} static inline int cmp( const Key& lhs, const Key& rhs) /* Better than operator< or std::less, because equality doesn't require 2 comparisons (???). */ { unsigned int n = lhs.size(); assert( n==rhs.size()); for ( unsigned int i=0; i0) min = i+1; else { m_cached = i; return m_items[i].second; } } } private: std::vector< value_type> m_items; // this is always sorted. int m_cached; }; int Fn1( virtual A& a); //void Fn2( virtual A& a1, virtual A& a2); int Fn1_( static A&) { return 0; } int Fn1_( static AB&) { return 0; } int Fn1_( static AC&) { return 0; } int Fn1_( static AD&) { return 0; } int Fn1_( static ACD&) { return 0; } int Fn1_( static ABE&) { return 0; } int Fn2_( A&, A&) { return 0; } int Fn1_cmm_implcall1_2_3_A3_AB( A&) { return 0; } int Blank( A& a) { //Fn1_cmm_implcall_cmm_param_cmm_classA_cmm_classAB( a); static const std::type_info* cache = &typeid( AB); if ( &typeid( a) == cache) return Fn1_cmm_implcall1_2_3_A3_AB( a); return 0; } int main( int argc, char** argv) { try { if ( argc!=2) { std::cerr << "expecting one parameter\n"; return 1; } fprintf( stderr, "%-25s", argv[1]); /* using fprintf instead of iostreams, because gcc 2.95 has limited support for std manipulators. */ A& ab = *new AB; A& ac = *new AC; A& ad = *new AD; A& acd = *new ACD; A& abe = *new ABE; (void) ab; (void) ac; (void) ad; (void) acd; (void) abe; double t_virtmethod, t_virtfn, t_method; int its = 2*1000*1000; // fill up cmm's internal dispatch caches a bit: Fn1( ab); Fn1( ac); Fn1( ad); Fn1( acd); Fn1( abe); { clock_t t=clock(); for ( int i=0; i