Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

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_IUnknown,  reinterpret_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