Tuesday, February 13, 2007

addressof


The address of an object can be retrieved without using the address-of operator with the following function template:

template<typename T>

T * addressof(T & v)

{

  return reinterpret_cast<T*>( &const_cast<char&>( reinterpret_cast<const volatile char &>( v ) ) );

}





Wednesday, February 07, 2007

Boost Interface Library, a variant for COM interface

Intrusive variant of BIL(http://www.kangaroologic.com/interfaces/)'s technique to implement COM interface. Unlikely virtual function calls in a normal COM object using AB, function calls in the COM object of this template version are potentially inlineable thus a certain degree of improved performance is expected at an expense of code bloat as usual in C++ template. (Disclaimer! This is an experimental code snippet.)

- main.cpp -

#include <iostream>

#include <cassert>

// #include <vld.h>

 

#include "Unknown2.hpp"

 

IID const IID_IFoo = { 0xe37b25e4, 0xddf9, 0x4624, { 0x9d, 0xa4, 0xa3, 0x91, 0x2e, 0x99, 0x83, 0x48 } };

IID const IID_IBar = { 0x040b23c2, 0x8790, 0x419e, { 0xa4, 0xe4, 0x9d, 0x6d, 0xdd, 0xa7, 0x4d, 0x39 } };

 

// --------------------------------------------------------------------------------

 

class FooBar

  : private Interface<IBar, FooBar>

  , private Interface<IFoo, FooBar>

{

private:

  long volatile m_cRef;

 

public:

  FooBar()

    : m_cRef( 0 )

  {

  }

 

  // IUnknown2

  STDMETHODIMP QueryInterface(REFIID iid, void ** ppvObject)

  {

    if(0 == ppvObject)

      return E_POINTER;

 

    if(IID_IUnknown == iid)

      *ppvObject = Interface<IFoo, FooBar>::get_pointer();

    else if(IID_IFoo == iid)

      *ppvObject = Interface<IFoo, FooBar>::get_pointer();

    else if(IID_IBar == iid)

      *ppvObject = Interface<IBar, FooBar>::get_pointer();

    else

    {

      *ppvObject = 0;

      return E_NOINTERFACE;

    }

 

    reinterpret_cast<IUnknown2 *>( *ppvObject )->AddRef();

    return S_OK;

  }

  STDMETHODIMP_(ULONG) AddRef()

  {

    return ++m_cRef;

  }

  STDMETHODIMP_(ULONG) Release()

  {

    LONG res =  --m_cRef;

    if(0 == res)

      delete this;

    return res;

  }

 

  // IFoo

  void foofun(int) { std::cout << "void foofun(int)" << std::endl; }

  void __stdcall foofun2(int, long) { std::cout << "void foofun2(int, long)" << std::endl; }

 

  // IBar

  void barfun(int) { std::cout << "void barfun(int)" << std::endl; }

 

};

 

 

// --------------------------------------------------------------------------------

 

int main(int argc, char *argv[])

{

  FooBar * pfb = new FooBar;

  assert( 12 == sizeof( FooBar ) );  // 4 bytes per interface

 

  IUnknown2 * punk = 0;

  assert( SUCCEEDED( pfb->QueryInterface( IID_IUnknownreinterpret_cast<void **>( &punk ) ) ) );

 

  IFoo * pfoo = 0;

  assert( SUCCEEDED( punk->QueryInterface( IID_IFoo,    reinterpret_cast<void **>( &pfoo ) ) ) );

  punk->Release();

 

  pfoo->foofun(1);

  pfoo->foofun2(1, 2);

 

  IBar * pbar = 0;

  assert( SUCCEEDED( pfoo->QueryInterface( IID_IBar,    reinterpret_cast<void **>( &pbar ) ) ) );

  pfoo->Release();

 

  pbar->barfun(2);

  assert( SUCCEEDED( pbar->QueryInterface( IID_IUnknown, reinterpret_cast<void **>( &punk ) ) ) );

  pbar->Release();

 

  // QueryInterface is Symmetric

  assert( SUCCEEDED( punk->QueryInterface( IID_IFoo,    reinterpret_cast<void **>( &pfoo ) ) ) );

  assert( SUCCEEDED( pfoo->QueryInterface( IID_IUnknown, reinterpret_cast<void **>( &punk ) ) ) );

  pfoo->Release();

  punk->Release();

 

  // QueryInterface is Transitive

  assert( SUCCEEDED( punk->QueryInterface( IID_IFoo,    reinterpret_cast<void **>( &pfoo ) ) ) );

  assert( SUCCEEDED( pfoo->QueryInterface( IID_IBar,    reinterpret_cast<void **>( &pbar ) ) ) );

  assert( SUCCEEDED( pbar->QueryInterface( IID_IUnknown, reinterpret_cast<void **>( &punk ) ) ) );

  pfoo->Release();

  pbar->Release();

  punk->Release();

 

  // QueryInterface is Reflexive

  assert( SUCCEEDED( punk->QueryInterface( IID_IUnknown, reinterpret_cast<void **>( &punk ) ) ) );

  punk->Release();

  assert( SUCCEEDED( pfoo->QueryInterface( IID_IFoo,    reinterpret_cast<void **>( &pfoo ) ) ) );

  pfoo->Release();

  assert( SUCCEEDED( pbar->QueryInterface( IID_IBar,    reinterpret_cast<void **>( &pbar ) ) ) );

  pbar->Release();

 

 

  punk->Release();

 

  // --------------------------------------------------------------------------------

 

  system("PAUSE");

  return EXIT_SUCCESS;

}

- unknown2.hpp -

#if !defined(__UNKNOWN2_HPP__INCLUDED__)

#define __UNKNOWN2_HPP__INCLUDED__

 

#include <windows.h>

 

// --------------------------------------------------------------------------------

 

template<typename T> struct apply { typedef T type; };

 

// --------------------------------------------------------------------------------

 

template<typename TIface, typename T>

class Interface : protected TIface

{

protected:

  Interface() : TIface( apply<T>() ) { }

 

public:

  TIface * get_pointer() const

  {

    // Adjust void pointer as a pointer of Interface type first

    // then adjust the resultant as a pointer of TIface type again.

    return const_cast<TIface *>( static_cast<TIface const *>( static_cast<Interface const *>( this ) ) );

  }

 

};

 

// --------------------------------------------------------------------------------

 

class IUnknown2

{

  typedef IUnknown2  interface_type;

 

protected:

 

  void const * vtbl_ptr_;

 

  struct fxn_table

  {

    HRESULT (*QueryInterface)(void *, REFIID, void **);

    ULONG (*AddRef)(void *);

    ULONG (*Release)(void *);

 

    fxn_table()

      : QueryInterface( 0 )

      , AddRef( 0 )

      , Release( 0 )

    {

    }

 

    fxn_table(

      HRESULT (*QueryInterface_)(void *, REFIID, void **),

      ULONG (*AddRef_)(void *),

      ULONG (*Release_)(void *) )

      : QueryInterface( QueryInterface_ )

      , AddRef( AddRef_ )

      , Release( Release_ )

    {

    }

 

  };

 

  template<typename TIface, typename T> struct interface_stub

  {

    static HRESULT QueryInterface(void * obj_ptr, REFIID iid, void ** ppvObject)

    {

      // Adjust void pointer as a pointer of TIface type first

      // then adjust the resultant as a pointer of T type again to call the function.

      return static_cast<T *>( static_cast<TIface *>(obj_ptr) )->QueryInterface( iid, ppvObject );

    }

 

    static ULONG AddRef(void * obj_ptr)

    {

      return static_cast<T *>( static_cast<TIface *>(obj_ptr) )->AddRef();

    }

 

    static ULONG Release(void * obj_ptr)

    {

      return static_cast<T *>( static_cast<TIface *>(obj_ptr) )->Release();

    }

 

    static fxn_table * get_table()

    {

      static fxn_table static_table(

        &QueryInterface,

        &AddRef,

        &Release );

      return &static_table;

    }

  };

 

  IUnknown2(void const * table_ptr) : vtbl_ptr_( table_ptr )

  {

  }

 

public:

  template<class T>

  IUnknown2(apply<T>) : vtbl_ptr_( interface_stub<interface_type, typename apply<T>::type>::get_table() )

  {

  }

 

public:

  HRESULT QueryInterface(REFIID iid, void ** ppvObject)

  {

    return static_cast<fxn_table const *>( vtbl_ptr_ )->QueryInterface( this, iid, ppvObject );

  }

 

  ULONG AddRef()

  {

    return static_cast<fxn_table const *>( vtbl_ptr_ )->AddRef( this );

  }

 

  ULONG Release()

  {

    return static_cast<fxn_table const *>( vtbl_ptr_ )->Release( this );

  }

 

};  // class IUnknown2

 

// --------------------------------------------------------------------------------

 

class IFoo : public IUnknown2

{

  typedef IFoo                            interface_type;

  typedef IUnknown2                        base_interface_type;

  typedef base_interface_type::fxn_table  base_interface_fxn_table;

 

  template<typename TIface, typename T>

  struct rebind_base_interfacel_stub

  {

    typedef base_interface_type::interface_stub<TIface, T> type;

  };

 

protected:

  struct fxn_table : public base_interface_fxn_table

  {

    void (*foofun)(void *, int);

    void (*foofun2)(void *, int, long);

 

    fxn_table()

      : base_interface_fxn_table()

      , foofun( 0 ), foofun2( 0 )

    {

    }

 

    fxn_table(base_interface_fxn_table * base_table_ptr

      , void (*foofun_)(void *, int)

      , void (*foofun2_)(void *, int, long))

      : base_interface_fxn_table( *base_table_ptr )

      , foofun( foofun_ ), foofun2( foofun2_ )

    {

    }

  };

 

  template<typename TIface, typename T> struct interface_stub : public rebind_base_interfacel_stub<TIface, T>::type

  {

    static void foofun(void * obj_ptr, int a0)

    {

      // Adjust void pointer as a pointer of TIface type first

      // then adjust the resultant as a pointer of T type again to call the function.

      static_cast<T *>( static_cast<TIface *>(obj_ptr) )->foofun( a0 );

    }

 

    static void foofun2(void * obj_ptr, int a0, long a1)

    {

      static_cast<T *>( static_cast<TIface *>(obj_ptr) )->foofun2( a0, a1 );

    }

 

    static fxn_table * get_table()

    {

      static fxn_table static_table(

        typename rebind_base_interfacel_stub<TIface, T>::type::get_table(),

        &foofun,

        &foofun2);

      return &static_table;

    }

  };

 

  IFoo(void const * table_ptr) : base_interface_type( table_ptr )

  {

  }

 

public:

  template<class T>

  IFoo(apply<T>) : base_interface_type( interface_stub<interface_type, typename apply<T>::type>::get_table() )

  {

  }

 

  void foofun(int a0)

  {

    static_cast<fxn_table const *>( vtbl_ptr_ )->foofun( this, a0 );

  }

 

  void foofun2(int a0, long a1)

  {

    static_cast<fxn_table const *>( vtbl_ptr_ )->foofun2( this, a0, a1 );

  }

 

};  // class IFoo : public IUnknown2

 

// --------------------------------------------------------------------------------

 

class IBar : public IUnknown2

{

  typedef IBar                            interface_type;

  typedef IUnknown2                        base_interface_type;

  typedef base_interface_type::fxn_table  base_interface_fxn_table;

 

  template<typename TIface, typename T>

  struct rebind_base_interfacel_stub

  {

    typedef base_interface_type::interface_stub<TIface, T> type;

 

  };

 

protected:

  struct fxn_table : public base_interface_fxn_table

  {

    void (*barfun)(void *, int);

 

    fxn_table()

      : base_interface_fxn_table()

      , barfun( 0 )

    {

    }

 

    fxn_table(base_interface_fxn_table * base_table_ptr, void (*funfun_)(void *, int))

      : base_interface_fxn_table( *base_table_ptr )

      , barfun( funfun_ )

    {

    }

  };

 

  template<typename TIface, typename T> struct interface_stub : public rebind_base_interfacel_stub<TIface, T>::type

  {

    static void barfun(void * obj_ptr, int a0)

    {

      static_cast<T *>( static_cast<TIface *>(obj_ptr) )->barfun( a0 );

    }

 

    static fxn_table * get_table()

    {

      static fxn_table static_table(

        typename rebind_base_interfacel_stub<TIface, T>::type::get_table(),

        &barfun );

      return &static_table;

    }

  };

 

  IBar(void const * table_ptr) : base_interface_type( table_ptr )

  {

  }

 

public:

  template<class T>

  IBar(apply<T>) : base_interface_type( interface_stub<interface_type, typename apply<T>::type>::get_table() )

  {

  }

 

  void barfun(int a0)

  {

    static_cast<fxn_table const *>( vtbl_ptr_ )->barfun( this, a0 );

  }

 

};  // class IBar : public IUnknown2

 

 

#endif  // #if !defined(__UNKNOWN2_HPP__INCLUDED__)

CBOE Put/Call Ratio