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
// ----------------
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>
{
public:
......@@ -72,6 +72,33 @@ namespace dlib
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>
......@@ -258,6 +285,24 @@ namespace dlib
// 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 >
void set (
F& function_object,
......@@ -352,6 +397,40 @@ namespace dlib
// -------------------------------------------
// 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 >
......@@ -544,6 +623,20 @@ namespace dlib
// 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>
void set (
void (*funct)(T1),
......
......@@ -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 >
void set (
F& function_object,
......
......@@ -25,6 +25,8 @@ namespace
float val;
};
int global_var = 0;
struct add_functor
{
template <typename T, typename U, typename V>
......@@ -33,8 +35,19 @@ namespace
dlib::sleep(20);
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_to_zero (int& a) { a = 0; }
void gincrement (int& a) { ++a; }
......@@ -197,6 +210,34 @@ namespace
DLIB_CASSERT(a == 1,"");
DLIB_CASSERT(b == 2,"");
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
// ----------------------------------------------------------------------------------------
uint64 thread_pool::
add_task (
add_task_internal (
const bfp_type& bfp
)
{
......
......@@ -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>
uint64 add_task (
F& function_object,
......@@ -307,7 +348,7 @@ namespace dlib
bfp_type temp;
temp.set(function_object,arg1.get());
uint64 id = add_task(temp);
uint64 id = add_task_internal(temp);
// tie the future to this task
arg1.task_id = id;
......@@ -324,7 +365,7 @@ namespace dlib
{
bfp_type temp;
temp.set(obj,funct,arg1.get());
uint64 id = add_task(temp);
uint64 id = add_task_internal(temp);
// tie the future to this task
arg1.task_id = id;
......@@ -341,7 +382,7 @@ namespace dlib
{
bfp_type temp;
temp.set(obj,funct,arg1.get());
uint64 id = add_task(temp);
uint64 id = add_task_internal(temp);
// tie the future to this task
arg1.task_id = id;
......@@ -357,7 +398,7 @@ namespace dlib
{
bfp_type temp;
temp.set(funct,arg1.get());
uint64 id = add_task(temp);
uint64 id = add_task_internal(temp);
// tie the future to this task
arg1.task_id = id;
......@@ -379,7 +420,7 @@ namespace dlib
bfp_type temp;
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
arg1.task_id = id;
......@@ -400,7 +441,7 @@ namespace dlib
{
bfp_type temp;
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
arg1.task_id = id;
......@@ -421,7 +462,7 @@ namespace dlib
{
bfp_type temp;
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
arg1.task_id = id;
......@@ -441,7 +482,7 @@ namespace dlib
{
bfp_type temp;
temp.set(funct, arg1.get(), arg2.get());
uint64 id = add_task(temp);
uint64 id = add_task_internal(temp);
// tie the futures to this task
arg1.task_id = id;
......@@ -466,7 +507,7 @@ namespace dlib
bfp_type temp;
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
arg1.task_id = id;
......@@ -491,7 +532,7 @@ namespace dlib
{
bfp_type temp;
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
arg1.task_id = id;
......@@ -516,7 +557,7 @@ namespace dlib
{
bfp_type temp;
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
arg1.task_id = id;
......@@ -540,7 +581,7 @@ namespace dlib
{
bfp_type temp;
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
arg1.task_id = id;
......@@ -568,7 +609,7 @@ namespace dlib
bfp_type temp;
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
arg1.task_id = id;
......@@ -597,7 +638,7 @@ namespace dlib
{
bfp_type temp;
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
arg1.task_id = id;
......@@ -626,7 +667,7 @@ namespace dlib
{
bfp_type temp;
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
arg1.task_id = id;
......@@ -654,7 +695,7 @@ namespace dlib
{
bfp_type temp;
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
arg1.task_id = id;
......@@ -672,7 +713,7 @@ namespace dlib
private:
uint64 add_task (
uint64 add_task_internal (
const bfp_type& bfp
);
/*!
......
......@@ -450,7 +450,8 @@ namespace dlib
// --------------------------------------------------------------------------------
// 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>
......@@ -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:
// 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