diff options
Diffstat (limited to 'ml/dlib/dlib/member_function_pointer')
4 files changed, 1367 insertions, 0 deletions
diff --git a/ml/dlib/dlib/member_function_pointer/make_mfp.h b/ml/dlib/dlib/member_function_pointer/make_mfp.h new file mode 100644 index 000000000..fff9b27ea --- /dev/null +++ b/ml/dlib/dlib/member_function_pointer/make_mfp.h @@ -0,0 +1,179 @@ +// Copyright (C) 2011 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. +#ifndef DLIB_MAKE_MFp_H_ +#define DLIB_MAKE_MFp_H_ + +#include "member_function_pointer_kernel_1.h" +#include "make_mfp_abstract.h" + +namespace dlib +{ + +// ---------------------------------------------------------------------------------------- + + template < + typename T + > + member_function_pointer<> make_mfp ( + T& object, + void (T::*cb)() + ) + { + member_function_pointer<> temp; + temp.set(object, cb); + return temp; + } + + template < + typename T + > + member_function_pointer<> make_mfp ( + const T& object, + void (T::*cb)()const + ) + { + member_function_pointer<> temp; + temp.set(object, cb); + return temp; + } + +// ---------------------------------------------------------------------------------------- + + template < + typename T, + typename A1 + > + member_function_pointer<A1> make_mfp ( + T& object, + void (T::*cb)(A1) + ) + { + member_function_pointer<A1> temp; + temp.set(object, cb); + return temp; + } + + template < + typename T, + typename A1 + > + member_function_pointer<A1> make_mfp ( + const T& object, + void (T::*cb)(A1)const + ) + { + member_function_pointer<A1> temp; + temp.set(object, cb); + return temp; + } + +// ---------------------------------------------------------------------------------------- + + template < + typename T, + typename A1, + typename A2 + > + member_function_pointer<A1,A2> make_mfp ( + T& object, + void (T::*cb)(A1,A2) + ) + { + member_function_pointer<A1,A2> temp; + temp.set(object, cb); + return temp; + } + + template < + typename T, + typename A1, + typename A2 + > + member_function_pointer<A1,A2> make_mfp ( + const T& object, + void (T::*cb)(A1,A2)const + ) + { + member_function_pointer<A1,A2> temp; + temp.set(object, cb); + return temp; + } + +// ---------------------------------------------------------------------------------------- + + template < + typename T, + typename A1, + typename A2, + typename A3 + > + member_function_pointer<A1,A2,A3> make_mfp ( + T& object, + void (T::*cb)(A1,A2,A3) + ) + { + member_function_pointer<A1,A2,A3> temp; + temp.set(object, cb); + return temp; + } + + template < + typename T, + typename A1, + typename A2, + typename A3 + > + member_function_pointer<A1,A2,A3> make_mfp ( + const T& object, + void (T::*cb)(A1,A2,A3)const + ) + { + member_function_pointer<A1,A2,A3> temp; + temp.set(object, cb); + return temp; + } + +// ---------------------------------------------------------------------------------------- + + template < + typename T, + typename A1, + typename A2, + typename A3, + typename A4 + > + member_function_pointer<A1,A2,A3,A4> make_mfp ( + T& object, + void (T::*cb)(A1,A2,A3,A4) + ) + { + member_function_pointer<A1,A2,A3,A4> temp; + temp.set(object, cb); + return temp; + } + + template < + typename T, + typename A1, + typename A2, + typename A3, + typename A4 + > + member_function_pointer<A1,A2,A3,A4> make_mfp ( + const T& object, + void (T::*cb)(A1,A2,A3,A4)const + ) + { + member_function_pointer<A1,A2,A3,A4> temp; + temp.set(object, cb); + return temp; + } + +// ---------------------------------------------------------------------------------------- + +} + +#endif // DLIB_MAKE_MFp_H_ + + + diff --git a/ml/dlib/dlib/member_function_pointer/make_mfp_abstract.h b/ml/dlib/dlib/member_function_pointer/make_mfp_abstract.h new file mode 100644 index 000000000..5074ca9a7 --- /dev/null +++ b/ml/dlib/dlib/member_function_pointer/make_mfp_abstract.h @@ -0,0 +1,207 @@ +// Copyright (C) 2011 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. +#undef DLIB_MAKE_MFp_ABSTRACT_ +#ifdef DLIB_MAKE_MFp_ABSTRACT_ + +#include "member_function_pointer_kernel_abstract.h" + +namespace dlib +{ + +// ---------------------------------------------------------------------------------------- + + template < + typename T + > + member_function_pointer<> make_mfp ( + T& object, + void (T::*cb)() + ); + /*! + requires + - cb == a valid member function pointer for class T + ensures + - returns a member function pointer object MFP such that: + - MFP.is_set() == true + - calls to MFP() will call (object.*cb)() + !*/ + + template < + typename T + > + member_function_pointer<> make_mfp ( + const T& object, + void (T::*cb)()const + ); + /*! + requires + - cb == a valid member function pointer for class T + ensures + - returns a member function pointer object MFP such that: + - MFP.is_set() == true + - calls to MFP() will call (object.*cb)() + !*/ + +// ---------------------------------------------------------------------------------------- + + template < + typename T, + typename A1 + > + member_function_pointer<A1> make_mfp ( + T& object, + void (T::*cb)(A1 a1) + ); + /*! + requires + - cb == a valid member function pointer for class T + ensures + - returns a member function pointer object MFP such that: + - MFP.is_set() == true + - calls to MFP(a1) will call (object.*cb)(a1) + !*/ + + template < + typename T, + typename A1 + > + member_function_pointer<A1> make_mfp ( + const T& object, + void (T::*cb)(A1 a1)const + ); + /*! + requires + - cb == a valid member function pointer for class T + ensures + - returns a member function pointer object MFP such that: + - MFP.is_set() == true + - calls to MFP(a1) will call (object.*cb)(a1) + !*/ + +// ---------------------------------------------------------------------------------------- + + template < + typename T, + typename A1, + typename A2 + > + member_function_pointer<A1,A2> make_mfp ( + T& object, + void (T::*cb)(A1 a1, A2 a2) + ); + /*! + requires + - cb == a valid member function pointer for class T + ensures + - returns a member function pointer object MFP such that: + - MFP.is_set() == true + - calls to MFP(a1,a2) will call (object.*cb)(a1,a2) + !*/ + + template < + typename T, + typename A1, + typename A2 + > + member_function_pointer<A1,A2> make_mfp ( + const T& object, + void (T::*cb)(A1 a1, A2 a2)const + ); + /*! + requires + - cb == a valid member function pointer for class T + ensures + - returns a member function pointer object MFP such that: + - MFP.is_set() == true + - calls to MFP(a1,a2) will call (object.*cb)(a1,a2) + !*/ + +// ---------------------------------------------------------------------------------------- + + template < + typename T, + typename A1, + typename A2, + typename A3 + > + member_function_pointer<A1,A2,A3> make_mfp ( + T& object, + void (T::*cb)(A1 a1, A2 a2, A3 a3) + ); + /*! + requires + - cb == a valid member function pointer for class T + ensures + - returns a member function pointer object MFP such that: + - MFP.is_set() == true + - calls to MFP(a1,a2,a3) will call (object.*cb)(a1,a2,a3) + !*/ + + template < + typename T, + typename A1, + typename A2, + typename A3 + > + member_function_pointer<A1,A2,A3> make_mfp ( + const T& object, + void (T::*cb)(A1 a1, A2 a2, A3 a3)const + ); + /*! + requires + - cb == a valid member function pointer for class T + ensures + - returns a member function pointer object MFP such that: + - MFP.is_set() == true + - calls to MFP(a1,a2,a3) will call (object.*cb)(a1,a2,a3) + !*/ + +// ---------------------------------------------------------------------------------------- + + template < + typename T, + typename A1, + typename A2, + typename A3, + typename A4 + > + member_function_pointer<A1,A2,A3,A4> make_mfp ( + T& object, + void (T::*cb)(A1 a1, A2 a2, A3 a3, A4 a4) + ); + /*! + requires + - cb == a valid member function pointer for class T + ensures + - returns a member function pointer object MFP such that: + - MFP.is_set() == true + - calls to MFP(a1,a2,a3,a4) will call (object.*cb)(a1,a2,a3,a4) + !*/ + + template < + typename T, + typename A1, + typename A2, + typename A3, + typename A4 + > + member_function_pointer<A1,A2,A3,A4> make_mfp ( + const T& object, + void (T::*cb)(A1 a1, A2 a2, A3 a3, A4 a4)const + ); + /*! + requires + - cb == a valid member function pointer for class T + ensures + - returns a member function pointer object MFP such that: + - MFP.is_set() == true + - calls to MFP(a1,a2,a3,a4) will call (object.*cb)(a1,a2,a3,a4) + !*/ + +// ---------------------------------------------------------------------------------------- + +} + +#endif // DLIB_MAKE_MFp_ABSTRACT_ + + diff --git a/ml/dlib/dlib/member_function_pointer/member_function_pointer_kernel_1.h b/ml/dlib/dlib/member_function_pointer/member_function_pointer_kernel_1.h new file mode 100644 index 000000000..6cf5630b4 --- /dev/null +++ b/ml/dlib/dlib/member_function_pointer/member_function_pointer_kernel_1.h @@ -0,0 +1,498 @@ +// Copyright (C) 2005 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. +#ifndef DLIB_MEMBER_FUNCTION_POINTER_KERNEl_1_ +#define DLIB_MEMBER_FUNCTION_POINTER_KERNEl_1_ + +#include "../algs.h" +#include "member_function_pointer_kernel_abstract.h" +#include "../enable_if.h" +#include <new> + +namespace dlib +{ + +// ---------------------------------------------------------------------------------------- + + template < + typename PARAM1 = void, + typename PARAM2 = void, + typename PARAM3 = void, + typename PARAM4 = void + > + class member_function_pointer; + +// ---------------------------------------------------------------------------------------- + +#define DLIB_MFP_SC DLIB_ASSERT(cb != 0, \ + "\tvoid member_function_pointer::set" \ + << "\n\tthe member function pointer can't be null" \ + << "\n\tthis: " << this ); + + +#define DLIB_MFP_OC DLIB_ASSERT(this->is_set() == true , \ + "\tvoid member_function_pointer::operator()" \ + << "\n\tYou must call set() before you can use this function" \ + << "\n\tthis: " << this); + +// ---------------------------------------------------------------------------------------- + + template <unsigned long num_args> + class mfp_kernel_1_base_class + { + /* + All member function pointer classes inherit from this class. This + is where most of the things in a member function pointer are defined. + + The reason for the num_args template argument to this class is to prevent + any sort of implicit casting between derived member function pointer classes + that take different numbers of arguments. + */ + protected: + enum mfp_type { mfp_nonconst, mfp_const, mfp_null}; + + class mp_base_base + { + public: + mp_base_base(void* ptr, mfp_type type_) : o(ptr),type(type_) {} + virtual ~mp_base_base(){} + virtual void clone(void* ptr) const = 0; + virtual bool is_same (const mp_base_base* item) const = 0; + bool is_set () const { return o!=0; } + + void* const o; + const mfp_type type; + }; + + template <typename T> + class mp_null : public mp_base_base + { + public: + typedef void (T::*mfp_pointer_type)() ; + + mp_null (void* , mfp_pointer_type ) : mp_base_base(0,mfp_null), callback(0) {} + mp_null () : mp_base_base(0,mfp_null), callback(0) {} + + const mfp_pointer_type callback; + }; + + template <typename mp_impl> + class mp_impl_T : public mp_impl + { + /* + This class supplies the implementations clone() and is_same() for any + classes that inherit from mp_base_base. It does this in a very + roundabout way... + */ + + public: + typedef typename mp_impl::mfp_pointer_type mfp_pointer_type; + + mp_impl_T() : mp_impl(0,0) {} + mp_impl_T(void* ptr, mfp_pointer_type cb) : mp_impl(ptr,cb) {} + + template <unsigned long mem_size> + void safe_clone(stack_based_memory_block<mem_size>& buf) + { + // This is here just to validate the assumption that our block of memory we have made + // in mp_memory is the right size to store the data for this object. If you + // get a compiler error on this line then email me :) + COMPILE_TIME_ASSERT(sizeof(mp_impl_T) <= mem_size); + clone(buf.get()); + } + + void clone (void* ptr) const { new(ptr) mp_impl_T(this->o,this->callback); } + bool is_same (const mp_base_base* item) const + { + if (item->o == 0 && this->o == 0) + { + return true; + } + else if (item->o == this->o && this->type == item->type) + { + const mp_impl* i = reinterpret_cast<const mp_impl*>(item); + return (i->callback == this->callback); + } + return false; + } + }; + + struct dummy_base { virtual void nonnull() {}; virtual ~dummy_base(){}; int a; }; + struct dummy : virtual public dummy_base{ void nonnull() {}; }; + + typedef mp_impl_T<mp_null<dummy> > mp_null_impl; + public: + + mfp_kernel_1_base_class ( + const mfp_kernel_1_base_class& item + ) { item.mp()->clone(mp_memory.get()); } + + mfp_kernel_1_base_class ( + ) { mp_null_impl().safe_clone(mp_memory); } + + bool operator == ( + const mfp_kernel_1_base_class& item + ) const { return mp()->is_same(item.mp()); } + + bool operator != ( + const mfp_kernel_1_base_class& item + ) const { return !(*this == item); } + + mfp_kernel_1_base_class& operator= ( + const mfp_kernel_1_base_class& item + ) { mfp_kernel_1_base_class(item).swap(*this); return *this; } + + ~mfp_kernel_1_base_class ( + ) { destroy_mp_memory(); } + + void clear( + ) { mfp_kernel_1_base_class().swap(*this); } + + bool is_set ( + ) const { return mp()->is_set(); } + + private: + typedef void (dummy::*safe_bool)(); + + public: + operator safe_bool () const { return is_set() ? &dummy::nonnull : 0; } + bool operator!() const { return !is_set(); } + + void swap ( + mfp_kernel_1_base_class& item + ) + { + // make a temp copy of item + mfp_kernel_1_base_class temp(item); + + // destory the stuff in item + item.destroy_mp_memory(); + // copy *this into item + mp()->clone(item.mp_memory.get()); + + // destory the stuff in this + destroy_mp_memory(); + // copy temp into *this + temp.mp()->clone(mp_memory.get()); + } + + protected: + + // The reason for adding 1 here is because visual studio 2003 will sometimes + // try to compile this code with sizeof(mp_null_impl) == 0 (which is a bug in visual studio). + // Fortunately, no actual real instances of this template seem to end up with that screwed up + // value so everything works fine if we just add 1 so that this degenerate case doesn't cause + // trouble. Note that we know it all works fine because safe_clone() checks the size of this + // memory block whenever the member function pointer is used. + stack_based_memory_block<sizeof(mp_null_impl)+1> mp_memory; + + void destroy_mp_memory ( + ) + { + // Honestly this probably doesn't even do anything but I'm putting + // it here just for good measure. + mp()->~mp_base_base(); + } + + mp_base_base* mp () { return static_cast<mp_base_base*>(mp_memory.get()); } + const mp_base_base* mp () const { return static_cast<const mp_base_base*>(mp_memory.get()); } + + }; + +// ---------------------------------------------------------------------------------------- + + template <> + class member_function_pointer<void,void,void,void> : public mfp_kernel_1_base_class<0> + { + class mp_base : public mp_base_base { + public: + mp_base(void* ptr, mfp_type type_) : mp_base_base(ptr,type_) {} + virtual void call() const = 0; + }; + + template <typename T> + class mp_impl : public mp_base { + public: + typedef void (T::*mfp_pointer_type)() ; + void call () const { (static_cast<T*>(this->o)->*callback)(); } + + mp_impl ( void* object, mfp_pointer_type cb) : mp_base(object, mfp_nonconst), callback(cb) {} + const mfp_pointer_type callback; + }; + + template <typename T> + class mp_impl_const : public mp_base { + public: + typedef void ((T::*mfp_pointer_type)()const); + void call () const { (static_cast<const T*>(this->o)->*callback)(); } + + mp_impl_const ( void* object, mfp_pointer_type cb) : mp_base(object,mfp_const), callback(cb) {} + const mfp_pointer_type callback; + }; + + public: + typedef void param1_type; + typedef void param2_type; + typedef void param3_type; + typedef void param4_type; + + // These two typedefs are here for backwards compatibility with previous versions + // of dlib. + typedef member_function_pointer kernel_1a; + typedef member_function_pointer kernel_1a_c; + + + void operator() () const { DLIB_MFP_OC; static_cast<const mp_base*>(mp_memory.get())->call(); } + + // the reason for putting disable_if on this function is that it avoids an overload + // resolution bug in visual studio. + template <typename T> typename disable_if<is_const_type<T>,void>::type + set(T& object, typename mp_impl<T>::mfp_pointer_type cb) + { DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl<T> >(&object,cb).safe_clone(mp_memory); } + + template <typename T> void set(const T& object, typename mp_impl_const<T>::mfp_pointer_type cb) + { DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl_const<T> >((void*)&object,cb).safe_clone(mp_memory); } + + }; + +// ---------------------------------------------------------------------------------------- + + template < + typename PARAM1 + > + class member_function_pointer<PARAM1,void,void,void> : public mfp_kernel_1_base_class<1> + { + class mp_base : public mp_base_base { + public: + mp_base(void* ptr, mfp_type type_) : mp_base_base(ptr,type_) {} + virtual void call(PARAM1) const = 0; + }; + + template <typename T> + class mp_impl : public mp_base { + public: + typedef void (T::*mfp_pointer_type)(PARAM1) ; + void call (PARAM1 p1) const { (static_cast<T*>(this->o)->*callback)(p1); } + + mp_impl ( void* object, mfp_pointer_type cb) : mp_base(object, mfp_nonconst), callback(cb) {} + const mfp_pointer_type callback; + }; + + template <typename T> + class mp_impl_const : public mp_base { + public: + typedef void ((T::*mfp_pointer_type)(PARAM1)const); + void call (PARAM1 p1) const { (static_cast<const T*>(this->o)->*callback)(p1); } + + mp_impl_const ( void* object, mfp_pointer_type cb) : mp_base(object,mfp_const), callback(cb) {} + const mfp_pointer_type callback; + }; + + public: + typedef PARAM1 param1_type; + typedef void param2_type; + typedef void param3_type; + typedef void param4_type; + + // These two typedefs are here for backwards compatibility with previous versions + // of dlib. + typedef member_function_pointer kernel_1a; + typedef member_function_pointer kernel_1a_c; + + + void operator() (PARAM1 p1) const { DLIB_MFP_OC; static_cast<const mp_base*>(mp_memory.get())->call(p1); } + + // the reason for putting disable_if on this function is that it avoids an overload + // resolution bug in visual studio. + template <typename T> typename disable_if<is_const_type<T>,void>::type + set(T& object, typename mp_impl<T>::mfp_pointer_type cb) + { DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl<T> >(&object,cb).safe_clone(mp_memory); } + + template <typename T> void set(const T& object, typename mp_impl_const<T>::mfp_pointer_type cb) + { DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl_const<T> >((void*)&object,cb).safe_clone(mp_memory); } + + }; + +// ---------------------------------------------------------------------------------------- + + template < + typename PARAM1, + typename PARAM2 + > + class member_function_pointer<PARAM1,PARAM2,void,void> : public mfp_kernel_1_base_class<2> + { + class mp_base : public mp_base_base { + public: + mp_base(void* ptr, mfp_type type_) : mp_base_base(ptr,type_) {} + virtual void call(PARAM1,PARAM2) const = 0; + }; + + template <typename T> + class mp_impl : public mp_base { + public: + typedef void (T::*mfp_pointer_type)(PARAM1,PARAM2) ; + void call (PARAM1 p1, PARAM2 p2) const { (static_cast<T*>(this->o)->*callback)(p1,p2); } + + mp_impl ( void* object, mfp_pointer_type cb) : mp_base(object, mfp_nonconst), callback(cb) {} + const mfp_pointer_type callback; + }; + + template <typename T> + class mp_impl_const : public mp_base { + public: + typedef void ((T::*mfp_pointer_type)(PARAM1,PARAM2)const); + void call (PARAM1 p1, PARAM2 p2) const { (static_cast<const T*>(this->o)->*callback)(p1,p2); } + + mp_impl_const ( void* object, mfp_pointer_type cb) : mp_base(object,mfp_const), callback(cb) {} + const mfp_pointer_type callback; + }; + + public: + typedef PARAM1 param1_type; + typedef PARAM2 param2_type; + typedef void param3_type; + typedef void param4_type; + + // These two typedefs are here for backwards compatibility with previous versions + // of dlib. + typedef member_function_pointer kernel_1a; + typedef member_function_pointer kernel_1a_c; + + void operator() (PARAM1 p1, PARAM2 p2) const { DLIB_MFP_OC; static_cast<const mp_base*>(mp_memory.get())->call(p1,p2); } + + // the reason for putting disable_if on this function is that it avoids an overload + // resolution bug in visual studio. + template <typename T> typename disable_if<is_const_type<T>,void>::type + set(T& object, typename mp_impl<T>::mfp_pointer_type cb) + { DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl<T> >(&object,cb).safe_clone(mp_memory); } + + template <typename T> void set(const T& object, typename mp_impl_const<T>::mfp_pointer_type cb) + { DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl_const<T> >((void*)&object,cb).safe_clone(mp_memory); } + + }; + +// ---------------------------------------------------------------------------------------- + + template < + typename PARAM1, + typename PARAM2, + typename PARAM3 + > + class member_function_pointer<PARAM1,PARAM2,PARAM3,void> : public mfp_kernel_1_base_class<3> + { + class mp_base : public mp_base_base { + public: + mp_base(void* ptr, mfp_type type_) : mp_base_base(ptr,type_) {} + virtual void call(PARAM1,PARAM2,PARAM3) const = 0; + }; + + template <typename T> + class mp_impl : public mp_base { + public: + typedef void (T::*mfp_pointer_type)(PARAM1,PARAM2,PARAM3) ; + void call (PARAM1 p1, PARAM2 p2, PARAM3 p3) const { (static_cast<T*>(this->o)->*callback)(p1,p2,p3); } + + mp_impl ( void* object, mfp_pointer_type cb) : mp_base(object, mfp_nonconst), callback(cb) {} + const mfp_pointer_type callback; + }; + + template <typename T> + class mp_impl_const : public mp_base { + public: + typedef void ((T::*mfp_pointer_type)(PARAM1,PARAM2,PARAM3)const); + void call (PARAM1 p1, PARAM2 p2, PARAM3 p3) const { (static_cast<const T*>(this->o)->*callback)(p1,p2,p3); } + + mp_impl_const ( void* object, mfp_pointer_type cb) : mp_base(object,mfp_const), callback(cb) {} + const mfp_pointer_type callback; + }; + + public: + typedef PARAM1 param1_type; + typedef PARAM2 param2_type; + typedef PARAM3 param3_type; + typedef void param4_type; + + // These two typedefs are here for backwards compatibility with previous versions + // of dlib. + typedef member_function_pointer kernel_1a; + typedef member_function_pointer kernel_1a_c; + + void operator() (PARAM1 p1, PARAM2 p2, PARAM3 p3) const { DLIB_MFP_OC; static_cast<const mp_base*>(mp_memory.get())->call(p1,p2,p3); } + + // the reason for putting disable_if on this function is that it avoids an overload + // resolution bug in visual studio. + template <typename T> typename disable_if<is_const_type<T>,void>::type + set(T& object, typename mp_impl<T>::mfp_pointer_type cb) + { DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl<T> >(&object,cb).safe_clone(mp_memory); } + + template <typename T> void set(const T& object, typename mp_impl_const<T>::mfp_pointer_type cb) + { DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl_const<T> >((void*)&object,cb).safe_clone(mp_memory); } + + }; + +// ---------------------------------------------------------------------------------------- + + template < + typename PARAM1, + typename PARAM2, + typename PARAM3, + typename PARAM4 + > + class member_function_pointer : public mfp_kernel_1_base_class<4> + { + class mp_base : public mp_base_base { + public: + mp_base(void* ptr, mfp_type type_) : mp_base_base(ptr,type_) {} + virtual void call(PARAM1,PARAM2,PARAM3,PARAM4) const = 0; + }; + + template <typename T> + class mp_impl : public mp_base { + public: + typedef void (T::*mfp_pointer_type)(PARAM1,PARAM2,PARAM3, PARAM4) ; + void call (PARAM1 p1, PARAM2 p2, PARAM3 p3, PARAM4 p4) const { (static_cast<T*>(this->o)->*callback)(p1,p2,p3,p4); } + + mp_impl ( void* object, mfp_pointer_type cb) : mp_base(object, mfp_nonconst), callback(cb) {} + const mfp_pointer_type callback; + }; + + template <typename T> + class mp_impl_const : public mp_base { + public: + typedef void ((T::*mfp_pointer_type)(PARAM1,PARAM2,PARAM3,PARAM4)const); + void call (PARAM1 p1, PARAM2 p2, PARAM3 p3, PARAM4 p4) const { (static_cast<const T*>(this->o)->*callback)(p1,p2,p3,p4); } + + mp_impl_const ( void* object, mfp_pointer_type cb) : mp_base(object,mfp_const), callback(cb) {} + const mfp_pointer_type callback; + }; + + public: + typedef PARAM1 param1_type; + typedef PARAM2 param2_type; + typedef PARAM3 param3_type; + typedef PARAM4 param4_type; + + // These two typedefs are here for backwards compatibility with previous versions + // of dlib. + typedef member_function_pointer kernel_1a; + typedef member_function_pointer kernel_1a_c; + + void operator() (PARAM1 p1, PARAM2 p2, PARAM3 p3, PARAM4 p4) const + { DLIB_MFP_OC; static_cast<const mp_base*>(mp_memory.get())->call(p1,p2,p3,p4); } + + // the reason for putting disable_if on this function is that it avoids an overload + // resolution bug in visual studio. + template <typename T> typename disable_if<is_const_type<T>,void>::type + set(T& object, typename mp_impl<T>::mfp_pointer_type cb) + { DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl<T> >(&object,cb).safe_clone(mp_memory); } + + template <typename T> void set(const T& object, typename mp_impl_const<T>::mfp_pointer_type cb) + { DLIB_MFP_SC; destroy_mp_memory(); mp_impl_T<mp_impl_const<T> >((void*)&object,cb).safe_clone(mp_memory); } + + }; + +// ---------------------------------------------------------------------------------------- + +} + +#endif // DLIB_MEMBER_FUNCTION_POINTER_KERNEl_1_ + diff --git a/ml/dlib/dlib/member_function_pointer/member_function_pointer_kernel_abstract.h b/ml/dlib/dlib/member_function_pointer/member_function_pointer_kernel_abstract.h new file mode 100644 index 000000000..e152972ee --- /dev/null +++ b/ml/dlib/dlib/member_function_pointer/member_function_pointer_kernel_abstract.h @@ -0,0 +1,483 @@ +// Copyright (C) 2005 Davis E. King (davis@dlib.net) +// License: Boost Software License See LICENSE.txt for the full license. +#undef DLIB_MEMBER_FUNCTION_POINTER_KERNEl_ABSTRACT_ +#ifdef DLIB_MEMBER_FUNCTION_POINTER_KERNEl_ABSTRACT_ + +namespace dlib +{ + +// ---------------------------------------------------------------------------------------- + + template < + typename PARAM1 = void, + typename PARAM2 = void, + typename PARAM3 = void, + typename PARAM4 = void + > + class member_function_pointer; + +// ---------------------------------------------------------------------------------------- + + template <> + class member_function_pointer<void,void,void,void> + { + /*! + INITIAL VALUE + is_set() == false + + WHAT THIS OBJECT REPRESENTS + This object represents a member function pointer. It is useful because + instances of this object can be created without needing to know the type + of object whose member function we will be calling. + + There are five template specializations of this object. The first + represents a pointer to a member function taking no parameters, the + second represents a pointer to a member function taking one parameter, + the third to one taking two parameters, and so on. + + You specify the parameters to your member function pointer by filling in + the PARAM template parameters. For example: + + To use a pointer to a function with no parameters you would say: + member_function_pointer<> my_pointer; + To use a pointer to a function that takes a single int you would say: + member_function_pointer<int> my_pointer; + To use a pointer to a function that takes an int and then a reference + to a string you would say: + member_function_pointer<int,string&> my_pointer; + + Also note that the formal comments are only present for the first + template specialization. They are all exactly the same except for the + number of parameters each takes in its member function pointer. + !*/ + + public: + typedef void param1_type; + typedef void param2_type; + typedef void param3_type; + typedef void param4_type; + + member_function_pointer ( + ); + /*! + ensures + - #*this is properly initialized + !*/ + + member_function_pointer( + const member_function_pointer& item + ); + /*! + ensures + - *this == item + !*/ + + ~member_function_pointer ( + ); + /*! + ensures + - any resources associated with *this have been released + !*/ + + member_function_pointer& operator=( + const member_function_pointer& item + ); + /*! + ensures + - *this == item + !*/ + + bool operator == ( + const member_function_pointer& item + ) const; + /*! + ensures + - if (is_set() == false && item.is_set() == false) then + - returns true + - else if (both *this and item point to the same member function + in the same object instance) then + - returns true + - else + - returns false + !*/ + + bool operator != ( + const member_function_pointer& item + ) const; + /*! + ensures + - returns !(*this == item) + !*/ + + void clear( + ); + /*! + ensures + - #*this has its initial value + !*/ + + bool is_set ( + ) const; + /*! + ensures + - if (this->set() has been called) then + - returns true + - else + - returns false + !*/ + + template < + typename T + > + void set ( + T& object, + void (T::*cb)() + ); + /*! + requires + - cb == a valid member function pointer for class T + ensures + - #is_set() == true + - calls to this->operator() will call (object.*cb)() + !*/ + + template < + typename T + > + void set ( + const T& object, + void (T::*cb)()const + ); + /*! + requires + - cb == a valid member function pointer for class T + ensures + - #is_set() == true + - calls to this->operator() will call (object.*cb)() + !*/ + + operator some_undefined_pointer_type ( + ) const; + /*! + ensures + - if (is_set()) then + - returns a non 0 value + - else + - returns a 0 value + !*/ + + bool operator! ( + ) const; + /*! + ensures + - returns !is_set() + !*/ + + void operator () ( + ) const; + /*! + requires + - is_set() == true + ensures + - calls the member function on the object specified by the last + call to this->set() + throws + - any exception thrown by the member function specified by + the previous call to this->set(). + If any of these exceptions are thrown then the call to this + function will have no effect on *this. + !*/ + + void swap ( + member_function_pointer& item + ); + /*! + ensures + - swaps *this and item + !*/ + + }; + +// ---------------------------------------------------------------------------------------- + + template < + typename PARAM1 + > + class member_function_pointer<PARAM1,void,void,void> + { + public: + typedef PARAM1 param1_type; + typedef void param2_type; + typedef void param3_type; + typedef void param4_type; + + member_function_pointer (); + + member_function_pointer( + const member_function_pointer& item + ); + + ~member_function_pointer ( + ); + + member_function_pointer& operator=( + const member_function_pointer& item + ); + + bool operator == ( + const member_function_pointer& item + ) const; + + bool operator != ( + const member_function_pointer& item + ) const; + + void clear(); + + bool is_set () const; + + template <typename T> + void set ( + T& object, + void (T::*cb)(PARAM1) + ); + + template <typename T> + void set ( + const T& object, + void (T::*cb)(PARAM1)const + ); + + operator some_undefined_pointer_type ( + ) const; + + bool operator! ( + ) const; + + void operator () ( + PARAM1 param1 + ) const; + + void swap ( + member_function_pointer& item + ); + + }; + +// ---------------------------------------------------------------------------------------- + + template < + typename PARAM1, + typename PARAM2 + > + class member_function_pointer<PARAM1,PARAM2,void,void> + { + public: + typedef PARAM1 param1_type; + typedef PARAM2 param2_type; + typedef void param3_type; + typedef void param4_type; + + member_function_pointer (); + + member_function_pointer( + const member_function_pointer& item + ); + + ~member_function_pointer ( + ); + + member_function_pointer& operator=( + const member_function_pointer& item + ); + + bool operator == ( + const member_function_pointer& item + ) const; + + bool operator != ( + const member_function_pointer& item + ) const; + + void clear(); + + bool is_set () const; + + template <typename T> + void set ( + T& object, + void (T::*cb)(PARAM1,PARAM2) + ); + + template <typename T> + void set ( + const T& object, + void (T::*cb)(PARAM1,PARAM2)const + ); + + operator some_undefined_pointer_type ( + ) const; + + bool operator! ( + ) const; + + void operator () ( + PARAM1 param1, + PARAM2 param2 + ) const; + + void swap ( + member_function_pointer& item + ); + + }; + +// ---------------------------------------------------------------------------------------- + + template < + typename PARAM1, + typename PARAM2, + typename PARAM3 + > + class member_function_pointer<PARAM1,PARAM2,PARAM3,void> + { + public: + typedef PARAM1 param1_type; + typedef PARAM2 param2_type; + typedef PARAM3 param3_type; + typedef void param4_type; + + member_function_pointer (); + + member_function_pointer( + const member_function_pointer& item + ); + + ~member_function_pointer ( + ); + + member_function_pointer& operator=( + const member_function_pointer& item + ); + + bool operator == ( + const member_function_pointer& item + ) const; + + bool operator != ( + const member_function_pointer& item + ) const; + + void clear(); + + bool is_set () const; + + template <typename T> + void set ( + T& object, + void (T::*cb)(PARAM1,PARAM2,PARAM3) + ); + + template <typename T> + void set ( + const T& object, + void (T::*cb)(PARAM1,PARAM2,PARAM3)const + ); + + operator some_undefined_pointer_type ( + ) const; + + bool operator! ( + ) const; + + void operator () ( + PARAM1 param1, + PARAM2 param2, + PARAM2 param3 + ) const; + + void swap ( + member_function_pointer& item + ); + + }; + +// ---------------------------------------------------------------------------------------- + + template < + typename PARAM1, + typename PARAM2, + typename PARAM3, + typename PARAM4 + > + class member_function_pointer + { + public: + typedef PARAM1 param1_type; + typedef PARAM2 param2_type; + typedef PARAM3 param3_type; + typedef PARAM4 param4_type; + + member_function_pointer (); + + member_function_pointer( + const member_function_pointer& item + ); + + ~member_function_pointer ( + ); + + member_function_pointer& operator=( + const member_function_pointer& item + ); + + bool operator == ( + const member_function_pointer& item + ) const; + + bool operator != ( + const member_function_pointer& item + ) const; + + void clear(); + + bool is_set () const; + + template <typename T> + void set ( + T& object, + void (T::*cb)(PARAM1,PARAM2,PARAM3,PARAM4) + ); + + template <typename T> + void set ( + const T& object, + void (T::*cb)(PARAM1,PARAM2,PARAM3,PARAM4)const + ); + + operator some_undefined_pointer_type ( + ) const; + + bool operator! ( + ) const; + + void operator () ( + PARAM1 param1, + PARAM2 param2, + PARAM2 param3, + PARAM2 param4 + ) const; + + void swap ( + member_function_pointer& item + ); + + }; + +// ---------------------------------------------------------------------------------------- + + +} + +#endif // DLIB_MEMBER_FUNCTION_POINTER_KERNEl_ABSTRACT_ + |