simple duck detecor components pass unit test
This commit is contained in:
parent
8777aa585a
commit
e27d03c501
3 changed files with 107 additions and 66 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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> );
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue