summaryrefslogtreecommitdiffstats
path: root/ml/dlib/dlib/bound_function_pointer/bound_function_pointer_kernel_1.h
diff options
context:
space:
mode:
Diffstat (limited to 'ml/dlib/dlib/bound_function_pointer/bound_function_pointer_kernel_1.h')
-rw-r--r--ml/dlib/dlib/bound_function_pointer/bound_function_pointer_kernel_1.h774
1 files changed, 774 insertions, 0 deletions
diff --git a/ml/dlib/dlib/bound_function_pointer/bound_function_pointer_kernel_1.h b/ml/dlib/dlib/bound_function_pointer/bound_function_pointer_kernel_1.h
new file mode 100644
index 000000000..a39592742
--- /dev/null
+++ b/ml/dlib/dlib/bound_function_pointer/bound_function_pointer_kernel_1.h
@@ -0,0 +1,774 @@
+// Copyright (C) 2008 Davis E. King (davis@dlib.net)
+// License: Boost Software License See LICENSE.txt for the full license.
+#ifndef DLIB_BOUND_FUNCTION_POINTER_KERNEl_1_
+#define DLIB_BOUND_FUNCTION_POINTER_KERNEl_1_
+
+#include "../algs.h"
+#include "../member_function_pointer.h"
+#include "bound_function_pointer_kernel_abstract.h"
+
+namespace dlib
+{
+
+// ----------------------------------------------------------------------------------------
+
+ namespace bfp1_helpers
+ {
+ template <typename T> struct strip { typedef T type; };
+ template <typename T> struct strip<T&> { typedef T type; };
+
+ // ------------------------------------------------------------------------------------
+
+ class bound_function_helper_base_base
+ {
+ public:
+ virtual ~bound_function_helper_base_base(){}
+ virtual void call() const = 0;
+ virtual bool is_set() const = 0;
+ virtual void clone(void* ptr) const = 0;
+ };
+
+ // ------------------------------------------------------------------------------------
+
+ template <typename T1, typename T2, typename T3, typename T4>
+ class bound_function_helper_base : public bound_function_helper_base_base
+ {
+ public:
+ bound_function_helper_base():arg1(0), arg2(0), arg3(0), arg4(0) {}
+
+ typename strip<T1>::type* arg1;
+ typename strip<T2>::type* arg2;
+ typename strip<T3>::type* arg3;
+ typename strip<T4>::type* arg4;
+
+
+ member_function_pointer<T1,T2,T3,T4> mfp;
+ };
+
+ // ----------------
+
+ template <typename F, typename T1 = void, typename T2 = void, typename T3 = void, typename T4 = void>
+ class bound_function_helper : public bound_function_helper_base<T1,T2,T3,T4>
+ {
+ public:
+ void call() const
+ {
+ (*fp)(*this->arg1, *this->arg2, *this->arg3, *this->arg4);
+ }
+
+ typename strip<F>::type* fp;
+ };
+
+ template <typename T1, typename T2, typename T3, typename T4>
+ class bound_function_helper<void,T1,T2,T3,T4> : public bound_function_helper_base<T1,T2,T3,T4>
+ {
+ public:
+ void call() const
+ {
+ if (this->mfp) this->mfp(*this->arg1, *this->arg2, *this->arg3, *this->arg4);
+ else if (fp) fp(*this->arg1, *this->arg2, *this->arg3, *this->arg4);
+ }
+
+ void (*fp)(T1, T2, T3, T4);
+ };
+
+ // ----------------
+
+ template <typename F>
+ class bound_function_helper<F,void,void,void,void> : public bound_function_helper_base<void,void,void,void>
+ {
+ public:
+ void call() const
+ {
+ (*fp)();
+ }
+
+ typename strip<F>::type* fp;
+ };
+
+ template <>
+ class bound_function_helper<void,void,void,void,void> : public bound_function_helper_base<void,void,void,void>
+ {
+ public:
+ void call() const
+ {
+ if (this->mfp) this->mfp();
+ else if (fp) fp();
+ }
+
+ void (*fp)();
+ };
+
+ // ----------------
+
+ template <typename F, typename T1>
+ class bound_function_helper<F,T1,void,void,void> : public bound_function_helper_base<T1,void,void,void>
+ {
+ public:
+ void call() const
+ {
+ (*fp)(*this->arg1);
+ }
+
+ typename strip<F>::type* fp;
+ };
+
+ template <typename T1>
+ class bound_function_helper<void,T1,void,void,void> : public bound_function_helper_base<T1,void,void,void>
+ {
+ public:
+ void call() const
+ {
+ if (this->mfp) this->mfp(*this->arg1);
+ else if (fp) fp(*this->arg1);
+ }
+
+ void (*fp)(T1);
+ };
+
+ // ----------------
+
+ template <typename F, typename T1, typename T2>
+ class bound_function_helper<F,T1,T2,void,void> : public bound_function_helper_base<T1,T2,void,void>
+ {
+ public:
+ void call() const
+ {
+ (*fp)(*this->arg1, *this->arg2);
+ }
+
+ typename strip<F>::type* fp;
+ };
+
+ template <typename T1, typename T2>
+ class bound_function_helper<void,T1,T2,void,void> : public bound_function_helper_base<T1,T2,void,void>
+ {
+ public:
+ void call() const
+ {
+ if (this->mfp) this->mfp(*this->arg1, *this->arg2);
+ else if (fp) fp(*this->arg1, *this->arg2);
+ }
+
+ void (*fp)(T1, T2);
+ };
+
+ // ----------------
+
+ template <typename F, typename T1, typename T2, typename T3>
+ class bound_function_helper<F,T1,T2,T3,void> : public bound_function_helper_base<T1,T2,T3,void>
+ {
+ public:
+ void call() const
+ {
+ (*fp)(*this->arg1, *this->arg2, *this->arg3);
+ }
+
+ typename strip<F>::type* fp;
+ };
+
+ template <typename T1, typename T2, typename T3>
+ class bound_function_helper<void,T1,T2,T3,void> : public bound_function_helper_base<T1,T2,T3,void>
+ {
+ public:
+
+ void call() const
+ {
+ if (this->mfp) this->mfp(*this->arg1, *this->arg2, *this->arg3);
+ else if (fp) fp(*this->arg1, *this->arg2, *this->arg3);
+ }
+
+ void (*fp)(T1, T2, T3);
+ };
+
+ // ------------------------------------------------------------------------------------
+ // ------------------------------------------------------------------------------------
+
+ template <typename T>
+ class bound_function_helper_T : public T
+ {
+ public:
+ bound_function_helper_T(){ this->fp = 0;}
+
+ bool is_set() const
+ {
+ return this->fp != 0 || this->mfp.is_set();
+ }
+
+ 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 bf_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(bound_function_helper_T) <= mem_size);
+ clone(buf.get());
+ }
+
+ void clone (void* ptr) const
+ {
+ bound_function_helper_T* p = new(ptr) bound_function_helper_T();
+ p->arg1 = this->arg1;
+ p->arg2 = this->arg2;
+ p->arg3 = this->arg3;
+ p->arg4 = this->arg4;
+ p->fp = this->fp;
+ p->mfp = this->mfp;
+ }
+ };
+
+ }
+
+// ----------------------------------------------------------------------------------------
+
+ class bound_function_pointer
+ {
+ typedef bfp1_helpers::bound_function_helper_T<bfp1_helpers::bound_function_helper<void,int> > bf_null_type;
+
+ public:
+
+ // These typedefs are here for backwards compatibility with previous versions of
+ // dlib.
+ typedef bound_function_pointer kernel_1a;
+ typedef bound_function_pointer kernel_1a_c;
+
+
+ bound_function_pointer (
+ ) { bf_null_type().safe_clone(bf_memory); }
+
+ bound_function_pointer (
+ const bound_function_pointer& item
+ ) { item.bf()->clone(bf_memory.get()); }
+
+ ~bound_function_pointer()
+ { destroy_bf_memory(); }
+
+ bound_function_pointer& operator= (
+ const bound_function_pointer& item
+ ) { bound_function_pointer(item).swap(*this); return *this; }
+
+ void clear (
+ ) { bound_function_pointer().swap(*this); }
+
+ bool is_set (
+ ) const
+ {
+ return bf()->is_set();
+ }
+
+ void swap (
+ bound_function_pointer& item
+ )
+ {
+ // make a temp copy of item
+ bound_function_pointer temp(item);
+
+ // destory the stuff in item
+ item.destroy_bf_memory();
+ // copy *this into item
+ bf()->clone(item.bf_memory.get());
+
+ // destory the stuff in this
+ destroy_bf_memory();
+ // copy temp into *this
+ temp.bf()->clone(bf_memory.get());
+ }
+
+ void operator() (
+ ) const
+ {
+ // make sure requires clause is not broken
+ DLIB_ASSERT(is_set() == true ,
+ "\tvoid bound_function_pointer::operator()"
+ << "\n\tYou must call set() before you can use this function"
+ << "\n\tthis: " << this
+ );
+
+ bf()->call();
+ }
+
+ private:
+ struct dummy{ void nonnull() {}};
+ typedef void (dummy::*safe_bool)();
+
+ public:
+ operator safe_bool () const { return is_set() ? &dummy::nonnull : 0; }
+ bool operator!() const { return !is_set(); }
+
+ // -------------------------------------------
+ // set function object overloads
+ // -------------------------------------------
+
+ template <typename F>
+ void set (
+ F& function_object
+ )
+ {
+ COMPILE_TIME_ASSERT(is_function<F>::value == false);
+ COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
+
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<F> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.fp = &function_object;
+
+ temp.safe_clone(bf_memory);
+ }
+
+ template <typename F, typename A1 >
+ void set (
+ F& function_object,
+ A1& arg1
+ )
+ {
+ COMPILE_TIME_ASSERT(is_function<F>::value == false);
+ COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
+
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<F,A1> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.fp = &function_object;
+
+ temp.safe_clone(bf_memory);
+ }
+
+ template <typename F, typename A1, typename A2 >
+ void set (
+ F& function_object,
+ A1& arg1,
+ A2& arg2
+ )
+ {
+ COMPILE_TIME_ASSERT(is_function<F>::value == false);
+ COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
+
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<F,A1,A2> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.arg2 = &arg2;
+ temp.fp = &function_object;
+
+ temp.safe_clone(bf_memory);
+ }
+
+ template <typename F, typename A1, typename A2, typename A3 >
+ void set (
+ F& function_object,
+ A1& arg1,
+ A2& arg2,
+ A3& arg3
+ )
+ {
+ COMPILE_TIME_ASSERT(is_function<F>::value == false);
+ COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
+
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<F,A1,A2,A3> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.arg2 = &arg2;
+ temp.arg3 = &arg3;
+ temp.fp = &function_object;
+
+ temp.safe_clone(bf_memory);
+ }
+
+ template <typename F, typename A1, typename A2, typename A3, typename A4>
+ void set (
+ F& function_object,
+ A1& arg1,
+ A2& arg2,
+ A3& arg3,
+ A4& arg4
+ )
+ {
+ COMPILE_TIME_ASSERT(is_function<F>::value == false);
+ COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
+
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<F,A1,A2,A3,A4> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.arg2 = &arg2;
+ temp.arg3 = &arg3;
+ temp.arg4 = &arg4;
+ temp.fp = &function_object;
+
+ temp.safe_clone(bf_memory);
+ }
+
+ // -------------------------------------------
+ // set mfp overloads
+ // -------------------------------------------
+
+ template <typename T>
+ void set (
+ T& object,
+ void (T::*funct)()
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.mfp.set(object,funct);
+
+ temp.safe_clone(bf_memory);
+ }
+
+ template <typename T >
+ void set (
+ const T& object,
+ void (T::*funct)()const
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.mfp.set(object,funct);
+
+ temp.safe_clone(bf_memory);
+ }
+
+ // -------------------------------------------
+
+ template <typename T, typename T1, typename A1 >
+ void set (
+ T& object,
+ void (T::*funct)(T1),
+ A1& arg1
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void,T1> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.mfp.set(object,funct);
+
+ temp.safe_clone(bf_memory);
+ }
+
+ template <typename T, typename T1, typename A1 >
+ void set (
+ const T& object,
+ void (T::*funct)(T1)const,
+ A1& arg1
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void,T1> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.mfp.set(object,funct);
+
+ temp.safe_clone(bf_memory);
+ }
+
+ // ----------------
+
+ template <typename T, typename T1, typename A1,
+ typename T2, typename A2>
+ void set (
+ T& object,
+ void (T::*funct)(T1, T2),
+ A1& arg1,
+ A2& arg2
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void,T1,T2> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.arg2 = &arg2;
+ temp.mfp.set(object,funct);
+
+ temp.safe_clone(bf_memory);
+ }
+
+ template <typename T, typename T1, typename A1,
+ typename T2, typename A2>
+ void set (
+ const T& object,
+ void (T::*funct)(T1, T2)const,
+ A1& arg1,
+ A2& arg2
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void,T1,T2> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.arg2 = &arg2;
+ temp.mfp.set(object,funct);
+
+ temp.safe_clone(bf_memory);
+ }
+
+ // ----------------
+
+ template <typename T, typename T1, typename A1,
+ typename T2, typename A2,
+ typename T3, typename A3>
+ void set (
+ T& object,
+ void (T::*funct)(T1, T2, T3),
+ A1& arg1,
+ A2& arg2,
+ A3& arg3
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void,T1,T2,T3> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.arg2 = &arg2;
+ temp.arg3 = &arg3;
+ temp.mfp.set(object,funct);
+
+ temp.safe_clone(bf_memory);
+ }
+
+ template <typename T, typename T1, typename A1,
+ typename T2, typename A2,
+ typename T3, typename A3>
+ void set (
+ const T& object,
+ void (T::*funct)(T1, T2, T3)const,
+ A1& arg1,
+ A2& arg2,
+ A3& arg3
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void,T1,T2,T3> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.arg2 = &arg2;
+ temp.arg3 = &arg3;
+ temp.mfp.set(object,funct);
+
+ temp.safe_clone(bf_memory);
+ }
+
+ // ----------------
+
+ template <typename T, typename T1, typename A1,
+ typename T2, typename A2,
+ typename T3, typename A3,
+ typename T4, typename A4>
+ void set (
+ T& object,
+ void (T::*funct)(T1, T2, T3, T4),
+ A1& arg1,
+ A2& arg2,
+ A3& arg3,
+ A4& arg4
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void,T1,T2,T3,T4> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.arg2 = &arg2;
+ temp.arg3 = &arg3;
+ temp.arg4 = &arg4;
+ temp.mfp.set(object,funct);
+
+ temp.safe_clone(bf_memory);
+ }
+
+ template <typename T, typename T1, typename A1,
+ typename T2, typename A2,
+ typename T3, typename A3,
+ typename T4, typename A4>
+ void set (
+ const T& object,
+ void (T::*funct)(T1, T2, T3, T4)const,
+ A1& arg1,
+ A2& arg2,
+ A3& arg3,
+ A4& arg4
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void,T1,T2,T3,T4> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.arg2 = &arg2;
+ temp.arg3 = &arg3;
+ temp.arg4 = &arg4;
+ temp.mfp.set(object,funct);
+
+ temp.safe_clone(bf_memory);
+ }
+
+ // -------------------------------------------
+ // set fp overloads
+ // -------------------------------------------
+
+ void set (
+ void (*funct)()
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.fp = funct;
+
+ temp.safe_clone(bf_memory);
+ }
+
+ template <typename T1, typename A1>
+ void set (
+ void (*funct)(T1),
+ A1& arg1
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void,T1> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.fp = funct;
+
+ temp.safe_clone(bf_memory);
+ }
+
+ template <typename T1, typename A1,
+ typename T2, typename A2>
+ void set (
+ void (*funct)(T1, T2),
+ A1& arg1,
+ A2& arg2
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void,T1,T2> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.arg2 = &arg2;
+ temp.fp = funct;
+
+ temp.safe_clone(bf_memory);
+ }
+
+ template <typename T1, typename A1,
+ typename T2, typename A2,
+ typename T3, typename A3>
+ void set (
+ void (*funct)(T1, T2, T3),
+ A1& arg1,
+ A2& arg2,
+ A3& arg3
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void,T1,T2,T3> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.arg2 = &arg2;
+ temp.arg3 = &arg3;
+ temp.fp = funct;
+
+ temp.safe_clone(bf_memory);
+ }
+
+ template <typename T1, typename A1,
+ typename T2, typename A2,
+ typename T3, typename A3,
+ typename T4, typename A4>
+ void set (
+ void (*funct)(T1, T2, T3, T4),
+ A1& arg1,
+ A2& arg2,
+ A3& arg3,
+ A4& arg4
+ )
+ {
+ using namespace bfp1_helpers;
+ destroy_bf_memory();
+ typedef bound_function_helper_T<bound_function_helper<void,T1,T2,T3,T4> > bf_helper_type;
+
+ bf_helper_type temp;
+ temp.arg1 = &arg1;
+ temp.arg2 = &arg2;
+ temp.arg3 = &arg3;
+ temp.arg4 = &arg4;
+ temp.fp = funct;
+
+ temp.safe_clone(bf_memory);
+ }
+
+ // -------------------------------------------
+
+ private:
+
+ stack_based_memory_block<sizeof(bf_null_type)> bf_memory;
+
+ void destroy_bf_memory (
+ )
+ {
+ // Honestly, this probably doesn't even do anything but I'm putting
+ // it here just for good measure.
+ bf()->~bound_function_helper_base_base();
+ }
+
+ bfp1_helpers::bound_function_helper_base_base* bf ()
+ { return static_cast<bfp1_helpers::bound_function_helper_base_base*>(bf_memory.get()); }
+
+ const bfp1_helpers::bound_function_helper_base_base* bf () const
+ { return static_cast<const bfp1_helpers::bound_function_helper_base_base*>(bf_memory.get()); }
+
+ };
+
+// ----------------------------------------------------------------------------------------
+
+ inline void swap (
+ bound_function_pointer& a,
+ bound_function_pointer& b
+ ) { a.swap(b); }
+
+// ----------------------------------------------------------------------------------------
+
+}
+
+#endif // DLIB_BOUND_FUNCTION_POINTER_KERNEl_1_
+