Boost logo

Boost :

Subject: Re: [boost] [mpl] has_function
From: Ingo Loehken (Ingo.Loehken_at_[hidden])
Date: 2010-03-22 09:12:55


below you find the appropiate code, that checks if a set of functions is
declared for a type T,
where the declaration should be inherited from nsISupports (or any other
interface). So you'd
can determine, if the function is overloaded or not.

This code is inspired by the following article
http://groups.google.com/group/comp.lang.c++.moderated/tree/browse_frm/thread/4f7c7a96f9afbe44/c95a7b4c645e449f?pli=1

  /** Compile Time Predicate, which checks, if a type is a valid template
   * parameter for a COMPtr, where only interfaces are valid input
parameters.
   *
   * The idea is simple :
   * An interface always inherits from nsISupports and does not overload
the
   * pure virtual declarations of AddREf, Release and QueryInterface.
Therefore
   * the addresses of that function pointers need to be bound to
nsISupports.
   *
   * Of course, one issue remains unsolved :
   * What is with abstract classes, which inherit from nsISupports, but
already
   * have their own implementation ?
   * Currently there is no way, to check, if a class is pure virtual,
thus we
   * neglect that issue.
   *
   */
  template <typename T>
  struct IsCOMInterface
    : public Supports_::BasicTestPredicate<IsCOMInterface<T> >
  {
  private:
    // we are only able to determine this predicate for complete types, a
    // forward declare (incomplete type) may be a COM interface, but would
be
    // excluded as an error to its incompleteness. Therefore the only
thing,
    // that is always correct is to assert in such conditions.
    BOOST_MPL_ASSERT_RELATION((sizeof(T)),>,0);

    static T* Make();
    static false_t Test1(...);
    template <typename _1> static true_t Test1(_1*, equal<nsrefcnt
(__stdcall nsISupports::*)(),&_1::AddRef>* = 0);

    static false_t Test2(...);
    template <typename _1> static true_t Test2(_1*, equal<nsrefcnt
(__stdcall nsISupports::*)(),&_1::Release>* = 0);

    static false_t Test3(...);
    template <typename _1> static true_t Test3(_1*, equal<nsresult
(__stdcall nsISupports::*)(nsID const&,void**),&_1::QueryInterface>* = 0);

  public:
    static const value_type value = sizeof(Test1(Make())) == sizeof
(true_t) && sizeof(Test2(Make())) == sizeof(true_t) && sizeof(Test3(Make
())) == sizeof(true_t);
  };

  namespace IsCOMInterface_
  {
    BOOST_MPL_ASSERT((IsCOMInterface<nsISupports>));
    BOOST_MPL_ASSERT((IsCOMInterface<nsIWeakReference>));

    struct Test1 {};

    BOOST_MPL_ASSERT_NOT((IsCOMInterface<Test1>));

    struct Test2
    {
      NS_IMETHOD_(nsrefcnt) AddRef();
      NS_IMETHOD_(nsrefcnt) Release();
      NS_IMETHOD QueryInterface(nsID const&, void**);
    };

    BOOST_MPL_ASSERT_NOT((IsCOMInterface<Test2>));

    struct Test3
      : public nsISupports
    {
      NS_IMETHODIMP_(nsrefcnt) AddRef();
    };

    BOOST_MPL_ASSERT_NOT((IsCOMInterface<Test3>));
  }

namespace Supports_
{
  /**
   *
   */
  template <typename derivedT>
  struct BasicTestPredicate
  {
  protected:
    typedef char true_t;
    struct false_t{true_t dummy[2];};

    template <typename V, V> struct equal;

  public:
    typedef bool value_type;
    typedef derivedT type;
  };

} // namespace Supports_

Lorenzo Caminiti <lorcaminiti_at_[hidden]>
Sent by: boost-bounces_at_[hidden]
22.03.2010 13:33
Please respond to
boost_at_[hidden]

To
boost_at_[hidden]
cc

Subject
Re: [boost] [mpl] has_function

On Sun, Mar 21, 2010 at 2:43 PM, Ingo Loehken <Ingo.Loehken_at_[hidden]>
wrote:
> The only thing you can determine, is, if the type (class) of the last
> declaration is the
> one you expected. That means if you know that the first declaration of
> your function
> comes in from baseT, you can determine if a deriving class overwrites
that
> decl,
> and that is exactly what a deriving class needs to do to overload a
> virtual function.
>
> I myself use this pattern to determine, if a type is an XPCOM Interface
or
> not. Perhaps
> you'd like to check for something similiar.
>
> If interested in details, let me know.

Yes, I am interested. Can you please point me to some code that
programs this pattern?

Thanks a lot.
Lorenzo
_______________________________________________
Unsubscribe & other changes:
http://lists.boost.org/mailman/listinfo.cgi/boost


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