#if 0 /* -*-perl-*- */

# /*
# $Id: callback.h,v 1.9 2001/04/16 07:21:38 dm Exp $
# 
# This header file was automatically generated by itself.
# (Yup, it's a C++ header file and a perl script.)
#

# Copyright (C) 1998 David Mazieres (dm@uun.org)
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA
#
# Note: For the purposes of the GNU General Public License, source
# includes the source to the perl script, not just the resulting
# header file, callback.h.  However, since the perl script is
# conveniently embedded in the header file, you needn't do anything
# special to distribute source as long as you don't take the perl out
# of the header.

#
# WHAT IS THIS?
#
# This C++ header file defines the template class callback--a type
# that approximates function currying.
#
# An object of type callback<R, B1, B2> contains a member R operator()
# (B1, B2)--Thus callbacks are function objects with the first
# template type specifying the return of the function and the
# remaining arguments specifying the types of the arguments to pass
# the function.
#
# Callbacks can have any number of arguments up to $NA below.
# Template arguments that aren't specified default to void and don't
# need to be passed in.  Thus, a callback<int> acts like a function
# with signature "int fn ()", a callback<int, char *> acts like a
# function with signature "int fn (char *)", and so forth.
#
# Each callback class has two type members, ptr and ref, specyfing
# refcounted pointers and references to the callback object
# respectively.  (See refcnt.h for an explanation of ptr and ref).
#
# The function wrap is used to create references to callbacks.  Given
# a function with signature "R fn (A1, A2, A3)", wrap can generate
# the following references:
#
#    wrap (fn) -> callback<R, A1, A2, A3>::ref
#    wrap (fn, a1) -> callback<R, A2, A3>::ref
#    wrap (fn, a1, a2) -> callback<R, A3>::ref
#    wrap (fn, a1, a2, a3) -> callback<R>::ref
#
# When the resulting callback is actually called, it invokes fn.  The
# argument list it passes fn starts with whatever arguments were
# initially passed to wrap and then contains whatever arguments are
# given to the callback object.  For example, given fn above, this
# code ends up calling "fn (a1, a2, a3)" and assigning the return
# value to r;
#
#    R r;
#    A1 a1;
#    A2 a2;
#    A3 a3;
#    callback<R, A1>::ptr cb;
#
#    cb = wrap (fn, a1);
#    r = (*cb) (a2, a3);
#
# One can create callbacks from class methods as well as global
# functions.  To do this, simply pass the object as the first
# parameter to wrap, and the method as the second.  For example:
#
# struct foo {
#   void bar (int, char *);
#   callback<void, char *>::ref baz () {
#     return wrap (this, &foo::bar, 7);
#   }
# };
#
# Note the only way to generate pointers to class members in ANSI C++
# is with fully qualified member names.  "&foo::bar" cannot be
# abbreviated to "&bar" in the above example, though most C++
# compilers still accept that syntax.
#
# If wrap is called with a refcounted ref or ptr to a object, instead
# of a simple pointer, the resulting callback will maintain a
# reference to the object, ensuring it is not deleted.  For example,
# in the following code, baz returns a callback with a reference to
# the current object.  This ensures that a foo will not be deleted
# until after the callback has been deleted.  Without mkref, if a
# callback happened after the reference count on a foo object went to
# zero, the foo object would previously have been deleted and its
# vtable pointer likely clobbered, resulting in a core dump.
#
# struct foo : public virtual refcount {
#   virtual void bar (int, char *);
#   callback<void, char *>::ref baz () {
#     return wrap (mkref (this), &foo::bar, 7);
#   }
# };
#
# An example:
#
# void
# printstrings (char *a, char *b, char *c)
# {
#   printf ("%s %s %s\n", a, b, c);
# }
#
# int
# main ()
# {
#   callback<void, char *>::ref cb1 = wrap (printstrings, "cb1a", "cb1b");
#   callback<void, char *, char *>::ref cb2 = wrap (printstrings, "cb2a");
#   callback<void, char *, char *, char *>::ref cb3 = wrap (printstrings);
#
#   (*cb1) ("cb1c");                  // prints: cb1a cb1b cb1c
#   (*cb2) ("cb2b", "cb2c");          // prints: cb2a cb2b cb2c
#   (*cb3) ("cb3a", "cb3b", "cb3c");  // prints: cb3a cb3b cb3c
#
#   return 0;
# }


eval 'exec perl -w -S $0 ${1+"$@"}'
    if 0;


use strict;

my $NA = 5;
my $NB = 3;

my $PARTIALSPEC = 0;		# 0 May work around compiler bugs
my $RETURNVOID = 1;		# 0 May work around compiler bugs

my $verbosedestruct = 0;
my ($ia, $ib);

sub jc {
    join (', ', @_);
}

sub mklist ($$) {
    my ($pat, $n) = @_;
    my @res = map { my $ret = $pat; $ret =~ s/%/$_/g; $ret; } (1 .. $n);
    wantarray ? @res : jc (@res);
}

sub pcallback ($) {
    my $b = shift;
    my $tmpparam = jc ('class R', mklist ('class B%', $b));
    my $tmpargs = jc ('R', mklist ('B%', $b));
    my $specargs = $b == $NB ? '' : "<" . $tmpargs . ">";
    my $cbargs = mklist ('B%', $b);

    print <<"EOF";

template<$tmpparam>
class callback$specargs {
public:
  typedef ref<callback<$tmpargs> > ref;
  typedef ptr<callback<$tmpargs> > ptr;

  virtual R operator() ($cbargs) = 0;
  virtual ~callback () {}
};

EOF

    return if (!$PARTIALSPEC);

    my $rbparam = jc ('class R', mklist ('class B%', $b));
    my $bargs = jc (mklist ('const B% &b%', $b));
    my $blist = jc (mklist ('b%', $b));

    print <<"EOF";
template<$rbparam>
class refops<callback<$tmpargs> >
  typedef callback<$tmpargs> cb_t;
  REFOPS_DEFAULT (cb_t);
  R operator() ($bargs)
    { return (*p) ($blist); }
};

EOF

    return if ($RETURNVOID);

    my $bparam = mklist ('class B%', $b);
    $tmpargs = jc ('void', mklist ('B%', $b));

    print <<"EOF";
template<$bparam>
class refops<callback<$tmpargs> >
  typedef callback<$tmpargs> cb_t;
  REFOPS_DEFAULT (cb_t);
  void operator() ($bargs)
    { (*p) ($blist); }
};

EOF
}

sub pcallback_b_a ($$) {
    my ($b, $a) = @_;
    my $type = "callback_${b}_${a}";
    my $tmpparam = jc ('class R', mklist ('class B%', $b),
		       mklist ('class A%', $a));
    my $RBlist = jc ('R', mklist ('B%', $b));
    my $ABlist = jc (mklist ('A%', $a), mklist ('B%', $b));
    my $adecl = join ('', mklist ("  A% a%;\n", $a));
    my $aargs = jc ('cb_t ff', mklist ('const A% &aa%', $a));
    my $ainit = jc ('f (ff)', mklist ('a% (aa%)', $a));
    my $bargs = mklist ('B% b%', $b);
    my $ablist = jc (mklist ('a%', $a), mklist ('b%', $b));

    print <<"EOF";

template<$tmpparam>
class $type
  : public callback<$RBlist> {
  typedef R (*cb_t) ($ABlist);
  cb_t f;
${adecl}public:
  $type ($aargs)
    : $ainit {}
  R operator() ($bargs)
    { return f ($ablist); }
};
EOF

    return if ($RETURNVOID);

    my $specparam = jc (mklist ('class B%', $b), mklist ('class A%', $a));
    my $specargs = jc ('void', mklist ('B%', $b), mklist ('A%', $a));
    $RBlist = jc ('void', mklist ('B%', $b));

    print <<"EOF";

template<$specparam>
class $type<$specargs>
  : public callback<$RBlist> {
  typedef void (*cb_t) ($ABlist);
  cb_t f;
${adecl}public:
  $type ($aargs)
    : $ainit {}
  void operator() ($bargs)
    { f ($ablist); }
};
EOF
}

sub pcallback_c_b_a ($$) {
    my ($b, $a) = @_;
    my $type = "callback_c_${b}_${a}";
    my $tmpparam = jc ('class P, class C, class R', mklist ('class B%', $b),
		       mklist ('class A%', $a));
    my $RBlist = jc ('R', mklist ('B%', $b));
    my $ABlist = jc (mklist ('A%', $a), mklist ('B%', $b));
    my $adecl = join ('', mklist ("  A% a%;\n", $a));
    my $aargs = jc ('const P &cc, cb_t ff', mklist ('const A% &aa%', $a));
    my $ainit = jc ('c (cc), f (ff)', mklist ('a% (aa%)', $a));
    my $bargs = mklist ('B% b%', $b);
    my $ablist = jc (mklist ('a%', $a), mklist ('b%', $b));

    print <<"EOF";

template<$tmpparam>
class $type
  : public callback<$RBlist> {
  typedef R (C::*cb_t) ($ABlist);
  P c;
  cb_t f;
${adecl}public:
  $type ($aargs)
    : $ainit {}
  R operator() ($bargs)
    { return ((*c).*f) ($ablist); }
};
EOF

    return if ($RETURNVOID);

    my $specparam = jc ('class P, class C', mklist ('class B%', $b),
			mklist ('class A%', $a));
    my $specargs = jc ('P, C, void' , mklist ('B%', $b), mklist ('A%', $a));
    $RBlist = jc ('void', mklist ('B%', $b));

    print <<"EOF";

template<$specparam>
class $type<$specargs>
  : public callback<$RBlist> {
  typedef void (C::*cb_t) ($ABlist);
  P c;
  cb_t f;
${adecl}public:
  $type ($aargs)
    : $ainit {}
  void operator() ($bargs)
    { ((*c).*f) ($ablist); }
};
EOF
}

sub pwrap_b_a ($$) {
    my ($b, $a) = @_;
    my $tmpparam = jc ('class R', mklist ('class B%', $b),
		      mklist ('class A%, class AA%', $a));
    my $rtargs = jc ('R', mklist ('B%', $b), mklist ('A%', $a));
    my $rtype = "refcounted<callback_${b}_${a}<$rtargs> >";
    my $ABlist = jc (mklist ('A%', $a), mklist ('B%', $b));
    my $fargs = jc ("R (*f) ($ABlist)", mklist ('const AA% &a%', $a));
    my $falist = jc ('f', mklist ('a%', $a));

    print <<"EOF";

template<$tmpparam>
static inline $rtype *
wrap ($fargs)
{
  return New ($rtype) ($falist);
}
EOF
}

sub pwrap_c_b_a ($$) {
    my ($b, $a) = @_;
    my $tmpparam = jc ('class C', 'class R', mklist ('class B%', $b),
		      mklist ('class A%, class AA%', $a));
    my $rtargs = jc ('C *', 'C', 'R', mklist ('B%', $b), mklist ('A%', $a));
    my $rtype = "refcounted<callback_c_${b}_${a}<$rtargs> >";
    my $ABlist = jc (mklist ('A%', $a), mklist ('B%', $b));
    my $fargs = jc ("C *p, R (C::*f) ($ABlist)", mklist ('const AA% &a%', $a));
    my $falist = jc ('p, f', mklist ('a%', $a));

    print <<"EOF";

template<$tmpparam>
static inline $rtype *
wrap ($fargs)
{
  return New ($rtype) ($falist);
}
EOF

    $rtargs = jc ('ref<C>', 'C', 'R', mklist ('B%', $b), mklist ('A%', $a));
    $rtype = "refcounted<callback_c_${b}_${a}<$rtargs> >";
    $fargs = jc ("const ref<C> &p, R (C::*f) ($ABlist)",
		 mklist ('const AA% &a%', $a));
    my $f2args = jc ("const ptr<C> &p, R (C::*f) ($ABlist)",
		  mklist ('const AA% &a%', $a));
    my $f3args = jc ("const refcounted<C> *p, R (C::*f) ($ABlist)",
		  mklist ('const AA% &a%', $a));
    $falist = jc ('p, f', mklist ('a%', $a));

    print <<"EOF";

template<$tmpparam>
static inline $rtype *
wrap ($fargs)
{
  return New ($rtype) ($falist);
}
template<$tmpparam>
static inline $rtype *
wrap ($f2args)
{
  return New ($rtype) ($falist);
}
template<$tmpparam>
static inline $rtype *
wrap ($f3args)
{
  return New ($rtype) ($falist);
}
EOF
}


sub prefops () {
    return if ($PARTIALSPEC);
    my ($b, $opfn);

    $opfn = "R operator() () { return (*p) (); }\n";
    for ($b = 1; $b <= $NB; $b++) {
	my $tmpparam = mklist ("class BB%", $b);
	my $bparam = mklist ("const BB% &b%", $b);
	my $blist = mklist ("b%", $b);
	$opfn .= sprintf <<"EOF",
  template<$tmpparam>
  R operator() ($bparam)
    { return (*p) ($blist); }
EOF
    }

    printf <<"EOF",

template<%s>
class refops<callback<%s> > {
  typedef callback<%s> cb_t;
  REFOPS_DEFAULT (cb_t);
  $opfn};
EOF
    jc ('class R', mklist ("class B%", $NB)),
    jc ('R', mklist ("B%", $NB)),
    jc ('R', mklist ("B%", $NB));

    return if ($RETURNVOID);

    $opfn = "void operator() () { return (*p) (); }\n";
    for ($b = 1; $b <= $NB; $b++) {
	my $tmpparam = mklist ("class BB%", $b);
	my $bparam = mklist ("const BB% &b%", $b);
	my $blist = mklist ("b%", $b);
	$opfn .= sprintf <<"EOF",
  template<$tmpparam>
  void operator() ($bparam)
    { (*p) ($blist); }
EOF
    }

    printf <<"EOF",

template<%s>
class refops<callback<%s> > {
  typedef callback<%s> cb_t;
  REFOPS_DEFAULT (cb_t);
  $opfn};
EOF
    scalar mklist ("class B%", $NB),
    jc ('void', mklist ("B%", $NB)),
    jc ('void', mklist ("B%", $NB));
}



sub pfile () {
    printf "template<%s> class callback;\n",
    jc ('class R', mklist ('class B% = void', $NB));

    my ($a, $b);
    for ($b = 0; $b <= $NB; $b++) {
	pcallback ($b);
	for ($a = 0; $a <= $NA; $a++) {
	    pcallback_b_a ($b, $a); 
	    pwrap_b_a ($b, $a);
	    pcallback_c_b_a ($b, $a); 
	    pwrap_c_b_a ($b, $a);
	}
    }
    prefops;
}

seek DATA, 0, 0;
while (<DATA>) {
    print;
    last if m/^\#endif \/\* perl \*\/$/;
}

print <<'EOF';

#ifndef _CALLBACK_H_INCLUDED_
#define _CALLBACK_H_INCLUDED_ 1

#include "refcnt.h"

EOF

pfile;

print "\n", '#endif /', '* !_CALLBACK_H_INCLUDED_ *', '/', "\n";

__END__
# */
#endif /* perl */

#ifndef _CALLBACK_H_INCLUDED_
#define _CALLBACK_H_INCLUDED_ 1

#include "refcnt.h"

template<class R, class B1 = void, class B2 = void, class B3 = void> class callback;

template<class R>
class callback<R> {
public:
  typedef ref<callback<R> > ref;
  typedef ptr<callback<R> > ptr;

  virtual R operator() () = 0;
  virtual ~callback () {}
};


template<class R>
class callback_0_0
  : public callback<R> {
  typedef R (*cb_t) ();
  cb_t f;
public:
  callback_0_0 (cb_t ff)
    : f (ff) {}
  R operator() ()
    { return f (); }
};

template<class R>
static inline refcounted<callback_0_0<R> > *
wrap (R (*f) ())
{
  return New (refcounted<callback_0_0<R> >) (f);
}

template<class P, class C, class R>
class callback_c_0_0
  : public callback<R> {
  typedef R (C::*cb_t) ();
  P c;
  cb_t f;
public:
  callback_c_0_0 (const P &cc, cb_t ff)
    : c (cc), f (ff) {}
  R operator() ()
    { return ((*c).*f) (); }
};

template<class C, class R>
static inline refcounted<callback_c_0_0<C *, C, R> > *
wrap (C *p, R (C::*f) ())
{
  return New (refcounted<callback_c_0_0<C *, C, R> >) (p, f);
}

template<class C, class R>
static inline refcounted<callback_c_0_0<ref<C>, C, R> > *
wrap (const ref<C> &p, R (C::*f) ())
{
  return New (refcounted<callback_c_0_0<ref<C>, C, R> >) (p, f);
}
template<class C, class R>
static inline refcounted<callback_c_0_0<ref<C>, C, R> > *
wrap (const ptr<C> &p, R (C::*f) ())
{
  return New (refcounted<callback_c_0_0<ref<C>, C, R> >) (p, f);
}
template<class C, class R>
static inline refcounted<callback_c_0_0<ref<C>, C, R> > *
wrap (const refcounted<C> *p, R (C::*f) ())
{
  return New (refcounted<callback_c_0_0<ref<C>, C, R> >) (p, f);
}

template<class R, class A1>
class callback_0_1
  : public callback<R> {
  typedef R (*cb_t) (A1);
  cb_t f;
  A1 a1;
public:
  callback_0_1 (cb_t ff, const A1 &aa1)
    : f (ff), a1 (aa1) {}
  R operator() ()
    { return f (a1); }
};

template<class R, class A1, class AA1>
static inline refcounted<callback_0_1<R, A1> > *
wrap (R (*f) (A1), const AA1 &a1)
{
  return New (refcounted<callback_0_1<R, A1> >) (f, a1);
}

template<class P, class C, class R, class A1>
class callback_c_0_1
  : public callback<R> {
  typedef R (C::*cb_t) (A1);
  P c;
  cb_t f;
  A1 a1;
public:
  callback_c_0_1 (const P &cc, cb_t ff, const A1 &aa1)
    : c (cc), f (ff), a1 (aa1) {}
  R operator() ()
    { return ((*c).*f) (a1); }
};

template<class C, class R, class A1, class AA1>
static inline refcounted<callback_c_0_1<C *, C, R, A1> > *
wrap (C *p, R (C::*f) (A1), const AA1 &a1)
{
  return New (refcounted<callback_c_0_1<C *, C, R, A1> >) (p, f, a1);
}

template<class C, class R, class A1, class AA1>
static inline refcounted<callback_c_0_1<ref<C>, C, R, A1> > *
wrap (const ref<C> &p, R (C::*f) (A1), const AA1 &a1)
{
  return New (refcounted<callback_c_0_1<ref<C>, C, R, A1> >) (p, f, a1);
}
template<class C, class R, class A1, class AA1>
static inline refcounted<callback_c_0_1<ref<C>, C, R, A1> > *
wrap (const ptr<C> &p, R (C::*f) (A1), const AA1 &a1)
{
  return New (refcounted<callback_c_0_1<ref<C>, C, R, A1> >) (p, f, a1);
}
template<class C, class R, class A1, class AA1>
static inline refcounted<callback_c_0_1<ref<C>, C, R, A1> > *
wrap (const refcounted<C> *p, R (C::*f) (A1), const AA1 &a1)
{
  return New (refcounted<callback_c_0_1<ref<C>, C, R, A1> >) (p, f, a1);
}

template<class R, class A1, class A2>
class callback_0_2
  : public callback<R> {
  typedef R (*cb_t) (A1, A2);
  cb_t f;
  A1 a1;
  A2 a2;
public:
  callback_0_2 (cb_t ff, const A1 &aa1, const A2 &aa2)
    : f (ff), a1 (aa1), a2 (aa2) {}
  R operator() ()
    { return f (a1, a2); }
};

template<class R, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_0_2<R, A1, A2> > *
wrap (R (*f) (A1, A2), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_0_2<R, A1, A2> >) (f, a1, a2);
}

template<class P, class C, class R, class A1, class A2>
class callback_c_0_2
  : public callback<R> {
  typedef R (C::*cb_t) (A1, A2);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
public:
  callback_c_0_2 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2)
    : c (cc), f (ff), a1 (aa1), a2 (aa2) {}
  R operator() ()
    { return ((*c).*f) (a1, a2); }
};

template<class C, class R, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_0_2<C *, C, R, A1, A2> > *
wrap (C *p, R (C::*f) (A1, A2), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_0_2<C *, C, R, A1, A2> >) (p, f, a1, a2);
}

template<class C, class R, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_0_2<ref<C>, C, R, A1, A2> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_0_2<ref<C>, C, R, A1, A2> >) (p, f, a1, a2);
}
template<class C, class R, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_0_2<ref<C>, C, R, A1, A2> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_0_2<ref<C>, C, R, A1, A2> >) (p, f, a1, a2);
}
template<class C, class R, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_0_2<ref<C>, C, R, A1, A2> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_0_2<ref<C>, C, R, A1, A2> >) (p, f, a1, a2);
}

template<class R, class A1, class A2, class A3>
class callback_0_3
  : public callback<R> {
  typedef R (*cb_t) (A1, A2, A3);
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
public:
  callback_0_3 (cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3)
    : f (ff), a1 (aa1), a2 (aa2), a3 (aa3) {}
  R operator() ()
    { return f (a1, a2, a3); }
};

template<class R, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_0_3<R, A1, A2, A3> > *
wrap (R (*f) (A1, A2, A3), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_0_3<R, A1, A2, A3> >) (f, a1, a2, a3);
}

template<class P, class C, class R, class A1, class A2, class A3>
class callback_c_0_3
  : public callback<R> {
  typedef R (C::*cb_t) (A1, A2, A3);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
public:
  callback_c_0_3 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3)
    : c (cc), f (ff), a1 (aa1), a2 (aa2), a3 (aa3) {}
  R operator() ()
    { return ((*c).*f) (a1, a2, a3); }
};

template<class C, class R, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_0_3<C *, C, R, A1, A2, A3> > *
wrap (C *p, R (C::*f) (A1, A2, A3), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_0_3<C *, C, R, A1, A2, A3> >) (p, f, a1, a2, a3);
}

template<class C, class R, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_0_3<ref<C>, C, R, A1, A2, A3> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, A3), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_0_3<ref<C>, C, R, A1, A2, A3> >) (p, f, a1, a2, a3);
}
template<class C, class R, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_0_3<ref<C>, C, R, A1, A2, A3> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, A3), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_0_3<ref<C>, C, R, A1, A2, A3> >) (p, f, a1, a2, a3);
}
template<class C, class R, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_0_3<ref<C>, C, R, A1, A2, A3> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, A3), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_0_3<ref<C>, C, R, A1, A2, A3> >) (p, f, a1, a2, a3);
}

template<class R, class A1, class A2, class A3, class A4>
class callback_0_4
  : public callback<R> {
  typedef R (*cb_t) (A1, A2, A3, A4);
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
public:
  callback_0_4 (cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4)
    : f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4) {}
  R operator() ()
    { return f (a1, a2, a3, a4); }
};

template<class R, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_0_4<R, A1, A2, A3, A4> > *
wrap (R (*f) (A1, A2, A3, A4), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_0_4<R, A1, A2, A3, A4> >) (f, a1, a2, a3, a4);
}

template<class P, class C, class R, class A1, class A2, class A3, class A4>
class callback_c_0_4
  : public callback<R> {
  typedef R (C::*cb_t) (A1, A2, A3, A4);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
public:
  callback_c_0_4 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4)
    : c (cc), f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4) {}
  R operator() ()
    { return ((*c).*f) (a1, a2, a3, a4); }
};

template<class C, class R, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_0_4<C *, C, R, A1, A2, A3, A4> > *
wrap (C *p, R (C::*f) (A1, A2, A3, A4), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_0_4<C *, C, R, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}

template<class C, class R, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_0_4<ref<C>, C, R, A1, A2, A3, A4> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, A3, A4), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_0_4<ref<C>, C, R, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}
template<class C, class R, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_0_4<ref<C>, C, R, A1, A2, A3, A4> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, A3, A4), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_0_4<ref<C>, C, R, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}
template<class C, class R, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_0_4<ref<C>, C, R, A1, A2, A3, A4> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, A3, A4), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_0_4<ref<C>, C, R, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}

template<class R, class A1, class A2, class A3, class A4, class A5>
class callback_0_5
  : public callback<R> {
  typedef R (*cb_t) (A1, A2, A3, A4, A5);
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
  A5 a5;
public:
  callback_0_5 (cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4, const A5 &aa5)
    : f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4), a5 (aa5) {}
  R operator() ()
    { return f (a1, a2, a3, a4, a5); }
};

template<class R, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_0_5<R, A1, A2, A3, A4, A5> > *
wrap (R (*f) (A1, A2, A3, A4, A5), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_0_5<R, A1, A2, A3, A4, A5> >) (f, a1, a2, a3, a4, a5);
}

template<class P, class C, class R, class A1, class A2, class A3, class A4, class A5>
class callback_c_0_5
  : public callback<R> {
  typedef R (C::*cb_t) (A1, A2, A3, A4, A5);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
  A5 a5;
public:
  callback_c_0_5 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4, const A5 &aa5)
    : c (cc), f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4), a5 (aa5) {}
  R operator() ()
    { return ((*c).*f) (a1, a2, a3, a4, a5); }
};

template<class C, class R, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_0_5<C *, C, R, A1, A2, A3, A4, A5> > *
wrap (C *p, R (C::*f) (A1, A2, A3, A4, A5), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_0_5<C *, C, R, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}

template<class C, class R, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_0_5<ref<C>, C, R, A1, A2, A3, A4, A5> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, A3, A4, A5), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_0_5<ref<C>, C, R, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}
template<class C, class R, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_0_5<ref<C>, C, R, A1, A2, A3, A4, A5> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, A3, A4, A5), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_0_5<ref<C>, C, R, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}
template<class C, class R, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_0_5<ref<C>, C, R, A1, A2, A3, A4, A5> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, A3, A4, A5), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_0_5<ref<C>, C, R, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}

template<class R, class B1>
class callback<R, B1> {
public:
  typedef ref<callback<R, B1> > ref;
  typedef ptr<callback<R, B1> > ptr;

  virtual R operator() (B1) = 0;
  virtual ~callback () {}
};


template<class R, class B1>
class callback_1_0
  : public callback<R, B1> {
  typedef R (*cb_t) (B1);
  cb_t f;
public:
  callback_1_0 (cb_t ff)
    : f (ff) {}
  R operator() (B1 b1)
    { return f (b1); }
};

template<class R, class B1>
static inline refcounted<callback_1_0<R, B1> > *
wrap (R (*f) (B1))
{
  return New (refcounted<callback_1_0<R, B1> >) (f);
}

template<class P, class C, class R, class B1>
class callback_c_1_0
  : public callback<R, B1> {
  typedef R (C::*cb_t) (B1);
  P c;
  cb_t f;
public:
  callback_c_1_0 (const P &cc, cb_t ff)
    : c (cc), f (ff) {}
  R operator() (B1 b1)
    { return ((*c).*f) (b1); }
};

template<class C, class R, class B1>
static inline refcounted<callback_c_1_0<C *, C, R, B1> > *
wrap (C *p, R (C::*f) (B1))
{
  return New (refcounted<callback_c_1_0<C *, C, R, B1> >) (p, f);
}

template<class C, class R, class B1>
static inline refcounted<callback_c_1_0<ref<C>, C, R, B1> > *
wrap (const ref<C> &p, R (C::*f) (B1))
{
  return New (refcounted<callback_c_1_0<ref<C>, C, R, B1> >) (p, f);
}
template<class C, class R, class B1>
static inline refcounted<callback_c_1_0<ref<C>, C, R, B1> > *
wrap (const ptr<C> &p, R (C::*f) (B1))
{
  return New (refcounted<callback_c_1_0<ref<C>, C, R, B1> >) (p, f);
}
template<class C, class R, class B1>
static inline refcounted<callback_c_1_0<ref<C>, C, R, B1> > *
wrap (const refcounted<C> *p, R (C::*f) (B1))
{
  return New (refcounted<callback_c_1_0<ref<C>, C, R, B1> >) (p, f);
}

template<class R, class B1, class A1>
class callback_1_1
  : public callback<R, B1> {
  typedef R (*cb_t) (A1, B1);
  cb_t f;
  A1 a1;
public:
  callback_1_1 (cb_t ff, const A1 &aa1)
    : f (ff), a1 (aa1) {}
  R operator() (B1 b1)
    { return f (a1, b1); }
};

template<class R, class B1, class A1, class AA1>
static inline refcounted<callback_1_1<R, B1, A1> > *
wrap (R (*f) (A1, B1), const AA1 &a1)
{
  return New (refcounted<callback_1_1<R, B1, A1> >) (f, a1);
}

template<class P, class C, class R, class B1, class A1>
class callback_c_1_1
  : public callback<R, B1> {
  typedef R (C::*cb_t) (A1, B1);
  P c;
  cb_t f;
  A1 a1;
public:
  callback_c_1_1 (const P &cc, cb_t ff, const A1 &aa1)
    : c (cc), f (ff), a1 (aa1) {}
  R operator() (B1 b1)
    { return ((*c).*f) (a1, b1); }
};

template<class C, class R, class B1, class A1, class AA1>
static inline refcounted<callback_c_1_1<C *, C, R, B1, A1> > *
wrap (C *p, R (C::*f) (A1, B1), const AA1 &a1)
{
  return New (refcounted<callback_c_1_1<C *, C, R, B1, A1> >) (p, f, a1);
}

template<class C, class R, class B1, class A1, class AA1>
static inline refcounted<callback_c_1_1<ref<C>, C, R, B1, A1> > *
wrap (const ref<C> &p, R (C::*f) (A1, B1), const AA1 &a1)
{
  return New (refcounted<callback_c_1_1<ref<C>, C, R, B1, A1> >) (p, f, a1);
}
template<class C, class R, class B1, class A1, class AA1>
static inline refcounted<callback_c_1_1<ref<C>, C, R, B1, A1> > *
wrap (const ptr<C> &p, R (C::*f) (A1, B1), const AA1 &a1)
{
  return New (refcounted<callback_c_1_1<ref<C>, C, R, B1, A1> >) (p, f, a1);
}
template<class C, class R, class B1, class A1, class AA1>
static inline refcounted<callback_c_1_1<ref<C>, C, R, B1, A1> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, B1), const AA1 &a1)
{
  return New (refcounted<callback_c_1_1<ref<C>, C, R, B1, A1> >) (p, f, a1);
}

template<class R, class B1, class A1, class A2>
class callback_1_2
  : public callback<R, B1> {
  typedef R (*cb_t) (A1, A2, B1);
  cb_t f;
  A1 a1;
  A2 a2;
public:
  callback_1_2 (cb_t ff, const A1 &aa1, const A2 &aa2)
    : f (ff), a1 (aa1), a2 (aa2) {}
  R operator() (B1 b1)
    { return f (a1, a2, b1); }
};

template<class R, class B1, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_1_2<R, B1, A1, A2> > *
wrap (R (*f) (A1, A2, B1), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_1_2<R, B1, A1, A2> >) (f, a1, a2);
}

template<class P, class C, class R, class B1, class A1, class A2>
class callback_c_1_2
  : public callback<R, B1> {
  typedef R (C::*cb_t) (A1, A2, B1);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
public:
  callback_c_1_2 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2)
    : c (cc), f (ff), a1 (aa1), a2 (aa2) {}
  R operator() (B1 b1)
    { return ((*c).*f) (a1, a2, b1); }
};

template<class C, class R, class B1, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_1_2<C *, C, R, B1, A1, A2> > *
wrap (C *p, R (C::*f) (A1, A2, B1), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_1_2<C *, C, R, B1, A1, A2> >) (p, f, a1, a2);
}

template<class C, class R, class B1, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_1_2<ref<C>, C, R, B1, A1, A2> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, B1), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_1_2<ref<C>, C, R, B1, A1, A2> >) (p, f, a1, a2);
}
template<class C, class R, class B1, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_1_2<ref<C>, C, R, B1, A1, A2> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, B1), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_1_2<ref<C>, C, R, B1, A1, A2> >) (p, f, a1, a2);
}
template<class C, class R, class B1, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_1_2<ref<C>, C, R, B1, A1, A2> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, B1), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_1_2<ref<C>, C, R, B1, A1, A2> >) (p, f, a1, a2);
}

template<class R, class B1, class A1, class A2, class A3>
class callback_1_3
  : public callback<R, B1> {
  typedef R (*cb_t) (A1, A2, A3, B1);
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
public:
  callback_1_3 (cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3)
    : f (ff), a1 (aa1), a2 (aa2), a3 (aa3) {}
  R operator() (B1 b1)
    { return f (a1, a2, a3, b1); }
};

template<class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_1_3<R, B1, A1, A2, A3> > *
wrap (R (*f) (A1, A2, A3, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_1_3<R, B1, A1, A2, A3> >) (f, a1, a2, a3);
}

template<class P, class C, class R, class B1, class A1, class A2, class A3>
class callback_c_1_3
  : public callback<R, B1> {
  typedef R (C::*cb_t) (A1, A2, A3, B1);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
public:
  callback_c_1_3 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3)
    : c (cc), f (ff), a1 (aa1), a2 (aa2), a3 (aa3) {}
  R operator() (B1 b1)
    { return ((*c).*f) (a1, a2, a3, b1); }
};

template<class C, class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_1_3<C *, C, R, B1, A1, A2, A3> > *
wrap (C *p, R (C::*f) (A1, A2, A3, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_1_3<C *, C, R, B1, A1, A2, A3> >) (p, f, a1, a2, a3);
}

template<class C, class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_1_3<ref<C>, C, R, B1, A1, A2, A3> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, A3, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_1_3<ref<C>, C, R, B1, A1, A2, A3> >) (p, f, a1, a2, a3);
}
template<class C, class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_1_3<ref<C>, C, R, B1, A1, A2, A3> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, A3, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_1_3<ref<C>, C, R, B1, A1, A2, A3> >) (p, f, a1, a2, a3);
}
template<class C, class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_1_3<ref<C>, C, R, B1, A1, A2, A3> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, A3, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_1_3<ref<C>, C, R, B1, A1, A2, A3> >) (p, f, a1, a2, a3);
}

template<class R, class B1, class A1, class A2, class A3, class A4>
class callback_1_4
  : public callback<R, B1> {
  typedef R (*cb_t) (A1, A2, A3, A4, B1);
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
public:
  callback_1_4 (cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4)
    : f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4) {}
  R operator() (B1 b1)
    { return f (a1, a2, a3, a4, b1); }
};

template<class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_1_4<R, B1, A1, A2, A3, A4> > *
wrap (R (*f) (A1, A2, A3, A4, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_1_4<R, B1, A1, A2, A3, A4> >) (f, a1, a2, a3, a4);
}

template<class P, class C, class R, class B1, class A1, class A2, class A3, class A4>
class callback_c_1_4
  : public callback<R, B1> {
  typedef R (C::*cb_t) (A1, A2, A3, A4, B1);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
public:
  callback_c_1_4 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4)
    : c (cc), f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4) {}
  R operator() (B1 b1)
    { return ((*c).*f) (a1, a2, a3, a4, b1); }
};

template<class C, class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_1_4<C *, C, R, B1, A1, A2, A3, A4> > *
wrap (C *p, R (C::*f) (A1, A2, A3, A4, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_1_4<C *, C, R, B1, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}

template<class C, class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_1_4<ref<C>, C, R, B1, A1, A2, A3, A4> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, A3, A4, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_1_4<ref<C>, C, R, B1, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}
template<class C, class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_1_4<ref<C>, C, R, B1, A1, A2, A3, A4> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, A3, A4, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_1_4<ref<C>, C, R, B1, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}
template<class C, class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_1_4<ref<C>, C, R, B1, A1, A2, A3, A4> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, A3, A4, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_1_4<ref<C>, C, R, B1, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}

template<class R, class B1, class A1, class A2, class A3, class A4, class A5>
class callback_1_5
  : public callback<R, B1> {
  typedef R (*cb_t) (A1, A2, A3, A4, A5, B1);
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
  A5 a5;
public:
  callback_1_5 (cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4, const A5 &aa5)
    : f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4), a5 (aa5) {}
  R operator() (B1 b1)
    { return f (a1, a2, a3, a4, a5, b1); }
};

template<class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_1_5<R, B1, A1, A2, A3, A4, A5> > *
wrap (R (*f) (A1, A2, A3, A4, A5, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_1_5<R, B1, A1, A2, A3, A4, A5> >) (f, a1, a2, a3, a4, a5);
}

template<class P, class C, class R, class B1, class A1, class A2, class A3, class A4, class A5>
class callback_c_1_5
  : public callback<R, B1> {
  typedef R (C::*cb_t) (A1, A2, A3, A4, A5, B1);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
  A5 a5;
public:
  callback_c_1_5 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4, const A5 &aa5)
    : c (cc), f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4), a5 (aa5) {}
  R operator() (B1 b1)
    { return ((*c).*f) (a1, a2, a3, a4, a5, b1); }
};

template<class C, class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_1_5<C *, C, R, B1, A1, A2, A3, A4, A5> > *
wrap (C *p, R (C::*f) (A1, A2, A3, A4, A5, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_1_5<C *, C, R, B1, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}

template<class C, class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_1_5<ref<C>, C, R, B1, A1, A2, A3, A4, A5> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, A3, A4, A5, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_1_5<ref<C>, C, R, B1, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}
template<class C, class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_1_5<ref<C>, C, R, B1, A1, A2, A3, A4, A5> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, A3, A4, A5, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_1_5<ref<C>, C, R, B1, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}
template<class C, class R, class B1, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_1_5<ref<C>, C, R, B1, A1, A2, A3, A4, A5> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, A3, A4, A5, B1), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_1_5<ref<C>, C, R, B1, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}

template<class R, class B1, class B2>
class callback<R, B1, B2> {
public:
  typedef ref<callback<R, B1, B2> > ref;
  typedef ptr<callback<R, B1, B2> > ptr;

  virtual R operator() (B1, B2) = 0;
  virtual ~callback () {}
};


template<class R, class B1, class B2>
class callback_2_0
  : public callback<R, B1, B2> {
  typedef R (*cb_t) (B1, B2);
  cb_t f;
public:
  callback_2_0 (cb_t ff)
    : f (ff) {}
  R operator() (B1 b1, B2 b2)
    { return f (b1, b2); }
};

template<class R, class B1, class B2>
static inline refcounted<callback_2_0<R, B1, B2> > *
wrap (R (*f) (B1, B2))
{
  return New (refcounted<callback_2_0<R, B1, B2> >) (f);
}

template<class P, class C, class R, class B1, class B2>
class callback_c_2_0
  : public callback<R, B1, B2> {
  typedef R (C::*cb_t) (B1, B2);
  P c;
  cb_t f;
public:
  callback_c_2_0 (const P &cc, cb_t ff)
    : c (cc), f (ff) {}
  R operator() (B1 b1, B2 b2)
    { return ((*c).*f) (b1, b2); }
};

template<class C, class R, class B1, class B2>
static inline refcounted<callback_c_2_0<C *, C, R, B1, B2> > *
wrap (C *p, R (C::*f) (B1, B2))
{
  return New (refcounted<callback_c_2_0<C *, C, R, B1, B2> >) (p, f);
}

template<class C, class R, class B1, class B2>
static inline refcounted<callback_c_2_0<ref<C>, C, R, B1, B2> > *
wrap (const ref<C> &p, R (C::*f) (B1, B2))
{
  return New (refcounted<callback_c_2_0<ref<C>, C, R, B1, B2> >) (p, f);
}
template<class C, class R, class B1, class B2>
static inline refcounted<callback_c_2_0<ref<C>, C, R, B1, B2> > *
wrap (const ptr<C> &p, R (C::*f) (B1, B2))
{
  return New (refcounted<callback_c_2_0<ref<C>, C, R, B1, B2> >) (p, f);
}
template<class C, class R, class B1, class B2>
static inline refcounted<callback_c_2_0<ref<C>, C, R, B1, B2> > *
wrap (const refcounted<C> *p, R (C::*f) (B1, B2))
{
  return New (refcounted<callback_c_2_0<ref<C>, C, R, B1, B2> >) (p, f);
}

template<class R, class B1, class B2, class A1>
class callback_2_1
  : public callback<R, B1, B2> {
  typedef R (*cb_t) (A1, B1, B2);
  cb_t f;
  A1 a1;
public:
  callback_2_1 (cb_t ff, const A1 &aa1)
    : f (ff), a1 (aa1) {}
  R operator() (B1 b1, B2 b2)
    { return f (a1, b1, b2); }
};

template<class R, class B1, class B2, class A1, class AA1>
static inline refcounted<callback_2_1<R, B1, B2, A1> > *
wrap (R (*f) (A1, B1, B2), const AA1 &a1)
{
  return New (refcounted<callback_2_1<R, B1, B2, A1> >) (f, a1);
}

template<class P, class C, class R, class B1, class B2, class A1>
class callback_c_2_1
  : public callback<R, B1, B2> {
  typedef R (C::*cb_t) (A1, B1, B2);
  P c;
  cb_t f;
  A1 a1;
public:
  callback_c_2_1 (const P &cc, cb_t ff, const A1 &aa1)
    : c (cc), f (ff), a1 (aa1) {}
  R operator() (B1 b1, B2 b2)
    { return ((*c).*f) (a1, b1, b2); }
};

template<class C, class R, class B1, class B2, class A1, class AA1>
static inline refcounted<callback_c_2_1<C *, C, R, B1, B2, A1> > *
wrap (C *p, R (C::*f) (A1, B1, B2), const AA1 &a1)
{
  return New (refcounted<callback_c_2_1<C *, C, R, B1, B2, A1> >) (p, f, a1);
}

template<class C, class R, class B1, class B2, class A1, class AA1>
static inline refcounted<callback_c_2_1<ref<C>, C, R, B1, B2, A1> > *
wrap (const ref<C> &p, R (C::*f) (A1, B1, B2), const AA1 &a1)
{
  return New (refcounted<callback_c_2_1<ref<C>, C, R, B1, B2, A1> >) (p, f, a1);
}
template<class C, class R, class B1, class B2, class A1, class AA1>
static inline refcounted<callback_c_2_1<ref<C>, C, R, B1, B2, A1> > *
wrap (const ptr<C> &p, R (C::*f) (A1, B1, B2), const AA1 &a1)
{
  return New (refcounted<callback_c_2_1<ref<C>, C, R, B1, B2, A1> >) (p, f, a1);
}
template<class C, class R, class B1, class B2, class A1, class AA1>
static inline refcounted<callback_c_2_1<ref<C>, C, R, B1, B2, A1> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, B1, B2), const AA1 &a1)
{
  return New (refcounted<callback_c_2_1<ref<C>, C, R, B1, B2, A1> >) (p, f, a1);
}

template<class R, class B1, class B2, class A1, class A2>
class callback_2_2
  : public callback<R, B1, B2> {
  typedef R (*cb_t) (A1, A2, B1, B2);
  cb_t f;
  A1 a1;
  A2 a2;
public:
  callback_2_2 (cb_t ff, const A1 &aa1, const A2 &aa2)
    : f (ff), a1 (aa1), a2 (aa2) {}
  R operator() (B1 b1, B2 b2)
    { return f (a1, a2, b1, b2); }
};

template<class R, class B1, class B2, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_2_2<R, B1, B2, A1, A2> > *
wrap (R (*f) (A1, A2, B1, B2), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_2_2<R, B1, B2, A1, A2> >) (f, a1, a2);
}

template<class P, class C, class R, class B1, class B2, class A1, class A2>
class callback_c_2_2
  : public callback<R, B1, B2> {
  typedef R (C::*cb_t) (A1, A2, B1, B2);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
public:
  callback_c_2_2 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2)
    : c (cc), f (ff), a1 (aa1), a2 (aa2) {}
  R operator() (B1 b1, B2 b2)
    { return ((*c).*f) (a1, a2, b1, b2); }
};

template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_2_2<C *, C, R, B1, B2, A1, A2> > *
wrap (C *p, R (C::*f) (A1, A2, B1, B2), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_2_2<C *, C, R, B1, B2, A1, A2> >) (p, f, a1, a2);
}

template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_2_2<ref<C>, C, R, B1, B2, A1, A2> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, B1, B2), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_2_2<ref<C>, C, R, B1, B2, A1, A2> >) (p, f, a1, a2);
}
template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_2_2<ref<C>, C, R, B1, B2, A1, A2> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, B1, B2), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_2_2<ref<C>, C, R, B1, B2, A1, A2> >) (p, f, a1, a2);
}
template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_2_2<ref<C>, C, R, B1, B2, A1, A2> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, B1, B2), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_2_2<ref<C>, C, R, B1, B2, A1, A2> >) (p, f, a1, a2);
}

template<class R, class B1, class B2, class A1, class A2, class A3>
class callback_2_3
  : public callback<R, B1, B2> {
  typedef R (*cb_t) (A1, A2, A3, B1, B2);
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
public:
  callback_2_3 (cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3)
    : f (ff), a1 (aa1), a2 (aa2), a3 (aa3) {}
  R operator() (B1 b1, B2 b2)
    { return f (a1, a2, a3, b1, b2); }
};

template<class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_2_3<R, B1, B2, A1, A2, A3> > *
wrap (R (*f) (A1, A2, A3, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_2_3<R, B1, B2, A1, A2, A3> >) (f, a1, a2, a3);
}

template<class P, class C, class R, class B1, class B2, class A1, class A2, class A3>
class callback_c_2_3
  : public callback<R, B1, B2> {
  typedef R (C::*cb_t) (A1, A2, A3, B1, B2);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
public:
  callback_c_2_3 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3)
    : c (cc), f (ff), a1 (aa1), a2 (aa2), a3 (aa3) {}
  R operator() (B1 b1, B2 b2)
    { return ((*c).*f) (a1, a2, a3, b1, b2); }
};

template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_2_3<C *, C, R, B1, B2, A1, A2, A3> > *
wrap (C *p, R (C::*f) (A1, A2, A3, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_2_3<C *, C, R, B1, B2, A1, A2, A3> >) (p, f, a1, a2, a3);
}

template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_2_3<ref<C>, C, R, B1, B2, A1, A2, A3> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, A3, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_2_3<ref<C>, C, R, B1, B2, A1, A2, A3> >) (p, f, a1, a2, a3);
}
template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_2_3<ref<C>, C, R, B1, B2, A1, A2, A3> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, A3, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_2_3<ref<C>, C, R, B1, B2, A1, A2, A3> >) (p, f, a1, a2, a3);
}
template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_2_3<ref<C>, C, R, B1, B2, A1, A2, A3> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, A3, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_2_3<ref<C>, C, R, B1, B2, A1, A2, A3> >) (p, f, a1, a2, a3);
}

template<class R, class B1, class B2, class A1, class A2, class A3, class A4>
class callback_2_4
  : public callback<R, B1, B2> {
  typedef R (*cb_t) (A1, A2, A3, A4, B1, B2);
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
public:
  callback_2_4 (cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4)
    : f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4) {}
  R operator() (B1 b1, B2 b2)
    { return f (a1, a2, a3, a4, b1, b2); }
};

template<class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_2_4<R, B1, B2, A1, A2, A3, A4> > *
wrap (R (*f) (A1, A2, A3, A4, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_2_4<R, B1, B2, A1, A2, A3, A4> >) (f, a1, a2, a3, a4);
}

template<class P, class C, class R, class B1, class B2, class A1, class A2, class A3, class A4>
class callback_c_2_4
  : public callback<R, B1, B2> {
  typedef R (C::*cb_t) (A1, A2, A3, A4, B1, B2);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
public:
  callback_c_2_4 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4)
    : c (cc), f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4) {}
  R operator() (B1 b1, B2 b2)
    { return ((*c).*f) (a1, a2, a3, a4, b1, b2); }
};

template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_2_4<C *, C, R, B1, B2, A1, A2, A3, A4> > *
wrap (C *p, R (C::*f) (A1, A2, A3, A4, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_2_4<C *, C, R, B1, B2, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}

template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_2_4<ref<C>, C, R, B1, B2, A1, A2, A3, A4> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, A3, A4, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_2_4<ref<C>, C, R, B1, B2, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}
template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_2_4<ref<C>, C, R, B1, B2, A1, A2, A3, A4> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, A3, A4, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_2_4<ref<C>, C, R, B1, B2, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}
template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_2_4<ref<C>, C, R, B1, B2, A1, A2, A3, A4> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, A3, A4, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_2_4<ref<C>, C, R, B1, B2, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}

template<class R, class B1, class B2, class A1, class A2, class A3, class A4, class A5>
class callback_2_5
  : public callback<R, B1, B2> {
  typedef R (*cb_t) (A1, A2, A3, A4, A5, B1, B2);
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
  A5 a5;
public:
  callback_2_5 (cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4, const A5 &aa5)
    : f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4), a5 (aa5) {}
  R operator() (B1 b1, B2 b2)
    { return f (a1, a2, a3, a4, a5, b1, b2); }
};

template<class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_2_5<R, B1, B2, A1, A2, A3, A4, A5> > *
wrap (R (*f) (A1, A2, A3, A4, A5, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_2_5<R, B1, B2, A1, A2, A3, A4, A5> >) (f, a1, a2, a3, a4, a5);
}

template<class P, class C, class R, class B1, class B2, class A1, class A2, class A3, class A4, class A5>
class callback_c_2_5
  : public callback<R, B1, B2> {
  typedef R (C::*cb_t) (A1, A2, A3, A4, A5, B1, B2);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
  A5 a5;
public:
  callback_c_2_5 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4, const A5 &aa5)
    : c (cc), f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4), a5 (aa5) {}
  R operator() (B1 b1, B2 b2)
    { return ((*c).*f) (a1, a2, a3, a4, a5, b1, b2); }
};

template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_2_5<C *, C, R, B1, B2, A1, A2, A3, A4, A5> > *
wrap (C *p, R (C::*f) (A1, A2, A3, A4, A5, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_2_5<C *, C, R, B1, B2, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}

template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_2_5<ref<C>, C, R, B1, B2, A1, A2, A3, A4, A5> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, A3, A4, A5, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_2_5<ref<C>, C, R, B1, B2, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}
template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_2_5<ref<C>, C, R, B1, B2, A1, A2, A3, A4, A5> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, A3, A4, A5, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_2_5<ref<C>, C, R, B1, B2, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}
template<class C, class R, class B1, class B2, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_2_5<ref<C>, C, R, B1, B2, A1, A2, A3, A4, A5> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, A3, A4, A5, B1, B2), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_2_5<ref<C>, C, R, B1, B2, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}

template<class R, class B1, class B2, class B3>
class callback {
public:
  typedef ref<callback<R, B1, B2, B3> > ref;
  typedef ptr<callback<R, B1, B2, B3> > ptr;

  virtual R operator() (B1, B2, B3) = 0;
  virtual ~callback () {}
};


template<class R, class B1, class B2, class B3>
class callback_3_0
  : public callback<R, B1, B2, B3> {
  typedef R (*cb_t) (B1, B2, B3);
  cb_t f;
public:
  callback_3_0 (cb_t ff)
    : f (ff) {}
  R operator() (B1 b1, B2 b2, B3 b3)
    { return f (b1, b2, b3); }
};

template<class R, class B1, class B2, class B3>
static inline refcounted<callback_3_0<R, B1, B2, B3> > *
wrap (R (*f) (B1, B2, B3))
{
  return New (refcounted<callback_3_0<R, B1, B2, B3> >) (f);
}

template<class P, class C, class R, class B1, class B2, class B3>
class callback_c_3_0
  : public callback<R, B1, B2, B3> {
  typedef R (C::*cb_t) (B1, B2, B3);
  P c;
  cb_t f;
public:
  callback_c_3_0 (const P &cc, cb_t ff)
    : c (cc), f (ff) {}
  R operator() (B1 b1, B2 b2, B3 b3)
    { return ((*c).*f) (b1, b2, b3); }
};

template<class C, class R, class B1, class B2, class B3>
static inline refcounted<callback_c_3_0<C *, C, R, B1, B2, B3> > *
wrap (C *p, R (C::*f) (B1, B2, B3))
{
  return New (refcounted<callback_c_3_0<C *, C, R, B1, B2, B3> >) (p, f);
}

template<class C, class R, class B1, class B2, class B3>
static inline refcounted<callback_c_3_0<ref<C>, C, R, B1, B2, B3> > *
wrap (const ref<C> &p, R (C::*f) (B1, B2, B3))
{
  return New (refcounted<callback_c_3_0<ref<C>, C, R, B1, B2, B3> >) (p, f);
}
template<class C, class R, class B1, class B2, class B3>
static inline refcounted<callback_c_3_0<ref<C>, C, R, B1, B2, B3> > *
wrap (const ptr<C> &p, R (C::*f) (B1, B2, B3))
{
  return New (refcounted<callback_c_3_0<ref<C>, C, R, B1, B2, B3> >) (p, f);
}
template<class C, class R, class B1, class B2, class B3>
static inline refcounted<callback_c_3_0<ref<C>, C, R, B1, B2, B3> > *
wrap (const refcounted<C> *p, R (C::*f) (B1, B2, B3))
{
  return New (refcounted<callback_c_3_0<ref<C>, C, R, B1, B2, B3> >) (p, f);
}

template<class R, class B1, class B2, class B3, class A1>
class callback_3_1
  : public callback<R, B1, B2, B3> {
  typedef R (*cb_t) (A1, B1, B2, B3);
  cb_t f;
  A1 a1;
public:
  callback_3_1 (cb_t ff, const A1 &aa1)
    : f (ff), a1 (aa1) {}
  R operator() (B1 b1, B2 b2, B3 b3)
    { return f (a1, b1, b2, b3); }
};

template<class R, class B1, class B2, class B3, class A1, class AA1>
static inline refcounted<callback_3_1<R, B1, B2, B3, A1> > *
wrap (R (*f) (A1, B1, B2, B3), const AA1 &a1)
{
  return New (refcounted<callback_3_1<R, B1, B2, B3, A1> >) (f, a1);
}

template<class P, class C, class R, class B1, class B2, class B3, class A1>
class callback_c_3_1
  : public callback<R, B1, B2, B3> {
  typedef R (C::*cb_t) (A1, B1, B2, B3);
  P c;
  cb_t f;
  A1 a1;
public:
  callback_c_3_1 (const P &cc, cb_t ff, const A1 &aa1)
    : c (cc), f (ff), a1 (aa1) {}
  R operator() (B1 b1, B2 b2, B3 b3)
    { return ((*c).*f) (a1, b1, b2, b3); }
};

template<class C, class R, class B1, class B2, class B3, class A1, class AA1>
static inline refcounted<callback_c_3_1<C *, C, R, B1, B2, B3, A1> > *
wrap (C *p, R (C::*f) (A1, B1, B2, B3), const AA1 &a1)
{
  return New (refcounted<callback_c_3_1<C *, C, R, B1, B2, B3, A1> >) (p, f, a1);
}

template<class C, class R, class B1, class B2, class B3, class A1, class AA1>
static inline refcounted<callback_c_3_1<ref<C>, C, R, B1, B2, B3, A1> > *
wrap (const ref<C> &p, R (C::*f) (A1, B1, B2, B3), const AA1 &a1)
{
  return New (refcounted<callback_c_3_1<ref<C>, C, R, B1, B2, B3, A1> >) (p, f, a1);
}
template<class C, class R, class B1, class B2, class B3, class A1, class AA1>
static inline refcounted<callback_c_3_1<ref<C>, C, R, B1, B2, B3, A1> > *
wrap (const ptr<C> &p, R (C::*f) (A1, B1, B2, B3), const AA1 &a1)
{
  return New (refcounted<callback_c_3_1<ref<C>, C, R, B1, B2, B3, A1> >) (p, f, a1);
}
template<class C, class R, class B1, class B2, class B3, class A1, class AA1>
static inline refcounted<callback_c_3_1<ref<C>, C, R, B1, B2, B3, A1> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, B1, B2, B3), const AA1 &a1)
{
  return New (refcounted<callback_c_3_1<ref<C>, C, R, B1, B2, B3, A1> >) (p, f, a1);
}

template<class R, class B1, class B2, class B3, class A1, class A2>
class callback_3_2
  : public callback<R, B1, B2, B3> {
  typedef R (*cb_t) (A1, A2, B1, B2, B3);
  cb_t f;
  A1 a1;
  A2 a2;
public:
  callback_3_2 (cb_t ff, const A1 &aa1, const A2 &aa2)
    : f (ff), a1 (aa1), a2 (aa2) {}
  R operator() (B1 b1, B2 b2, B3 b3)
    { return f (a1, a2, b1, b2, b3); }
};

template<class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_3_2<R, B1, B2, B3, A1, A2> > *
wrap (R (*f) (A1, A2, B1, B2, B3), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_3_2<R, B1, B2, B3, A1, A2> >) (f, a1, a2);
}

template<class P, class C, class R, class B1, class B2, class B3, class A1, class A2>
class callback_c_3_2
  : public callback<R, B1, B2, B3> {
  typedef R (C::*cb_t) (A1, A2, B1, B2, B3);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
public:
  callback_c_3_2 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2)
    : c (cc), f (ff), a1 (aa1), a2 (aa2) {}
  R operator() (B1 b1, B2 b2, B3 b3)
    { return ((*c).*f) (a1, a2, b1, b2, b3); }
};

template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_3_2<C *, C, R, B1, B2, B3, A1, A2> > *
wrap (C *p, R (C::*f) (A1, A2, B1, B2, B3), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_3_2<C *, C, R, B1, B2, B3, A1, A2> >) (p, f, a1, a2);
}

template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_3_2<ref<C>, C, R, B1, B2, B3, A1, A2> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, B1, B2, B3), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_3_2<ref<C>, C, R, B1, B2, B3, A1, A2> >) (p, f, a1, a2);
}
template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_3_2<ref<C>, C, R, B1, B2, B3, A1, A2> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, B1, B2, B3), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_3_2<ref<C>, C, R, B1, B2, B3, A1, A2> >) (p, f, a1, a2);
}
template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2>
static inline refcounted<callback_c_3_2<ref<C>, C, R, B1, B2, B3, A1, A2> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, B1, B2, B3), const AA1 &a1, const AA2 &a2)
{
  return New (refcounted<callback_c_3_2<ref<C>, C, R, B1, B2, B3, A1, A2> >) (p, f, a1, a2);
}

template<class R, class B1, class B2, class B3, class A1, class A2, class A3>
class callback_3_3
  : public callback<R, B1, B2, B3> {
  typedef R (*cb_t) (A1, A2, A3, B1, B2, B3);
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
public:
  callback_3_3 (cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3)
    : f (ff), a1 (aa1), a2 (aa2), a3 (aa3) {}
  R operator() (B1 b1, B2 b2, B3 b3)
    { return f (a1, a2, a3, b1, b2, b3); }
};

template<class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_3_3<R, B1, B2, B3, A1, A2, A3> > *
wrap (R (*f) (A1, A2, A3, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_3_3<R, B1, B2, B3, A1, A2, A3> >) (f, a1, a2, a3);
}

template<class P, class C, class R, class B1, class B2, class B3, class A1, class A2, class A3>
class callback_c_3_3
  : public callback<R, B1, B2, B3> {
  typedef R (C::*cb_t) (A1, A2, A3, B1, B2, B3);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
public:
  callback_c_3_3 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3)
    : c (cc), f (ff), a1 (aa1), a2 (aa2), a3 (aa3) {}
  R operator() (B1 b1, B2 b2, B3 b3)
    { return ((*c).*f) (a1, a2, a3, b1, b2, b3); }
};

template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_3_3<C *, C, R, B1, B2, B3, A1, A2, A3> > *
wrap (C *p, R (C::*f) (A1, A2, A3, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_3_3<C *, C, R, B1, B2, B3, A1, A2, A3> >) (p, f, a1, a2, a3);
}

template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_3_3<ref<C>, C, R, B1, B2, B3, A1, A2, A3> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, A3, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_3_3<ref<C>, C, R, B1, B2, B3, A1, A2, A3> >) (p, f, a1, a2, a3);
}
template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_3_3<ref<C>, C, R, B1, B2, B3, A1, A2, A3> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, A3, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_3_3<ref<C>, C, R, B1, B2, B3, A1, A2, A3> >) (p, f, a1, a2, a3);
}
template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3>
static inline refcounted<callback_c_3_3<ref<C>, C, R, B1, B2, B3, A1, A2, A3> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, A3, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3)
{
  return New (refcounted<callback_c_3_3<ref<C>, C, R, B1, B2, B3, A1, A2, A3> >) (p, f, a1, a2, a3);
}

template<class R, class B1, class B2, class B3, class A1, class A2, class A3, class A4>
class callback_3_4
  : public callback<R, B1, B2, B3> {
  typedef R (*cb_t) (A1, A2, A3, A4, B1, B2, B3);
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
public:
  callback_3_4 (cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4)
    : f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4) {}
  R operator() (B1 b1, B2 b2, B3 b3)
    { return f (a1, a2, a3, a4, b1, b2, b3); }
};

template<class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_3_4<R, B1, B2, B3, A1, A2, A3, A4> > *
wrap (R (*f) (A1, A2, A3, A4, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_3_4<R, B1, B2, B3, A1, A2, A3, A4> >) (f, a1, a2, a3, a4);
}

template<class P, class C, class R, class B1, class B2, class B3, class A1, class A2, class A3, class A4>
class callback_c_3_4
  : public callback<R, B1, B2, B3> {
  typedef R (C::*cb_t) (A1, A2, A3, A4, B1, B2, B3);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
public:
  callback_c_3_4 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4)
    : c (cc), f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4) {}
  R operator() (B1 b1, B2 b2, B3 b3)
    { return ((*c).*f) (a1, a2, a3, a4, b1, b2, b3); }
};

template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_3_4<C *, C, R, B1, B2, B3, A1, A2, A3, A4> > *
wrap (C *p, R (C::*f) (A1, A2, A3, A4, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_3_4<C *, C, R, B1, B2, B3, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}

template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_3_4<ref<C>, C, R, B1, B2, B3, A1, A2, A3, A4> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, A3, A4, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_3_4<ref<C>, C, R, B1, B2, B3, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}
template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_3_4<ref<C>, C, R, B1, B2, B3, A1, A2, A3, A4> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, A3, A4, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_3_4<ref<C>, C, R, B1, B2, B3, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}
template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4>
static inline refcounted<callback_c_3_4<ref<C>, C, R, B1, B2, B3, A1, A2, A3, A4> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, A3, A4, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4)
{
  return New (refcounted<callback_c_3_4<ref<C>, C, R, B1, B2, B3, A1, A2, A3, A4> >) (p, f, a1, a2, a3, a4);
}

template<class R, class B1, class B2, class B3, class A1, class A2, class A3, class A4, class A5>
class callback_3_5
  : public callback<R, B1, B2, B3> {
  typedef R (*cb_t) (A1, A2, A3, A4, A5, B1, B2, B3);
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
  A5 a5;
public:
  callback_3_5 (cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4, const A5 &aa5)
    : f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4), a5 (aa5) {}
  R operator() (B1 b1, B2 b2, B3 b3)
    { return f (a1, a2, a3, a4, a5, b1, b2, b3); }
};

template<class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_3_5<R, B1, B2, B3, A1, A2, A3, A4, A5> > *
wrap (R (*f) (A1, A2, A3, A4, A5, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_3_5<R, B1, B2, B3, A1, A2, A3, A4, A5> >) (f, a1, a2, a3, a4, a5);
}

template<class P, class C, class R, class B1, class B2, class B3, class A1, class A2, class A3, class A4, class A5>
class callback_c_3_5
  : public callback<R, B1, B2, B3> {
  typedef R (C::*cb_t) (A1, A2, A3, A4, A5, B1, B2, B3);
  P c;
  cb_t f;
  A1 a1;
  A2 a2;
  A3 a3;
  A4 a4;
  A5 a5;
public:
  callback_c_3_5 (const P &cc, cb_t ff, const A1 &aa1, const A2 &aa2, const A3 &aa3, const A4 &aa4, const A5 &aa5)
    : c (cc), f (ff), a1 (aa1), a2 (aa2), a3 (aa3), a4 (aa4), a5 (aa5) {}
  R operator() (B1 b1, B2 b2, B3 b3)
    { return ((*c).*f) (a1, a2, a3, a4, a5, b1, b2, b3); }
};

template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_3_5<C *, C, R, B1, B2, B3, A1, A2, A3, A4, A5> > *
wrap (C *p, R (C::*f) (A1, A2, A3, A4, A5, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_3_5<C *, C, R, B1, B2, B3, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}

template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_3_5<ref<C>, C, R, B1, B2, B3, A1, A2, A3, A4, A5> > *
wrap (const ref<C> &p, R (C::*f) (A1, A2, A3, A4, A5, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_3_5<ref<C>, C, R, B1, B2, B3, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}
template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_3_5<ref<C>, C, R, B1, B2, B3, A1, A2, A3, A4, A5> > *
wrap (const ptr<C> &p, R (C::*f) (A1, A2, A3, A4, A5, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_3_5<ref<C>, C, R, B1, B2, B3, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}
template<class C, class R, class B1, class B2, class B3, class A1, class AA1, class A2, class AA2, class A3, class AA3, class A4, class AA4, class A5, class AA5>
static inline refcounted<callback_c_3_5<ref<C>, C, R, B1, B2, B3, A1, A2, A3, A4, A5> > *
wrap (const refcounted<C> *p, R (C::*f) (A1, A2, A3, A4, A5, B1, B2, B3), const AA1 &a1, const AA2 &a2, const AA3 &a3, const AA4 &a4, const AA5 &a5)
{
  return New (refcounted<callback_c_3_5<ref<C>, C, R, B1, B2, B3, A1, A2, A3, A4, A5> >) (p, f, a1, a2, a3, a4, a5);
}

template<class R, class B1, class B2, class B3>
class refops<callback<R, B1, B2, B3> > {
  typedef callback<R, B1, B2, B3> cb_t;
  REFOPS_DEFAULT (cb_t);
  R operator() () { return (*p) (); }
  template<class BB1>
  R operator() (const BB1 &b1)
    { return (*p) (b1); }
  template<class BB1, class BB2>
  R operator() (const BB1 &b1, const BB2 &b2)
    { return (*p) (b1, b2); }
  template<class BB1, class BB2, class BB3>
  R operator() (const BB1 &b1, const BB2 &b2, const BB3 &b3)
    { return (*p) (b1, b2, b3); }
};

#endif /* !_CALLBACK_H_INCLUDED_ */
