C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

supports_syntax facility, does this code really work?

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated)
View previous topic :: View next topic  
Author Message
Howard Gardner
Guest





PostPosted: Tue Jul 11, 2006 2:37 am    Post subject: supports_syntax facility, does this code really work? Reply with quote



/*

This program exercises the facility supports_syntax, which
would be handy to use in conjuntion with boost::enable_if.

supports_syntax< SUBJECT, SYNTAX >::value is true if and
only if SUBJECT supports the syntax that SYNTAX checks for.

There are no requirements on SUBJECT. SYNTAX must be
written carefully. This program demonstrates checking
for a member type, a member variable, a member function,
and a nonmember function. The example syntax here is
deliberately minimal. I've tried some more complex
syntax: sometimes I've gotten it to work, and sometimes
I haven't.

I arrived at this implementation through a little research
(sizeof trick, SFINAE) and heroic quantities of experiment.

This code would be very useful(!) in template metaprogramming,
but I'm afraid of it. Since I arrived at it through experiment,
it's quite possible that it just exploits bugs in the compiler
that I'm using. I keep trying to make simplifications that
break it, so there are certainly things about it that I don't
understand.

I'll give the two big mysteries names:

1) syntax dummy parameter

All of the syntax checks are template classes taking one
template parameter, which is a dummy. If I take this dummy
parameter away from syntax_member_type, the code still works.
If I take it away from syntax_member_variable,
syntax_member_function, or syntax_nonmember_function, though,
the code breaks.

2) nonmember_function double overload

Why do I have to supply TWO overloads of nonmember function?
If I supply only one, the code breaks.

*/

#include <fstream>
using std::cout;
using std::endl;

// An empty class to be used as a dummy type
struct
dummy
{
};

// Another empty class to be used as a dummy type
struct
another_dummy
{
};

// An empty class that has none of the syntax I'm checking for
struct
has_nothing
{
};

// A class that defines a type
struct
has_member_type
{
typedef
int
member_type;
};

// Checks that a type is defined
template< typename xDummy = dummy >
// syntax dummy parameter - take this away, still works
struct
syntax_member_type
{
template
<
typename xSubject,
typename = typename xSubject::member_type
Quote:

struct match;

};

// A class that has a member variable
struct
has_member_variable
{
int
member_variable;
};

// Checks for a member variable
template< typename xDummy = dummy >
// syntax dummy parameter - take this away, breaks code
struct
syntax_member_variable
{
template
<
typename xSubject,
int (xSubject::*) = &xSubject::member_variable
Quote:

struct match;

};

// A class that has a member function
struct
has_member_function
{
void
member_function();
};

// Checks for a member function
template< typename xDummy = dummy >
// syntax dummy parameter - take this away, breaks code
struct
syntax_member_function
{
template
<
typename xSubject,
void (xSubject::*)() = &xSubject::member_function
Quote:

struct match;

};

// A class that is used as a parameter for
// a nonmember function
struct
has_nonmember_function
{
};

void
nonmember_function(has_nonmember_function);

// Checks for a nonmember function
void
nonmember_function(dummy);

void
nonmember_function(another_dummy);

/*
nonmember_function overload - there have to be at least two
overloads of nonmember function or the code breaks. As it
sits, there are three. I can take one of them away and all
is well. If I take two of them away, the code breaks.
*/

template< typename xDummy = dummy >
// syntax dummy parameter - take this away, breaks code
struct
syntax_nonmember_function
{
template
<
typename xSubject,
void (*)( xSubject ) = nonmember_function
Quote:

struct match;

};

// The engine
template< typename xSubject, typename xSyntax >
struct supports_syntax
{
private:

// yes and no are guaranteed to have different sizes
typedef
char
yes;

class
no
{
yes c[2];
};

// Return a yes if there is a match
template< typename uxSubject >
static
yes
func
(
typename xSyntax::template match< uxSubject > *
);

// Return a no if there is no match
template< typename uxSubject >
static
no
func
(
...
);

public:

static
const bool
value
= ( sizeof( func< xSubject >( 0 ) ) == sizeof( yes ) );
};

int
main()
{
// Member type
cout
<< supports_syntax
<
has_member_type, syntax_member_type< >
Quote:

::value

<< endl;

cout
<< supports_syntax
<
has_nothing,
syntax_member_type< >
Quote:

::value

<< endl;

// Member variable
cout
<< supports_syntax
<
has_member_variable,
syntax_member_variable< >
Quote:

::value

<< endl;

cout
<< supports_syntax
<
has_nothing,
syntax_member_variable< >
Quote:

::value

<< endl;

// Member function
cout
<< supports_syntax
<
has_member_function,
syntax_member_function< >
Quote:

::value

<< endl;

cout
<< supports_syntax
<
has_nothing,
syntax_member_function< >
Quote:

::value

<< endl;

// Non member function
cout
<< supports_syntax
<
has_nonmember_function,
syntax_nonmember_function< >
Quote:

::value

<< endl;

cout
<< supports_syntax
<
has_nothing,
syntax_nonmember_function< >
Quote:

::value

<< endl;
}

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ Language (Moderated) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.