simple duck detecor components pass unit test

This commit is contained in:
Fischlurch 2010-01-02 09:07:10 +01:00
parent 8777aa585a
commit e27d03c501
3 changed files with 107 additions and 66 deletions

View file

@ -89,57 +89,85 @@ namespace lib {
namespace meta {
/////////////////////////////TODO: still hard wired for a first test....
template<typename TY>
class DetectNested
{
template<class X>
static Yes_t check(typename X::Core *);
template<class>
static No_t check(...);
public:
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0)));
};
template<typename TY>
class DetectMember
{
template<typename X, int i = sizeof(&X::honk)>
struct Probe
{ };
template<class X>
static Yes_t check(Probe<X>*);
template<class>
static No_t check(...);
public:
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0)));
};
template<typename TY>
class DetectFunSig
{
template<typename X, X& (X::*)(void)>
struct Probe
{ };
template<class X>
static Yes_t check(Probe<X,&X::honk>*);
template<class>
static No_t check(...);
public:
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0)));
};
} // namespace meta
} // namespace lib
/** Detector for a nested type.
* Defines a metafunction (template), allowing to detect
* if a type TY in question has a nested type or typedef
* with the given name. To answer this question, instantiate
* resulting HasNested_XXX template with the type in question
* and check the static bool value field.
*/
#define META_DETECT_NESTED(_TYPE_) \
template<typename TY> \
class HasNested_##_TYPE_ \
{ \
\
template<class X> \
static Yes_t check(typename X::_TYPE_ *); \
template<class> \
static No_t check(...); \
\
public: \
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
};
/** Detector for a nested member (field or function).
* Defines a metafunction (template), allowing to detect
* the presence of a member with the given name within
* a type in question.
*/
#define META_DETECT_MEMBER(_NAME_) \
template<typename TY> \
class HasMember_##_NAME_ \
{ \
template<typename X, int i = sizeof(&X::_NAME_)> \
struct Probe \
{ }; \
\
template<class X> \
static Yes_t check(Probe<X> * ); \
template<class> \
static No_t check(...); \
\
public: \
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
};
/** Detector for a specific member function.
* Defines a metafunction (template), allowing to detect
* the presence of a member function with the specific
* signature, as defined by the parameters. Note this
* check will probably fail if there are overloads
*/
#define META_DETECT_FUNCTION(_RET_TYPE_,_FUN_NAME_,_ARGS_) \
template<typename TY> \
class HasFunSig_##_FUN_NAME_ \
{ \
template<typename X, _RET_TYPE_ (X::*)_ARGS_> \
struct Probe \
{ }; \
\
template<class X> \
static Yes_t check(Probe<X, &X::_FUN_NAME_> * ); \
template<class> \
static No_t check(...); \
\
public: \
static const bool value = (sizeof(Yes_t)==sizeof(check<TY>(0))); \
};
#endif

View file

@ -182,7 +182,13 @@ return: 0
END
PLANNED "Duck typing support" DuckDetector_test <<END
TEST "Duck typing support" DuckDetector_test <<END
out: HasNested_Core<PropperGander> : Yes
out: HasNested_Core<Propaganda> : No
out: HasMember_honk<PropperGander> : Yes
out: HasMember_honk<Propaganda> : Yes
out: HasFunSig_honk<PropperGander> : Yes
out: HasFunSig_honk<Propaganda> : No
return: 0
END

View file

@ -23,7 +23,7 @@
#include "lib/test/run.hpp"
#include "lib/meta/duck-detector.hpp"
#include "lib/util.hpp" /////////////TODO
#include "lib/util.hpp"
#include <iostream>
@ -31,30 +31,33 @@
namespace lib {
namespace meta{
namespace test{
//using std::string;
using std::cout;
using std::endl;
namespace { // some test ducks....
struct PropperGander
{
class Core;
PropperGander& honk();
PropperGander& honk (long,long);
};
struct Propaganda
{
void honk();
void honk(float);
};
#define DO_CHECK(_EXPR_) cout << STRINGIFY(_EXPR_) << "\t = " << _EXPR_::value << endl;
}//(End) with test ducks
#define SHOW_CHECK(_EXPR_) cout << STRINGIFY(_EXPR_) << "\t : " << (_EXPR_::value? "Yes":"No") << endl;
/***********************************************************************************
* @test verify building predicates to detect properties of a type at compile time.
@ -65,19 +68,23 @@ namespace test{
*/
class DuckDetector_test : public Test
{
META_DETECT_NESTED(Core);
META_DETECT_MEMBER(honk);
META_DETECT_FUNCTION(PropperGander&, honk, (long,long));
void
run (Arg)
{
DO_CHECK( DetectNested<PropperGander> );
DO_CHECK( DetectNested<Propaganda> );
SHOW_CHECK( HasNested_Core<PropperGander> );
SHOW_CHECK( HasNested_Core<Propaganda> );
DO_CHECK( DetectMember<PropperGander> );
DO_CHECK( DetectMember<Propaganda> );
SHOW_CHECK( HasMember_honk<PropperGander> );
SHOW_CHECK( HasMember_honk<Propaganda> );
DO_CHECK( DetectFunSig<PropperGander> );
DO_CHECK( DetectFunSig<Propaganda> );
UNIMPLEMENTED ("detect the propaganda");
SHOW_CHECK( HasFunSig_honk<PropperGander> );
SHOW_CHECK( HasFunSig_honk<Propaganda> );
}
};