Commit e5c1db1c authored by Davis King's avatar Davis King

Modified the thread_pool and bound_function_pointer so that they can

easily deal with functions that take no arguments.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%402972
parent 0c5c7006
...@@ -47,7 +47,7 @@ namespace dlib ...@@ -47,7 +47,7 @@ namespace dlib
// ---------------- // ----------------
template <typename F, typename T1, typename T2 = void, typename T3 = void, typename T4 = void> 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> class bound_function_helper : public bound_function_helper_base<T1,T2,T3,T4>
{ {
public: public:
...@@ -72,6 +72,33 @@ namespace dlib ...@@ -72,6 +72,33 @@ namespace dlib
void (*fp)(T1, T2, T3, T4); 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> template <typename F, typename T1>
...@@ -258,6 +285,24 @@ namespace dlib ...@@ -258,6 +285,24 @@ namespace dlib
// set function object overloads // 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.data);
}
template <typename F, typename A1 > template <typename F, typename A1 >
void set ( void set (
F& function_object, F& function_object,
...@@ -352,6 +397,40 @@ namespace dlib ...@@ -352,6 +397,40 @@ namespace dlib
// ------------------------------------------- // -------------------------------------------
// set mfp overloads // 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.data);
}
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.data);
}
// ------------------------------------------- // -------------------------------------------
template <typename T, typename T1, typename A1 > template <typename T, typename T1, typename A1 >
...@@ -544,6 +623,20 @@ namespace dlib ...@@ -544,6 +623,20 @@ namespace dlib
// set fp overloads // 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.data);
}
template <typename T1, typename A1> template <typename T1, typename A1>
void set ( void set (
void (*funct)(T1), void (*funct)(T1),
......
...@@ -121,6 +121,58 @@ namespace dlib ...@@ -121,6 +121,58 @@ namespace dlib
// ---------------------- // ----------------------
template <typename F>
void set (
F& function_object
);
/*!
requires
- function_object() is a valid expression
ensures
- #is_set() == true
- calls to this->operator() will call function_object()
(This seems pointless but it is a useful base case)
!*/
template < typename T>
void set (
T& object,
void (T::*funct)()
);
/*!
requires
- funct == a valid member function pointer for class T
ensures
- #is_set() == true
- calls to this->operator() will call (object.*funct)()
!*/
template < typename T>
void set (
const T& object,
void (T::*funct)()const
);
/*!
requires
- funct == a valid bound function pointer for class T
ensures
- #is_set() == true
- calls to this->operator() will call (object.*funct)()
!*/
void set (
void (*funct)()
);
/*!
requires
- funct == a valid function pointer
ensures
- #is_set() == true
- calls to this->operator() will call funct()
!*/
// ----------------------
template <typename F, typename A1 > template <typename F, typename A1 >
void set ( void set (
F& function_object, F& function_object,
......
...@@ -25,6 +25,8 @@ namespace ...@@ -25,6 +25,8 @@ namespace
float val; float val;
}; };
int global_var = 0;
struct add_functor struct add_functor
{ {
template <typename T, typename U, typename V> template <typename T, typename U, typename V>
...@@ -33,8 +35,19 @@ namespace ...@@ -33,8 +35,19 @@ namespace
dlib::sleep(20); dlib::sleep(20);
res = a + b; res = a + b;
} }
void set_global_var() { global_var = 9; }
void set_global_var_const() const { global_var = 9; }
void operator()()
{
global_var = 9;
}
}; };
void set_global_var() { global_var = 9; }
void gset_struct_to_zero (some_struct& a) { a.val = 0; } void gset_struct_to_zero (some_struct& a) { a.val = 0; }
void gset_to_zero (int& a) { a = 0; } void gset_to_zero (int& a) { a = 0; }
void gincrement (int& a) { ++a; } void gincrement (int& a) { ++a; }
...@@ -197,6 +210,34 @@ namespace ...@@ -197,6 +210,34 @@ namespace
DLIB_CASSERT(a == 1,""); DLIB_CASSERT(a == 1,"");
DLIB_CASSERT(b == 2,""); DLIB_CASSERT(b == 2,"");
DLIB_CASSERT(res == 3,""); DLIB_CASSERT(res == 3,"");
global_var = 0;
DLIB_CASSERT(global_var == 0,"");
id = tp.add_task(&set_global_var);
tp.wait_for_task(id);
DLIB_CASSERT(global_var == 9,"");
global_var = 0;
DLIB_CASSERT(global_var == 0,"");
id = tp.add_task(f);
tp.wait_for_task(id);
DLIB_CASSERT(global_var == 9,"");
global_var = 0;
DLIB_CASSERT(global_var == 0,"");
id = tp.add_task(f, &add_functor::set_global_var);
tp.wait_for_task(id);
DLIB_CASSERT(global_var == 9,"");
global_var = 0;
DLIB_CASSERT(global_var == 0,"");
id = tp.add_task(f, &add_functor::set_global_var_const);
tp.wait_for_task(id);
DLIB_CASSERT(global_var == 9,"");
} }
} }
} }
......
...@@ -228,7 +228,7 @@ namespace dlib ...@@ -228,7 +228,7 @@ namespace dlib
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
uint64 thread_pool:: uint64 thread_pool::
add_task ( add_task_internal (
const bfp_type& bfp const bfp_type& bfp
) )
{ {
......
...@@ -296,6 +296,47 @@ namespace dlib ...@@ -296,6 +296,47 @@ namespace dlib
// -------------------- // --------------------
template <typename F>
uint64 add_task (
F& function_object
)
{
COMPILE_TIME_ASSERT(is_function<F>::value == false);
COMPILE_TIME_ASSERT(is_pointer_type<F>::value == false);
bfp_type temp;
temp.set(function_object);
uint64 id = add_task_internal(temp);
return id;
}
template <typename T>
uint64 add_task (
const T& obj,
void (T::*funct)() const
)
{
bfp_type temp;
temp.set(obj,funct);
uint64 id = add_task_internal(temp);
return id;
}
uint64 add_task (
void (*funct)()
)
{
bfp_type temp;
temp.set(funct);
uint64 id = add_task_internal(temp);
return id;
}
// --------------------
template <typename F, typename A1> template <typename F, typename A1>
uint64 add_task ( uint64 add_task (
F& function_object, F& function_object,
...@@ -307,7 +348,7 @@ namespace dlib ...@@ -307,7 +348,7 @@ namespace dlib
bfp_type temp; bfp_type temp;
temp.set(function_object,arg1.get()); temp.set(function_object,arg1.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the future to this task // tie the future to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -324,7 +365,7 @@ namespace dlib ...@@ -324,7 +365,7 @@ namespace dlib
{ {
bfp_type temp; bfp_type temp;
temp.set(obj,funct,arg1.get()); temp.set(obj,funct,arg1.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the future to this task // tie the future to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -341,7 +382,7 @@ namespace dlib ...@@ -341,7 +382,7 @@ namespace dlib
{ {
bfp_type temp; bfp_type temp;
temp.set(obj,funct,arg1.get()); temp.set(obj,funct,arg1.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the future to this task // tie the future to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -357,7 +398,7 @@ namespace dlib ...@@ -357,7 +398,7 @@ namespace dlib
{ {
bfp_type temp; bfp_type temp;
temp.set(funct,arg1.get()); temp.set(funct,arg1.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the future to this task // tie the future to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -379,7 +420,7 @@ namespace dlib ...@@ -379,7 +420,7 @@ namespace dlib
bfp_type temp; bfp_type temp;
temp.set(function_object, arg1.get(), arg2.get()); temp.set(function_object, arg1.get(), arg2.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the future to this task // tie the future to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -400,7 +441,7 @@ namespace dlib ...@@ -400,7 +441,7 @@ namespace dlib
{ {
bfp_type temp; bfp_type temp;
temp.set(obj, funct, arg1.get(), arg2.get()); temp.set(obj, funct, arg1.get(), arg2.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the futures to this task // tie the futures to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -421,7 +462,7 @@ namespace dlib ...@@ -421,7 +462,7 @@ namespace dlib
{ {
bfp_type temp; bfp_type temp;
temp.set(obj, funct, arg1.get(), arg2.get()); temp.set(obj, funct, arg1.get(), arg2.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the futures to this task // tie the futures to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -441,7 +482,7 @@ namespace dlib ...@@ -441,7 +482,7 @@ namespace dlib
{ {
bfp_type temp; bfp_type temp;
temp.set(funct, arg1.get(), arg2.get()); temp.set(funct, arg1.get(), arg2.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the futures to this task // tie the futures to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -466,7 +507,7 @@ namespace dlib ...@@ -466,7 +507,7 @@ namespace dlib
bfp_type temp; bfp_type temp;
temp.set(function_object, arg1.get(), arg2.get(), arg3.get()); temp.set(function_object, arg1.get(), arg2.get(), arg3.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the future to this task // tie the future to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -491,7 +532,7 @@ namespace dlib ...@@ -491,7 +532,7 @@ namespace dlib
{ {
bfp_type temp; bfp_type temp;
temp.set(obj, funct, arg1.get(), arg2.get(), arg3.get()); temp.set(obj, funct, arg1.get(), arg2.get(), arg3.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the futures to this task // tie the futures to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -516,7 +557,7 @@ namespace dlib ...@@ -516,7 +557,7 @@ namespace dlib
{ {
bfp_type temp; bfp_type temp;
temp.set(obj, funct, arg1.get(), arg2.get(), arg3.get()); temp.set(obj, funct, arg1.get(), arg2.get(), arg3.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the futures to this task // tie the futures to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -540,7 +581,7 @@ namespace dlib ...@@ -540,7 +581,7 @@ namespace dlib
{ {
bfp_type temp; bfp_type temp;
temp.set(funct, arg1.get(), arg2.get(), arg3.get()); temp.set(funct, arg1.get(), arg2.get(), arg3.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the futures to this task // tie the futures to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -568,7 +609,7 @@ namespace dlib ...@@ -568,7 +609,7 @@ namespace dlib
bfp_type temp; bfp_type temp;
temp.set(function_object, arg1.get(), arg2.get(), arg3.get(), arg4.get()); temp.set(function_object, arg1.get(), arg2.get(), arg3.get(), arg4.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the future to this task // tie the future to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -597,7 +638,7 @@ namespace dlib ...@@ -597,7 +638,7 @@ namespace dlib
{ {
bfp_type temp; bfp_type temp;
temp.set(obj, funct, arg1.get(), arg2.get(), arg3.get(), arg4.get()); temp.set(obj, funct, arg1.get(), arg2.get(), arg3.get(), arg4.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the futures to this task // tie the futures to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -626,7 +667,7 @@ namespace dlib ...@@ -626,7 +667,7 @@ namespace dlib
{ {
bfp_type temp; bfp_type temp;
temp.set(obj, funct, arg1.get(), arg2.get(), arg3.get(), arg4.get()); temp.set(obj, funct, arg1.get(), arg2.get(), arg3.get(), arg4.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the futures to this task // tie the futures to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -654,7 +695,7 @@ namespace dlib ...@@ -654,7 +695,7 @@ namespace dlib
{ {
bfp_type temp; bfp_type temp;
temp.set(funct, arg1.get(), arg2.get(), arg3.get(), arg4.get()); temp.set(funct, arg1.get(), arg2.get(), arg3.get(), arg4.get());
uint64 id = add_task(temp); uint64 id = add_task_internal(temp);
// tie the futures to this task // tie the futures to this task
arg1.task_id = id; arg1.task_id = id;
...@@ -672,7 +713,7 @@ namespace dlib ...@@ -672,7 +713,7 @@ namespace dlib
private: private:
uint64 add_task ( uint64 add_task_internal (
const bfp_type& bfp const bfp_type& bfp
); );
/*! /*!
......
...@@ -450,7 +450,8 @@ namespace dlib ...@@ -450,7 +450,8 @@ namespace dlib
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
// The remainder of this class just contains overloads for add_task() that take up // The remainder of this class just contains overloads for add_task() that take up
// to 4 futures. Their behavior is identical to the above add_task() functions. // to 4 futures (as well as 0 futures). Their behavior is identical to the above
// add_task() functions.
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
template <typename F, typename A1, typename A2> template <typename F, typename A1, typename A2>
...@@ -579,6 +580,23 @@ namespace dlib ...@@ -579,6 +580,23 @@ namespace dlib
// -------------------- // --------------------
template <typename F>
uint64 add_task (
F& function_object
);
template <typename T>
uint64 add_task (
const T& obj,
void (T::*funct)() const,
);
uint64 add_task (
void (*funct)()
);
// --------------------
private: private:
// restricted functions // restricted functions
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment