|
|
|
|
|
#ifndef DLIB_ANY_FUNCTION_RETURN |
|
#error "You aren't supposed to directly #include this file. #include <dlib/any.h> instead." |
|
#endif |
|
|
|
#ifdef _MSC_VER
|
|
|
|
|
|
#pragma warning(disable : 4180) |
|
#endif |
|
|
|
#ifdef DLIB_ANY_FUNCTION_RETURN |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public: |
|
typedef typename sig_traits<function_type>::result_type result_type; |
|
typedef typename sig_traits<function_type>::arg1_type arg1_type; |
|
typedef typename sig_traits<function_type>::arg2_type arg2_type; |
|
typedef typename sig_traits<function_type>::arg3_type arg3_type; |
|
typedef typename sig_traits<function_type>::arg4_type arg4_type; |
|
typedef typename sig_traits<function_type>::arg5_type arg5_type; |
|
typedef typename sig_traits<function_type>::arg6_type arg6_type; |
|
typedef typename sig_traits<function_type>::arg7_type arg7_type; |
|
typedef typename sig_traits<function_type>::arg8_type arg8_type; |
|
typedef typename sig_traits<function_type>::arg9_type arg9_type; |
|
typedef typename sig_traits<function_type>::arg10_type arg10_type; |
|
const static unsigned long num_args = sig_traits<function_type>::num_args; |
|
|
|
any_function() |
|
{ |
|
} |
|
|
|
any_function ( |
|
const any_function& item |
|
) |
|
{ |
|
if (item.data) |
|
{ |
|
item.data->copy_to(data); |
|
} |
|
} |
|
|
|
template <typename T> |
|
any_function ( |
|
const T& item |
|
) |
|
{ |
|
typedef typename basic_type<T>::type U; |
|
data.reset(new derived<U,function_type>(item)); |
|
} |
|
|
|
void clear ( |
|
) |
|
{ |
|
data.reset(); |
|
} |
|
|
|
template <typename T> |
|
bool contains ( |
|
) const |
|
{ |
|
typedef typename basic_type<T>::type U; |
|
return dynamic_cast<derived<U,function_type>*>(data.get()) != 0; |
|
} |
|
|
|
bool is_empty( |
|
) const |
|
{ |
|
return data.get() == 0; |
|
} |
|
|
|
bool is_set( |
|
) const |
|
{ |
|
return !is_empty(); |
|
} |
|
|
|
template <typename T> |
|
T& cast_to( |
|
) |
|
{ |
|
typedef typename basic_type<T>::type U; |
|
derived<U,function_type>* d = dynamic_cast<derived<U,function_type>*>(data.get()); |
|
if (d == 0) |
|
{ |
|
throw bad_any_cast(); |
|
} |
|
|
|
return d->item; |
|
} |
|
|
|
template <typename T> |
|
const T& cast_to( |
|
) const |
|
{ |
|
typedef typename basic_type<T>::type U; |
|
derived<U,function_type>* d = dynamic_cast<derived<U,function_type>*>(data.get()); |
|
if (d == 0) |
|
{ |
|
throw bad_any_cast(); |
|
} |
|
|
|
return d->item; |
|
} |
|
|
|
template <typename T> |
|
T& get( |
|
) |
|
{ |
|
typedef typename basic_type<T>::type U; |
|
derived<U,function_type>* d = dynamic_cast<derived<U,function_type>*>(data.get()); |
|
if (d == 0) |
|
{ |
|
d = new derived<U,function_type>(); |
|
data.reset(d); |
|
} |
|
|
|
return d->item; |
|
} |
|
|
|
any_function& operator= ( |
|
const any_function& item |
|
) |
|
{ |
|
any_function(item).swap(*this); |
|
return *this; |
|
} |
|
|
|
void swap ( |
|
any_function& item |
|
) |
|
{ |
|
data.swap(item.data); |
|
} |
|
|
|
result_type operator()(DLIB_ANY_FUNCTION_ARG_LIST) const |
|
{ validate(); DLIB_ANY_FUNCTION_RETURN data->evaluate(DLIB_ANY_FUNCTION_ARGS); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private: |
|
|
|
void validate () const |
|
{ |
|
|
|
DLIB_ASSERT(is_empty() == false, |
|
"\t result_type any_function::operator()" |
|
<< "\n\t You can't call operator() on an empty any_function" |
|
<< "\n\t this: " << this |
|
); |
|
} |
|
|
|
|
|
template <typename FT> |
|
struct Tbase |
|
{ |
|
virtual ~Tbase() {} |
|
virtual result_type evaluate () const = 0; |
|
virtual void copy_to ( std::unique_ptr<Tbase>& dest) const = 0; |
|
}; |
|
|
|
template < |
|
typename T, |
|
typename A1 |
|
> |
|
struct Tbase<T (A1)> |
|
{ |
|
virtual ~Tbase() {} |
|
virtual T evaluate ( A1) const = 0; |
|
virtual void copy_to ( std::unique_ptr<Tbase>& dest) const = 0; |
|
}; |
|
|
|
template < |
|
typename T, |
|
typename A1, typename A2 |
|
> |
|
struct Tbase<T (A1,A2)> |
|
{ |
|
virtual ~Tbase() {} |
|
virtual T evaluate (A1,A2) const = 0; |
|
virtual void copy_to ( std::unique_ptr<Tbase>& dest) const = 0; |
|
}; |
|
|
|
template < |
|
typename T, |
|
typename A1, typename A2, typename A3 |
|
> |
|
struct Tbase<T (A1,A2,A3)> |
|
{ |
|
virtual ~Tbase() {} |
|
virtual T evaluate (A1,A2,A3) const = 0; |
|
virtual void copy_to ( std::unique_ptr<Tbase>& dest) const = 0; |
|
}; |
|
|
|
template < |
|
typename T, |
|
typename A1, typename A2, typename A3, |
|
typename A4 |
|
> |
|
struct Tbase<T (A1,A2,A3,A4)> |
|
{ |
|
virtual ~Tbase() {} |
|
virtual T evaluate (A1,A2,A3,A4) const = 0; |
|
virtual void copy_to ( std::unique_ptr<Tbase>& dest) const = 0; |
|
}; |
|
|
|
template < |
|
typename T, |
|
typename A1, typename A2, typename A3, |
|
typename A4, typename A5 |
|
> |
|
struct Tbase<T (A1,A2,A3,A4,A5)> |
|
{ |
|
virtual ~Tbase() {} |
|
virtual T evaluate (A1,A2,A3,A4,A5) const = 0; |
|
virtual void copy_to ( std::unique_ptr<Tbase>& dest) const = 0; |
|
}; |
|
|
|
template < |
|
typename T, |
|
typename A1, typename A2, typename A3, |
|
typename A4, typename A5, typename A6 |
|
> |
|
struct Tbase<T (A1,A2,A3,A4,A5,A6)> |
|
{ |
|
virtual ~Tbase() {} |
|
virtual T evaluate (A1,A2,A3,A4,A5,A6) const = 0; |
|
virtual void copy_to ( std::unique_ptr<Tbase>& dest) const = 0; |
|
}; |
|
|
|
template < |
|
typename T, |
|
typename A1, typename A2, typename A3, |
|
typename A4, typename A5, typename A6, |
|
typename A7 |
|
> |
|
struct Tbase<T (A1,A2,A3,A4,A5,A6,A7)> |
|
{ |
|
virtual ~Tbase() {} |
|
virtual T evaluate (A1,A2,A3,A4,A5,A6,A7) const = 0; |
|
virtual void copy_to ( std::unique_ptr<Tbase>& dest) const = 0; |
|
}; |
|
|
|
template < |
|
typename T, |
|
typename A1, typename A2, typename A3, |
|
typename A4, typename A5, typename A6, |
|
typename A7, typename A8 |
|
> |
|
struct Tbase<T (A1,A2,A3,A4,A5,A6,A7,A8)> |
|
{ |
|
virtual ~Tbase() {} |
|
virtual T evaluate (A1,A2,A3,A4,A5,A6,A7,A8) const = 0; |
|
virtual void copy_to ( std::unique_ptr<Tbase>& dest) const = 0; |
|
}; |
|
|
|
template < |
|
typename T, |
|
typename A1, typename A2, typename A3, |
|
typename A4, typename A5, typename A6, |
|
typename A7, typename A8, typename A9 |
|
> |
|
struct Tbase<T (A1,A2,A3,A4,A5,A6,A7,A8,A9)> |
|
{ |
|
virtual ~Tbase() {} |
|
virtual T evaluate (A1,A2,A3,A4,A5,A6,A7,A8,A9) const = 0; |
|
virtual void copy_to ( std::unique_ptr<Tbase>& dest) const = 0; |
|
}; |
|
|
|
template < |
|
typename T, |
|
typename A1, typename A2, typename A3, |
|
typename A4, typename A5, typename A6, |
|
typename A7, typename A8, typename A9, |
|
typename A10 |
|
> |
|
struct Tbase<T (A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)> |
|
{ |
|
virtual ~Tbase() {} |
|
virtual T evaluate (A1,A2,A3,A4,A5,A6,A7,A8,A9,A10) const = 0; |
|
virtual void copy_to ( std::unique_ptr<Tbase>& dest) const = 0; |
|
}; |
|
|
|
typedef Tbase<function_type> base; |
|
|
|
|
|
|
|
|
|
|
|
template <typename T, typename enabled = void> |
|
struct funct_type { typedef T type; }; |
|
template <typename T> |
|
struct funct_type<T, typename enable_if<is_function<T> >::type> { typedef T* type; }; |
|
|
|
template <typename T> |
|
static typename enable_if<is_function<T>,const T*>::type copy (const T& item) { return &item; } |
|
template <typename T> |
|
static typename disable_if<is_function<T>,const T&>::type copy (const T& item) { return item; } |
|
|
|
template <typename T, typename U> |
|
static typename enable_if<is_function<T>,const T&>::type deref (const U& item) { return *item; } |
|
template <typename T, typename U> |
|
static typename disable_if<is_function<T>,const T&>::type deref (const U& item) { return item; } |
|
|
|
|
|
|
|
#define DLIB_ANY_FUNCTION_DERIVED_BOILERPLATE \ |
|
typename funct_type<T>::type item; \ |
|
derived() {} \ |
|
derived(const T& val) : item(copy(val)) {} \ |
|
virtual void copy_to ( std::unique_ptr<base>& dest) const \ |
|
{ dest.reset(new derived(deref<T>(item))); } |
|
|
|
template <typename T, typename FT> |
|
struct derived : public base |
|
{ |
|
DLIB_ANY_FUNCTION_DERIVED_BOILERPLATE |
|
|
|
virtual result_type evaluate ( |
|
) const { DLIB_ANY_FUNCTION_RETURN item(); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
template <typename T, typename A1> |
|
struct derived<T,result_type (A1)> : public base |
|
{ |
|
DLIB_ANY_FUNCTION_DERIVED_BOILERPLATE |
|
|
|
virtual result_type evaluate ( |
|
A1 a1 |
|
) const { DLIB_ANY_FUNCTION_RETURN item(a1); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
template <typename T, typename A1, typename A2> |
|
struct derived<T,result_type (A1,A2)> : public base |
|
{ |
|
DLIB_ANY_FUNCTION_DERIVED_BOILERPLATE |
|
|
|
virtual result_type evaluate ( |
|
A1 a1, A2 a2 |
|
) const { DLIB_ANY_FUNCTION_RETURN item(a1,a2); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
template <typename T, typename A1, typename A2, typename A3> |
|
struct derived<T,result_type (A1,A2,A3)> : public base |
|
{ |
|
DLIB_ANY_FUNCTION_DERIVED_BOILERPLATE |
|
|
|
virtual result_type evaluate ( |
|
A1 a1, A2 a2, A3 a3 |
|
) const { DLIB_ANY_FUNCTION_RETURN item(a1,a2,a3); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
template <typename T, typename A1, typename A2, typename A3, |
|
typename A4> |
|
struct derived<T,result_type (A1,A2,A3,A4)> : public base |
|
{ |
|
DLIB_ANY_FUNCTION_DERIVED_BOILERPLATE |
|
|
|
virtual result_type evaluate ( |
|
A1 a1, A2 a2, A3 a3, A4 a4 |
|
) const { DLIB_ANY_FUNCTION_RETURN item(a1,a2,a3,a4); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
template <typename T, typename A1, typename A2, typename A3, |
|
typename A4, typename A5> |
|
struct derived<T,result_type (A1,A2,A3,A4,A5)> : public base |
|
{ |
|
DLIB_ANY_FUNCTION_DERIVED_BOILERPLATE |
|
|
|
virtual result_type evaluate ( |
|
A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 |
|
) const { DLIB_ANY_FUNCTION_RETURN item(a1,a2,a3,a4,a5); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
template <typename T, typename A1, typename A2, typename A3, |
|
typename A4, typename A5, typename A6> |
|
struct derived<T,result_type (A1,A2,A3,A4,A5,A6)> : public base |
|
{ |
|
DLIB_ANY_FUNCTION_DERIVED_BOILERPLATE |
|
|
|
virtual result_type evaluate ( |
|
A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6 |
|
) const { DLIB_ANY_FUNCTION_RETURN item(a1,a2,a3,a4,a5,a6); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
template <typename T, typename A1, typename A2, typename A3, |
|
typename A4, typename A5, typename A6, |
|
typename A7> |
|
struct derived<T,result_type (A1,A2,A3,A4,A5,A6,A7)> : public base |
|
{ |
|
DLIB_ANY_FUNCTION_DERIVED_BOILERPLATE |
|
|
|
virtual result_type evaluate ( |
|
A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7 |
|
) const { DLIB_ANY_FUNCTION_RETURN item(a1,a2,a3,a4,a5,a6,a7); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
template <typename T, typename A1, typename A2, typename A3, |
|
typename A4, typename A5, typename A6, |
|
typename A7, typename A8> |
|
struct derived<T,result_type (A1,A2,A3,A4,A5,A6,A7,A8)> : public base |
|
{ |
|
DLIB_ANY_FUNCTION_DERIVED_BOILERPLATE |
|
|
|
virtual result_type evaluate ( |
|
A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8 |
|
) const { DLIB_ANY_FUNCTION_RETURN item(a1,a2,a3,a4,a5,a6,a7,a8); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
template <typename T, typename A1, typename A2, typename A3, |
|
typename A4, typename A5, typename A6, |
|
typename A7, typename A8, typename A9> |
|
struct derived<T,result_type (A1,A2,A3,A4,A5,A6,A7,A8,A9)> : public base |
|
{ |
|
DLIB_ANY_FUNCTION_DERIVED_BOILERPLATE |
|
|
|
virtual result_type evaluate ( |
|
A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9 |
|
) const { DLIB_ANY_FUNCTION_RETURN item(a1,a2,a3,a4,a5,a6,a7,a8,a9); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
template <typename T, typename A1, typename A2, typename A3, |
|
typename A4, typename A5, typename A6, |
|
typename A7, typename A8, typename A9, |
|
typename A10> |
|
struct derived<T,result_type (A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)> : public base |
|
{ |
|
DLIB_ANY_FUNCTION_DERIVED_BOILERPLATE |
|
|
|
virtual result_type evaluate ( |
|
A1 a1, A2 a2, A3 a3, A4 a4, A5 a5, A6 a6, A7 a7, A8 a8, A9 a9, A10 a10 |
|
) const { DLIB_ANY_FUNCTION_RETURN item(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); } |
|
|
|
|
|
|
|
|
|
|
|
|
|
}; |
|
|
|
std::unique_ptr<base> data; |
|
|
|
#undef DLIB_ANY_FUNCTION_DERIVED_BOILERPLATE |
|
|
|
#endif |
|
|
|
|