Boost logo

Boost :

Subject: Re: [boost] [Signal] Variadic template implementation of signal/slot
From: Frank Mori Hess (frank.hess_at_[hidden])
Date: 2009-05-22 11:12:45


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Thursday 21 May 2009, Kevin Brandon wrote:
> So with this all said, would there be any interest in having an
> attempt of Signals/Signals2 in varaidic template form?

If you like, you can try implementing a signals2/variadic_signal.hpp based on
the preprocessor template code in signals2/detail/signal_template.hpp. I
guess you'll have to wrap all the non-signature template parameters for the
signal in a policy class that can be passed as the first template parameter
to variadic_signal, since the variadic template parameter pack has to be
last. I played around a bit with replacements for the arg1_type, arg2_type,
etc typedefs, see the "signature" template in the attached file. It lets you
extract the arity and individual argument types from the template parameter
pack.

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)

iEYEARECAAYFAkoWwPAACgkQ5vihyNWuA4WfCwCdF0RBo3aaeDcmCkj88x17rABw
28AAn37J3491L+aLk2SZzOo/2iI1pE2g
=jkM+
-----END PGP SIGNATURE-----

--Boundary-00=_wDsFK0pAKBU0ZWq
Content-Type: text/x-c++src; charset="iso 8859-15"; name="template_varargs.cpp"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
        filename="template_varargs.cpp"

#include <cassert>
#include <iostream>
#include <string>
#include <typeinfo>

namespace detail
{
  template<unsigned, typename ... Args> class arg_type;

  template<typename T, typename ... Args> class arg_type<0, T, Args...>
  {
  public:
    typedef T type;
  };

  template<unsigned n, typename T, typename ... Args> class arg_type<n, T, Args...>
  {
  public:
    typedef typename arg_type<n - 1, Args...>::type type;
  };

  template<typename ... Args> class arity;

  template<typename T>
  class arity<T>
  {
  public:
    static const unsigned value = 0;
  };

  template<typename T, typename ... Args>
  class arity<T, Args...>
  {
  public:
    static const unsigned value = arity<Args...>::value + 1;
  };
}

template<typename ... Args>
class signature
{
public:
  static const unsigned arity = detail::arity<Args...>::value;
  typedef typename detail::arg_type<0, Args...>::type result_type;
  template<unsigned n> class arg
  {
  public:
    typedef typename detail::arg_type<n + 1, Args...>::type type;
  };
};

int main()
{
  typedef signature<int, double, std::string> signature_type;
  std::cout << "arity is " << signature_type::arity << std::endl;
  std::cout << "result type name is " << typeid(signature_type::result_type).name() << std::endl;
  std::cout << "arg 0 type name is " << typeid(signature_type::arg<0>::type).name() << std::endl;
  std::cout << "arg 1 type name is " << typeid(signature_type::arg<1>::type).name() << std::endl;

  assert(signature_type::arity == 2);
  assert(typeid(signature_type::result_type) == typeid(int));
  assert(typeid(signature_type::arg<0>::type) == typeid(double));
  assert(typeid(signature_type::arg<1>::type) == typeid(std::string));

  return 0;
}
--Boundary-00=_wDsFK0pAKBU0ZWq--


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