Commit 8b656240 authored by Davis King's avatar Davis King

Added the DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST() macro and switched some

code over to use it.
parent 08f71653
...@@ -790,6 +790,51 @@ namespace dlib ...@@ -790,6 +790,51 @@ namespace dlib
template <long x, long y> template <long x, long y>
struct tmin<x,y,typename enable_if_c<(y < x)>::type> { const static long value = y; }; struct tmin<x,y,typename enable_if_c<(y < x)>::type> { const static long value = y; };
// ----------------------------------------------------------------------------------------
#define DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST(testname, returnT, funct_name, args) \
struct _two_bytes_##testname { char a[2]; }; \
template < typename T, returnT (T::*funct)args > \
struct _helper_##testname { typedef char type; }; \
template <typename T> \
char _has_##testname##_helper( typename _helper_##testname<T,&T::funct_name >::type ) { return 0;} \
template <typename T> \
_two_bytes_##testname _has_##testname##_helper(int) { return _two_bytes_##testname();} \
template <typename T> struct _##testname##workaroundbug { \
const static unsigned long U = sizeof(_has_##testname##_helper<T>('a')); }; \
template <typename T, unsigned long U = _##testname##workaroundbug<T>::U > \
struct testname { static const bool value = false; }; \
template <typename T> \
struct testname<T,1> { static const bool value = true; };
/*!A DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST
The DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST() macro is used to define traits templates
that tell you if a class has a certain member function. For example, to make a
test to see if a class has a public method with the signature void print(int) you
would say:
DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST(has_print, void, print, (int))
Then you can check if a class, T, has this method by looking at the boolean value:
has_print<T>::value
which will be true if the member function is in the T class.
Note that you can test for member functions taking no arguments by simply passing
in empty () like so:
DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST(has_print, void, print, ())
This would test for a member of the form:
void print().
To test for const member functions you would use a statement such as this:
DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST(has_print, void, print, ()const)
This would test for a member of the form:
void print() const.
To test for const templated member functions you would use a statement such as this:
DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST(has_print, void, template print<int>, ())
This would test for a member of the form:
template <typename T> void print().
!*/
// ---------------------------------------------------------------------------------------- // ----------------------------------------------------------------------------------------
/*!A is_function /*!A is_function
......
...@@ -59,46 +59,12 @@ namespace dlib ...@@ -59,46 +59,12 @@ namespace dlib
namespace impl namespace impl
{ {
template < DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST(
typename T, has_reject_labeling,
bool (T::*funct)(const typename T::sequence_type&, const matrix_exp<matrix<unsigned long> >&, unsigned long)const bool,
> template reject_labeling<matrix<unsigned long> >,
struct hrlh_helper (const typename T::sequence_type&, const matrix_exp<matrix<unsigned long> >&, unsigned long)const
{ );
typedef char type;
};
template <typename T>
char has_reject_labeling_helper( typename hrlh_helper<T,&T::template reject_labeling<matrix<unsigned long> > >::type = 0 ) { return 0;}
struct two_bytes
{
char a[2];
};
template <typename T>
two_bytes has_reject_labeling_helper(int) { return two_bytes();}
template <typename T>
struct work_around_visual_studio_bug
{
const static unsigned long U = sizeof(has_reject_labeling_helper<T>('a'));
};
// This is a template to tell you if a feature_extractor has a reject_labeling function or not.
template <typename T, unsigned long U = work_around_visual_studio_bug<T>::U >
struct has_reject_labeling
{
static const bool value = false;
};
template <typename T>
struct has_reject_labeling <T,1>
{
static const bool value = true;
};
template <typename feature_extractor, typename EXP, typename sequence_type> template <typename feature_extractor, typename EXP, typename sequence_type>
typename enable_if<has_reject_labeling<feature_extractor>,bool>::type call_reject_labeling_if_exists ( typename enable_if<has_reject_labeling<feature_extractor>,bool>::type call_reject_labeling_if_exists (
......
...@@ -13,6 +13,35 @@ namespace ...@@ -13,6 +13,35 @@ namespace
using namespace std; using namespace std;
dlib::logger dlog("test.is_same_object"); dlib::logger dlog("test.is_same_object");
DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST(has_booya_template, void, template booya<int>, (std::string)const);
DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST(has_funct_int, void, funct, (int));
DLIB_MAKE_HAS_MEMBER_FUNCTION_TEST(has_funct_double, void, funct, (double));
class htest
{
public:
template <typename EXP>
void booya(std::string) const {}
void funct(double) {}
};
class htest2
{
public:
void funct(int) {}
};
void test_metaprog()
{
DLIB_TEST(has_booya_template<htest>::value == true)
DLIB_TEST(has_booya_template<htest2>::value == false)
DLIB_TEST(has_funct_int<htest>::value == false)
DLIB_TEST(has_funct_int<htest2>::value == true)
DLIB_TEST(has_funct_double<htest>::value == true)
DLIB_TEST(has_funct_double<htest2>::value == false)
}
class is_same_object_tester : public tester class is_same_object_tester : public tester
{ {
...@@ -79,6 +108,7 @@ namespace ...@@ -79,6 +108,7 @@ namespace
go2<false>(sd, sd2); go2<false>(sd, sd2);
go2<false>(sb, sd); go2<false>(sb, sd);
test_metaprog();
} }
}; };
......
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