[MPL] implementing a "trait"?

I want to mark certain types as being of a category of my invention (e.g. is_pretty), for purposes of using enable_if in the same manner is standard type traits such as is_arithmetic etc. The trait will be false by default, and I'd declare something to nominate types that should be seen to have that trait. I want it to follow inheritance; if B has been declared to be in my category, and C is derived from B, then C will also be in that category without needing to do anything more (though some way to turn it _off_ would be available). Can someone advise me on an easy way to structure this? Thanks, —John

namespace john {
template <typename T>
struct is_pretty : boost::false_type {};
template <>
struct is_pretty<foo> : boost::true_type {};
template <>
struct is_pretty<bar> : boost::true_type {};
// ...
}
BOOST_MPL_ASSERT((john::is_pretty<foo>));
BOOST_MPL_ASSERT((john::is_pretty<bar>));
Regards,
Rodrigo Madera
On Tue, Feb 4, 2014 at 4:03 PM, John M. Dlugosz
I want to mark certain types as being of a category of my invention (e.g. is_pretty), for purposes of using enable_if in the same manner is standard type traits such as is_arithmetic etc.
The trait will be false by default, and I'd declare something to nominate types that should be seen to have that trait. I want it to follow inheritance; if B has been declared to be in my category, and C is derived from B, then C will also be in that category without needing to do anything more (though some way to turn it _off_ would be available).
Can someone advise me on an easy way to structure this?
Thanks, --John
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

On 2/4/2014 12:24 PM, Rodrigo Madera wrote:
namespace john { template <typename T> struct is_pretty : boost::false_type {};
template <> struct is_pretty<foo> : boost::true_type {};
template <> struct is_pretty<bar> : boost::true_type {};
// ... }
That's pretty much what I started with, but it doesn't handle automatic inheritance as the main template is used for anything not exactly specialized. And I don't like that it would require specializing a template in another namespace, which is awkward at best.

On Tue, Feb 4, 2014 at 4:44 PM, John M. Dlugosz
That's pretty much what I started with, but it doesn't handle automatic inheritance as the main template is used for anything not exactly specialized.
I see. Maybe if you provide the code you have so far, it could bring more light. I'm curious on the "turning it off" part.
And I don't like that it would require specializing a template in another namespace, which is awkward at best.
That's only my preference. There is no need to have one. Regards, Rodrigo Madera

John M. Dlugosz schreef op 04-Feb-14 7:03 PM:
I want to mark certain types as being of a category of my invention (e.g. is_pretty), for purposes of using enable_if in the same manner is standard type traits such as is_arithmetic etc.
The trait will be false by default, and I'd declare something to nominate types that should be seen to have that trait. I want it to follow inheritance; if B has been declared to be in my category, and C is derived from B, then C will also be in that category without needing to do anything more (though some way to turn it _off_ would be available).
I use typedef void has_some_interface; inside the class to identify that a class implements some interface. I could write out a global test template and specialization to do facilitate the checking, but I prefer the macro #define ASSERT_PROVIDES_INTERFACE( T, V ) \ template< class t, class x = void > struct V \ { static constexpr bool value = false; }; \ template< class t > struct V< t, typename t::V > \ { static constexpr bool value = true; }; \ static_assert( \ V< T >::value, \ "the " #T " template argument doesn't provide " #V \ ); (the \'s line up in a non-proporitionally font) which writes them 'locally'. Use it like this: struct implements_some_interface { typedef void has_some_interface; . . . }; template< class t > class uses_some_interface { ASSERT_PROVIDES_INTERFACE( t, some_interface ); . . . }; The error message issued by GCC when the feature id type is not provided is reasonably close to the top of the error list. In practice I write the identification type in an 'archetype' class that serves to identify the interface elements that an real implementation must provide (sort of an abstract base class, but for compile-time inheritance): struct char_out_channel_archetype { typedef void has_char_out_channel; static void put( char c ); }; struct char_in_channel_archetype { typedef void has_char_in_channel; static char get( ); }; struct uart : public char_out_channel_archetype, public char_in_channel_archetype { static void put( char c ){ . . . } static char get(){ . . . } }; A pity that I can't use 'override' to make sure that the implementations realy override a declaration in a base class, that works only for non-static methods. (WHY??) Wouter van Ooijen

On 2/4/2014 12:52 PM, Wouter van Ooijen wrote:
I use
typedef void has_some_interface;
inside the class to identify that a class implements some interface.
That's the kind I was looking for; thanks.
In practice I write the identification type in an 'archetype'
I see that the archetype provides the typedef, but what's the point of the static functions? You have to use the actual concrete type to call the right function, so having them declared in the base class doesn't let you use them in the manner of a virtual function.

On 5/02/2014 20:57, Quoth John M. Dlugosz:
I see that the archetype provides the typedef, but what's the point of the static functions? You have to use the actual concrete type to call the right function, so having them declared in the base class doesn't let you use them in the manner of a virtual function.
It's not completely silly; given a static method A::F and a class B that derives from A, then attempting to call B::F will end up calling A::F if B does not define its own function that hides that. (And in this context, the base method presumably asserts or something.) Most compilers will generate a warning with this usage, though, so it's not really considered good style.

John M. Dlugosz
The trait will be false by default, and I'd declare something to nominate types that should be seen to have that trait. I want it to follow inheritance; if B has been declared to be in my category, and C is derived from B, then C will also be in that category without needing to do anything more (though some way to turn it _off_ would be available).
This may or may not be what you're looking for:
#include

-----Original Message-----
From: Boost-users [mailto:boost-users-bounces@lists.boost.org] On Behalf Of John M. Dlugosz
I want to mark certain types as being of a category of my invention (e.g. is_pretty), for purposes of using enable_if in the same manner is standard type traits such as is_arithmetic etc.
The trait will be false by default, and I'd declare something to nominate types that should be seen to have that trait. I want it to follow inheritance; if B has been declared to be in my category, and C is derived from B, then C will also be in that category without needing to do anything more (though some way to turn it _off_ would be available).
-----End Original Message-----
The following works for me, but I am not sure if it is because of a working or a failing compiler:
Best wishes, Alex
#include <iostream>
#include <string>
#include

-----Original Message-----
From: Boost-users [mailto:boost-users-bounces@lists.boost.org] On Behalf Of
Alex
Sent: 07 February 2014 18:48
To: boost-users@lists.boost.org
Subject: Re: [Boost-users] [MPL] implementing a "trait"?
-----Original Message-----
From: Boost-users [mailto:boost-users-bounces@lists.boost.org] On Behalf Of
John M. Dlugosz
I want to mark certain types as being of a category of my invention (e.g.
is_pretty), for purposes of using enable_if in the same manner is standard
type traits such as is_arithmetic etc.
The trait will be false by default, and I'd declare something to nominate
types that should be seen to have that trait. I want it to follow
inheritance; if B has been declared to be in my category, and C is derived
from B, then C will also be in that category without needing to do anything
more (though some way to turn it _off_ would be available).
-----End Original Message-----
Now have a simpler solution:
#include <iostream>
#include

On 2/8/2014 11:44 AM, Alex wrote:
Now have a simpler solution: // use this struct to "read" the traits from the functions template<class T> struct trait { typedef decltype(is_pretty_function(std::declval
())) is_pretty; };
Nice! These things are getting easier with newer compiler features.
participants (6)
-
Alex
-
Gavin Lambert
-
John M. Dlugosz
-
Louis Dionne
-
Rodrigo Madera
-
Wouter van Ooijen