refactored plugin api; refactored callback library; added signals library

git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/trunk@44 8a3a26a2-13c4-0310-b231-cf6edde360e5
This commit is contained in:
spog
2006-04-09 17:15:13 +00:00
parent ba55f1bbf6
commit 6ee91d153e
127 changed files with 3723 additions and 2092 deletions

View File

@@ -107,3 +107,179 @@ namespace ExampleReferenceCaller
}
#endif
namespace
{
class A1
{
};
class A2
{
};
class A3
{
};
class A4
{
};
class Test
{
public:
void test0()
{
}
typedef Member<Test, void, &Test::test0> Test0;
typedef MemberCaller<Test, &Test::test0> Test0Caller;
void test0const() const
{
}
typedef ConstMember<Test, void, &Test::test0const> Test0Const;
typedef ConstMemberCaller<Test, &Test::test0const> Test0ConstCaller;
void test1(A1)
{
}
typedef Member1<Test, A1, void, &Test::test1> Test1;
typedef MemberCaller1<Test, A1, &Test::test1> Test1Caller;
void test1const(A1) const
{
}
typedef ConstMember1<Test, A1, void, &Test::test1const> Test1Const;
typedef ConstMemberCaller1<Test, A1, &Test::test1const> Test1ConstCaller;
void test2(A1, A2)
{
}
typedef Member2<Test, A1, A2, void, &Test::test2> Test2;
void test2const(A1, A2) const
{
}
typedef ConstMember2<Test, A1, A2, void, &Test::test2const> Test2Const;
void test3(A1, A2, A3)
{
}
typedef Member3<Test, A1, A2, A3, void, &Test::test3> Test3;
void test3const(A1, A2, A3) const
{
}
typedef ConstMember3<Test, A1, A2, A3, void, &Test::test3const> Test3Const;
};
void test0free()
{
}
typedef FreeCaller<&test0free> Test0FreeCaller;
void test1free(A1)
{
}
typedef FreeCaller1<A1, &test1free> Test1FreeCaller;
void test2free(A1, A2)
{
}
typedef Function2<A1, A2, void, &test2free> Test2Free;
void test3free(A1, A2, A3)
{
}
typedef Function3<A1, A2, A3, void, &test3free> Test3Free;
void test0(Test& test)
{
}
typedef ReferenceCaller<Test, &test0> Test0Caller;
void test0const(const Test& test)
{
}
typedef ConstReferenceCaller<Test, &test0const> Test0ConstCaller;
void test0p(Test* test)
{
}
typedef PointerCaller<Test, &test0p> Test0PCaller;
void test0constp(const Test* test)
{
}
typedef ConstPointerCaller<Test, &test0constp> Test0ConstPCaller;
void test1(Test& test, A1)
{
}
typedef ReferenceCaller1<Test, A1, &test1> Test1Caller;
void test1const(const Test& test, A1)
{
}
typedef ConstReferenceCaller1<Test, A1, &test1const> Test1ConstCaller;
void test1p(Test* test, A1)
{
}
typedef PointerCaller1<Test, A1, &test1p> Test1PCaller;
void test1constp(const Test* test, A1)
{
}
typedef ConstPointerCaller1<Test, A1, &test1constp> Test1ConstPCaller;
void test2(Test& test, A1, A2)
{
}
typedef Function3<Test&, A1, A2, void, &test2> Test2;
void test3(Test& test, A1, A2, A3)
{
}
typedef Function4<Test&, A1, A2, A3, void, &test3> Test3;
void instantiate()
{
Test test;
const Test& testconst = test;
{
Callback a = Test0FreeCaller();
Callback b = Test::Test0Caller(test);
b = makeCallback0(Test::Test0(), test);
Callback c = Test::Test0ConstCaller(testconst);
c = makeCallback0(Test::Test0Const(), test);
Callback d = Test0Caller(test);
Callback e = Test0ConstCaller(testconst);
Callback f = Test0PCaller(&test);
Callback g = Test0ConstPCaller(&testconst);
a();
bool u = a != b;
}
{
typedef Callback1<A1> TestCallback1;
TestCallback1 a = Test1FreeCaller();
TestCallback1 b = Test::Test1Caller(test);
b = makeCallback1(Test::Test1(), test);
TestCallback1 c = Test::Test1ConstCaller(testconst);
c = makeCallback1(Test::Test1Const(), test);
TestCallback1 d = Test1Caller(test);
TestCallback1 e = Test1ConstCaller(testconst);
TestCallback1 f = Test1PCaller(&test);
TestCallback1 g = Test1ConstPCaller(&testconst);
a(A1());
bool u = a != b;
}
{
typedef Callback2<A1, A2> TestCallback2;
TestCallback2 a = makeStatelessCallback2(Test2Free());
TestCallback2 b = makeCallback2(Test2(), test);
TestCallback2 c = makeCallback2(Test::Test2(), test);
TestCallback2 d = makeCallback2(Test::Test2Const(), test);
a(A1(), A2());
bool u = a != b;
}
{
typedef Callback3<A1, A2, A3> TestCallback3;
TestCallback3 a = makeStatelessCallback3(Test3Free());
TestCallback3 b = makeCallback3(Test3(), test);
TestCallback3 c = makeCallback3(Test::Test3(), test);
TestCallback3 d = makeCallback3(Test::Test3Const(), test);
a(A1(), A2(), A3());
bool u = a != b;
}
}
}

View File

@@ -23,28 +23,206 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#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)
{
typedef void (*Thunk)(void*);
void* m_environment;
Thunk m_thunk;
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);
}
static void nullThunk(void*)
{
}
template<typename Type>
class ConvertFromOpaque
{
};
template<typename Type>
class ConvertFromOpaque<Type&>
{
public:
Callback() : m_environment(0), m_thunk(nullThunk)
static Type& apply(void* p)
{
return *static_cast<Type*>(p);
}
};
template<typename Type>
class ConvertFromOpaque<const Type&>
{
public:
static const Type& apply(void* p)
{
return *static_cast<Type*>(p);
}
};
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:
static const Type* apply(void* p)
{
return static_cast<Type*>(p);
}
};
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)
{
}
Callback(void* environment, Thunk function) : m_environment(environment), m_thunk(function)
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 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);
}
};
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 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 typename Thunk_>
class CallbackBase
{
void* m_environment;
Thunk_ m_thunk;
public:
typedef Thunk_ Thunk;
CallbackBase(void* environment, Thunk function) : m_environment(environment), m_thunk(function)
{
}
void* getEnvironment() const
@@ -55,113 +233,226 @@ public:
{
return m_thunk;
}
void operator()() const
{
m_thunk(m_environment);
}
};
inline bool operator==(const Callback& self, const Callback& other)
template<typename typename Thunk>
inline bool operator==(const CallbackBase<Thunk>& self, const CallbackBase<Thunk>& other)
{
return self.getEnvironment() == other.getEnvironment() && self.getThunk() == other.getThunk();
}
inline bool operator<(const Callback& self, const Callback& other)
template<typename typename Thunk>
inline bool operator!=(const CallbackBase<Thunk>& self, const CallbackBase<Thunk>& other)
{
return !(self == other);
}
template<typename 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());
}
/// \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*)>
{
typedef CallbackBase<Result (*)(void*)> Base;
static Result nullThunk(void*)
{
}
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, Thunk function) : Base(environment, function)
{
}
result_type operator()() const
{
return getThunk()(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>
class Callback1
template<typename FirstArgument, typename Result>
class Callback1 : public CallbackBase<Result (*)(void*, FirstArgument)>
{
typedef void (*Thunk)(void*, FirstArgument);
void* m_environment;
Thunk m_thunk;
static void nullThunk(void*, FirstArgument)
typedef CallbackBase<Result (*)(void*, FirstArgument)> Base;
static Result nullThunk(void*, FirstArgument)
{
}
public:
typedef FirstArgument first_argument_type;
typedef Result result_type;
Callback1() : m_environment(0), m_thunk(nullThunk)
Callback1() : Base(0, nullThunk)
{
}
Callback1(void* environment, Thunk function) : m_environment(environment), m_thunk(function)
template<typename Caller>
Callback1(const BindFirstOpaque1<Caller>& caller) : Base(caller.getEnvironment(), BindFirstOpaque1<Caller>::thunk)
{
}
void* getEnvironment() const
Callback1(void* environment, Thunk function) : Base(environment, function)
{
return m_environment;
}
Thunk getThunk() const
result_type operator()(FirstArgument firstArgument) const
{
return m_thunk;
}
void operator()(FirstArgument firstArgument) const
{
m_thunk(m_environment, firstArgument);
return getThunk()(getEnvironment(), firstArgument);
}
};
template<typename FirstArgument>
inline bool operator==(const Callback1<FirstArgument>& self, const Callback1<FirstArgument>& other)
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 self.getEnvironment() == other.getEnvironment() && self.getThunk() == other.getThunk();
return Callback1<typename Caller::second_argument_type, typename Caller::result_type>(BindFirstOpaque1<Caller>(callee));
}
template<typename FirstArgument>
inline bool operator<(const Callback1<FirstArgument>& self, const Callback1<FirstArgument>& other)
template<typename Caller>
inline Callback1<typename Caller::second_argument_type, typename Caller::result_type> makeStatelessCallback1(const Caller& caller)
{
return self.getEnvironment() < other.getEnvironment() ||
(!(other.getEnvironment() < self.getEnvironment()) && self.getThunk() < other.getThunk());
return makeCallback1(Caller1To2<Caller>(), 0);
}
template<typename Functor>
class FunctorInvoke
/// \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)>
{
public:
inline void operator()(Functor functor)
typedef CallbackBase<Result (*)(void*, FirstArgument, SecondArgument)> Base;
static Result nullThunk(void*, FirstArgument, SecondArgument)
{
functor();
}
public:
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, Thunk function) : Base(environment, function)
{
}
result_type operator()(FirstArgument firstArgument, SecondArgument secondArgument) const
{
return getThunk()(getEnvironment(), firstArgument, secondArgument);
}
};
typedef FunctorInvoke<Callback> CallbackInvoke;
template<typename Functor, typename FirstArgument>
class Functor1Invoke
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)
{
FirstArgument m_firstArgument;
public:
Functor1Invoke(FirstArgument firstArgument) : m_firstArgument(firstArgument)
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);
}
/// \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)
{
}
inline void operator()(Functor functor)
public:
typedef FirstArgument first_argument_type;
typedef SecondArgument second_argument_type;
typedef ThirdArgument third_argument_type;
typedef Result result_type;
Callback3() : Base(0, nullThunk)
{
functor(m_firstArgument);
}
template<typename Caller>
Callback3(const BindFirstOpaque3<Caller>& caller) : Base(caller.getEnvironment(), BindFirstOpaque3<Caller>::thunk)
{
}
Callback3(void* environment, Thunk function) : Base(environment, function)
{
}
result_type operator()(FirstArgument firstArgument, SecondArgument secondArgument, ThirdArgument thirdArgument) const
{
return getThunk()(getEnvironment(), firstArgument, secondArgument, thirdArgument);
}
};
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;
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.
@@ -170,25 +461,12 @@ typedef Callback1<const SizeImportCallback&> SizeExportCallback;
/// \skipline MemberCaller example
/// \until end example
template<typename Environment, void (Environment::*member)()>
class MemberCaller
class MemberCaller : public BindFirstOpaque< Member<Environment, void, member> >
{
Environment& m_environment;
public:
MemberCaller(Environment& environment) : m_environment(environment)
MemberCaller(Environment& environment) : BindFirstOpaque< Member<Environment, void, member> >(environment)
{
}
void* getEnvironment() const
{
return &m_environment;
}
static void thunk(void* environment)
{
((*reinterpret_cast<Environment*>(environment)).*member)();
}
operator Callback() const
{
return Callback(getEnvironment(), thunk);
}
};
/// \brief Forms a Callback from a const Environment reference and a const Environment member-function.
@@ -197,71 +475,32 @@ public:
/// \skipline MemberCaller example
/// \until end example
template<typename Environment, void (Environment::*member)() const>
class ConstMemberCaller
class ConstMemberCaller : public BindFirstOpaque< ConstMember<Environment, void, member> >
{
const Environment& m_environment;
public:
ConstMemberCaller(const Environment& environment) : m_environment(environment)
ConstMemberCaller(const Environment& environment) : BindFirstOpaque< ConstMember<Environment, void, member> >(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);
}
};
/// \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
class MemberCaller1 : public BindFirstOpaque1< Member1<Environment, FirstArgument, void, member> >
{
Environment& m_environment;
public:
MemberCaller1(Environment& environment) : m_environment(environment)
MemberCaller1(Environment& environment) : BindFirstOpaque1< Member1<Environment, FirstArgument, void, member> >(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);
}
};
/// \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
class ConstMemberCaller1 : public BindFirstOpaque1< ConstMember1<Environment, FirstArgument, void, member> >
{
const Environment& m_environment;
public:
ConstMemberCaller1(const Environment& environment) : m_environment(environment)
ConstMemberCaller1(const Environment& environment) : BindFirstOpaque1< ConstMember1<Environment, FirstArgument, void, member> >(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);
}
};
/// \brief Forms a Callback from a non-const Environment reference and a free function which operates on a non-const Environment reference.
@@ -270,25 +509,12 @@ public:
/// \skipline ReferenceCaller example
/// \until end example
template<typename Environment, void (*func)(Environment&)>
class ReferenceCaller
class ReferenceCaller : public BindFirstOpaque< Function1<Environment&, void, func> >
{
Environment& m_environment;
public:
ReferenceCaller(Environment& environment) : m_environment(environment)
ReferenceCaller(Environment& environment) : BindFirstOpaque< Function1<Environment&, void, func> >(environment)
{
}
void* getEnvironment() const
{
return &m_environment;
}
static void thunk(void* environment)
{
(func)(*reinterpret_cast<Environment*>(environment));
}
operator Callback() const
{
return Callback(getEnvironment(), thunk);
}
};
/// \brief Forms a Callback from a const Environment reference and a free function which operates on a const Environment reference.
@@ -297,201 +523,91 @@ public:
/// \skipline ReferenceCaller example
/// \until end example
template<typename Environment, void (*func)(const Environment&)>
class ConstReferenceCaller
class ConstReferenceCaller : public BindFirstOpaque< Function1<const Environment&, void, func> >
{
const Environment& m_environment;
public:
ConstReferenceCaller(const Environment& environment) : m_environment(environment)
ConstReferenceCaller(const Environment& environment) : BindFirstOpaque< Function1<const Environment&, void, func> >(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);
}
};
/// \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
class ReferenceCaller1 : public BindFirstOpaque1< Function2<Environment&, FirstArgument, void, func> >
{
Environment& m_environment;
public:
ReferenceCaller1(Environment& environment) : m_environment(environment)
ReferenceCaller1(Environment& environment) : BindFirstOpaque1< Function2<Environment&, FirstArgument, void, func> >(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);
}
};
/// \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
class ConstReferenceCaller1 : public BindFirstOpaque1< Function2<const Environment&, FirstArgument, void, func> >
{
const Environment& m_environment;
public:
ConstReferenceCaller1(const Environment& environment) : m_environment(environment)
ConstReferenceCaller1(const Environment& environment) : BindFirstOpaque1< Function2<const Environment&, FirstArgument, void, func> >(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);
}
};
/// \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
class PointerCaller : public BindFirstOpaque< Function1<Environment*, void, func> >
{
Environment* m_environment;
public:
PointerCaller(Environment* environment) : m_environment(environment)
PointerCaller(Environment* environment) : BindFirstOpaque< Function1<Environment*, void, func> >(environment)
{
}
void* getEnvironment() const
{
return m_environment;
}
static void thunk(void* environment)
{
(func)(reinterpret_cast<Environment*>(environment));
}
operator Callback() const
{
return Callback(getEnvironment(), thunk);
}
};
/// \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
class ConstPointerCaller : public BindFirstOpaque< Function1<const Environment*, void, func> >
{
const Environment* m_environment;
public:
ConstPointerCaller(const Environment* environment) : m_environment(environment)
ConstPointerCaller(const Environment* environment) : BindFirstOpaque< Function1<const Environment*, void, func> >(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);
}
};
/// \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
class PointerCaller1 : public BindFirstOpaque1< Function2<Environment*, FirstArgument, void, func> >
{
Environment* m_environment;
public:
PointerCaller1(Environment* environment) : m_environment(environment)
PointerCaller1(Environment* environment) : BindFirstOpaque1< Function2<Environment*, FirstArgument, void, func> >(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);
}
};
/// \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
class ConstPointerCaller1 : public BindFirstOpaque1< Function2<const Environment*, FirstArgument, void, func> >
{
const Environment* m_environment;
public:
ConstPointerCaller1(const Environment* environment) : m_environment(environment)
ConstPointerCaller1(const Environment* environment) : BindFirstOpaque1< Function2<const Environment*, FirstArgument, void, func> >(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);
}
};
/// \brief Forms a Callback from a free function which takes no arguments.
template<void (*func)()>
class FreeCaller
class FreeCaller : public BindFirstOpaque< Caller0To1< Function0<void, func> > >
{
public:
void* getEnvironment() const
FreeCaller() : BindFirstOpaque< Caller0To1< Function0<void, func> > >(0)
{
return 0;
}
static void thunk(void*)
{
(func)();
}
operator Callback() const
{
return Callback(getEnvironment(), thunk);
}
};
/// \brief Forms a Callback from a free function which takes a single argument.
template<typename FirstArgument, void (*func)(FirstArgument)>
class FreeCaller1
class FreeCaller1 : public BindFirstOpaque1< Caller1To2< Function1<FirstArgument, void, func> > >
{
public:
void* getEnvironment() const
FreeCaller1() : BindFirstOpaque1< Caller1To2< Function1<FirstArgument, void, func> > >(0)
{
return 0;
}
static void thunk(void*, FirstArgument firstArgument)
{
(func)(firstArgument);
}
operator Callback1<FirstArgument>() const
{
return Callback1<FirstArgument>(getEnvironment(), thunk);
}
};
@@ -534,4 +650,21 @@ inline Callback1<typename Functor::first_argument_type> makeCallback1(const Func
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

View File

@@ -0,0 +1,3 @@
#include "callbackfwd.h"

View File

@@ -0,0 +1,18 @@
#if !defined(INCLUDED_CALLBACKFWD_H)
#define INCLUDED_CALLBACKFWD_H
template<typename Return>
class Callback0;
typedef Callback0<void> Callback;
template<typename FirstArgument, typename Result = void>
class Callback1;
template<typename FirstArgument, typename SecondArgument, typename Result = void>
class Callback2;
template<typename FirstArgument, typename SecondArgument, typename ThirdArgument, typename Result = void>
class Callback3;
#endif

View File

@@ -0,0 +1,3 @@
#include "functional.h"

319
libs/generic/functional.h Normal file
View File

@@ -0,0 +1,319 @@
#if !defined(INCLUDED_FUNCTIONAL_H)
#define INCLUDED_FUNCTIONAL_H
template<typename Object, typename R, R (Object::*member)()>
class Member
{
public:
typedef Object& first_argument_type;
typedef R result_type;
static result_type call(first_argument_type object)
{
return (object.*member)();
}
};
template<typename Object, typename R, R (Object::*member)() const>
class ConstMember
{
public:
typedef const Object& first_argument_type;
typedef R result_type;
static result_type call(first_argument_type object)
{
return (object.*member)();
}
};
template<typename Object, typename A1, typename R, R (Object::*member)(A1)>
class Member1
{
public:
typedef Object& first_argument_type;
typedef A1 second_argument_type;
typedef R result_type;
static result_type call(first_argument_type object, second_argument_type a1)
{
return (object.*member)(a1);
}
};
template<typename Object, typename A1, typename R, R (Object::*member)(A1) const>
class ConstMember1
{
public:
typedef const Object& first_argument_type;
typedef A1 second_argument_type;
typedef R result_type;
static result_type call(first_argument_type object, second_argument_type a1)
{
return (object.*member)(a1);
}
};
template<typename Object, typename A2, typename A3, typename R, R (Object::*member)(A2, A3)>
class Member2
{
public:
typedef Object& first_argument_type;
typedef A2 second_argument_type;
typedef A3 third_argument_type;
typedef R result_type;
static result_type call(first_argument_type object, second_argument_type a2, third_argument_type a3)
{
return (object.*member)(a2, a3);
}
};
template<typename Object, typename A2, typename A3, typename R, R (Object::*member)(A2, A3) const>
class ConstMember2
{
public:
typedef const Object& first_argument_type;
typedef A2 second_argument_type;
typedef A3 third_argument_type;
typedef R result_type;
static result_type call(first_argument_type object, second_argument_type a2, third_argument_type a3)
{
return (object.*member)(a2, a3);
}
};
template<typename Object, typename A2, typename A3, typename A4, typename R, R (Object::*member)(A2, A3, A4)>
class Member3
{
public:
typedef Object& first_argument_type;
typedef A2 second_argument_type;
typedef A3 third_argument_type;
typedef A4 fourth_argument_type;
typedef R result_type;
static result_type call(first_argument_type object, second_argument_type a2, third_argument_type a3, fourth_argument_type a4)
{
return (object.*member)(a2, a3, a4);
}
};
template<typename Object, typename A2, typename A3, typename A4, typename R, R (Object::*member)(A2, A3, A4) const>
class ConstMember3
{
public:
typedef const Object& first_argument_type;
typedef A2 second_argument_type;
typedef A3 third_argument_type;
typedef A4 fourth_argument_type;
typedef R result_type;
static result_type call(first_argument_type object, second_argument_type a2, third_argument_type a3, fourth_argument_type a4)
{
return (object.*member)(a2, a3, a4);
}
};
template<typename R, R (*func)()>
class Function0
{
public:
typedef R result_type;
static result_type call()
{
return (func)();
}
};
template<typename A1, typename R, R (*func)(A1)>
class Function1
{
public:
typedef A1 first_argument_type;
typedef R result_type;
static result_type call(first_argument_type a1)
{
return (func)(a1);
}
};
template<typename A1, typename A2, typename R, R (*func)(A1, A2)>
class Function2
{
public:
typedef A1 first_argument_type;
typedef A2 second_argument_type;
typedef R result_type;
static result_type call(first_argument_type a1, second_argument_type a2)
{
return (func)(a1, a2);
}
};
template<typename A1, typename A2, typename A3, typename R, R (*func)(A1, A2, A3)>
class Function3
{
public:
typedef A1 first_argument_type;
typedef A2 second_argument_type;
typedef A3 third_argument_type;
typedef R result_type;
static result_type call(first_argument_type a1, second_argument_type a2, third_argument_type a3)
{
return (func)(a1, a2, a3);
}
};
template<typename A1, typename A2, typename A3, typename A4, typename R, R (*func)(A1, A2, A3, A4)>
class Function4
{
public:
typedef A1 first_argument_type;
typedef A2 second_argument_type;
typedef A3 third_argument_type;
typedef A4 fourth_argument_type;
typedef R result_type;
static result_type call(first_argument_type a1, second_argument_type a2, third_argument_type a3, fourth_argument_type a4)
{
return (func)(a1, a2, a3, a4);
}
};
template<typename Caller, typename FirstArgument = void*>
class Caller0To1
{
public:
typedef FirstArgument first_argument_type;
typedef typename Caller::result_type result_type;
static result_type call(first_argument_type)
{
return Caller::call();
}
};
template<typename Caller, typename FirstArgument = void*>
class Caller1To2
{
public:
typedef FirstArgument first_argument_type;
typedef typename Caller::first_argument_type second_argument_type;
typedef typename Caller::result_type result_type;
static result_type call(first_argument_type, second_argument_type a2)
{
return Caller::call(a2);
}
};
template<typename Caller, typename FirstArgument = void*>
class Caller2To3
{
public:
typedef FirstArgument first_argument_type;
typedef typename Caller::first_argument_type second_argument_type;
typedef typename Caller::second_argument_type third_argument_type;
typedef typename Caller::result_type result_type;
static result_type call(first_argument_type, second_argument_type a2, third_argument_type a3)
{
return Caller::call(a2, a3);
}
};
template<typename Caller, typename FirstArgument = void*>
class Caller3To4
{
public:
typedef FirstArgument first_argument_type;
typedef typename Caller::first_argument_type second_argument_type;
typedef typename Caller::second_argument_type third_argument_type;
typedef typename Caller::third_argument_type fourth_argument_type;
typedef typename Caller::result_type result_type;
static result_type call(first_argument_type, second_argument_type a2, third_argument_type a3, fourth_argument_type a4)
{
return Caller::call(a2, a3, a4);
}
};
template<typename Functor>
class FunctorInvoke
{
public:
typedef typename Functor::result_type result_type;
inline result_type operator()(Functor functor)
{
return functor();
}
};
template<typename Functor>
class Functor1Invoke
{
typename Functor::first_argument_type a1;
public:
typedef typename Functor::first_argument_type first_argument_type;
typedef typename Functor::result_type result_type;
Functor1Invoke(first_argument_type a1) : a1(a1)
{
}
inline result_type operator()(Functor functor)
{
return functor(a1);
}
};
template<typename Functor>
class Functor2Invoke
{
typename Functor::first_argument_type a1;
typename Functor::second_argument_type a2;
public:
typedef typename Functor::first_argument_type first_argument_type;
typedef typename Functor::second_argument_type second_argument_type;
typedef typename Functor::result_type result_type;
Functor2Invoke(first_argument_type a1, second_argument_type a2)
: a1(a1), a2(a2)
{
}
inline result_type operator()(Functor functor)
{
return functor(a1, a2);
}
};
template<typename Functor>
class Functor3Invoke
{
typename Functor::first_argument_type a1;
typename Functor::second_argument_type a2;
typename Functor::third_argument_type a3;
public:
typedef typename Functor::first_argument_type first_argument_type;
typedef typename Functor::second_argument_type second_argument_type;
typedef typename Functor::third_argument_type third_argument_type;
typedef typename Functor::result_type result_type;
Functor3Invoke(first_argument_type a1, second_argument_type a2, third_argument_type a3)
: a1(a1), a2(a2), a3(a3)
{
}
inline result_type operator()(Functor functor)
{
return functor(a1, a2, a3);
}
};
template<typename Type, typename Other, typename True, typename False>
class TypeEqual
{
template<typename Matched>
class Match
{
public:
typedef False type;
};
template<>
class Match<Other>
{
public:
typedef True type;
};
public:
typedef typename Match<Type>::type type;
};
#endif