Boost logo

Boost :

From: Larry Evans (jcampbell3_at_[hidden])
Date: 2002-01-17 20:15:25


How would smart_ptr handle pointee multiple inheritance? For
example, how could it do what prox_mi does in the attached
file? The subj_base class could be replaced with something like
a reference count base class, either intrusive or not.


//Purpose:
// prototype prox for multi-inherited subjects
//Result:
#include <cstddef>
#include <iostream>
using namespace std;
//----------------------
  struct
subj_base
  {
  }
  ;//end subj_base
//----------------------
  struct
prox_base
  {
        typedef
      subj_base
    subj_type
      ;
        typedef
      prox_base
    my_type
      ;
    prox_base(my_type const&a_prox)
      : m_subj(a_prox.m_subj)
      {}
      my_type const&
    operator=(my_type const&a_prox)
      { m_subj = a_prox.m_subj
      ; return *this
      ;}
      my_type const&
    operator=(subj_type*a_subj)
      { m_subj = a_subj
      ; return *this
      ;}
      subj_type*
    get_subj(void)const
      { return m_subj
      ;}
  protected:
    prox_base(subj_type*a_subj)
      : m_subj(a_subj)
      {}
      void
    put_subj(subj_type*a_subj)
      { m_subj = a_subj
      ;}
  private:
      subj_type*
    m_subj
      ;
  }
  ;//end prox_base struct
//----------------------
template
  < typename Subject
>
  struct
prox_make
  : public prox_base
  {
    prox_make(void)
      : prox_base(new Subject)
      {}
      Subject*
    get_subj(void)const
      { return static_cast<Subject*>(prox_base::get_subj())
      ;}
  }
  ;//end prox_make
//----------------------
template
  < typename SubjTo
  , typename SubjFrom=SubjTo
>
  struct
prox_mi
  : public prox_base
  {
        typedef
      prox_base::subj_type
    subj_base
      ;
        typedef
      prox_mi<SubjTo,SubjFrom>
    my_type
      ;
    template
      < typename SubjDerived
>
      subj_base*
    from2base(SubjDerived*a_subj)
      {
      ; SubjTo*to_subj=a_subj //check conversion
      ; subj_base*base_subj=static_cast<SubjDerived*>(to_subj)
      ; return base_subj
      ;}
    prox_mi(prox_make<SubjFrom>const&a_make)
      : prox_base(from2base(a_make.get_subj()))
      {}
    template
      < typename SubjDerived
>
    prox_mi(prox_mi<SubjDerived,SubjFrom>const&a_prox)
      : prox_base(from2base(a_prox.get_to()))
      {}
    template
      < typename SubjDerived
>
      my_type const&
    operator=(prox_mi<SubjDerived,SubjFrom>const&a_prox)
      {
      ; prox_base::put_subj(from2base(a_prox.get_to()))
      ; return *this
      ;}
      subj_base*
    get_base(void)const
      {
      ; subj_base*base_subj=static_cast<subj_base*>(get_subj())
      ; return base_subj
      ;}
      SubjTo*
    get_to(void)const
      {
      ; SubjFrom*f_subj=static_cast<SubjFrom*>(get_base())
      ; SubjTo*t_subj = f_subj
      ; return t_subj
      ;}
  }
  ;//end prox_mi
//----------------------
struct subjA
  : public subj_base
  { int m_a;
    subjA(void)
      : m_a(0)
      {}
  }
  ;
//----------------------
struct subjB
  { char m_b;
  }
  ;
//----------------------
struct subjC
  { bool m_c;
  }
  ;
//----------------------
struct subjAB
  : public subjA
  , public subjB
  {
  }
  ;
//----------------------
struct subjABC
  : public subjAB
  , public subjC
  {
  }
  ;
//----------------------
template
  < typename subjTO
  , typename subjMI
>
  void
test(const char*test)
  {
  ; prox_make<subjMI> sMI
  ; typedef prox_base::subj_type subj_base
  ; prox_mi<subjTO,subjMI> pMI(sMI)
  ; subj_base*pBase=pMI.get_base()
  ; subjTO*pTO=pMI.get_to()
  ; char*cBase=static_cast<char*>((void*)pBase)
  ; char*cTO=static_cast<char*>((void*)pTO)
  ; ptrdiff_t d=cTO-cBase
  ; cout<<test<<":ptrdiff="<<d<<endl
  ;}
//----------------------
  int
main(void)
  {
  ; int result=0
  ; typedef subjAB subjMI
  ; test<subjAB,subjMI>("cAB-cBase")
  ; test<subjA,subjMI>("cA-cBase")
  ; test<subjB,subjMI>("cB-cBase")
  ; {
    ; typedef subjABC subjMI
    ; typedef subjAB subjDER
    ; typedef subjB subjTO
    ; prox_make<subjMI> a_make
    ; prox_mi<subjDER,subjMI> a_der(a_make)
    ; subjDER*der_subj= a_der.get_to()
    ; subjTO*to_subj= der_subj
    ; prox_mi<subjTO,subjMI> a_to(a_der)
    ; to_subj=a_to.get_to()
    ; ptrdiff_t d = static_cast<char*>((void*)to_subj)-static_cast<char*>((void*)der_subj)
    ; cout<<"ptrdiff to_subj-der_subj = "<<d<<endl
    ;}
  ; return result
  ;}


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk