/* Copyright (C) 2008 to 2016 Chris Vine

The library comprised in this file or of which this file is part is
distributed by Chris Vine under the GNU Lesser General Public
License as follows:

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public License
   as published by the Free Software Foundation; either version 2.1 of
   the License, or (at your option) any later version.

   This library 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
   Lesser General Public License, version 2.1, for more details.

   You should have received a copy of the GNU Lesser General Public
   License, version 2.1, along with this library (see the file LGPL.TXT
   which came with this source code package in the c++-gtk-utils
   sub-directory); if not, write to the Free Software Foundation, Inc.,
   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

However, it is not intended that the object code of a program whose
source code instantiates a template from this file or uses macros or
inline functions (of any length) should by reason only of that
instantiation or use be subject to the restrictions of use in the GNU
Lesser General Public License.  With that in mind, the words "and
macros, inline functions and instantiations of templates (of any
length)" shall be treated as substituted for the words "and small
macros and small inline functions (ten lines or less in length)" in
the fourth paragraph of section 5 of that licence.  This does not
affect any other reason why object code may be subject to the
restrictions in that licence (nor for the avoidance of doubt does it
affect the application of section 2 of that licence to modifications
of the source code in this file).

*/

#ifndef CGU_CALLBACK_H
#define CGU_CALLBACK_H

/**
 * @file callback.h
 * @brief This file provides classes for type erasure.
 *
 * \#include <c++-gtk-utils/callback.h>
 *
 * These classes provide type erasure on callable objects.  They
 * comprise a generic callback creation and execution interface for
 * closures.  There is a basic Callback::Callback type, which is an
 * entire closure or 'thunk', where all values are bound into the
 * object, and is completely opaque.  Callback::CallbackArg<T...> is a
 * class which takes unbound arguments of the template types when the
 * object is dispatched.  (The opaque Callback::Callback type is a
 * typedef for Callback::CallbackArg<>: the two types are
 * interchangeable.)
 *
 * Objects of these classes are normally constructed using the
 * Callback::lambda() factory function, which takes any callable
 * object such as a lambda expression or the return value of
 * std::bind, and returns a pointer to a Callback/CallbackArg object
 * allocated on free store.  When using Callback::lambda(), the
 * unbound argument types (if any) must be passed as explicit template
 * parameters.
 *
 * Callback/CallbackArg objects can also be constructed using the
 * Callback::make() and Callback::make_ref() factory functions, which
 * can be useful where invoking standalone functions or object
 * methods.
 *
 * From version 2.0.23, a convenience Callback::to_unique() function
 * is available which will construct a std::unique_ptr object from a
 * Callback/CallbackArg object returned by Callback::lambda(),
 * Callback::make() or Callback::make_ref(), for the purpose of taking
 * ownership of the Callback/CallbackArg object.  This function is
 * mainly intended for use with the auto keyword, to avoid having to
 * write out the type of the unique_ptr object in longhand.
 * Corresponding Callback::to_functor() and
 * Callback::to_safe_functor() functions are also provided.
 *
 * The Callback/CallbackArg classes do not provide for a return
 * value. If a result is wanted, users should pass an unbound argument
 * by reference or pointer (or pointer to pointer).
 *
 * The Callback::make() and Callback::make_ref() functions
 * -------------------------------------------------------
 *
 * The Callback::make() and Callback::make_ref() functions construct a
 * Callback/CallbackArg object from a function pointer (or an object
 * reference and member function pointer) together with bound
 * arguments.  They provide for a maximum of five bound arguments, and
 * the unbound arguments (if any) must be the last (trailing)
 * arguments of the relevant function or method to be called.
 *
 * Callback::make() does a direct type mapping from the bound
 * arguments of the function or method represented by the callback
 * object to the arguments stored by it and is for use when all bound
 * arguments are simple fundamental types such as pointers (including
 * C strings), integers or floating points.
 *
 * Callback::make_ref() is for use where bound arguments include class
 * types or one or more of the types of the bound arguments include a
 * const reference.  It will accomplish perfect forwarding (by lvalue
 * reference or rvalue reference) when constructing the callback and
 * will also ensure that a copy of any object to be passed by const
 * reference (as well as any taken by value) is kept in order to avoid
 * dangling references.  Note however that where a member function is
 * called, the object of which the target function is a member must
 * still be in existence when the Callback/CallbackArg object is
 * dispatched and, unlike Callback::make(), Callback::make_ref()
 * cannot be used with overloaded functions except with explicit
 * disambiguation.
 *
 * Callback::make() can also construct a Callback/CallbackArg object
 * from a std::function object.
 *
 * Callback::FunctorArg and Callback::SafeFunctorArg classes
 * ---------------------------------------------------------
 *
 * Functor/FunctorArg objects hold a Callback/CallbackArg object by
 * SharedPtr to enable them to be shared by reference counting, and
 * SafeFunctor/SafeFunctorArg objects hold them by SharedLockPtr,
 * which have a thread safe reference count so that they may be shared
 * between different threads.  These classes also have an operator()()
 * method so as to be callable with function syntax.
 *
 * Memory allocation
 * -----------------
 *
 * If the library is installed using the
 * \--with-glib-memory-slices-no-compat configuration option, any
 * Callback/CallbackArg object will be constructed in glib memory
 * slices rather than in the generic C++ free store.
 *
 * Usage
 * -----
 *
 * Using Callback::lambda():
 *
 * @code 
 *   using namespace Cgu;
 *
 *   // here cb1 is of type Callback::Callback*
 *   auto cb1 = Callback::lambda<>([]() {std::cout << "Hello world\n";});
 *   cb1->dispatch();
 *   delete cb1;
 *
 *   // here Callback::to_unique() is used to make a std::unique_ptr object to
 *   // manage the callback. cb2 is of type std::unique_ptr<const Callback::Callback>
 *   auto cb2 = Callback::to_unique(Callback::lambda<>([]() {std::cout << "Hello world\n";}));
 *   cb2->dispatch();
 *
 *   // the same using Callback::Functor
 *   Callback::Functor f1{Callback::lambda<>([]() {std::cout << "Hello world\n";})};
 *   f1();
 *
 *   int k = 5;
 *   // here cb3 is of type std::unique_ptr<const Callback::CallbackArg<int, int&>>
 *   auto cb3 = Callback::to_unique(Callback::lambda<int, int&>([=] (int i, int& j) {j = k * 10 * i;}));
 *   int res;
 *   cb3->dispatch(2, res);
 *   std::cout << k << " times 10 times 2 is " << res << '\n';
 *
 *   // the same using Callback::FunctorArg
 *   Callback::FunctorArg<int, int&> f2{Callback::lambda<int, int&>([=] (int i, int& j) {j = k * 10 * i;})};
 *   f2(2, res);
 *   std::cout << k << " times 10 times 2 is " << res << '\n';
 * @endcode
 *
 * Using Callback::make(), with a class object my_obj of type MyClass,
 * with a method void MyClass::my_method(int, int, const char*):
 *
 * @code 
 *   using namespace Cgu;
 *
 *   int arg1 = 1, arg2 = 5;
 *
 *   // here cb1 is of type Callback::Callback*
 *   auto cb1 = Callback::make(my_obj, &MyClass::my_method, arg1, arg2, "Hello\n");
 *   cb1->dispatch();
 *   delete cb1;
 *
 *   // here cb2 is of type std::unique_ptr<const Callback::Callback>
 *   auto cb2 = Callback::to_unique(Callback::make(my_obj, &MyClass::my_method, arg1, arg2, "Hello\n"));
 *   cb2->dispatch();
 *
 *   // the same using Callback::Functor
 *   Callback::Functor f1{Callback::make(my_obj, &MyClass::my_method, arg1, arg2, "Hello\n")};
 *   f1();
 *
 *   // here cb3 is of type std::unique_ptr<const Callback::CallbackArg<int, const char*>>
 *   auto cb3 = Callback::to_unique(Callback::make(my_obj, &MyClass::my_method, arg1));
 *   cb3->dispatch(arg2, "Hello\n");
 *
 *   // the same using Callback::FunctorArg
 *   Callback::FunctorArg<int, const char*> f2{Callback::make(my_obj, &MyClass::my_method, arg1)};
 *   f2(arg2, "Hello\n");
 * @endcode
 *
 * Using Callback::make_ref(), with a class object my_obj of type
 * MyClass, with a method void MyClass::my_method(int, const
 * Something&):
 *
 * @code
 *   int arg1 = 1;
 *   Something arg2;
 *   // here cb is of type std::unique_ptr<const Callback::Callback>
 *   auto cb = Callback::to_unique(Callback::make_ref(my_obj, &MyClass::my_method, arg1, arg2));
 * @endcode
 *
 * Posting of callbacks
 * --------------------
 *
 * This file also provides a Callback::post() function which will
 * execute a callback in a glib main loop and can be used (amongst
 * other things) to pass an event from a worker thread to the main
 * program thread.  In that respect, it provides an alternative to the
 * Notifier class.  It is passed a pointer to a Callback::Callback
 * object created with a call to Callback::lambda(), Callback::make(),
 * Callback::make_ref().
 *
 * To provide for thread-safe automatic disconnection of the callback
 * if the callback represents or calls into a non-static method of an
 * object which may be destroyed before the callback executes in the
 * main loop, include a Releaser as a public member of that object and
 * pass the Releaser object as the second argument of
 * Callback::post().  Note that for this to be race free, the lifetime
 * of the remote object whose method is to be invoked must be
 * determined by the thread to whose main loop the callback has been
 * attached.  When the main loop begins invoking the execution of the
 * callback, the remote object must either wholly exist (in which case
 * the callback will be invoked) or have been destroyed (in which case
 * the callback will be ignored), and not be in some transient
 * half-state governed by another thread.
 *
 * Advantages as against Notifier:
 * 
 * 1. If there are a lot of different events requiring callbacks to be
 *    dispatched in the program from worker threads to the main
 *    thread, this avoids having separate Notifier objects for each
 *    event.
 * 2. It is easier to pass arguments with varying values - they can be
 *    passed as bound arguments of the callback and no special
 *    synchronisation is normally required (the call to
 *    g_source_attach() invokes locking of the main loop which will
 *    have the effect of ensuring memory visibility).  With a Notifier
 *    object it may be necessary to use an asynchronous queue to pass
 *    variable values (or to bind a reference to the data, thus
 *    normally requiring separate synchronisation).
 * 3. Although the callback would normally be sent for execution by
 *    the main program loop, and that is the default, it can be sent
 *    for execution by any thread which has its own
 *    GMainContext/GMainLoop objects.  Thus callbacks can be passed
 *    for execution between worker threads, or from the main program
 *    thread to worker threads, as well as from worker threads to the
 *    main program thread.
 *
 * Disadvantages as against Notifier:
 *
 * 1. Less efficient, as a new callback object has to be created on
 *    freestore every time the callback is invoked, together with a
 *    new SafeEmitter object if a Releaser is used to track the
 *    callback.
 * 2. Multiple callbacks relevant to a single event cannot be invoked
 *    from a single call for the event - each callback has to be
 *    separately dispatched.
 */

/**
 * @namespace Cgu::Callback
 * @brief This namespace provides classes for type erasure.
 *
 * \#include <c++-gtk-utils/callback.h>
 *
 * These classes provide type erasure on callable objects.  They
 * comprise a generic callback creation and execution interface for
 * closures.  There is a basic Callback::Callback type, which is an
 * entire closure or 'thunk', where all values are bound into the
 * object, and is completely opaque.  Callback::CallbackArg<T...> is a
 * class which takes unbound arguments of the template types when the
 * object is dispatched.  (The opaque Callback::Callback type is a
 * typedef for Callback::CallbackArg<>: the two types are
 * interchangeable.)
 *
 * Objects of these classes are normally constructed using the
 * Callback::lambda() factory function, which takes any callable
 * object such as a lambda expression or the return value of
 * std::bind, and returns a pointer to a Callback/CallbackArg object
 * allocated on free store.  When using Callback::lambda(), the
 * unbound argument types (if any) must be passed as explicit template
 * parameters.
 *
 * Callback/CallbackArg objects can also be constructed using the
 * Callback::make() and Callback::make_ref() factory functions, which
 * can be useful where invoking standalone functions or object
 * methods.
 *
 * From version 2.0.23, a convenience Callback::to_unique() function
 * is available which will construct a std::unique_ptr object from a
 * Callback/CallbackArg object returned by Callback::lambda(),
 * Callback::make() or Callback::make_ref(), for the purpose of taking
 * ownership of the Callback/CallbackArg object.  This function is
 * mainly intended for use with the auto keyword, to avoid having to
 * write out the type of the unique_ptr object in longhand.
 * Corresponding Callback::to_functor() and
 * Callback::to_safe_functor() functions are also provided.
 *
 * The Callback/CallbackArg classes do not provide for a return
 * value. If a result is wanted, users should pass an unbound argument
 * by reference or pointer (or pointer to pointer).
 *
 * The Callback::make() and Callback::make_ref() functions
 * -------------------------------------------------------
 *
 * The Callback::make() and Callback::make_ref() functions construct a
 * Callback/CallbackArg object from a function pointer (or an object
 * reference and member function pointer) together with bound
 * arguments.  They provide for a maximum of five bound arguments, and
 * the unbound arguments (if any) must be the last (trailing)
 * arguments of the relevant function or method to be called.
 *
 * Callback::make() does a direct type mapping from the bound
 * arguments of the function or method represented by the callback
 * object to the arguments stored by it and is for use when all bound
 * arguments are simple fundamental types such as pointers (including
 * C strings), integers or floating points.
 *
 * Callback::make_ref() is for use where bound arguments include class
 * types or one or more of the types of the bound arguments include a
 * const reference.  It will accomplish perfect forwarding (by lvalue
 * reference or rvalue reference) when constructing the callback and
 * will also ensure that a copy of any object to be passed by const
 * reference (as well as any taken by value) is kept in order to avoid
 * dangling references.  Note however that where a member function is
 * called, the object of which the target function is a member must
 * still be in existence when the Callback/CallbackArg object is
 * dispatched and, unlike Callback::make(), Callback::make_ref()
 * cannot be used with overloaded functions except with explicit
 * disambiguation.
 *
 * Callback::make() can also construct a Callback/CallbackArg object
 * from a std::function object.
 *
 * Callback::FunctorArg and Callback::SafeFunctorArg classes
 * ---------------------------------------------------------
 *
 * Functor/FunctorArg objects hold a Callback/CallbackArg object by
 * SharedPtr to enable them to be shared by reference counting, and
 * SafeFunctor/SafeFunctorArg objects hold them by SharedLockPtr,
 * which have a thread safe reference count so that they may be shared
 * between different threads.  These classes also have an operator()()
 * method so as to be callable with function syntax.
 *
 * Memory allocation
 * -----------------
 *
 * If the library is installed using the
 * \--with-glib-memory-slices-no-compat configuration option, any
 * Callback/CallbackArg object will be constructed in glib memory
 * slices rather than in the generic C++ free store.
 *
 * Usage
 * -----
 *
 * Using Callback::lambda():
 *
 * @code 
 *   using namespace Cgu;
 *
 *   // here cb1 is of type Callback::Callback*
 *   auto cb1 = Callback::lambda<>([]() {std::cout << "Hello world\n";});
 *   cb1->dispatch();
 *   delete cb1;
 *
 *   // here Callback::to_unique() is used to make a std::unique_ptr object to
 *   // manage the callback. cb2 is of type std::unique_ptr<const Callback::Callback>
 *   auto cb2 = Callback::to_unique(Callback::lambda<>([]() {std::cout << "Hello world\n";}));
 *   cb2->dispatch();
 *
 *   // the same using Callback::Functor
 *   Callback::Functor f1{Callback::lambda<>([]() {std::cout << "Hello world\n";})};
 *   f1();
 *
 *   int k = 5;
 *   // here cb3 is of type std::unique_ptr<const Callback::CallbackArg<int, int&>>
 *   auto cb3 = Callback::to_unique(Callback::lambda<int, int&>([=] (int i, int& j) {j = k * 10 * i;}));
 *   int res;
 *   cb3->dispatch(2, res);
 *   std::cout << k << " times 10 times 2 is " << res << '\n';
 *
 *   // the same using Callback::FunctorArg
 *   Callback::FunctorArg<int, int&> f2{Callback::lambda<int, int&>([=] (int i, int& j) {j = k * 10 * i;})};
 *   f2(2, res);
 *   std::cout << k << " times 10 times 2 is " << res << '\n';
 * @endcode
 *
 * Using Callback::make(), with a class object my_obj of type MyClass,
 * with a method void MyClass::my_method(int, int, const char*):
 *
 * @code 
 *   using namespace Cgu;
 *
 *   int arg1 = 1, arg2 = 5;
 *
 *   // here cb1 is of type Callback::Callback*
 *   auto cb1 = Callback::make(my_obj, &MyClass::my_method, arg1, arg2, "Hello\n");
 *   cb1->dispatch();
 *   delete cb1;
 *
 *   // here cb2 is of type std::unique_ptr<const Callback::Callback>
 *   auto cb2 = Callback::to_unique(Callback::make(my_obj, &MyClass::my_method, arg1, arg2, "Hello\n"));
 *   cb2->dispatch();
 *
 *   // the same using Callback::Functor
 *   Callback::Functor f1{Callback::make(my_obj, &MyClass::my_method, arg1, arg2, "Hello\n")};
 *   f1();
 *
 *   // here cb3 is of type std::unique_ptr<const Callback::CallbackArg<int, const char*>>
 *   auto cb3 = Callback::to_unique(Callback::make(my_obj, &MyClass::my_method, arg1));
 *   cb3->dispatch(arg2, "Hello\n");
 *
 *   // the same using Callback::FunctorArg
 *   Callback::FunctorArg<int, const char*> f2{Callback::make(my_obj, &MyClass::my_method, arg1)};
 *   f2(arg2, "Hello\n");
 * @endcode
 *
 * Using Callback::make_ref(), with a class object my_obj of type
 * MyClass, with a method void MyClass::my_method(int, const
 * Something&):
 *
 * @code
 *   int arg1 = 1;
 *   Something arg2;
 *   // here cb is of type std::unique_ptr<const Callback::Callback>
 *   auto cb = Callback::to_unique(Callback::make_ref(my_obj, &MyClass::my_method, arg1, arg2));
 * @endcode
 *
 * Posting of callbacks
 * --------------------
 *
 * This namespace also provides a Callback::post() function which will
 * execute a callback in a glib main loop and can be used (amongst
 * other things) to pass an event from a worker thread to the main
 * program thread.  In that respect, it provides an alternative to the
 * Notifier class.  It is passed a pointer to a Callback::Callback
 * object created with a call to Callback::lambda(), Callback::make(),
 * Callback::make_ref().
 *
 * To provide for thread-safe automatic disconnection of the callback
 * if the callback represents or calls into a non-static method of an
 * object which may be destroyed before the callback executes in the
 * main loop, include a Releaser as a public member of that object and
 * pass the Releaser object as the second argument of
 * Callback::post().  Note that for this to be race free, the lifetime
 * of the remote object whose method is to be invoked must be
 * determined by the thread to whose main loop the callback has been
 * attached.  When the main loop begins invoking the execution of the
 * callback, the remote object must either wholly exist (in which case
 * the callback will be invoked) or have been destroyed (in which case
 * the callback will be ignored), and not be in some transient
 * half-state governed by another thread.
 *
 * Advantages as against Notifier:
 * 
 * 1. If there are a lot of different events requiring callbacks to be
 *    dispatched in the program from worker threads to the main
 *    thread, this avoids having separate Notifier objects for each
 *    event.
 * 2. It is easier to pass arguments with varying values - they can be
 *    passed as bound arguments of the callback and no special
 *    synchronisation is normally required (the call to
 *    g_source_attach() invokes locking of the main loop which will
 *    have the effect of ensuring memory visibility).  With a Notifier
 *    object it may be necessary to use an asynchronous queue to pass
 *    variable values (or to bind a reference to the data, thus
 *    normally requiring separate synchronisation).
 * 3. Although the callback would normally be sent for execution by
 *    the main program loop, and that is the default, it can be sent
 *    for execution by any thread which has its own
 *    GMainContext/GMainLoop objects.  Thus callbacks can be passed
 *    for execution between worker threads, or from the main program
 *    thread to worker threads, as well as from worker threads to the
 *    main program thread.
 *
 * Disadvantages as against Notifier:
 *
 * 1. Less efficient, as a new callback object has to be created on
 *    freestore every time the callback is invoked, together with a
 *    new SafeEmitter object if a Releaser is used to track the
 *    callback.
 * 2. Multiple callbacks relevant to a single event cannot be invoked
 *    from a single call for the event - each callback has to be
 *    separately dispatched.
 */

#include <functional>  // for std::less, std::function and std::hash<T*>
#include <utility>     // for std::move and std::forward
#include <memory>      // for std::unique_ptr
#include <cstddef>     // for std::size_t
#include <type_traits> // for std::remove_reference and std::remove_const

#include <glib.h>

#include <c++-gtk-utils/shared_ptr.h>
#include <c++-gtk-utils/param.h>
#include <c++-gtk-utils/cgu_config.h>

namespace Cgu {

namespace Callback {

/*
   The CallbackArg class could be additionally templated to provide a
   return value, but that would affect the simplicity of the
   interface, and if a case were to arise where a result is needed, an
   alternative is for users to pass an argument by reference or
   pointer (or pointer to pointer) rather than have a return value.
*/

/* Declare the two interface types */

template <class... FreeArgs> class CallbackArg;
typedef CallbackArg<> Callback;

/* now the class definitions */

/**
 * @class CallbackArg callback.h c++-gtk-utils/callback.h
 * @brief The callback interface class
 * @sa Callback namespace
 * @sa FunctorArg SafeFunctorArg
 *
 * This class provides type erasure for callable objects.  The
 * CallbackArg type is constructed on free store and can wrap any
 * callable object, such as a lambda expression or the return value of
 * std::bind.
 *
 * The class is particularly relevant where a callable object with
 * bound values needs to be handed safely between threads, or in other
 * cases where a callback object has to be passed by pointer (which
 * will happen at some stage with glib or pthreads).  They are
 * therefore useful for general event passing when used together with
 * the Callback::post() functions or as the continuation for GIO async
 * operations, and are more efficient than constructing std::function
 * objects on free store and passing them by pointer (they avoid one
 * level of indirection and only require one rather than two
 * allocations).
 *
 * The classes are also used in the Emitter/EmitterArg and
 * SafeEmitter/SafeEmitterArg classes in emitter.h, which enable
 * callable objects to be connected to an emitter and provide for
 * automatic disconnection where a class object whose member a
 * callback represents or calls into ceases to exist.  They are also
 * used internally to implement the Thread::Future and
 * Thread::TaskManager classes.
 * 
 * The template types are the types of the unbound arguments, if any.
 * Callback::CallbackArg<> is typedef'ed to Callback::Callback.  The
 * main method of constructing a Callback/CallbackArg object is with
 * the Callback::lambda() factory function.  When using
 * Callback::lambda(), the unbound argument types (if any) must be
 * passed as explicit template parameters.
 *
 * Callback/CallbackArg classes do not provide for a return value.  If
 * a result is wanted, users should pass an unbound argument by
 * reference or pointer (or pointer to pointer).
 *
 * @b Usage
 *
 * These are examples:
 *
 * @code 
 *   using namespace Cgu;
 *
 *   // here cb1 is of type Callback::Callback*
 *   auto cb1 = Callback::lambda<>([]() {std::cout << "Hello world\n";});
 *   cb1->dispatch();
 *   delete cb1;
 *
 *   // here Callback::to_unique() is used to make a std::unique_ptr object to
 *   // manage the callback. cb2 is of type std::unique_ptr<const Callback::Callback>
 *   auto cb2 = Callback::to_unique(Callback::lambda<>([]() {std::cout << "Hello world\n";}));
 *   cb2->dispatch();
 *
 *   // here cb3 is of type std::unique_ptr<const Callback::CallbackArg<int, int&>>
 *   auto cb3 = Callback::to_unique(Callback::lambda<int, int&>([] (int i, int& j) {j = 10 * i;}));
 *   int res;
 *   cb3->dispatch(2, res);
 *   std::cout << "10 times 2 is " << res << '\n';
 * @endcode
 *
 * For further background, including about the Callback::make(),
 * Callback::make_ref() and Callback::to_unique() functions, read
 * this: Callback
 */

template <class... FreeArgs>
class CallbackArg {
public:
/* Because dispatch() is a virtual function, we cannot templatise it
 * with a view to preserving r-value forwarding of temporary objects
 * passed as a free argument.  But this would rarely be relevant
 * anyway - it would only be relevant if the target function were to
 * take an argument by r-value reference and a temporary were to be
 * passed to it.  In such a case virtual dispatch is at the cost of a
 * copy of the temporary.
 */
/**
 * This will execute the referenced function, callable object or class
 * method encapsulated by this class.  It will only throw if the
 * dispatched function, callable object or class method throws, or if
 * the copy constructor of a free or bound argument throws and it is
 * not a reference argument.  It is thread safe if the referenced
 * function or class method is thread safe.
 * @param args The unbound arguments to be passed to the referenced
 * function, callable object or class method, if any.
 * @note We use dispatch() to execute the callback, because the
 * callback would normally be invoked through a base class pointer.
 * To invoke it through operator()(), use the FunctorArg or
 * SafeFunctorArg wrapper class.
 */
  virtual void dispatch(typename Cgu::Param<FreeArgs>::ParamType... args) const = 0;

/**
 *  The constructor will not throw unless the copy constructor of an
 *  argument bound to the derived implementation class throws.
 */
  CallbackArg() {}

/**
 *  The destructor will not throw unless the destructor of an argument
 *  bound to the derived implementation class throws.
 */
  virtual ~CallbackArg() {}

/* these functions will be inherited by the derived callback classes */
#ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
  CGU_GLIB_MEMORY_SLICES_FUNCS
#endif
};

/**
 * A function for making a std::unique_ptr object from a
 * Cgu::Callback::CallbackArg object (say, as constructed by
 * Cgu::Callback::lambda(), Cgu::Callback::make() or
 * Cgu::Callback::make_ref()), for the purpose of taking ownership of
 * the CallbackArg object.  It is thread safe and will not throw.
 *
 * This function is mainly intended for use with the auto keyword, to
 * avoid having to write out the type of the unique_ptr object in
 * longhand.  For example:
 *
 * @code
 * using namespace Cgu;
 * // here a std::unique_ptr<const Cgu::Callback::CallbackArg<const std::string&>> object is constructed
 * auto cb = Callback::to_unique(Callback::lambda<const std::string&>([] (const std::string& s) {
 *   std::cout << s;
 * }));
 * cb->dispatch("Hello\n");
 * @endcode
 *
 * This function cannot be used to overcome the problems of C++'s
 * unconstrained partial evaluation rules for functions taking more
 * than one argument (the lack of such constraints is a poor design
 * choice for a language with exceptions such as C++).  For example, a
 * function:
 *
 * @code
 * void do_it(std::unique_ptr<const Cgu::Callback::Callback> cb1,
 *            std::unique_ptr<const Cgu::Callback::Callback> cb2);
 * @endcode
 * should not be called like this:
 * @code
 * do_it(Callback::to_unique(Callback::lambda<>([]() {...;})),
 *       Callback::to_unique(Callback::lambda<>([]() {...;})));
 * @endcode
 *
 * This is because one possible sequencing that C++ permits is as
 * follows:
 *
 * 1. Construct the callback object for the first argument by calling
 * Callback::lambda().
 * 2. Construct the callback object for the second argument by calling
 * Callback::lambda().
 * 3. Initialize a std::unique_ptr object for the second argument by
 * calling Callback::to_unique().
 * 4. Initialize a std::unique_ptr object for the first argument by
 * calling Callback::to_unique().
 * 5. Enter do_it().
 *
 * Because step 2 is permitted to precede step 4, if step 2 throws
 * then the object constructed at step 1 will be leaked.  To avoid
 * this, explicit sequencing must be provided for in the code, as
 * follows:
 *
 * @code
 * auto cb1 = Callback::to_unique(Callback::lambda<>([]() {...;}));
 * auto cb2 = Callback::to_unique(Callback::lambda<>([]() {...;}));
 * do_it(std::move(cb1),
 *       std::move(cb2));
 * @endcode
 *
 * The Cgu::Callback::CallbackArg object held by the unique_ptr
 * returned by this function is const.  This is because all the
 * interfaces in this library also take const
 * Cgu::Callback::CallbackArg objects (and their only method, the
 * dispatch() method, is const).  However, if constructed using
 * Cgu::Callback::lambda(), Cgu::Callback::make() or
 * Cgu::Callback::make_ref(), the Cgu::Callback::CallbackArg object
 * can safely be cast to non-const.
 *
 * @param cb The CallbackArg object which is to be managed by a
 * std::unique_ptr.
 * @return The std::unique_ptr object.
 *
 * Since 2.0.23
 */
template<class... T>
std::unique_ptr<const CallbackArg<T...>> to_unique(const CallbackArg<T...>* cb) {
  return std::unique_ptr<const CallbackArg<T...>>(cb);
}

/* The four basic functor types */

template <class... FreeArgs> class FunctorArg;
template <class... FreeArgs> class SafeFunctorArg;
typedef FunctorArg<> Functor;
typedef SafeFunctorArg<> SafeFunctor;

/* Functor friend functions */

// we can use built-in operator == when comparing pointers referencing
// different objects of the same type
/**
 * Two FunctorArg objects compare equal if the addresses of the
 * CallbackArg objects they contain are the same.  This comparison
 * operator does not throw.
 */
template <class... T>
bool operator==(const FunctorArg<T...>& f1, const FunctorArg<T...>& f2) {
  return (f1.cb_s.get() == f2.cb_s.get());
}

/**
 * Two FunctorArg objects compare unequal if the addresses of the
 * CallbackArg objects they contain are not the same.  This comparison
 * operator does not throw.
 */
template <class... T>
bool operator!=(const FunctorArg<T...>& f1, const FunctorArg<T...>& f2) {
  return !(f1 == f2);
}

// we must use std::less rather than the < built-in operator for
// pointers to objects not within the same array or object: "For
// templates greater, less, greater_equal, and less_equal, the
// specializations for any pointer type yield a total order, even if
// the built-in operators <, >, <=, >= do not." (para 20.3.3/8).
/**
 * One FunctorArg object is less than another if the address of the
 * CallbackArg object contained by the first is regarded by std::less
 * as less than the address of the CallbackArg object contained by the
 * other.  This comparison operator does not throw unless std::less
 * applied to pointer types throws (which it would not do with any
 * sane implementation).
 */
template <class... T>
bool operator<(const FunctorArg<T...>& f1, const FunctorArg<T...>& f2) {
  return std::less<const CallbackArg<T...>*>()(f1.cb_s.get(), f2.cb_s.get());
}

/**
 * Two SafeFunctorArg objects compare equal if the addresses of the
 * CallbackArg objects they contain are the same.  This comparison
 * operator does not throw.
 */
template <class... T>
bool operator==(const SafeFunctorArg<T...>& f1, const SafeFunctorArg<T...>& f2) {
  return (f1.cb_s.get() == f2.cb_s.get());
}

/**
 * Two SafeFunctorArg objects compare unequal if the addresses of the
 * CallbackArg objects they contain are not the same.  This comparison
 * operator does not throw.
 */
template <class... T>
bool operator!=(const SafeFunctorArg<T...>& f1, const SafeFunctorArg<T...>& f2) {
  return !(f1 == f2);
}

/**
 * One SafeFunctorArg object is less than another if the address of
 * the CallbackArg object contained by the first is regarded by
 * std::less as less than the address of the CallbackArg object
 * contained by the other.  This comparison operator does not throw
 * unless std::less applied to pointer types throws (which it would
 * not do with any sane implementation).
 */
template <class... T>
bool operator<(const SafeFunctorArg<T...>& f1, const SafeFunctorArg<T...>& f2) {
  return std::less<const CallbackArg<T...>*>()(f1.cb_s.get(), f2.cb_s.get());
}

} // namespace Callback
} // namespace Cgu

// doxygen produces long filenames that tar can't handle:
// we have generic documentation for std::hash specialisations
// in doxygen.main.in
#ifndef DOXYGEN_PARSING

/* These structs allow FunctorArg and SafeFunctorArg objects to be
   keys in unordered associative containers */
namespace std {
template <class... T>
struct hash<Cgu::Callback::FunctorArg<T...>> {
  typedef std::size_t result_type;
  typedef Cgu::Callback::FunctorArg<T...> argument_type;
  result_type operator()(const argument_type& f) const {
    // this is fine: std::hash structs do not normally contain data and
    // std::hash<T*> certainly won't, so we don't have overhead constructing
    // std::hash<T*> on the fly
    return std::hash<const Cgu::Callback::CallbackArg<T...>*>()(f.cb_s.get());
  }
};
template <class... T>
struct hash<Cgu::Callback::SafeFunctorArg<T...>> {
  typedef std::size_t result_type;
  typedef Cgu::Callback::SafeFunctorArg<T...> argument_type;
  result_type operator()(const argument_type& f) const {
    // this is fine: std::hash structs do not normally contain data and
    // std::hash<T*> certainly won't, so we don't have overhead constructing
    // std::hash<T*> on the fly
    return std::hash<const Cgu::Callback::CallbackArg<T...>*>()(f.cb_s.get());
  }
};
} // namespace std

#endif // DOXYGEN_PARSING

namespace Cgu {
namespace Callback {

/* the functor classes */

/**
 * @class FunctorArg callback.h c++-gtk-utils/callback.h
 * @brief Functor class holding a Callback::CallbackArg object.
 * @sa SafeFunctorArg
 * @sa Callback namespace
 *
 * This class wraps a CallbackArg object.  The callback object is kept
 * by SharedPtr so the functor can be copied and offers automatic
 * lifetime management of the wrapped callback object, as well as
 * providing an operator()() function.  Ownership is taken of the
 * CallbackArg object passed to the constructor taking a CallbackArg
 * pointer, so that constructor should be treated like a shared
 * pointer constructor - only pass a newly allocated object to it (or
 * copy construct it or assign to it from another existing FunctorArg
 * object).  The template types are the types of the unbound
 * arguments, if any.  Callback::FunctorArg<> is typedef'ed to
 * Callback::Functor.
 *
 * The constructor taking a Callback::CallbackArg pointer is not
 * marked explicit, so the results of Callback::lambda(),
 * Callback::make() or Callback::make_ref() can be passed directly to
 * a function taking a Callback::FunctorArg argument, and implicit
 * conversion will take place.
 *
 * Functor/FunctorArg classes do not provide for a return value.  If
 * a result is wanted, users should pass an unbound argument by
 * reference or pointer (or pointer to pointer).
 *
 * @b Usage
 *
 * These are examples:
 *
 * @code 
 *   using namespace Cgu;
 *
 *   // here f1 is directly initialized using the type conversion constructor
 *   Callback::Functor f1{Callback::lambda<>([] () {std::cout << "Hello world\n";})};
 *   f1();
 *
 *   // here Callback::to_functor() is used to enable use of the auto keyword.
 *   // f2 is of type Callback::Functor
 *   auto f2 = Callback::to_functor(Callback::lambda<>([] () {std::cout << "Hello world\n";}));
 *   f2();
 *
 *   // here f3 is of type Callback::FunctorArg<int, int&>
 *   auto f3 = Callback::to_functor(Callback::lambda<int, int&>([] (int i, int& j) {j = 10 * i;}));
 *   int res;
 *   f3(2, res);
 *   std::cout << "10 times 2 is " << res << '\n';
 * @endcode
 *
 * For further background, including about the Callback::make(),
 * Callback::make_ref() and Callback::to_functor() functions, read
 * this: Callback
 */

template <class... FreeArgs>
class FunctorArg {
  SharedPtr<const CallbackArg<FreeArgs...>> cb_s;
public:
/* Because CallbackArg::dispatch() is a virtual function, it is
 * pointless templatising this function with a view to preserving
 * r-value forwarding of temporary objects passed as a free argument,
 * because the r-value typeness will be discarded in dispatch().  But
 * this would rarely be relevant anyway - it would only be relevant if
 * the target function were to take an argument by r-value reference
 * and a temporary were to be passed to it.  In such a case virtual
 * dispatch is at the cost of a copy of the temporary.
 */
/**
 * This will execute the function, callable object or class method
 * represented by the callback encapsulated by this object, or do
 * nothing if this object has not been initialized with a callback.
 * It will only throw if the executed function, callable object or
 * class method throws, or if the copy constructor of a free or bound
 * argument throws and it is not a reference argument.  It is thread
 * safe if the referenced function or class method is thread safe.
 * @param args The unbound arguments to be passed to the referenced
 * function, callable object or class method, if any.
 */
  void operator()(typename Cgu::Param<FreeArgs>::ParamType... args) const {
    if (cb_s.get()) cb_s->dispatch(args...);
  }

/** 
 * This function does not throw.
 * @param f The assignor.
 * @return The functor object after assignment.
 */ 
  FunctorArg& operator=(const FunctorArg& f) {cb_s = f.cb_s; return *this;}

/** 
 * This function does not throw.
 * @param f The functor to be moved.
 * @return The functor object after the move operation.
 */ 
  FunctorArg& operator=(FunctorArg&& f) {cb_s = std::move(f.cb_s); return *this;}

/**
 * Two FunctorArg objects compare equal if the addresses of the
 * CallbackArg objects they contain are the same.  This comparison
 * operator does not throw.
 */
  friend bool operator== <>(const FunctorArg&, const FunctorArg&);

/**
 * One FunctorArg object is less than another if the address of the
 * CallbackArg object contained by the first is regarded by std::less
 * as less than the address of the CallbackArg object contained by the
 * other.  This comparison operator does not throw.
 */
  friend bool operator< <>(const FunctorArg&, const FunctorArg&);

  friend struct std::hash<FunctorArg>;

/**
 * Constructor of first FunctorArg holding the referenced callback.
 * As it is not marked explicit, it is also a type conversion
 * constructor.
 * @param cb The CallbackArg object which the functor is to manage.
 * @exception std::bad_alloc This might throw std::bad_alloc if
 * memory is exhausted and the system throws in that case.  Note that
 * if such an exception is thrown, then this constructor will clean
 * itself up and also delete the callback object passed to it.
 * @note std::bad_alloc will not be thrown if the library has been
 * installed using the \--with-glib-memory-slices-no-compat
 * configuration option: instead glib will terminate the program if it
 * is unable to obtain memory from the operating system.
 */
  FunctorArg(const CallbackArg<FreeArgs...>* cb): cb_s(cb) {}

/** 
 * The copy constructor does not throw.
 * @param f The assignor
 */ 
  FunctorArg(const FunctorArg& f): cb_s(f.cb_s) {}

/** 
 * The move constructor does not throw.
 * @param f The functor to be moved.
 */ 
  FunctorArg(FunctorArg&& f): cb_s(std::move(f.cb_s)) {}

 /**
  * Default constructor, where a Callback::CallbackArg object is to be
  * assigned later (via the type conversion constructor and/or the
  * assignment operator).  This constructor does not throw.
  */
  FunctorArg() {}

/* Only has effect if --with-glib-memory-slices-compat or
   --with-glib-memory-slices-no-compat option picked */
  CGU_GLIB_MEMORY_SLICES_FUNCS
};

/**
 * @class SafeFunctorArg callback.h c++-gtk-utils/callback.h
 * @brief Functor class holding a Callback::CallbackArg object, with
 * thread-safe reference count.
 * @sa FunctorArg
 * @sa Callback namespace
 *
 * This class wraps a CallbackArg object.  It is the same as
 * Callback::FunctorArg except that it will provide synchronisation of
 * the reference count between threads.  Use it where a functor
 * wrapper object is to be passed between threads.  The FunctorArg
 * documentation gives further details.  The
 * Callback::to_safe_functor() function can be used in place of the
 * Callback::to_functor() function when constructing a
 * Callback::SafeFunctorArg object using the auto keyword.
 *
 * Callback::SafeFunctorArg<> is typedef'ed to Callback::SafeFunctor.
 *
 * For further background, including about the Callback::make(),
 * Callback::make_ref() and Callback::to_safe_functor() functions,
 * read this: Callback
 */

template <class... FreeArgs>
class SafeFunctorArg {
  SharedLockPtr<const CallbackArg<FreeArgs...>> cb_s;
public:
/**
 * This will execute the function, callable object or class method
 * represented by the callback encapsulated by this object, or do
 * nothing if this object has not been initialized with a callback.
 * It will only throw if the executed function, callable object or
 * class method throws, or if the copy constructor of a free or bound
 * argument throws and it is not a reference argument.  It is thread
 * safe if the referenced function or class method is thread safe.
 * @param args The unbound arguments to be passed to the referenced
 * function, callable object or class method, if any.
 */
  void operator()(typename Cgu::Param<FreeArgs>::ParamType... args) const {
    if (cb_s.get()) cb_s->dispatch(args...);
  }

/** 
 * This function does not throw.
 * @param f The assignor.
 * @return The functor object after assignment.
 */ 
  SafeFunctorArg& operator=(const SafeFunctorArg& f) {cb_s = f.cb_s; return *this;}

/** 
 * This function does not throw.
 * @param f The functor to be moved.
 * @return The functor object after the move operation.
 */ 
  SafeFunctorArg& operator=(SafeFunctorArg&& f) {cb_s = std::move(f.cb_s); return *this;}

/**
 * Two SafeFunctorArg objects compare equal if the addresses of the
 * CallbackArg objects they contain are the same.  This comparison
 * operator does not throw.
 */
  friend bool operator== <>(const SafeFunctorArg&, const SafeFunctorArg&);

/**
 * One SafeFunctorArg object is less than another if the address of
 * the CallbackArg object contained by the first is regarded by
 * std::less as less than the address of the CallbackArg object
 * contained by the other.  This comparison operator does not throw.
 */
  friend bool operator< <>(const SafeFunctorArg&, const SafeFunctorArg&);

  friend struct std::hash<SafeFunctorArg>;

 /**
 * Constructor of first SafeFunctorArg holding the referenced
 * callback.  As it is not marked explicit, it is also a type
 * conversion constructor.
 * @param cb The CallbackArg object which the functor is to manage.
 * @exception std::bad_alloc This might throw std::bad_alloc if
 * memory is exhausted and the system throws in that case.  Note that
 * if such an exception is thrown, then this constructor will clean
 * itself up and also delete the callback object passed to it.
 * @note std::bad_alloc will not be thrown if the library has been
 * installed using the \--with-glib-memory-slices-no-compat
 * configuration option: instead glib will terminate the program if it
 * is unable to obtain memory from the operating system.
 */
  SafeFunctorArg(const CallbackArg<FreeArgs...>* cb): cb_s(cb) {}

/** 
 * The copy constructor does not throw.
 * @param f The assignor.
 */ 
  SafeFunctorArg(const SafeFunctorArg& f): cb_s(f.cb_s) {}

/** 
 * The move constructor does not throw.
 * @param f The functor to be moved.
 */ 
  SafeFunctorArg(SafeFunctorArg&& f): cb_s(std::move(f.cb_s)) {}

 /**
  * Default constructor, where a Callback::CallbackArg object is to be
  * assigned later (via the type conversion constructor and/or the
  * assignment operator).  This constructor does not throw.
  * @note The reference count maintained with respect to the contained
  * callback object is thread-safe, so SafeFunctorArg objects may be
  * copied between threads by the implicit assignment operator and put
  * in different containers in different threads.  They use a
  * SharedLockPtr object to hold the referenced callback object.
  */
  SafeFunctorArg() {}

/* Only has effect if --with-glib-memory-slices-compat or
   --with-glib-memory-slices-no-compat option picked */
  CGU_GLIB_MEMORY_SLICES_FUNCS
};

/**
 * A function for making a Cgu::Callback::FunctorArg object from a
 * Cgu::Callback::CallbackArg object, for the purpose of taking
 * ownership of the CallbackArg object.  It is thread safe.
 *
 * Because the constructor of FunctorArg taking a pointer is not
 * explicit and can therefore be used for implicit type conversion,
 * this function will not often be needed.  It is mainly intended for
 * use when constructing a named object in local scope with the auto
 * keyword, to avoid having to write out the type of the FunctorArg
 * object in longhand.  For example:
 *
 * @code
 * using namespace Cgu;
 * // here a Cgu::Callback::FunctorArg<const std::string&> object is constructed
 * auto f = Callback::to_functor(Callback::lambda<const std::string&>([] (const std::string& s) {
 *   std::cout << s;
 * }));
 * f("Hello\n");
 * @endcode
 *
 * @param cb The CallbackArg object which is to be managed by a
 * functor.
 * @return The FunctorArg object.
 * @exception std::bad_alloc This function might throw std::bad_alloc
 * if memory is exhausted and the system throws in that case.  Note
 * that if such an exception is thrown, then this function will delete
 * the callback object passed to it.
 * @note std::bad_alloc will not be thrown if the library has been
 * installed using the \--with-glib-memory-slices-no-compat
 * configuration option: instead glib will terminate the program if it
 * is unable to obtain memory from the operating system.
 *
 * Since 2.0.23
 */
template<class... T>
FunctorArg<T...> to_functor(const CallbackArg<T...>* cb) {
  return cb;
}

/**
 * A function for making a Cgu::Callback::SafeFunctorArg object from a
 * Cgu::Callback::CallbackArg object, for the purpose of taking
 * ownership of the CallbackArg object.  It is thread safe.
 *
 * Because the constructor of SafeFunctorArg taking a pointer is not
 * explicit and can therefore be used for implicit type conversion,
 * this function will not often be needed.  It is mainly intended for
 * use when constructing a named object in local scope with the auto
 * keyword, to avoid having to write out the type of the
 * SafeFunctorArg object in longhand.  For example:
 *
 * @code
 * using namespace Cgu;
 * // here a Cgu::Callback::SafeFunctorArg<const std::string&> object is constructed
 * auto f = Callback::to_safe_functor(Callback::lambda<const std::string&>([] (const std::string& s) {
 *   std::cout << s;
 * }));
 * f("Hello\n");
 * @endcode
 *
 * @param cb The CallbackArg object which is to be managed by a
 * functor.
 * @return The SafeFunctorArg object.
 * @exception std::bad_alloc This function might throw std::bad_alloc
 * if memory is exhausted and the system throws in that case.  Note
 * that if such an exception is thrown, then this function will delete
 * the callback object passed to it.
 * @note std::bad_alloc will not be thrown if the library has been
 * installed using the \--with-glib-memory-slices-no-compat
 * configuration option: instead glib will terminate the program if it
 * is unable to obtain memory from the operating system.
 *
 * Since 2.0.23
 */
template<class... T>
SafeFunctorArg<T...> to_safe_functor(const CallbackArg<T...>* cb) {
  return cb;
}

/* the callback implementation classes */

template <class T, class... FreeArgs>
class Callback0: public CallbackArg<FreeArgs...> {
public:
  typedef void (T::* MemFunc)(FreeArgs...);
private:
  T* obj;
  MemFunc func;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    (obj->*func)(free_args...);
  }
  Callback0(T& obj_, MemFunc func_): obj(&obj_), func(func_) {}
};

template <bool unref, class T, class BoundArg, class... FreeArgs>
class Callback1: public CallbackArg<FreeArgs...> {
public:
  typedef void (T::* MemFunc)(BoundArg, FreeArgs...);
private:
  T* obj;
  MemFunc func;
  typename Cgu::RemoveRefCond<BoundArg, unref>::Type arg;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    (obj->*func)(arg, free_args...);
  }
  template <class Arg>
  Callback1(T& obj_, MemFunc func_,
	    Arg&& arg_): obj(&obj_), func(func_), arg(std::forward<Arg>(arg_)) {}
};

template <bool unref, class T, class BoundArg1, class BoundArg2, class... FreeArgs>
class Callback2: public CallbackArg<FreeArgs...> {
public:
  typedef void (T::* MemFunc)(BoundArg1, BoundArg2, FreeArgs...);
private:
  T* obj;
  MemFunc func;
  typename Cgu::RemoveRefCond<BoundArg1, unref>::Type arg1;
  typename Cgu::RemoveRefCond<BoundArg2, unref>::Type arg2;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    (obj->*func)(arg1, arg2, free_args...);
  }
  template <class Arg1, class Arg2>
  Callback2(T& obj_, MemFunc func_,
	    Arg1&& arg1_,
	    Arg2&& arg2_): obj(&obj_), func(func_),
                           arg1(std::forward<Arg1>(arg1_)),
                           arg2(std::forward<Arg2>(arg2_)) {}
};

template <bool unref, class T, class BoundArg1, class BoundArg2, class BoundArg3, class... FreeArgs>
class Callback3: public CallbackArg<FreeArgs...> {
public:
  typedef void (T::* MemFunc)(BoundArg1, BoundArg2, BoundArg3, FreeArgs...);
private:
  T* obj;
  MemFunc func;
  typename Cgu::RemoveRefCond<BoundArg1, unref>::Type arg1;
  typename Cgu::RemoveRefCond<BoundArg2, unref>::Type arg2;
  typename Cgu::RemoveRefCond<BoundArg3, unref>::Type arg3;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    (obj->*func)(arg1, arg2, arg3, free_args...);
  }
  template <class Arg1, class Arg2, class Arg3>
  Callback3(T& obj_, MemFunc func_,
	    Arg1&& arg1_,
	    Arg2&& arg2_,
	    Arg3&& arg3_):
              obj(&obj_), func(func_),
	      arg1(std::forward<Arg1>(arg1_)),
	      arg2(std::forward<Arg2>(arg2_)),
	      arg3(std::forward<Arg3>(arg3_)) {}
};

template <bool unref, class T, class BoundArg1, class BoundArg2, class BoundArg3, 
          class BoundArg4, class... FreeArgs>
class Callback4: public CallbackArg<FreeArgs...> {
public:
  typedef void (T::* MemFunc)(BoundArg1, BoundArg2, BoundArg3, BoundArg4, FreeArgs...);
private:
  T* obj;
  MemFunc func;
  typename Cgu::RemoveRefCond<BoundArg1, unref>::Type arg1;
  typename Cgu::RemoveRefCond<BoundArg2, unref>::Type arg2;
  typename Cgu::RemoveRefCond<BoundArg3, unref>::Type arg3;
  typename Cgu::RemoveRefCond<BoundArg4, unref>::Type arg4;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    (obj->*func)(arg1, arg2, arg3, arg4, free_args...);
  }
  template <class Arg1, class Arg2, class Arg3, class Arg4>
  Callback4(T& obj_, MemFunc func_,
	    Arg1&& arg1_,
	    Arg2&& arg2_,
	    Arg3&& arg3_,
	    Arg4&& arg4_):
              obj(&obj_), func(func_),
	      arg1(std::forward<Arg1>(arg1_)),
	      arg2(std::forward<Arg2>(arg2_)),
	      arg3(std::forward<Arg3>(arg3_)),
	      arg4(std::forward<Arg4>(arg4_)) {}
};

template <bool unref, class T, class BoundArg1, class BoundArg2, class BoundArg3, 
          class BoundArg4, class BoundArg5, class... FreeArgs>
class Callback5: public CallbackArg<FreeArgs...> {
public:
  typedef void (T::* MemFunc)(BoundArg1, BoundArg2, BoundArg3,
			      BoundArg4, BoundArg5, FreeArgs...);
private:
  T* obj;
  MemFunc func;
  typename Cgu::RemoveRefCond<BoundArg1, unref>::Type arg1;
  typename Cgu::RemoveRefCond<BoundArg2, unref>::Type arg2;
  typename Cgu::RemoveRefCond<BoundArg3, unref>::Type arg3;
  typename Cgu::RemoveRefCond<BoundArg4, unref>::Type arg4;
  typename Cgu::RemoveRefCond<BoundArg5, unref>::Type arg5;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    (obj->*func)(arg1, arg2, arg3, arg4, arg5, free_args...);
  }
  template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
  Callback5(T& obj_, MemFunc func_,
	    Arg1&& arg1_,
	    Arg2&& arg2_,
	    Arg3&& arg3_,
	    Arg4&& arg4_,
	    Arg5&& arg5_):
              obj(&obj_), func(func_),
	      arg1(std::forward<Arg1>(arg1_)),
	      arg2(std::forward<Arg2>(arg2_)),
	      arg3(std::forward<Arg3>(arg3_)),
	      arg4(std::forward<Arg4>(arg4_)),
	      arg5(std::forward<Arg5>(arg5_)) {}
};

/* const versions, for binding to const methods */

template <class T, class... FreeArgs>
class Callback0_const: public CallbackArg<FreeArgs...> {
public:
  typedef void (T::* MemFunc)(FreeArgs...) const;
private:
  const T* obj;
  MemFunc func;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    (obj->*func)(free_args...);
  }
  Callback0_const(const T& obj_, MemFunc func_): obj(&obj_), func(func_) {}
};

template <bool unref, class T, class BoundArg, class... FreeArgs>
class Callback1_const: public CallbackArg<FreeArgs...> {
public:
  typedef void (T::* MemFunc)(BoundArg, FreeArgs...) const;
private:
  const T* obj;
  MemFunc func;
  typename Cgu::RemoveRefCond<BoundArg, unref>::Type arg;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    (obj->*func)(arg, free_args...);
  }
  template <class Arg>
  Callback1_const(const T& obj_, MemFunc func_,
		  Arg&& arg_): obj(&obj_), func(func_), arg(std::forward<Arg>(arg_)) {}
};

template <bool unref, class T, class BoundArg1, class BoundArg2, class... FreeArgs>
class Callback2_const: public CallbackArg<FreeArgs...> {
public:
  typedef void (T::* MemFunc)(BoundArg1, BoundArg2, FreeArgs...) const;
private:
  const T* obj;
  MemFunc func;
  typename Cgu::RemoveRefCond<BoundArg1, unref>::Type arg1;
  typename Cgu::RemoveRefCond<BoundArg2, unref>::Type arg2;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    (obj->*func)(arg1, arg2, free_args...);
  }
  template <class Arg1, class Arg2>
  Callback2_const(const T& obj_, MemFunc func_,
		  Arg1&& arg1_,
		  Arg2&& arg2_): obj(&obj_), func(func_),
                                 arg1(std::forward<Arg1>(arg1_)),
                                 arg2(std::forward<Arg2>(arg2_)) {}
};

template <bool unref, class T, class BoundArg1, class BoundArg2, class BoundArg3, class... FreeArgs>
class Callback3_const: public CallbackArg<FreeArgs...> {
public:
  typedef void (T::* MemFunc)(BoundArg1, BoundArg2, BoundArg3, FreeArgs...) const;
private:
  const T* obj;
  MemFunc func;
  typename Cgu::RemoveRefCond<BoundArg1, unref>::Type arg1;
  typename Cgu::RemoveRefCond<BoundArg2, unref>::Type arg2;
  typename Cgu::RemoveRefCond<BoundArg3, unref>::Type arg3;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    (obj->*func)(arg1, arg2, arg3, free_args...);
  }
  template <class Arg1, class Arg2, class Arg3>
  Callback3_const(const T& obj_, MemFunc func_,
		  Arg1&& arg1_,
		  Arg2&& arg2_,
		  Arg3&& arg3_):
                    obj(&obj_), func(func_),
		    arg1(std::forward<Arg1>(arg1_)),
		    arg2(std::forward<Arg2>(arg2_)),
		    arg3(std::forward<Arg3>(arg3_)) {}
};

template <bool unref, class T, class BoundArg1, class BoundArg2, class BoundArg3, 
          class BoundArg4, class... FreeArgs>
class Callback4_const: public CallbackArg<FreeArgs...> {
public:
  typedef void (T::* MemFunc)(BoundArg1, BoundArg2, BoundArg3, BoundArg4, FreeArgs...) const;
private:
  const T* obj;
  MemFunc func;
  typename Cgu::RemoveRefCond<BoundArg1, unref>::Type arg1;
  typename Cgu::RemoveRefCond<BoundArg2, unref>::Type arg2;
  typename Cgu::RemoveRefCond<BoundArg3, unref>::Type arg3;
  typename Cgu::RemoveRefCond<BoundArg4, unref>::Type arg4;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    (obj->*func)(arg1, arg2, arg3, arg4, free_args...);
  }
  template <class Arg1, class Arg2, class Arg3, class Arg4>
  Callback4_const(const T& obj_, MemFunc func_,
		  Arg1&& arg1_,
		  Arg2&& arg2_,
		  Arg3&& arg3_,
		  Arg4&& arg4_):
                    obj(&obj_), func(func_),
		    arg1(std::forward<Arg1>(arg1_)),
		    arg2(std::forward<Arg2>(arg2_)),
		    arg3(std::forward<Arg3>(arg3_)),
		    arg4(std::forward<Arg4>(arg4_)) {}
};

template <bool unref, class T, class BoundArg1, class BoundArg2, class BoundArg3, 
          class BoundArg4, class BoundArg5, class... FreeArgs>
class Callback5_const: public CallbackArg<FreeArgs...> {
public:
  typedef void (T::* MemFunc)(BoundArg1, BoundArg2, BoundArg3,
			      BoundArg4, BoundArg5, FreeArgs...) const;
private:
  const T* obj;
  MemFunc func;
  typename Cgu::RemoveRefCond<BoundArg1, unref>::Type arg1;
  typename Cgu::RemoveRefCond<BoundArg2, unref>::Type arg2;
  typename Cgu::RemoveRefCond<BoundArg3, unref>::Type arg3;
  typename Cgu::RemoveRefCond<BoundArg4, unref>::Type arg4;
  typename Cgu::RemoveRefCond<BoundArg5, unref>::Type arg5;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    (obj->*func)(arg1, arg2, arg3, arg4, arg5, free_args...);
  }
  template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
  Callback5_const(const T& obj_, MemFunc func_,
		  Arg1&& arg1_,
		  Arg2&& arg2_,
		  Arg3&& arg3_,
		  Arg4&& arg4_,
		  Arg5&& arg5_):
                    obj(&obj_), func(func_),
		    arg1(std::forward<Arg1>(arg1_)),
		    arg2(std::forward<Arg2>(arg2_)),
		    arg3(std::forward<Arg3>(arg3_)),
		    arg4(std::forward<Arg4>(arg4_)),
		    arg5(std::forward<Arg5>(arg5_)) {}
};

/* for static class methods and non-class functions */

template <class... FreeArgs>
class Callback0_static: public CallbackArg<FreeArgs...> {
public:
  typedef void (*Func)(FreeArgs...);
private:
  Func func;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    func(free_args...);
  }
  Callback0_static(Func func_): func(func_) {}
};

template <bool unref, class BoundArg, class... FreeArgs>
class Callback1_static: public CallbackArg<FreeArgs...> {
public:
  typedef void (*Func)(BoundArg, FreeArgs...);
private:
  Func func;
  typename Cgu::RemoveRefCond<BoundArg, unref>::Type arg;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    func(arg, free_args...);
  }
  template <class Arg>
  Callback1_static(Func func_, Arg&& arg_): func(func_), arg(std::forward<Arg>(arg_)) {}
};

template <bool unref, class BoundArg1, class BoundArg2, class... FreeArgs>
class Callback2_static: public CallbackArg<FreeArgs...> {
public:
  typedef void (*Func)(BoundArg1, BoundArg2, FreeArgs...);
private:
  Func func;
  typename Cgu::RemoveRefCond<BoundArg1, unref>::Type arg1;
  typename Cgu::RemoveRefCond<BoundArg2, unref>::Type arg2;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    func(arg1, arg2, free_args...);
  }
  template <class Arg1, class Arg2>
  Callback2_static(Func func_, Arg1&& arg1_,
		   Arg2&& arg2_): func(func_),
                                  arg1(std::forward<Arg1>(arg1_)),
                                  arg2(std::forward<Arg2>(arg2_)) {}
};

template <bool unref, class BoundArg1, class BoundArg2, class BoundArg3, class... FreeArgs>
class Callback3_static: public CallbackArg<FreeArgs...> {
public:
  typedef void (*Func)(BoundArg1, BoundArg2, BoundArg3, FreeArgs...);
private:
  Func func;
  typename Cgu::RemoveRefCond<BoundArg1, unref>::Type arg1;
  typename Cgu::RemoveRefCond<BoundArg2, unref>::Type arg2;
  typename Cgu::RemoveRefCond<BoundArg3, unref>::Type arg3;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    func(arg1, arg2, arg3, free_args...);
  }
  template <class Arg1, class Arg2, class Arg3>
  Callback3_static(Func func_,
		   Arg1&& arg1_,
		   Arg2&& arg2_,
		   Arg3&& arg3_):
                     func(func_),
		     arg1(std::forward<Arg1>(arg1_)),
		     arg2(std::forward<Arg2>(arg2_)),
		     arg3(std::forward<Arg3>(arg3_)) {}
};

template <bool unref, class BoundArg1, class BoundArg2, class BoundArg3, 
          class BoundArg4, class... FreeArgs>
class Callback4_static: public CallbackArg<FreeArgs...> {
public:
  typedef void (*Func)(BoundArg1, BoundArg2, BoundArg3, BoundArg4, FreeArgs...);
private:
  Func func;
  typename Cgu::RemoveRefCond<BoundArg1, unref>::Type arg1;
  typename Cgu::RemoveRefCond<BoundArg2, unref>::Type arg2;
  typename Cgu::RemoveRefCond<BoundArg3, unref>::Type arg3;
  typename Cgu::RemoveRefCond<BoundArg4, unref>::Type arg4;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    func(arg1, arg2, arg3, arg4, free_args...);
  }
  template <class Arg1, class Arg2, class Arg3, class Arg4>
  Callback4_static(Func func_,
		   Arg1&& arg1_,
		   Arg2&& arg2_,
		   Arg3&& arg3_,
		   Arg4&& arg4_):
                     func(func_),
		     arg1(std::forward<Arg1>(arg1_)),
		     arg2(std::forward<Arg2>(arg2_)),
		     arg3(std::forward<Arg3>(arg3_)),
		     arg4(std::forward<Arg4>(arg4_)) {}
};

template <bool unref, class BoundArg1, class BoundArg2, class BoundArg3, 
          class BoundArg4, class BoundArg5, class... FreeArgs>
class Callback5_static: public CallbackArg<FreeArgs...> {
public:
  typedef void (*Func)(BoundArg1, BoundArg2, BoundArg3,
		       BoundArg4, BoundArg5, FreeArgs...);
private:
  Func func;
  typename Cgu::RemoveRefCond<BoundArg1, unref>::Type arg1;
  typename Cgu::RemoveRefCond<BoundArg2, unref>::Type arg2;
  typename Cgu::RemoveRefCond<BoundArg3, unref>::Type arg3;
  typename Cgu::RemoveRefCond<BoundArg4, unref>::Type arg4;
  typename Cgu::RemoveRefCond<BoundArg5, unref>::Type arg5;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {
    func(arg1, arg2, arg3, arg4, arg5, free_args...);
  }
  template <class Arg1, class Arg2, class Arg3, class Arg4, class Arg5>
  Callback5_static(Func func_,
		   Arg1&& arg1_,
		   Arg2&& arg2_,
		   Arg3&& arg3_,
		   Arg4&& arg4_,
		   Arg5&& arg5_):
                     func(func_),
		     arg1(std::forward<Arg1>(arg1_)),
		     arg2(std::forward<Arg2>(arg2_)),
		     arg3(std::forward<Arg3>(arg3_)),
		     arg4(std::forward<Arg4>(arg4_)),
		     arg5(std::forward<Arg5>(arg5_)) {}
};

// TODO: Version 2.0.9 provides a Callback_lambda class for callable
// objects which makes the specialized Callback_function class
// redundant.  At an API break we can remove the Callback_function
// class and modify the Callback::make() helper function overload for
// std::function objects to construct a Callback_lambda object
// instead.  Doing it now would not affect ABI compatibility as the
// library produces these only by base pointer, but a user may have
// instantiated them by hand in user code.
template <class... FreeArgs>
class Callback_function: public CallbackArg<FreeArgs...> {
  std::function<void(FreeArgs...)> f;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {f(free_args...);}
  Callback_function(const std::function<void(FreeArgs...)>& f_): f(f_) {}
  Callback_function(std::function<void(FreeArgs...)>&& f_): f(std::move(f_)) {}
};

// generic class for callable objects such as lambdas
template <class Lambda, class... FreeArgs>
class Callback_lambda: public CallbackArg<FreeArgs...> {
  // making 'l' mutable means that Callback_lamdba objects can contain
  // mutable lambda expressions
  mutable Lambda l;
public:
  void dispatch(typename Cgu::Param<FreeArgs>::ParamType... free_args) const {l(free_args...);}
  template <class L> Callback_lambda(L&& l_): l(std::forward<L>(l_)) {}
};

/* Convenience functions making callback objects on freestore.  These
 * can for example be passed as the first argument of the
 * Thread::start() method in thread.h. They are also used by the
 * Callback::post() function.
*/

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case.  This exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option (instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).
 */
template <class T, class... FreeArgs>
CallbackArg<FreeArgs...>* make(T& t,
			       void (T::*func)(FreeArgs...)) {
  return new Callback0<T, FreeArgs...>{t, func};
}

/**
 * DEPRECATED.
 *
 * Since this function constructs a callback which does not take a
 * bound argument, it is a synonym for make() (the two are identical).
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case.  This exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option (instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).
 */
template <class T, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(T& t,
				   void (T::*func)(FreeArgs...)) {
  return new Callback0<T, FreeArgs...>{t, func};
}

/**
 * Since this function constructs a callback which does not take a
 * bound argument, it is a synonym for make() (the two are identical).
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case.  This exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option (instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).
 *
 * Since 2.0.0-rc3
 */
template <class T, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(T& t,
				   void (T::*func)(FreeArgs...)) {
  return new Callback0<T, FreeArgs...>{t, func};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg, class... FreeArgs>
CallbackArg<FreeArgs...>* make(T& t,
			       void (T::*func)(BoundArg, FreeArgs...),
			       BoundArg arg) {
  return new Callback1<false, T, BoundArg, FreeArgs...>{t, func, arg};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(T& t,
				   void (T::*func)(BoundArg, FreeArgs...),
				   const BoundArg& arg) {
  return new Callback1<false, T, BoundArg, FreeArgs...>{t, func, arg};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class T, class BoundArg, class Arg, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(T& t,
				   void (T::*func)(BoundArg, FreeArgs...),
				   Arg&& arg) {
  return new Callback1<true, T, BoundArg, FreeArgs...>{t, func, std::forward<Arg>(arg)};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class... FreeArgs>
CallbackArg<FreeArgs...>* make(T& t,
			       void (T::*func)(BoundArg1, BoundArg2, FreeArgs...),
			       BoundArg1 arg1,
			       BoundArg2 arg2) {
  return new Callback2<false, T, BoundArg1, BoundArg2, FreeArgs...>{t, func, arg1, arg2};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(T& t,
				   void (T::*func)(BoundArg1, BoundArg2, FreeArgs...),
				   const BoundArg1& arg1,
				   const BoundArg2& arg2) {
  return new Callback2<false, T, BoundArg1, BoundArg2, FreeArgs...>{t, func, arg1, arg2};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class T, class BoundArg1, class BoundArg2,
          class Arg1, class Arg2, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(T& t,
				   void (T::*func)(BoundArg1, BoundArg2, FreeArgs...),
				   Arg1&& arg1,
				   Arg2&& arg2) {
  return new Callback2<true, T, BoundArg1, BoundArg2, FreeArgs...>{t, func,
                                                                   std::forward<Arg1>(arg1),
                                                                   std::forward<Arg2>(arg2)};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3, class... FreeArgs>
CallbackArg<FreeArgs...>* make(T& t,
			       void (T::*func)(BoundArg1, BoundArg2, BoundArg3, FreeArgs...),
			       BoundArg1 arg1,
			       BoundArg2 arg2,
			       BoundArg3 arg3) {
  return new Callback3<false, T, BoundArg1, BoundArg2, BoundArg3, FreeArgs...>{t, func, arg1, arg2, arg3};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(T& t,
				   void (T::*func)(BoundArg1, BoundArg2, BoundArg3, FreeArgs...),
				   const BoundArg1& arg1,
				   const BoundArg2& arg2,
				   const BoundArg3& arg3) {
  return new Callback3<false, T, BoundArg1, BoundArg2, BoundArg3, FreeArgs...>{t, func, arg1, arg2, arg3};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3,
          class Arg1, class Arg2, class Arg3, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(T& t,
				   void (T::*func)(BoundArg1, BoundArg2, BoundArg3, FreeArgs...),
				   Arg1&& arg1,
				   Arg2&& arg2,
				   Arg3&& arg3) {
  return new Callback3<true, T, BoundArg1, BoundArg2, BoundArg3, FreeArgs...>{t, func,
                                                                              std::forward<Arg1>(arg1),
                                                                              std::forward<Arg2>(arg2),
                                                                              std::forward<Arg3>(arg3)};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3,
          class BoundArg4, class... FreeArgs>
CallbackArg<FreeArgs...>* make(T& t,
			       void (T::*func)(BoundArg1, BoundArg2, BoundArg3,
					       BoundArg4, FreeArgs...),
			       BoundArg1 arg1,
			       BoundArg2 arg2,
			       BoundArg3 arg3,
			       BoundArg4 arg4) {
  return new Callback4<false, T, BoundArg1, BoundArg2, BoundArg3,
                       BoundArg4, FreeArgs...>{t, func, arg1, arg2, arg3, arg4};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3,
          class BoundArg4, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(T& t,
				   void (T::*func)(BoundArg1, BoundArg2, BoundArg3,
						   BoundArg4, FreeArgs...),
				   const BoundArg1& arg1,
				   const BoundArg2& arg2,
				   const BoundArg3& arg3,
				   const BoundArg4& arg4) {
  return new Callback4<false, T, BoundArg1, BoundArg2, BoundArg3,
                       BoundArg4, FreeArgs...>{t, func, arg1, arg2, arg3, arg4};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3, class BoundArg4,
          class Arg1, class Arg2, class Arg3, class Arg4, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(T& t,
				   void (T::*func)(BoundArg1, BoundArg2, BoundArg3,
						   BoundArg4, FreeArgs...),
				   Arg1&& arg1,
				   Arg2&& arg2,
				   Arg3&& arg3,
				   Arg4&& arg4) {
  return new Callback4<true, T, BoundArg1, BoundArg2, BoundArg3,
                       BoundArg4, FreeArgs...>{t, func,
                                               std::forward<Arg1>(arg1),
                                               std::forward<Arg2>(arg2),
                                               std::forward<Arg3>(arg3),
                                               std::forward<Arg4>(arg4)};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3,
          class BoundArg4, class BoundArg5, class... FreeArgs>
CallbackArg<FreeArgs...>* make(T& t,
			       void (T::*func)(BoundArg1, BoundArg2, BoundArg3,
					       BoundArg4, BoundArg5, FreeArgs...),
			       BoundArg1 arg1,
			       BoundArg2 arg2,
			       BoundArg3 arg3,
			       BoundArg4 arg4,
			       BoundArg5 arg5) {
  return new Callback5<false, T, BoundArg1, BoundArg2, BoundArg3,
                       BoundArg4, BoundArg5, FreeArgs...>{t, func, arg1, arg2, arg3, arg4, arg5};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3,
          class BoundArg4, class BoundArg5, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(T& t,
				   void (T::*func)(BoundArg1, BoundArg2, BoundArg3,
						   BoundArg4, BoundArg5, FreeArgs...),
				   const BoundArg1& arg1,
				   const BoundArg2& arg2,
				   const BoundArg3& arg3,
				   const BoundArg4& arg4,
				   const BoundArg5& arg5) {
  return new Callback5<false, T, BoundArg1, BoundArg2, BoundArg3,
                       BoundArg4, BoundArg5, FreeArgs...>{t, func, arg1, arg2, arg3, arg4, arg5};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3, class BoundArg4, class BoundArg5,
          class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(T& t,
				   void (T::*func)(BoundArg1, BoundArg2, BoundArg3,
						   BoundArg4, BoundArg5, FreeArgs...),
				   Arg1&& arg1,
				   Arg2&& arg2,
				   Arg3&& arg3,
				   Arg4&& arg4,
				   Arg5&& arg5) {
  return new Callback5<true, T, BoundArg1, BoundArg2, BoundArg3,
                       BoundArg4, BoundArg5, FreeArgs...>{t, func,
                                                          std::forward<Arg1>(arg1),
                                                          std::forward<Arg2>(arg2),
                                                          std::forward<Arg3>(arg3),
                                                          std::forward<Arg4>(arg4),
                                                          std::forward<Arg5>(arg5)};
}

/* const versions, for binding to const methods */

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case.  This exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option (instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).
 */
template <class T, class... FreeArgs>
CallbackArg<FreeArgs...>* make(const T& t,
			       void (T::*func)(FreeArgs...) const) {
  return new Callback0_const<T, FreeArgs...>{t, func};
}

/**
 * DEPRECATED.
 *
 * Since this function constructs a callback which does not take a
 * bound argument, it is a synonym for make() (the two are identical).
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case.  This exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option (instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).
 */
template <class T, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(const T& t,
				   void (T::*func)(FreeArgs...) const) {
  return new Callback0_const<T, FreeArgs...>{t, func};
}

/**
 * Since this function constructs a callback which does not take a
 * bound argument, it is a synonym for make() (the two are identical).
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case.  This exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option (instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).
 *
 * Since 2.0.0-rc3
 */
template <class T, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(const T& t,
				   void (T::*func)(FreeArgs...) const) {
  return new Callback0_const<T, FreeArgs...>{t, func};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg, class... FreeArgs>
CallbackArg<FreeArgs...>* make(const T& t,
			       void (T::*func)(BoundArg, FreeArgs...) const,
			       BoundArg arg) {
  return new Callback1_const<false, T, BoundArg, FreeArgs...>{t, func, arg};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(const T& t,
				   void (T::*func)(BoundArg, FreeArgs...) const,
				   const BoundArg& arg) {
  return new Callback1_const<false, T, BoundArg, FreeArgs...>{t, func, arg};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class T, class BoundArg, class Arg, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(const T& t,
				   void (T::*func)(BoundArg, FreeArgs...) const,
				   Arg&& arg) {
  return new Callback1_const<true, T, BoundArg, FreeArgs...>{t, func, std::forward<Arg>(arg)};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class... FreeArgs>
CallbackArg<FreeArgs...>* make(const T& t,
			       void (T::*func)(BoundArg1, BoundArg2, FreeArgs...) const,
			       BoundArg1 arg1,
			       BoundArg2 arg2) {
  return new Callback2_const<false, T, BoundArg1, BoundArg2, FreeArgs...>{t, func, arg1, arg2};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(const T& t,
				   void (T::*func)(BoundArg1, BoundArg2, FreeArgs...) const,
				   const BoundArg1& arg1,
				   const BoundArg2& arg2) {
  return new Callback2_const<false, T, BoundArg1, BoundArg2, FreeArgs...>{t, func, arg1, arg2};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class T, class BoundArg1, class BoundArg2,
          class Arg1, class Arg2, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(const T& t,
				   void (T::*func)(BoundArg1, BoundArg2, FreeArgs...) const,
				   Arg1&& arg1,
				   Arg2&& arg2) {
  return new Callback2_const<true, T, BoundArg1, BoundArg2, FreeArgs...>{t, func,
                                                                         std::forward<Arg1>(arg1),
                                                                         std::forward<Arg2>(arg2)};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3, class... FreeArgs>
CallbackArg<FreeArgs...>* make(const T& t,
			       void (T::*func)(BoundArg1, BoundArg2, BoundArg3, FreeArgs...) const,
			       BoundArg1 arg1,
			       BoundArg2 arg2,
			       BoundArg3 arg3) {
  return new Callback3_const<false, T, BoundArg1, BoundArg2, BoundArg3, FreeArgs...>{t, func, arg1, arg2, arg3};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(const T& t,
				   void (T::*func)(BoundArg1, BoundArg2, BoundArg3, FreeArgs...) const,
				   const BoundArg1& arg1,
				   const BoundArg2& arg2,
				   const BoundArg3& arg3) {
  return new Callback3_const<false, T, BoundArg1, BoundArg2, BoundArg3, FreeArgs...>{t, func, arg1, arg2, arg3};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3,
          class Arg1, class Arg2, class Arg3, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(const T& t,
				   void (T::*func)(BoundArg1, BoundArg2, BoundArg3, FreeArgs...) const,
				   Arg1&& arg1,
				   Arg2&& arg2,
				   Arg3&& arg3) {
  return new Callback3_const<true, T, BoundArg1, BoundArg2, BoundArg3, FreeArgs...>{t, func,
                                                                                    std::forward<Arg1>(arg1),
                                                                                    std::forward<Arg2>(arg2),
                                                                                    std::forward<Arg3>(arg3)};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3,
          class BoundArg4, class... FreeArgs>
CallbackArg<FreeArgs...>* make(const T& t,
			       void (T::*func)(BoundArg1, BoundArg2, BoundArg3,
					       BoundArg4, FreeArgs...) const,
			       BoundArg1 arg1,
			       BoundArg2 arg2,
			       BoundArg3 arg3,
			       BoundArg4 arg4) {
  return new Callback4_const<false, T, BoundArg1, BoundArg2, BoundArg3,
                             BoundArg4, FreeArgs...>{t, func, arg1, arg2, arg3, arg4};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3,
          class BoundArg4, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(const T& t,
				   void (T::*func)(BoundArg1, BoundArg2, BoundArg3,
						   BoundArg4, FreeArgs...) const,
				   const BoundArg1& arg1,
				   const BoundArg2& arg2,
				   const BoundArg3& arg3,
				   const BoundArg4& arg4) {
  return new Callback4_const<false, T, BoundArg1, BoundArg2, BoundArg3,
                             BoundArg4, FreeArgs...>{t, func, arg1, arg2, arg3, arg4};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3, class BoundArg4,
          class Arg1, class Arg2, class Arg3, class Arg4, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(const T& t,
				   void (T::*func)(BoundArg1, BoundArg2, BoundArg3,
						   BoundArg4, FreeArgs...) const,
				   Arg1&& arg1,
				   Arg2&& arg2,
				   Arg3&& arg3,
				   Arg4&& arg4) {
  return new Callback4_const<true, T, BoundArg1, BoundArg2, BoundArg3,
                             BoundArg4, FreeArgs...>{t, func,
                                                     std::forward<Arg1>(arg1),
                                                     std::forward<Arg2>(arg2),
                                                     std::forward<Arg3>(arg3),
                                                     std::forward<Arg4>(arg4)};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3,
          class BoundArg4, class BoundArg5, class... FreeArgs>
CallbackArg<FreeArgs...>* make(const T& t,
			       void (T::*func)(BoundArg1, BoundArg2, BoundArg3,
					       BoundArg4, BoundArg5, FreeArgs...) const,
			       BoundArg1 arg1,
			       BoundArg2 arg2,
			       BoundArg3 arg3,
			       BoundArg4 arg4,
			       BoundArg5 arg5) {
  return new Callback5_const<false, T, BoundArg1, BoundArg2, BoundArg3,
                             BoundArg4, BoundArg5, FreeArgs...>{t, func, arg1, arg2, arg3, arg4, arg5};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3,
          class BoundArg4, class BoundArg5, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(const T& t,
				   void (T::*func)(BoundArg1, BoundArg2, BoundArg3,
						   BoundArg4, BoundArg5, FreeArgs...) const,
				   const BoundArg1& arg1,
				   const BoundArg2& arg2,
				   const BoundArg3& arg3,
				   const BoundArg4& arg4,
				   const BoundArg5& arg5) {
  return new Callback5_const<false, T, BoundArg1, BoundArg2, BoundArg3,
                             BoundArg4, BoundArg5, FreeArgs...>{t, func, arg1, arg2, arg3, arg4, arg5};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class T, class BoundArg1, class BoundArg2, class BoundArg3, class BoundArg4, class BoundArg5,
          class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(const T& t,
				   void (T::*func)(BoundArg1, BoundArg2, BoundArg3,
						   BoundArg4, BoundArg5, FreeArgs...) const,
				   Arg1&& arg1,
				   Arg2&& arg2,
				   Arg3&& arg3,
				   Arg4&& arg4,
				   Arg5&& arg5) {
  return new Callback5_const<true, T, BoundArg1, BoundArg2, BoundArg3,
                             BoundArg4, BoundArg5, FreeArgs...>{t, func,
                                                                std::forward<Arg1>(arg1),
                                                                std::forward<Arg2>(arg2),
                                                                std::forward<Arg3>(arg3),
                                                                std::forward<Arg4>(arg4),
                                                                std::forward<Arg5>(arg5)};
}

/* for static class methods and non-class functions */

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case.  This exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option (instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).
 */
template <class... FreeArgs>
CallbackArg<FreeArgs...>* make(void (*func)(FreeArgs...)) {
  return new Callback0_static<FreeArgs...>{func};
}

/**
 * DEPRECATED.
 *
 * Since this function constructs a callback which does not take a
 * bound argument, it is a synonym for make() (the two are identical).
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case.  This exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option (instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).
 */
template <class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(void (*func)(FreeArgs...)) {
  return new Callback0_static<FreeArgs...>{func};
}

/**
 * Since this function constructs a callback which does not take a
 * bound argument, it is a synonym for make() (the two are identical).
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case.  This exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option (instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).
 *
 * Since 2.0.0-rc3
 */
template <class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(void (*func)(FreeArgs...)) {
  return new Callback0_static<FreeArgs...>{func};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class BoundArg, class... FreeArgs>
CallbackArg<FreeArgs...>* make(void (*func)(BoundArg, FreeArgs...),
			       BoundArg arg) {
  return new Callback1_static<false, BoundArg, FreeArgs...>{func, arg};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class BoundArg, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(void (*func)(BoundArg, FreeArgs...),
				   const BoundArg& arg) {
  return new Callback1_static<false, BoundArg, FreeArgs...>{func, arg};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class BoundArg, class Arg, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(void (*func)(BoundArg, FreeArgs...),
				   Arg&& arg) {
  return new Callback1_static<true, BoundArg, FreeArgs...>{func, std::forward<Arg>(arg)};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class BoundArg1, class BoundArg2, class... FreeArgs>
CallbackArg<FreeArgs...>* make(void (*func)(BoundArg1, BoundArg2, FreeArgs...),
			       BoundArg1 arg1,
			       BoundArg2 arg2) {
  return new Callback2_static<false, BoundArg1, BoundArg2, FreeArgs...>{func, arg1, arg2};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class BoundArg1, class BoundArg2, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(void (*func)(BoundArg1, BoundArg2, FreeArgs...),
				   const BoundArg1& arg1,
				   const BoundArg2& arg2) {
  return new Callback2_static<false, BoundArg1, BoundArg2, FreeArgs...>{func, arg1, arg2};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class BoundArg1, class BoundArg2, class Arg1, class Arg2, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(void (*func)(BoundArg1, BoundArg2, FreeArgs...),
				   Arg1&& arg1,
				   Arg2&& arg2) {
  return new Callback2_static<true, BoundArg1, BoundArg2, FreeArgs...>{func,
                                                                       std::forward<Arg1>(arg1),
                                                                       std::forward<Arg2>(arg2)};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class BoundArg1, class BoundArg2, class BoundArg3, class... FreeArgs>
CallbackArg<FreeArgs...>* make(void (*func)(BoundArg1, BoundArg2, BoundArg3, FreeArgs...),
			       BoundArg1 arg1,
			       BoundArg2 arg2,
			       BoundArg3 arg3) {
  return new Callback3_static<false, BoundArg1, BoundArg2, BoundArg3, FreeArgs...>{func, arg1, arg2, arg3};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class BoundArg1, class BoundArg2, class BoundArg3, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(void (*func)(BoundArg1, BoundArg2, BoundArg3, FreeArgs...),
				   const BoundArg1& arg1,
				   const BoundArg2& arg2,
				   const BoundArg3& arg3) {
  return new Callback3_static<false, BoundArg1, BoundArg2, BoundArg3, FreeArgs...>{func, arg1, arg2, arg3};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class BoundArg1, class BoundArg2, class BoundArg3,
          class Arg1, class Arg2, class Arg3, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(void (*func)(BoundArg1, BoundArg2, BoundArg3, FreeArgs...),
				   Arg1&& arg1,
				   Arg2&& arg2,
				   Arg3&& arg3) {
  return new Callback3_static<true, BoundArg1, BoundArg2, BoundArg3, FreeArgs...>{func,
                                                                                  std::forward<Arg1>(arg1),
                                                                                  std::forward<Arg2>(arg2),
                                                                                  std::forward<Arg3>(arg3)};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class BoundArg1, class BoundArg2, class BoundArg3,
          class BoundArg4, class... FreeArgs>
CallbackArg<FreeArgs...>* make(void (*func)(BoundArg1, BoundArg2, BoundArg3,
					    BoundArg4, FreeArgs...),
			       BoundArg1 arg1,
			       BoundArg2 arg2,
			       BoundArg3 arg3,
			       BoundArg4 arg4) {
  return new Callback4_static<false, BoundArg1, BoundArg2, BoundArg3,
                              BoundArg4, FreeArgs...>{func, arg1, arg2, arg3, arg4};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class BoundArg1, class BoundArg2, class BoundArg3,
          class BoundArg4, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(void (*func)(BoundArg1, BoundArg2, BoundArg3,
						BoundArg4, FreeArgs...),
				   const BoundArg1& arg1,
				   const BoundArg2& arg2,
				   const BoundArg3& arg3,
				   const BoundArg4& arg4) {
  return new Callback4_static<false, BoundArg1, BoundArg2, BoundArg3,
                              BoundArg4, FreeArgs...>{func, arg1, arg2, arg3, arg4};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class BoundArg1, class BoundArg2, class BoundArg3, class BoundArg4,
          class Arg1, class Arg2, class Arg3, class Arg4, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(void (*func)(BoundArg1, BoundArg2, BoundArg3,
						BoundArg4, FreeArgs...),
				   Arg1&& arg1,
				   Arg2&& arg2,
				   Arg3&& arg3,
				   Arg4&& arg4) {
  return new Callback4_static<true, BoundArg1, BoundArg2, BoundArg3,
                              BoundArg4, FreeArgs...>{func,
                                                      std::forward<Arg1>(arg1),
                                                      std::forward<Arg2>(arg2),
                                                      std::forward<Arg3>(arg3),
                                                      std::forward<Arg4>(arg4)};
}

/**
 * A convenience function to make Callback::CallbackArg objects
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class BoundArg1, class BoundArg2, class BoundArg3,
          class BoundArg4, class BoundArg5, class... FreeArgs>
CallbackArg<FreeArgs...>* make(void (*func)(BoundArg1, BoundArg2, BoundArg3,
					    BoundArg4, BoundArg5, FreeArgs...),
			       BoundArg1 arg1,
			       BoundArg2 arg2,
			       BoundArg3 arg3,
			       BoundArg4 arg4,
			       BoundArg5 arg5) {
  return new Callback5_static<false, BoundArg1, BoundArg2, BoundArg3,
                              BoundArg4, BoundArg5, FreeArgs...>{func, arg1, arg2, arg3, arg4, arg5};
}

/**
 * DEPRECATED: use Callback::make_ref() instead.
 *
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function receives an argument of
 * class type by value which is to be a bound argument, so the
 * compiler is not able to carry out copy elision when constructing
 * the callback object.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class BoundArg1, class BoundArg2, class BoundArg3,
          class BoundArg4, class BoundArg5, class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(void (*func)(BoundArg1, BoundArg2, BoundArg3,
						BoundArg4, BoundArg5, FreeArgs...),
				   const BoundArg1& arg1,
				   const BoundArg2& arg2,
				   const BoundArg3& arg3,
				   const BoundArg4& arg4,
				   const BoundArg5& arg5) {
  return new Callback5_static<false, BoundArg1, BoundArg2, BoundArg3,
                              BoundArg4, BoundArg5, FreeArgs...>{func, arg1, arg2, arg3, arg4, arg5};
}

/**
 * An alternative function to make Callback::CallbackArg objects,
 * which is for use where a target function either receives a class
 * type bound argument by value, or receives a bound argument by
 * reference to const in a case where the generated CallbackArg object
 * is to store a copy of that argument instead of just keeping a
 * reference.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws.
 *
 * Since 2.0.0-rc3
 */
template <class BoundArg1, class BoundArg2, class BoundArg3, class BoundArg4, class BoundArg5,
          class Arg1, class Arg2, class Arg3, class Arg4, class Arg5, class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(void (*func)(BoundArg1, BoundArg2, BoundArg3,
						BoundArg4, BoundArg5, FreeArgs...),
				   Arg1&& arg1,
				   Arg2&& arg2,
				   Arg3&& arg3,
				   Arg4&& arg4,
				   Arg5&& arg5) {
  return new Callback5_static<true, BoundArg1, BoundArg2, BoundArg3,
                              BoundArg4, BoundArg5, FreeArgs...>{func,
                                                                 std::forward<Arg1>(arg1),
                                                                 std::forward<Arg2>(arg2),
                                                                 std::forward<Arg3>(arg3),
                                                                 std::forward<Arg4>(arg4),
                                                                 std::forward<Arg5>(arg5)};
}

/* for std::function objects */

/**
 * A convenience function to make Callback::CallbackArg objects from
 * std::function objects.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class... FreeArgs>
CallbackArg<FreeArgs...>* make(const std::function<void(FreeArgs...)>& f) {
  return new Callback_function<FreeArgs...>{f};
}

/**
 * DEPRECATED.
 *
 * A convenience function to make Callback::Callback objects from
 * std::function objects.  Since this function takes no bound argument
 * (and bound arguments are bound into the std::function object), it
 * is a synonym for make() (the two are identical).
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(const std::function<void(FreeArgs...)>& f) {
  return new Callback_function<FreeArgs...>{f};
}

/**
 * A convenience function to make Callback::Callback objects from
 * std::function objects.  Since this function takes no bound argument
 * (and bound arguments are bound into the std::function object), it
 * is a synonym for make() (the two are identical).
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(const std::function<void(FreeArgs...)>& f) {
  return new Callback_function<FreeArgs...>{f};
}

/**
 * A convenience function to make Callback::CallbackArg objects from
 * std::function objects.
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class... FreeArgs>
CallbackArg<FreeArgs...>* make(std::function<void(FreeArgs...)>&& f) {
  return new Callback_function<FreeArgs...>{std::move(f)};
}

/**
 * DEPRECATED.
 *
 * A convenience function to make Callback::Callback objects from
 * std::function objects.  Since this function takes no bound argument
 * (and bound arguments are bound into the std::function object), it
 * is a synonym for make() (the two are identical).
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class... FreeArgs>
CallbackArg<FreeArgs...>* make_val(std::function<void(FreeArgs...)>&& f) {
  return new Callback_function<FreeArgs...>{std::move(f)};
}

/**
 * A convenience function to make Callback::Callback objects from
 * std::function objects.  Since this function takes no bound argument
 * (and bound arguments are bound into the std::function object), it
 * is a synonym for make() (the two are identical).
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of a bound argument throws and it is not a reference
 * argument.
 */
template <class... FreeArgs>
CallbackArg<FreeArgs...>* make_ref(std::function<void(FreeArgs...)>&& f) {
  return new Callback_function<FreeArgs...>{std::move(f)};
}

// This helper function to construct Callback_lambda objects could be
// implemented as a further overload of Callback::make().  No best
// match ambiguities would arise, because even when Callback::make()
// is passed a function pointer without bound arguments, the overload
// of Callback::make taking a function pointer (as opposed to a
// generic callable object) would still comprise the best match.
// However, to construct Callback_lambda objects, the unbound
// arguments need to be specified by hand, which doesn't happen with
// Callback::make() (it would only be necessary to specify an explicit
// type where a mutable reference argument is to be bound to the
// callback object).  It seems to me to be less confusing to the user
// therefore to have a separate Callback::lambda() helper function.
// However, if you disagree please let me know.

// template parameter packs do not need to be placed last in the case
// of function templates, as type deduction is available for the last
// parameter: there is in fact no function parameter pack in
// Callback::lambda() (function parameter packs must come last).
/**
 * A convenience function to make Callback::CallbackArg objects from
 * C++11/14 lambda expressions, or from any other arbitrary callable
 * object.  The types of the unbound arguments (if any) must be
 * explicitly specified as template parameters, as they cannot be
 * deduced.  From version 2.0.10, this function can be called for
 * lambda expressions which are declared mutable (in version 2.0.9,
 * this function could only be called for non-mutable lambda
 * expressions).  From version 2.0.16, this function can be passed
 * callable objects which are lvalues as well as rvalues (prior to
 * version 2.0.16, it could only be passed callable objects which are
 * rvalues).
 * @exception std::bad_alloc It might throw std::bad_alloc if memory
 * is exhausted and the system throws in that case (this exception
 * will not be thrown if the library has been installed using the
 * \--with-glib-memory-slices-no-compat configuration option: instead
 * glib will terminate the program if it is unable to obtain memory
 * from the operating system).  It will also throw if the copy or move
 * constructor of an object captured by the lambda expression throws.
 *
 * Since 2.0.9
 */
template <class... FreeArgs, class Lambda>
CallbackArg<FreeArgs...>* lambda(Lambda&& l) {
  typedef typename std::remove_const<typename std::remove_reference<Lambda>::type>::type LType;
  return new Callback_lambda<LType, FreeArgs...>{std::forward<Lambda>(l)};
}

} // namespace Callback

class Releaser;

namespace Callback {

/**
 * Posts a callback for execution by a glib main loop.  It is
 * thread-safe provided that (if glib < 2.32 is used) g_thread_init()
 * has been called.  glib >= 2.32 does not require g_thread_init() to
 * be called.  This function will not throw.
 * @param cb The callback object.  Ownership is taken of this object,
 * and it will be deleted when it has been finished with.
 * @param priority The priority to be given to the callback in the
 * main loop.  In ascending order of priorities, priorities are
 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
 * G_PRIORITY_DEFAULT_IDLE.  This determines the order in which the
 * callback will appear in the event list in the main loop, not the
 * priority which the OS will adopt
 * @param context The glib main loop context in which the callback is
 * to be executed (the default of NULL will cause the callback to be
 * executed in the main program loop, and this is usually what is
 * wanted).
 * @note 1. Cancellation of the receiving thread is blocked when the
 * callback executes.
 * @note 2. If the callback throws an exception, the exception will be
 * consumed to protect the main loop and a g_critical() warning will
 * be issued.
 */
void post(const Callback* cb, gint priority = G_PRIORITY_DEFAULT_IDLE,
	  GMainContext* context = 0);

/**
 * Posts a callback for execution by a glib main loop.  It is
 * thread-safe provided that (if glib < 2.32 is used) g_thread_init()
 * has been called.  glib >= 2.32 does not require g_thread_init() to
 * be called.  This function will not throw.
 * @param cb The callback object.  Ownership is taken of this object,
 * and it will be deleted when it has been finished with.
 * @param r A Releaser object for automatic disconnection of the
 * callback before it executes in the main loop (mainly relevant if
 * the callback represents a non-static member function of an object
 * which may be destroyed before the callback executes).
 * @param priority The priority to be given to the callback in the
 * main loop.  In ascending order of priorities, priorities are
 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
 * G_PRIORITY_DEFAULT_IDLE.  This determines the order in which the
 * callback will appear in the event list in the main loop, not the
 * priority which the OS will adopt.
 * @param context The glib main loop context in which the callback is
 * to be executed (the default of NULL will cause the callback to be
 * executed in the main program loop, and this is usually what is
 * wanted).
 * @exception std::bad_alloc This function might throw std::bad_alloc
 * if memory is exhausted and the system throws in that case.  If it
 * does so, the Callback object will be disposed of.
 * @exception Cgu::Thread::MutexError This function might throw
 * Cgu:Thread::MutexError if initialisation of the mutex in a
 * SafeEmitterArg object constructed by this function fails.  If it
 * does so, the Callback object will be disposed of.  (It is often not
 * worth checking for this exception, as it means either memory is
 * exhausted or pthread has run out of other resources to create new
 * mutexes.)
 * @note 1. Cancellation of the receiving thread is blocked when the
 * callback executes.
 * @note 2. If the callback throws an exception, the exception will be
 * consumed to protect the main loop and a g_critical() warning will
 * be issued.
 * @note 3. By virtue of the Releaser object, it is in theory possible
 * (if memory is exhausted and the system throws in that case) that an
 * internal SafeEmitterArg object will throw std::bad_alloc when
 * emitting/executing the callback in the glib main loop, with the
 * result that the relevant callback will not execute (instead the
 * exception will be consumed and a g_critical() warning will be
 * issued).  This is rarely of any relevance because glib will abort
 * the program if it is itself unable to obtain memory from the
 * operating system.  However, where it is relevant, design the
 * program so that it is not necessary to provide a releaser object.
 */
void post(const Callback* cb, Releaser& r,
	  gint priority = G_PRIORITY_DEFAULT_IDLE, GMainContext* context = 0);

} // namespace Callback

} // namespace Cgu

#endif
