Added an any_function which supports the same functionality as std::function from the

upcoming C++0x standard.  I added this so dlib can be modified to easily support lambda
functions while still being compilable on compilers which don't support the new
std::function.

--HG--
extra : convert_revision : svn%3Afdd8eb12-d10e-0410-9acb-85c331704f74/trunk%404130
This commit is contained in:
Davis King 2011-02-06 21:04:20 +00:00
parent 8837d626e1
commit 3ad1facf9e
5 changed files with 1200 additions and 0 deletions

View File

@ -6,6 +6,7 @@
#include "any/any.h"
#include "any/any_trainer.h"
#include "any/any_decision_function.h"
#include "any/any_function.h"
#endif // DLIB_AnY_

381
dlib/any/any_function.h Normal file
View File

@ -0,0 +1,381 @@
// Copyright (C) 2011 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_AnY_FUNCTION_H__
#define DLIB_AnY_FUNCTION_H__
#include "any.h"
#include "../smart_pointers.h"
#include "any_function_abstract.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
template <typename T>
struct sig_traits {};
template <
typename T
>
struct sig_traits<T ()>
{
typedef T result_type;
typedef void arg1_type;
typedef void arg2_type;
typedef void arg3_type;
typedef void arg4_type;
typedef void arg5_type;
typedef void arg6_type;
typedef void arg7_type;
typedef void arg8_type;
typedef void arg9_type;
typedef void arg10_type;
const static unsigned long num_args = 0;
};
template <
typename T,
typename A1
>
struct sig_traits<T (A1)>
{
typedef T result_type;
typedef A1 arg1_type;
typedef void arg2_type;
typedef void arg3_type;
typedef void arg4_type;
typedef void arg5_type;
typedef void arg6_type;
typedef void arg7_type;
typedef void arg8_type;
typedef void arg9_type;
typedef void arg10_type;
const static unsigned long num_args = 1;
};
template <
typename T,
typename A1, typename A2
>
struct sig_traits<T (A1,A2)>
{
typedef T result_type;
typedef A1 arg1_type;
typedef A2 arg2_type;
typedef void arg3_type;
typedef void arg4_type;
typedef void arg5_type;
typedef void arg6_type;
typedef void arg7_type;
typedef void arg8_type;
typedef void arg9_type;
typedef void arg10_type;
const static unsigned long num_args = 2;
};
template <
typename T,
typename A1, typename A2, typename A3
>
struct sig_traits<T (A1,A2,A3)>
{
typedef T result_type;
typedef A1 arg1_type;
typedef A2 arg2_type;
typedef A3 arg3_type;
typedef void arg4_type;
typedef void arg5_type;
typedef void arg6_type;
typedef void arg7_type;
typedef void arg8_type;
typedef void arg9_type;
typedef void arg10_type;
const static unsigned long num_args = 3;
};
template <
typename T,
typename A1, typename A2, typename A3,
typename A4
>
struct sig_traits<T (A1,A2,A3,A4)>
{
typedef T result_type;
typedef A1 arg1_type;
typedef A2 arg2_type;
typedef A3 arg3_type;
typedef A4 arg4_type;
typedef void arg5_type;
typedef void arg6_type;
typedef void arg7_type;
typedef void arg8_type;
typedef void arg9_type;
typedef void arg10_type;
const static unsigned long num_args = 4;
};
template <
typename T,
typename A1, typename A2, typename A3,
typename A4, typename A5
>
struct sig_traits<T (A1,A2,A3,A4,A5)>
{
typedef T result_type;
typedef A1 arg1_type;
typedef A2 arg2_type;
typedef A3 arg3_type;
typedef A4 arg4_type;
typedef A5 arg5_type;
typedef void arg6_type;
typedef void arg7_type;
typedef void arg8_type;
typedef void arg9_type;
typedef void arg10_type;
const static unsigned long num_args = 5;
};
template <
typename T,
typename A1, typename A2, typename A3,
typename A4, typename A5, typename A6
>
struct sig_traits<T (A1,A2,A3,A4,A5,A6)>
{
typedef T result_type;
typedef A1 arg1_type;
typedef A2 arg2_type;
typedef A3 arg3_type;
typedef A4 arg4_type;
typedef A5 arg5_type;
typedef A6 arg6_type;
typedef void arg7_type;
typedef void arg8_type;
typedef void arg9_type;
typedef void arg10_type;
const static unsigned long num_args = 6;
};
template <
typename T,
typename A1, typename A2, typename A3,
typename A4, typename A5, typename A6,
typename A7
>
struct sig_traits<T (A1,A2,A3,A4,A5,A6,A7)>
{
typedef T result_type;
typedef A1 arg1_type;
typedef A2 arg2_type;
typedef A3 arg3_type;
typedef A4 arg4_type;
typedef A5 arg5_type;
typedef A6 arg6_type;
typedef A7 arg7_type;
typedef void arg8_type;
typedef void arg9_type;
typedef void arg10_type;
const static unsigned long num_args = 7;
};
template <
typename T,
typename A1, typename A2, typename A3,
typename A4, typename A5, typename A6,
typename A7, typename A8
>
struct sig_traits<T (A1,A2,A3,A4,A5,A6,A7,A8)>
{
typedef T result_type;
typedef A1 arg1_type;
typedef A2 arg2_type;
typedef A3 arg3_type;
typedef A4 arg4_type;
typedef A5 arg5_type;
typedef A6 arg6_type;
typedef A7 arg7_type;
typedef A8 arg8_type;
typedef void arg9_type;
typedef void arg10_type;
const static unsigned long num_args = 8;
};
template <
typename T,
typename A1, typename A2, typename A3,
typename A4, typename A5, typename A6,
typename A7, typename A8, typename A9
>
struct sig_traits<T (A1,A2,A3,A4,A5,A6,A7,A8,A9)>
{
typedef T result_type;
typedef A1 arg1_type;
typedef A2 arg2_type;
typedef A3 arg3_type;
typedef A4 arg4_type;
typedef A5 arg5_type;
typedef A6 arg6_type;
typedef A7 arg7_type;
typedef A8 arg8_type;
typedef A9 arg9_type;
typedef void arg10_type;
const static unsigned long num_args = 9;
};
template <
typename T,
typename A1, typename A2, typename A3,
typename A4, typename A5, typename A6,
typename A7, typename A8, typename A9,
typename A10
>
struct sig_traits<T (A1,A2,A3,A4,A5,A6,A7,A8,A9,A10)>
{
typedef T result_type;
typedef A1 arg1_type;
typedef A2 arg2_type;
typedef A3 arg3_type;
typedef A4 arg4_type;
typedef A5 arg5_type;
typedef A6 arg6_type;
typedef A7 arg7_type;
typedef A8 arg8_type;
typedef A9 arg9_type;
typedef A10 arg10_type;
const static unsigned long num_args = 10;
};
// ----------------------------------------------------------------------------------------
template <
typename function_type,
// These arguments are used to control the overloading. A user should
// not set with them.
typename Enabled = void,
unsigned long Num_args = sig_traits<function_type>::num_args
>
class any_function
{
private:
any_function() {}
/* !!!!!!!! ERRORS ON THE ABOVE LINE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
An error on this line means you are trying to use a function signature
with more than the supported number of arguments. The current version
of dlib only supports up to 10 arguments.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
};
// The following preprocessor commands build the various overloaded versions
// of any_function for different numbers of commands and void vs. non-void return
// types.
// 0 arguments
#define DLIB_ANY_FUNCTION_ARG_LIST
#define DLIB_ANY_FUNCTION_ARGS
#define DLIB_ANY_FUNCTION_NUM_ARGS 0
#include "any_function_impl2.h"
// 1 argument
#define DLIB_ANY_FUNCTION_ARG_LIST arg1_type a1
#define DLIB_ANY_FUNCTION_ARGS a1
#define DLIB_ANY_FUNCTION_NUM_ARGS 1
#include "any_function_impl2.h"
// 2 arguments
#define DLIB_ANY_FUNCTION_ARG_LIST arg1_type a1, arg2_type a2
#define DLIB_ANY_FUNCTION_ARGS a1,a2
#define DLIB_ANY_FUNCTION_NUM_ARGS 2
#include "any_function_impl2.h"
// 3 arguments
#define DLIB_ANY_FUNCTION_ARG_LIST arg1_type a1, arg2_type a2, arg3_type a3
#define DLIB_ANY_FUNCTION_ARGS a1,a2,a3
#define DLIB_ANY_FUNCTION_NUM_ARGS 3
#include "any_function_impl2.h"
// 4 arguments
#define DLIB_ANY_FUNCTION_ARG_LIST arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4
#define DLIB_ANY_FUNCTION_ARGS a1,a2,a3,a4
#define DLIB_ANY_FUNCTION_NUM_ARGS 4
#include "any_function_impl2.h"
// 5 arguments
#define DLIB_ANY_FUNCTION_ARG_LIST arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, \
arg5_type a5
#define DLIB_ANY_FUNCTION_ARGS a1,a2,a3,a4,a5
#define DLIB_ANY_FUNCTION_NUM_ARGS 5
#include "any_function_impl2.h"
// 6 arguments
#define DLIB_ANY_FUNCTION_ARG_LIST arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, \
arg5_type a5, arg6_type a6
#define DLIB_ANY_FUNCTION_ARGS a1,a2,a3,a4,a5,a6
#define DLIB_ANY_FUNCTION_NUM_ARGS 6
#include "any_function_impl2.h"
// 7 arguments
#define DLIB_ANY_FUNCTION_ARG_LIST arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, \
arg5_type a5, arg6_type a6, arg7_type a7
#define DLIB_ANY_FUNCTION_ARGS a1,a2,a3,a4,a5,a6,a7
#define DLIB_ANY_FUNCTION_NUM_ARGS 7
#include "any_function_impl2.h"
// 8 arguments
#define DLIB_ANY_FUNCTION_ARG_LIST arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, \
arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8
#define DLIB_ANY_FUNCTION_ARGS a1,a2,a3,a4,a5,a6,a7,a8
#define DLIB_ANY_FUNCTION_NUM_ARGS 8
#include "any_function_impl2.h"
// 9 arguments
#define DLIB_ANY_FUNCTION_ARG_LIST arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, \
arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8, \
arg9_type a9
#define DLIB_ANY_FUNCTION_ARGS a1,a2,a3,a4,a5,a6,a7,a8,a9
#define DLIB_ANY_FUNCTION_NUM_ARGS 9
#include "any_function_impl2.h"
// 10 arguments
#define DLIB_ANY_FUNCTION_ARG_LIST arg1_type a1, arg2_type a2, arg3_type a3, arg4_type a4, \
arg5_type a5, arg6_type a6, arg7_type a7, arg8_type a8, \
arg9_type a9, arg10_type a10
#define DLIB_ANY_FUNCTION_ARGS a1,a2,a3,a4,a5,a6,a7,a8,a9,a10
#define DLIB_ANY_FUNCTION_NUM_ARGS 10
#include "any_function_impl2.h"
// ----------------------------------------------------------------------------------------
template <typename function_type>
inline void swap (
any_function<function_type>& a,
any_function<function_type>& b
) { a.swap(b); }
// ----------------------------------------------------------------------------------------
template <typename T, typename function_type>
T& any_cast(any_function<function_type>& a) { return a.template cast_to<T>(); }
template <typename T, typename function_type>
const T& any_cast(const any_function<function_type>& a) { return a.template cast_to<T>(); }
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_AnY_FUNCTION_H__

View File

@ -0,0 +1,285 @@
// Copyright (C) 2011 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#undef DLIB_AnY_FUNCTION_ABSTRACT_H_
#ifdef DLIB_AnY_FUNCTION_ABSTRACT_H_
#include "any_abstract.h"
#include "../algs.h"
namespace dlib
{
// ----------------------------------------------------------------------------------------
template <
typename function_type
>
class any_function
{
/*!
REQUIREMENTS ON function_type
This type should be a function signature. Some examples are:
void (int,int) // a function returning nothing and taking two ints
void () // a function returning nothing and taking no arguments
char (double&) // a function returning a char and taking a reference to a double
The number of arguments in the function must be no greater than 10.
INITIAL VALUE
- is_empty() == true
- for all T: contains<T>() == false
WHAT THIS OBJECT REPRESENTS
This object is a version of dlib::any that is restricted to containing
elements which are some kind of function object with an operator() which
matches the function signature defined by function_type.
Here is an example:
#include <iostream>
#include <string>
#include "dlib/any.h"
using namespace std;
void print_message(string str) { cout << str << endl; }
int main()
{
dlib::any_function<void(string)> f;
f = print_message;
f("hello world"); // calls print_message("hello world")
}
Note that any_function objects can be used to store general function
objects (i.e. defined by a class with an overloaded operator()) in
addition to regular global functions.
!*/
public:
// This is the type of object returned by function_type functions.
typedef result_type_for_function_type result_type;
// Typedefs defining the argument types. If an argument does not exist
// then it is set to void.
typedef type_of_first_argument_in_funct_type arg1_type;
typedef type_of_second_argument_in_funct_type arg2_type;
...
typedef type_of_last_argument_in_funct_type arg10_type;
const static unsigned long num_args = total_number_of_non_void_arguments;
any_function(
);
/*!
ensures
- this object is properly initialized
!*/
any_function (
const any_function& item
);
/*!
ensures
- copies the state of item into *this.
- Note that *this and item will contain independent copies of the
contents of item. That is, this function performs a deep
copy and therefore does not result in *this containing
any kind of reference to item.
!*/
template < typename T >
any_function (
const T& item
);
/*!
ensures
- #contains<T>() == true
- #cast_to<T>() == item
(i.e. a copy of item will be stored in *this)
!*/
void clear (
);
/*!
ensures
- #*this will have its default value. I.e. #is_empty() == true
!*/
template <typename T>
bool contains (
) const;
/*!
ensures
- if (this object currently contains an object of type T) then
- returns true
- else
- returns false
!*/
bool is_empty(
) const;
/*!
ensures
- if (this object contains any kind of object) then
- returns true
- else
- returns false
!*/
result_type operator() (
) const;
/*!
requires
- is_empty() == false
- the signature defined by function_type takes no arguments
ensures
- Let F denote the function object contained within *this. Then
this function performs:
return F()
or if result_type is void then this function performs:
F()
!*/
result_type operator() (
const arg1_type& a1
) const;
/*!
requires
- is_empty() == false
- the signature defined by function_type takes one argument
ensures
- Let F denote the function object contained within *this. Then
this function performs:
return F(a1)
or if result_type is void then this function performs:
F(a1)
!*/
result_type operator() (
const arg1_type& a1,
const arg2_type& a2
) const;
/*!
requires
- is_empty() == false
- the signature defined by function_type takes two arguments
ensures
- Let F denote the function object contained within *this. Then
this function performs:
return F(a1,a2)
or if result_type is void then this function performs:
F(a1,a2)
!*/
/* !!!!!!!!! NOTE !!!!!!!!!
In addition to the above, operator() is defined for up to 10 arguments.
They are not listed here because it would clutter the documentation.
!!!!!!!!! NOTE !!!!!!!!! */
template <typename T>
T& cast_to(
);
/*!
ensures
- if (contains<T>() == true) then
- returns a non-const reference to the object contained within *this
- else
- throws bad_any_cast
!*/
template <typename T>
const T& cast_to(
) const;
/*!
ensures
- if (contains<T>() == true) then
- returns a const reference to the object contained within *this
- else
- throws bad_any_cast
!*/
template <typename T>
T& get(
);
/*!
ensures
- #is_empty() == false
- #contains<T>() == true
- if (contains<T>() == true)
- returns a non-const reference to the object contained in *this.
- else
- Constructs an object of type T inside *this
- Any previous object stored in this any_function object is destructed and its
state is lost.
- returns a non-const reference to the newly created T object.
!*/
any_function& operator= (
const any_function& item
);
/*!
ensures
- copies the state of item into *this.
- Note that *this and item will contain independent copies of the
contents of item. That is, this function performs a deep
copy and therefore does not result in *this containing
any kind of reference to item.
!*/
void swap (
any_function& item
);
/*!
ensures
- swaps *this and item
!*/
};
// ----------------------------------------------------------------------------------------
template <
typename function_type
>
inline void swap (
any_function<function_type>& a,
any_function<function_type>& b
) { a.swap(b); }
/*!
provides a global swap function
!*/
// ----------------------------------------------------------------------------------------
template <
typename T,
typename function_type
>
T& any_cast(
any_function<function_type>& a
) { return a.cast_to<T>(); }
/*!
ensures
- returns a.cast_to<T>()
!*/
// ----------------------------------------------------------------------------------------
template <
typename T,
typename function_type
>
const T& any_cast(
const any_function<function_type>& a
) { return a.cast_to<T>(); }
/*!
ensures
- returns a.cast_to<T>()
!*/
// ----------------------------------------------------------------------------------------
}
#endif // DLIB_AnY_FUNCTION_ABSTRACT_H_

View File

@ -0,0 +1,501 @@
// Copyright (C) 2011 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ANY_FUNCTION_RETURN
#error "You aren't supposed to directly #include this file. #include <dlib/any.h> instead."
#endif
#ifdef DLIB_ANY_FUNCTION_RETURN
// This file contains the body of the any_function class. We use the
// preprocessor to generate many different versions. There are
// versions which return a value and those which return void. For
// each of these types there are versions with differing numbers
// of arguments.
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;
}
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); }
/* !!!!!!!! ERRORS ON THE ABOVE LINE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
If you are getting an error on the above line then it means you
have attempted to call a dlib::any_function but you have supplied
arguments which don't match the function signature used by the
dlib::any_function.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
private:
void validate () const
{
// make sure requires clause is not broken
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 ( scoped_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 ( scoped_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 ( scoped_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 ( scoped_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 ( scoped_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 ( scoped_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 ( scoped_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 ( scoped_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 ( scoped_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 ( scoped_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 ( scoped_ptr<Tbase>& dest) const = 0;
};
typedef Tbase<function_type> base;
// -----------------------------------------------
// Some templates to help deal with the weirdness of storing C function types (rather than pointer to functions).
// Basically, we make sure things always get turned into function pointers even if the user gives a function reference.
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(const T& val) : item(copy(val)) {} \
virtual void copy_to ( scoped_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(); }
/* !!!!!!!! ERRORS ON THE ABOVE LINE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
If you are getting an error on the above line then it means you
have attempted to assign a function or function object to a
dlib::any_function but the signatures of the source and
destination functions don't match.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
};
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); }
/* !!!!!!!! ERRORS ON THE ABOVE LINE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
If you are getting an error on the above line then it means you
have attempted to assign a function or function object to a
dlib::any_function but the signatures of the source and
destination functions don't match.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
};
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); }
/* !!!!!!!! ERRORS ON THE ABOVE LINE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
If you are getting an error on the above line then it means you
have attempted to assign a function or function object to a
dlib::any_function but the signatures of the source and
destination functions don't match.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
};
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); }
/* !!!!!!!! ERRORS ON THE ABOVE LINE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
If you are getting an error on the above line then it means you
have attempted to assign a function or function object to a
dlib::any_function but the signatures of the source and
destination functions don't match.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
};
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); }
/* !!!!!!!! ERRORS ON THE ABOVE LINE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
If you are getting an error on the above line then it means you
have attempted to assign a function or function object to a
dlib::any_function but the signatures of the source and
destination functions don't match.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
};
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); }
/* !!!!!!!! ERRORS ON THE ABOVE LINE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
If you are getting an error on the above line then it means you
have attempted to assign a function or function object to a
dlib::any_function but the signatures of the source and
destination functions don't match.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
};
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); }
/* !!!!!!!! ERRORS ON THE ABOVE LINE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
If you are getting an error on the above line then it means you
have attempted to assign a function or function object to a
dlib::any_function but the signatures of the source and
destination functions don't match.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
};
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); }
/* !!!!!!!! ERRORS ON THE ABOVE LINE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
If you are getting an error on the above line then it means you
have attempted to assign a function or function object to a
dlib::any_function but the signatures of the source and
destination functions don't match.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
};
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); }
/* !!!!!!!! ERRORS ON THE ABOVE LINE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
If you are getting an error on the above line then it means you
have attempted to assign a function or function object to a
dlib::any_function but the signatures of the source and
destination functions don't match.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
};
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); }
/* !!!!!!!! ERRORS ON THE ABOVE LINE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
If you are getting an error on the above line then it means you
have attempted to assign a function or function object to a
dlib::any_function but the signatures of the source and
destination functions don't match.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
};
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); }
/* !!!!!!!! ERRORS ON THE ABOVE LINE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
If you are getting an error on the above line then it means you
have attempted to assign a function or function object to a
dlib::any_function but the signatures of the source and
destination functions don't match.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
};
scoped_ptr<base> data;
#endif // DLIB_ANY_FUNCTION_RETURN

View File

@ -0,0 +1,32 @@
// Copyright (C) 2011 Davis E. King (davis@dlib.net)
// License: Boost Software License See LICENSE.txt for the full license.
#ifndef DLIB_ANY_FUNCTION_ARG_LIST
#error "You aren't supposed to directly #include this file. #include <dlib/any.h> instead."
#endif
#ifdef DLIB_ANY_FUNCTION_ARG_LIST
// The case where function_type has a non-void return type
template <typename function_type, typename Enabled>
class any_function<function_type, Enabled, DLIB_ANY_FUNCTION_NUM_ARGS>
{
#define DLIB_ANY_FUNCTION_RETURN return
#include "any_function_impl.h"
#undef DLIB_ANY_FUNCTION_RETURN
};
// The case where function_type has a void return type
template <typename function_type>
class any_function<function_type, typename sig_traits<function_type>::type, DLIB_ANY_FUNCTION_NUM_ARGS>
{
#define DLIB_ANY_FUNCTION_RETURN
#include "any_function_impl.h"
#undef DLIB_ANY_FUNCTION_RETURN
};
#undef DLIB_ANY_FUNCTION_ARG_LIST
#undef DLIB_ANY_FUNCTION_ARGS
#undef DLIB_ANY_FUNCTION_NUM_ARGS
#endif // DLIB_ANY_FUNCTION_ARG_LIST