]> de.git.xonotic.org Git - xonotic/netradiant.git/blobdiff - libs/generic/callback.h
Fix MSYS2 issues
[xonotic/netradiant.git] / libs / generic / callback.h
index e5a8c8b4ad04403ea3d2e76c9d6eddd377eed91d..2ce007fcb2780fbedfdb4b2adee11567f509786d 100644 (file)
 /*
-Copyright (C) 2001-2006, William Joseph.
-All Rights Reserved.
+   Copyright (C) 2001-2006, William Joseph.
+   All Rights Reserved.
 
-This file is part of GtkRadiant.
+   This file is part of GtkRadiant.
 
-GtkRadiant is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or
-(at your option) any later version.
+   GtkRadiant is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
 
-GtkRadiant is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-GNU General Public License for more details.
+   GtkRadiant is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
 
-You should have received a copy of the GNU General Public License
-along with GtkRadiant; if not, write to the Free Software
-Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-*/
+   You should have received a copy of the GNU General Public License
+   along with GtkRadiant; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
 
-#if !defined(INCLUDED_GENERIC_CLOSURE_H)
+#if !defined( INCLUDED_GENERIC_CLOSURE_H )
 #define INCLUDED_GENERIC_CLOSURE_H
 
 /// \file
-/// \brief Type-safe techniques for binding the first argument of an anonymous callback. 
+/// \brief Type-safe techniques for binding the first argument of an opaque callback.
 
 #include <cstddef>
+#include "functional.h"
+#include "callbackfwd.h"
 
-/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer.
-///
-/// Use with the callback constructors MemberCaller, ConstMemberCaller, ReferenceCaller, ConstReferenceCaller, PointerCaller, ConstPointerCaller and FreeCaller.
-class Callback
+template<typename Type>
+inline void* convertToOpaque( Type* t ){
+       return t;
+}
+template<typename Type>
+inline void* convertToOpaque( const Type* t ){
+       return const_cast<Type*>( t );
+}
+template<typename Type>
+inline void* convertToOpaque( Type& t ){
+       return &t;
+}
+template<typename Type>
+inline void* convertToOpaque( const Type& t ){
+       return const_cast<Type*>( &t );
+}
+
+
+template<typename Type>
+class ConvertFromOpaque
 {
-  typedef void (*Thunk)(void*);
-  void* m_environment;
-  Thunk m_thunk;
+};
 
-  static void nullThunk(void*)
-  {
-  }
+template<typename Type>
+class ConvertFromOpaque<Type&>
+{
+public:
+static Type& apply( void* p ){
+       return *static_cast<Type*>( p );
+}
+};
 
+template<typename Type>
+class ConvertFromOpaque<const Type&>
+{
 public:
-  Callback() : m_environment(0), m_thunk(nullThunk)
-  {
-  }
-  Callback(void* environment, Thunk function) : m_environment(environment), m_thunk(function)
-  {
-  }
-  void* getEnvironment() const
-  {
-    return m_environment;
-  }
-  Thunk getThunk() const
-  {
-    return m_thunk;
-  }
-  void operator()() const
-  {
-    m_thunk(m_environment);
-  }
+static const Type& apply( void* p ){
+       return *static_cast<Type*>( p );
+}
 };
 
-inline bool operator==(const Callback& self, const Callback& other)
+
+template<typename Type>
+class ConvertFromOpaque<Type*>
 {
-  return self.getEnvironment() == other.getEnvironment() && self.getThunk() == other.getThunk();
+public:
+static Type* apply( void* p ){
+       return static_cast<Type*>( p );
 }
-inline bool operator<(const Callback& self, const Callback& other)
+};
+
+template<typename Type>
+class ConvertFromOpaque<const Type*>
 {
-  return self.getEnvironment() < other.getEnvironment() || 
-        (!(other.getEnvironment() < self.getEnvironment()) && self.getThunk() < other.getThunk()); 
+public:
+static const Type* apply( void* p ){
+       return static_cast<Type*>( p );
 }
+};
 
-/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer and one other argument. 
-///
-/// Use with the callback constructors MemberCaller1, ConstMemberCaller1, ReferenceCaller1, ConstReferenceCaller1, PointerCaller1, ConstPointerCaller1 and FreeCaller1.
-template<typename FirstArgument>
-class Callback1
+template<typename Caller>
+class BindFirstOpaque
+{
+typedef typename Caller::first_argument_type FirstBound;
+FirstBound firstBound;
+public:
+typedef typename Caller::result_type result_type;
+explicit BindFirstOpaque( FirstBound firstBound ) : firstBound( firstBound ){
+}
+result_type operator()() const {
+       return Caller::call( firstBound );
+}
+FirstBound getBound() const {
+       return firstBound;
+}
+static result_type thunk( void* environment ){
+       return Caller::call( ConvertFromOpaque<FirstBound>::apply( environment ) );
+}
+void* getEnvironment() const {
+       return convertToOpaque( firstBound );
+}
+};
+
+template<typename Caller>
+class BindFirstOpaque1
 {
-  typedef void (*Thunk)(void*, FirstArgument);
-  void* m_environment;
-  Thunk m_thunk;
+typedef typename Caller::first_argument_type FirstBound;
+FirstBound firstBound;
+public:
+typedef typename Caller::second_argument_type first_argument_type;
+typedef typename Caller::result_type result_type;
+explicit BindFirstOpaque1( FirstBound firstBound ) : firstBound( firstBound ){
+}
+result_type operator()( first_argument_type a1 ) const {
+       return Caller::call( firstBound, a1 );
+}
+FirstBound getBound() const {
+       return firstBound;
+}
+static result_type thunk( void* environment, first_argument_type a1 ){
+       return Caller::call( ConvertFromOpaque<FirstBound>::apply( environment ), a1 );
+}
+void* getEnvironment() const {
+       return convertToOpaque( firstBound );
+}
+};
 
-  static void nullThunk(void*, FirstArgument)
-  {
-  }
+template<typename Caller>
+class BindFirstOpaque2
+{
+typedef typename Caller::first_argument_type FirstBound;
+FirstBound firstBound;
+public:
+typedef typename Caller::second_argument_type first_argument_type;
+typedef typename Caller::third_argument_type second_argument_type;
+typedef typename Caller::result_type result_type;
+explicit BindFirstOpaque2( FirstBound firstBound ) : firstBound( firstBound ){
+}
+result_type operator()( first_argument_type a1, second_argument_type a2 ) const {
+       return Caller::call( firstBound, a1, a2 );
+}
+FirstBound getBound() const {
+       return firstBound;
+}
+static result_type thunk( void* environment, first_argument_type a1, second_argument_type a2 ){
+       return Caller::call( ConvertFromOpaque<FirstBound>::apply( environment ), a1, a2 );
+}
+void* getEnvironment() const {
+       return convertToOpaque( firstBound );
+}
+};
 
+template<typename Caller>
+class BindFirstOpaque3
+{
+typedef typename Caller::first_argument_type FirstBound;
+FirstBound firstBound;
 public:
-  typedef FirstArgument first_argument_type;
-
-  Callback1() : m_environment(0), m_thunk(nullThunk)
-  {
-  }
-  Callback1(void* environment, Thunk function) : m_environment(environment), m_thunk(function)
-  {
-  }
-  void* getEnvironment() const
-  {
-    return m_environment;
-  }
-  Thunk getThunk() const
-  {
-    return m_thunk;
-  }
-  void operator()(FirstArgument firstArgument) const
-  {
-    m_thunk(m_environment, firstArgument);
-  }
+typedef typename Caller::second_argument_type first_argument_type;
+typedef typename Caller::third_argument_type second_argument_type;
+typedef typename Caller::fourth_argument_type third_argument_type;
+typedef typename Caller::result_type result_type;
+explicit BindFirstOpaque3( FirstBound firstBound ) : firstBound( firstBound ){
+}
+result_type operator()( first_argument_type a1, second_argument_type a2, third_argument_type a3 ) const {
+       return Caller::call( firstBound, a1, a2, a3 );
+}
+FirstBound getBound() const {
+       return firstBound;
+}
+static result_type thunk( void* environment, first_argument_type a1, second_argument_type a2, third_argument_type a3 ){
+       return Caller::call( ConvertFromOpaque<FirstBound>::apply( environment ), a1, a2, a3 );
+}
+void* getEnvironment() const {
+       return convertToOpaque( firstBound );
+}
 };
 
-template<typename FirstArgument>
-inline bool operator==(const Callback1<FirstArgument>& self, const Callback1<FirstArgument>& other)
+template<typename Thunk_>
+class CallbackBase
 {
-  return self.getEnvironment() == other.getEnvironment() && self.getThunk() == other.getThunk();
+void* m_environment;
+Thunk_ m_thunk;
+public:
+typedef Thunk_ Thunk;
+CallbackBase( void* environment, Thunk function ) : m_environment( environment ), m_thunk( function ){
+}
+void* getEnvironment() const {
+       return m_environment;
+}
+Thunk getThunk() const {
+       return m_thunk;
+}
+};
+
+template<typename Thunk>
+inline bool operator==( const CallbackBase<Thunk>& self, const CallbackBase<Thunk>& other ){
+       return self.getEnvironment() == other.getEnvironment() && self.getThunk() == other.getThunk();
+}
+template<typename Thunk>
+inline bool operator!=( const CallbackBase<Thunk>& self, const CallbackBase<Thunk>& other ){
+       return !( self == other );
+}
+template<typename Thunk>
+inline bool operator<( const CallbackBase<Thunk>& self, const CallbackBase<Thunk>& other ){
+       return self.getEnvironment() < other.getEnvironment() ||
+                  ( !( other.getEnvironment() < self.getEnvironment() ) && self.getThunk() < other.getThunk() );
 }
-template<typename FirstArgument>
-inline bool operator<(const Callback1<FirstArgument>& self, const Callback1<FirstArgument>& other)
+
+
+/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer.
+///
+/// Use with the callback constructors MemberCaller, ConstMemberCaller, ReferenceCaller, ConstReferenceCaller, PointerCaller, ConstPointerCaller and FreeCaller.
+template<typename Result>
+class Callback0 : public CallbackBase<Result ( * )( void* )>
 {
-  return self.getEnvironment() < other.getEnvironment() || 
-        (!(other.getEnvironment() < self.getEnvironment()) && self.getThunk() < other.getThunk()); 
+typedef CallbackBase<Result ( * )( void* )> Base;
+static Result nullThunk( void* ){
 }
 
-template<typename Functor>
-class FunctorInvoke
+public:
+typedef Result result_type;
+
+Callback0() : Base( 0, nullThunk ){
+}
+template<typename Caller>
+Callback0( const BindFirstOpaque<Caller>& caller ) : Base( caller.getEnvironment(), BindFirstOpaque<Caller>::thunk ){
+}
+Callback0( void* environment, typename Base::Thunk function ) : Base( environment, function ){
+}
+result_type operator()() const {
+       return Base::getThunk() ( Base::getEnvironment() );
+}
+};
+
+template<typename Caller>
+inline Callback0<typename Caller::result_type> makeCallback0( const Caller& caller, typename Caller::first_argument_type callee ){
+       return Callback0<typename Caller::result_type>( BindFirstOpaque<Caller>( callee ) );
+}
+template<typename Caller>
+inline Callback0<typename Caller::result_type> makeStatelessCallback0( const Caller& caller ){
+       return makeCallback0( Caller0To1<Caller>(), 0 );
+}
+
+typedef Callback0<void> Callback;
+
+
+
+/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer and one other argument.
+///
+/// Use with the callback constructors MemberCaller1, ConstMemberCaller1, ReferenceCaller1, ConstReferenceCaller1, PointerCaller1, ConstPointerCaller1 and FreeCaller1.
+template<typename FirstArgument, typename Result>
+class Callback1 : public CallbackBase<Result ( * )( void*, FirstArgument )>
 {
+typedef CallbackBase<Result ( * )( void*, FirstArgument )> Base;
+static Result nullThunk( void*, FirstArgument ){
+}
+
 public:
-  inline void operator()(Functor functor)
-  {
-    functor();
-  }
+typedef FirstArgument first_argument_type;
+typedef Result result_type;
+
+Callback1() : Base( 0, nullThunk ){
+}
+template<typename Caller>
+Callback1( const BindFirstOpaque1<Caller>& caller ) : Base( caller.getEnvironment(), BindFirstOpaque1<Caller>::thunk ){
+}
+Callback1( void* environment, typename Base::Thunk function ) : Base( environment, function ){
+}
+result_type operator()( FirstArgument firstArgument ) const {
+       return Base::getThunk() ( Base::getEnvironment(), firstArgument );
+}
 };
 
-typedef FunctorInvoke<Callback> CallbackInvoke;
+template<typename Caller>
+inline Callback1<typename Caller::second_argument_type, typename Caller::result_type> makeCallback1( const Caller& caller, typename Caller::first_argument_type callee ){
+       return Callback1<typename Caller::second_argument_type, typename Caller::result_type>( BindFirstOpaque1<Caller>( callee ) );
+}
+template<typename Caller>
+inline Callback1<typename Caller::second_argument_type, typename Caller::result_type> makeStatelessCallback1( const Caller& caller ){
+       return makeCallback1( Caller1To2<Caller>(), 0 );
+}
 
 
-template<typename Functor, typename FirstArgument>
-class Functor1Invoke
+/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer and two other arguments.
+///
+template<typename FirstArgument, typename SecondArgument, typename Result>
+class Callback2 : public CallbackBase<Result ( * )( void*, FirstArgument, SecondArgument )>
 {
-  FirstArgument m_firstArgument;
+typedef CallbackBase<Result ( * )( void*, FirstArgument, SecondArgument )> Base;
+static Result nullThunk( void*, FirstArgument, SecondArgument ){
+}
+
 public:
-  Functor1Invoke(FirstArgument firstArgument) : m_firstArgument(firstArgument)
-  {
-  }
-  inline void operator()(Functor functor)
-  {
-    functor(m_firstArgument);
-  }
+typedef FirstArgument first_argument_type;
+typedef SecondArgument second_argument_type;
+typedef Result result_type;
+
+Callback2() : Base( 0, nullThunk ){
+}
+template<typename Caller>
+Callback2( const BindFirstOpaque2<Caller>& caller ) : Base( caller.getEnvironment(), BindFirstOpaque2<Caller>::thunk ){
+}
+Callback2( void* environment, typename Base::Thunk function ) : Base( environment, function ){
+}
+result_type operator()( FirstArgument firstArgument, SecondArgument secondArgument ) const {
+       return Base::getThunk() ( Base::getEnvironment(), firstArgument, secondArgument );
+}
 };
 
+template<typename Caller>
+inline Callback2<
+       typename Caller::second_argument_type,
+       typename Caller::third_argument_type,
+       typename Caller::result_type
+       > makeCallback2( const Caller& caller, typename Caller::first_argument_type callee ){
+       return Callback2<
+                          typename Caller::second_argument_type,
+                          typename Caller::third_argument_type,
+                          typename Caller::result_type
+                          >( BindFirstOpaque2<Caller>( callee ) );
+}
+template<typename Caller>
+inline Callback2<
+       typename Caller::first_argument_type,
+       typename Caller::second_argument_type,
+       typename Caller::result_type
+       > makeStatelessCallback2( const Caller& caller ){
+       return makeCallback2( Caller2To3<Caller>(), 0 );
+}
 
-typedef Callback1<bool> BoolImportCallback;
-typedef Callback1<const BoolImportCallback&> BoolExportCallback;
 
-typedef Callback1<int> IntImportCallback;
-typedef Callback1<const IntImportCallback&> IntExportCallback;
+/// \brief Combines a void pointer with a pointer to a function which operates on a void pointer and three other arguments.
+///
+template<typename FirstArgument, typename SecondArgument, typename ThirdArgument, typename Result>
+class Callback3 : public CallbackBase<Result ( * )( void*, FirstArgument, SecondArgument, ThirdArgument )>
+{
+typedef CallbackBase<Result ( * )( void*, FirstArgument, SecondArgument, ThirdArgument )> Base;
+static Result nullThunk( void*, FirstArgument, SecondArgument, ThirdArgument ){
+}
 
-typedef Callback1<float> FloatImportCallback;
-typedef Callback1<const FloatImportCallback&> FloatExportCallback;
+public:
+typedef FirstArgument first_argument_type;
+typedef SecondArgument second_argument_type;
+typedef ThirdArgument third_argument_type;
+typedef Result result_type;
 
-typedef Callback1<const char*> StringImportCallback;
-typedef Callback1<const StringImportCallback&> StringExportCallback;
+Callback3() : Base( 0, nullThunk ){
+}
+template<typename Caller>
+Callback3( const BindFirstOpaque3<Caller>& caller ) : Base( caller.getEnvironment(), BindFirstOpaque3<Caller>::thunk ){
+}
+Callback3( void* environment, typename Base::Thunk function ) : Base( environment, function ){
+}
+result_type operator()( FirstArgument firstArgument, SecondArgument secondArgument, ThirdArgument thirdArgument ) const {
+       return Base::getThunk() ( Base::getEnvironment(), firstArgument, secondArgument, thirdArgument );
+}
+};
 
-typedef Callback1<std::size_t> SizeImportCallback;
-typedef Callback1<const SizeImportCallback&> SizeExportCallback;
+template<typename Caller>
+inline Callback3<
+       typename Caller::second_argument_type,
+       typename Caller::third_argument_type,
+       typename Caller::fourth_argument_type,
+       typename Caller::result_type
+       > makeCallback3( const Caller& caller, typename Caller::first_argument_type callee ){
+       return Callback3<
+                          typename Caller::second_argument_type,
+                          typename Caller::third_argument_type,
+                          typename Caller::fourth_argument_type,
+                          typename Caller::result_type
+                          >( BindFirstOpaque3<Caller>( callee ) );
+}
+template<typename Caller>
+inline Callback3<
+       typename Caller::first_argument_type,
+       typename Caller::second_argument_type,
+       typename Caller::third_argument_type,
+       typename Caller::result_type
+       > makeStatelessCallback3( const Caller& caller ){
+       return makeCallback3( Caller3To4<Caller>(), 0 );
+}
 
 
 /// \brief Forms a Callback from a non-const Environment reference and a non-const Environment member-function.
@@ -169,26 +398,12 @@ typedef Callback1<const SizeImportCallback&> SizeExportCallback;
 /// \dontinclude generic/callback.cpp
 /// \skipline MemberCaller example
 /// \until end example
-template<typename Environment, void (Environment::*member)()>
-class MemberCaller
+template<typename Environment, void( Environment::*member ) ( )>
+class MemberCaller : public BindFirstOpaque< Member<Environment, void, member> >
 {
-  Environment& m_environment;
 public:
-  MemberCaller(Environment& environment) : m_environment(environment)
-  {
-  }
-  void* getEnvironment() const
-  {
-    return &m_environment;
-  }
-  static void thunk(void* environment)
-  {
-    ((*reinterpret_cast<Environment*>(environment)).*member)();
-  }
-  operator Callback() const
-  {
-    return Callback(getEnvironment(), thunk);
-  }
+MemberCaller( Environment& environment ) : BindFirstOpaque< Member<Environment, void, member> >( environment ){
+}
 };
 
 /// \brief Forms a Callback from a const Environment reference and a const Environment member-function.
@@ -196,72 +411,30 @@ public:
 /// \dontinclude generic/callback.cpp
 /// \skipline MemberCaller example
 /// \until end example
-template<typename Environment, void (Environment::*member)() const>
-class ConstMemberCaller
+template<typename Environment, void( Environment::*member ) ( ) const>
+class ConstMemberCaller : public BindFirstOpaque< ConstMember<Environment, void, member> >
 {
-  const Environment& m_environment;
 public:
-  ConstMemberCaller(const Environment& environment) : m_environment(environment)
-  {
-  }
-  void* getEnvironment() const
-  {
-    return const_cast<Environment*>(&m_environment);
-  }
-  static void thunk(void* environment)
-  {
-    ((*reinterpret_cast<const Environment*>(environment)).*member)();
-  }
-  operator Callback() const
-  {
-    return Callback(getEnvironment(), thunk);
-  }
+ConstMemberCaller( const Environment& environment ) : BindFirstOpaque< ConstMember<Environment, void, member> >( environment ){
+}
 };
 
 /// \brief Forms a Callback from a non-const Environment reference and a const Environment member-function which takes one argument.
-template<typename Environment, typename FirstArgument, void (Environment::*member)(FirstArgument)>
-class MemberCaller1
+template<typename Environment, typename FirstArgument, void( Environment::*member ) (FirstArgument)>
+class MemberCaller1 : public BindFirstOpaque1< Member1<Environment, FirstArgument, void, member> >
 {
-  Environment& m_environment;
 public:
-  MemberCaller1(Environment& environment) : m_environment(environment)
-  {
-  }
-  void* getEnvironment() const
-  {
-    return &m_environment;
-  }
-  static void thunk(void* environment, FirstArgument firstArgument)
-  {
-    ((*reinterpret_cast<Environment*>(environment)).*member)(firstArgument);
-  }
-  operator Callback1<FirstArgument>() const
-  {
-    return Callback1<FirstArgument>(getEnvironment(), thunk);
-  }
+MemberCaller1( Environment& environment ) : BindFirstOpaque1< Member1<Environment, FirstArgument, void, member> >( environment ){
+}
 };
 
 /// \brief Forms a Callback from a const Environment reference and a const Environment member-function which takes one argument.
-template<typename Environment, typename FirstArgument, void (Environment::*member)(FirstArgument) const>
-class ConstMemberCaller1
+template<typename Environment, typename FirstArgument, void( Environment::*member ) (FirstArgument) const>
+class ConstMemberCaller1 : public BindFirstOpaque1< ConstMember1<Environment, FirstArgument, void, member> >
 {
-  const Environment& m_environment;
 public:
-  ConstMemberCaller1(const Environment& environment) : m_environment(environment)
-  {
-  }
-  void* getEnvironment() const
-  {
-    return const_cast<Environment*>(&m_environment);
-  }
-  static void thunk(void* environment, FirstArgument firstArgument)
-  {
-    ((*reinterpret_cast<Environment*>(environment)).*member)(firstArgument);
-  }
-  operator Callback1<FirstArgument>() const
-  {
-    return Callback1<FirstArgument>(getEnvironment(), thunk);
-  }
+ConstMemberCaller1( const Environment& environment ) : BindFirstOpaque1< ConstMember1<Environment, FirstArgument, void, member> >( environment ){
+}
 };
 
 /// \brief Forms a Callback from a non-const Environment reference and a free function which operates on a non-const Environment reference.
@@ -269,26 +442,12 @@ public:
 /// \dontinclude generic/callback.cpp
 /// \skipline ReferenceCaller example
 /// \until end example
-template<typename Environment, void (*func)(Environment&)> 
-class ReferenceCaller
+template<typename Environment, void( *func ) (Environment&)>
+class ReferenceCaller : public BindFirstOpaque< Function1<Environment&, void, func> >
 {
-  Environment& m_environment;
 public:
-  ReferenceCaller(Environment& environment) : m_environment(environment)
-  {
-  }
-  void* getEnvironment() const
-  {
-    return &m_environment;
-  }
-  static void thunk(void* environment)
-  {
-    (func)(*reinterpret_cast<Environment*>(environment));
-  }
-  operator Callback() const
-  {
-    return Callback(getEnvironment(), thunk);
-  }
+ReferenceCaller( Environment& environment ) : BindFirstOpaque< Function1<Environment&, void, func> >( environment ){
+}
 };
 
 /// \brief Forms a Callback from a const Environment reference and a free function which operates on a const Environment reference.
@@ -296,242 +455,136 @@ public:
 /// \dontinclude generic/callback.cpp
 /// \skipline ReferenceCaller example
 /// \until end example
-template<typename Environment, void (*func)(const Environment&)> 
-class ConstReferenceCaller
+template<typename Environment, void( *func ) (const Environment&)>
+class ConstReferenceCaller : public BindFirstOpaque< Function1<const Environment&, void, func> >
 {
-  const Environment& m_environment;
 public:
-  ConstReferenceCaller(const Environment& environment) : m_environment(environment)
-  {
-  }
-  void* getEnvironment() const
-  {
-    return const_cast<Environment*>(&m_environment);
-  }
-  static void thunk(void* environment)
-  {
-    (func)(*reinterpret_cast<const Environment*>(environment));
-  }
-  operator Callback() const
-  {
-    return Callback(getEnvironment(), thunk);
-  }
+ConstReferenceCaller( const Environment& environment ) : BindFirstOpaque< Function1<const Environment&, void, func> >( environment ){
+}
 };
 
 /// \brief Forms a Callback from a non-const Environment reference and a free function which operates on a non-const Environment reference and one other argument.
-template<typename Environment, typename FirstArgument, void (*func)(Environment&, FirstArgument)> 
-class ReferenceCaller1
+template<typename Environment, typename FirstArgument, void( *func ) ( Environment&, FirstArgument )>
+class ReferenceCaller1 : public BindFirstOpaque1< Function2<Environment&, FirstArgument, void, func> >
 {
-  Environment& m_environment;
 public:
-  ReferenceCaller1(Environment& environment) : m_environment(environment)
-  {
-  }
-  void* getEnvironment() const
-  {
-    return &m_environment;
-  }
-  static void thunk(void* environment, FirstArgument firstArgument)
-  {
-    (func)(*reinterpret_cast<Environment*>(environment), firstArgument);
-  }
-  operator Callback1<FirstArgument>() const
-  {
-    return Callback1<FirstArgument>(getEnvironment(), thunk);
-  }
+ReferenceCaller1( Environment& environment ) : BindFirstOpaque1< Function2<Environment&, FirstArgument, void, func> >( environment ){
+}
 };
 
 /// \brief Forms a Callback from a const Environment reference and a free function which operates on a const Environment reference and one other argument.
-template<typename Environment, typename FirstArgument, void (*func)(const Environment&, FirstArgument)> 
-class ConstReferenceCaller1
+template<typename Environment, typename FirstArgument, void( *func ) ( const Environment&, FirstArgument )>
+class ConstReferenceCaller1 : public BindFirstOpaque1< Function2<const Environment&, FirstArgument, void, func> >
 {
-  const Environment& m_environment;
 public:
-  ConstReferenceCaller1(const Environment& environment) : m_environment(environment)
-  {
-  }
-  void* getEnvironment() const
-  {
-    return const_cast<Environment*>(&m_environment);
-  }
-  static void thunk(void* environment, FirstArgument firstArgument)
-  {
-    (func)(*reinterpret_cast<const Environment*>(environment), firstArgument);
-  }
-  operator Callback1<FirstArgument>() const
-  {
-    return Callback1<FirstArgument>(getEnvironment(), thunk);
-  }
+ConstReferenceCaller1( const Environment& environment ) : BindFirstOpaque1< Function2<const Environment&, FirstArgument, void, func> >( environment ){
+}
 };
 
 /// \brief Forms a Callback from a non-const Environment pointer and a free function which operates on a non-const Environment pointer.
-template<typename Environment, void (*func)(Environment*)> 
-class PointerCaller
+template<typename Environment, void( *func ) (Environment*)>
+class PointerCaller : public BindFirstOpaque< Function1<Environment*, void, func> >
 {
-  Environment* m_environment;
 public:
-  PointerCaller(Environment* environment) : m_environment(environment)
-  {
-  }
-  void* getEnvironment() const
-  {
-    return m_environment;
-  }
-  static void thunk(void* environment)
-  {
-    (func)(reinterpret_cast<Environment*>(environment));
-  }
-  operator Callback() const
-  {
-    return Callback(getEnvironment(), thunk);
-  }
+PointerCaller( Environment* environment ) : BindFirstOpaque< Function1<Environment*, void, func> >( environment ){
+}
 };
 
 /// \brief Forms a Callback from a const Environment pointer and a free function which operates on a const Environment pointer.
-template<typename Environment, void (*func)(const Environment*)> 
-class ConstPointerCaller
+template<typename Environment, void( *func ) (const Environment*)>
+class ConstPointerCaller : public BindFirstOpaque< Function1<const Environment*, void, func> >
 {
-  const Environment* m_environment;
 public:
-  ConstPointerCaller(const Environment* environment) : m_environment(environment)
-  {
-  }
-  void* getEnvironment() const
-  {
-    return const_cast<Environment*>(m_environment);
-  }
-  static void thunk(void* environment)
-  {
-    (func)(reinterpret_cast<const Environment*>(environment));
-  }
-  operator Callback() const
-  {
-    return Callback(getEnvironment(), thunk);
-  }
+ConstPointerCaller( const Environment* environment ) : BindFirstOpaque< Function1<const Environment*, void, func> >( environment ){
+}
 };
 
 /// \brief Forms a Callback from a non-const Environment pointer and a free function which operates on a non-const Environment pointer and one other argument.
-template<typename Environment, typename FirstArgument, void (*func)(Environment*, FirstArgument)> 
-class PointerCaller1
+template<typename Environment, typename FirstArgument, void( *func ) ( Environment*, FirstArgument )>
+class PointerCaller1 : public BindFirstOpaque1< Function2<Environment*, FirstArgument, void, func> >
 {
-  Environment* m_environment;
 public:
-  PointerCaller1(Environment* environment) : m_environment(environment)
-  {
-  }
-  void* getEnvironment() const
-  {
-    return m_environment;
-  }
-  static void thunk(void* environment, FirstArgument firstArgument)
-  {
-    (func)(reinterpret_cast<Environment*>(environment), firstArgument);
-  }
-  operator Callback1<FirstArgument>() const
-  {
-    return Callback1<FirstArgument>(getEnvironment(), thunk);
-  }
+PointerCaller1( Environment* environment ) : BindFirstOpaque1< Function2<Environment*, FirstArgument, void, func> >( environment ){
+}
 };
 
 /// \brief Forms a Callback from a const Environment pointer and a free function which operates on a const Environment pointer and one other argument.
-template<typename Environment, typename FirstArgument, void (*func)(const Environment*, FirstArgument)> 
-class ConstPointerCaller1
+template<typename Environment, typename FirstArgument, void( *func ) ( const Environment*, FirstArgument )>
+class ConstPointerCaller1 : public BindFirstOpaque1< Function2<const Environment*, FirstArgument, void, func> >
 {
-  const Environment* m_environment;
 public:
-  ConstPointerCaller1(const Environment* environment) : m_environment(environment)
-  {
-  }
-  void* getEnvironment() const
-  {
-    return const_cast<Environment*>(m_environment);
-  }
-  static void thunk(void* environment, FirstArgument firstArgument)
-  {
-    (func)(reinterpret_cast<const Environment*>(environment), firstArgument);
-  }
-  operator Callback1<FirstArgument>() const
-  {
-    return Callback1<FirstArgument>(getEnvironment(), thunk);
-  }
+ConstPointerCaller1( const Environment* environment ) : BindFirstOpaque1< Function2<const Environment*, FirstArgument, void, func> >( environment ){
+}
 };
 
-
 /// \brief Forms a Callback from a free function which takes no arguments.
-template<void (*func)()> 
-class FreeCaller
+template<void( *func ) ( )>
+class FreeCaller : public BindFirstOpaque< Caller0To1< Function0<void, func> > >
 {
 public:
-  void* getEnvironment() const
-  {
-    return 0;
-  }
-  static void thunk(void*)
-  {
-    (func)();
-  }
-  operator Callback() const
-  {
-    return Callback(getEnvironment(), thunk);
-  }
+FreeCaller() : BindFirstOpaque< Caller0To1< Function0<void, func> > >( 0 ){
+}
 };
 
 /// \brief Forms a Callback from a free function which takes a single argument.
-template<typename FirstArgument, void (*func)(FirstArgument)> 
-class FreeCaller1
+template<typename FirstArgument, void( *func ) (FirstArgument)>
+class FreeCaller1 : public BindFirstOpaque1< Caller1To2< Function1<FirstArgument, void, func> > >
 {
 public:
-  void* getEnvironment() const
-  {
-    return 0;
-  }
-  static void thunk(void*, FirstArgument firstArgument)
-  {
-    (func)(firstArgument);
-  }
-  operator Callback1<FirstArgument>() const
-  {
-    return Callback1<FirstArgument>(getEnvironment(), thunk);
-  }
+FreeCaller1() : BindFirstOpaque1< Caller1To2< Function1<FirstArgument, void, func> > >( 0 ){
+}
 };
 
 
 /// \brief Constructs a Callback from a non-const \p functor with zero arguments.
-/// 
+///
 /// \param Functor Must define \c operator()().
 template<typename Functor>
-inline Callback makeCallback(Functor& functor)
-{
-  return Callback(MemberCaller<Functor, &Functor::operator()>(functor));
+inline Callback makeCallback( Functor& functor ){
+       return Callback( MemberCaller<Functor, &Functor::operator()>( functor ) );
 }
 
 /// \brief  Constructs a Callback from a const \p functor with zero arguments.
-/// 
+///
 /// \param Functor Must define const \c operator()().
 template<typename Functor>
-inline Callback makeCallback(const Functor& functor)
-{
-  return Callback(ConstMemberCaller<Functor, &Functor::operator()>(functor));
+inline Callback makeCallback( const Functor& functor ){
+       return Callback( ConstMemberCaller<Functor, &Functor::operator()>( functor ) );
 }
 
 /// \brief  Constructs a Callback1 from a non-const \p functor with one argument.
-/// 
+///
 /// \param Functor Must define \c first_argument_type and \c operator()(first_argument_type).
 template<typename Functor>
-inline Callback1<typename Functor::first_argument_type> makeCallback1(Functor& functor)
-{
-  typedef typename Functor::first_argument_type FirstArgument;
-  return Callback1<FirstArgument>(MemberCaller1<Functor, FirstArgument, &Functor::operator()>(functor));
+inline Callback1<typename Functor::first_argument_type> makeCallback1( Functor& functor ){
+       typedef typename Functor::first_argument_type FirstArgument;
+       return Callback1<FirstArgument>( MemberCaller1<Functor, FirstArgument, &Functor::operator()>( functor ) );
 }
 
 /// \brief  Constructs a Callback1 from a const \p functor with one argument.
-/// 
+///
 /// \param Functor Must define \c first_argument_type and const \c operator()(first_argument_type).
 template<typename Functor>
-inline Callback1<typename Functor::first_argument_type> makeCallback1(const Functor& functor)
-{
-  typedef typename Functor::first_argument_type FirstArgument;
-  return Callback1<FirstArgument>(ConstMemberCaller1<Functor, FirstArgument, &Functor::operator()>(functor));
+inline Callback1<typename Functor::first_argument_type> makeCallback1( const Functor& functor ){
+       typedef typename Functor::first_argument_type FirstArgument;
+       return Callback1<FirstArgument>( ConstMemberCaller1<Functor, FirstArgument, &Functor::operator()>( functor ) );
 }
 
+
+typedef Callback1<bool> BoolImportCallback;
+typedef Callback1<const BoolImportCallback&> BoolExportCallback;
+
+typedef Callback1<int> IntImportCallback;
+typedef Callback1<const IntImportCallback&> IntExportCallback;
+
+typedef Callback1<float> FloatImportCallback;
+typedef Callback1<const FloatImportCallback&> FloatExportCallback;
+
+typedef Callback1<const char*> StringImportCallback;
+typedef Callback1<const StringImportCallback&> StringExportCallback;
+
+typedef Callback1<std::size_t> SizeImportCallback;
+typedef Callback1<const SizeImportCallback&> SizeExportCallback;
+
+
 #endif