[range] Trying to make an "is_range" metafunction

Hello all, I am trying to make an "is_range" metafunction that (essentially) returns mpl::true_ when the template parameter is a range (as defined by the boost::range library). I can do this if I create a specialization for every "non-range" type currently specialized by the library (such as built-in arrays, char strings, etc.). However, I'd like to have is_range work for a user-defined range without the user *also* needing to specialize is_range. I tried something like this: ////////////////////////////////////////////////////////////////////// BOOST_MPL_HAS_XXX_TRAIT_DEF(type) template < bool B > struct is_range_impl : boost::mpl::false_ {}; template <> struct is_range_impl< true > : boost::mpl::true_ {}; template < typename R > struct is_range : is_range_impl< has_type< boost::range_iterator< R > >::value > {}; ////////////////////////////////////////////////////////////////////// Which does fine if R is a range (even when you use the non-intrinsic method of defining a custom class as a range), but if R is *not* a range, the compiler complains that "iterator" is not a member of the class that I'm passing as the parameter, because it defaults to using the embedded "iterator" type in the parameter. Is there a better way to define is_range so that it will work? I imagine that I'd have to use SFINAE somehow, but I can't quite see how to put it together. Many thanks ahead of time, -- John Moeller

John Moeller
Hello all,
I am trying to make an "is_range" metafunction that (essentially) returns mpl::true_ when the template parameter is a range (as defined by the boost::range library).
I can do this if I create a specialization for every "non-range" type currently specialized by the library (such as built-in arrays, char strings, etc.). However, I'd like to have is_range work for a user-defined range without the user *also* needing to specialize is_range.
I tried something like this:
////////////////////////////////////////////////////////////////////// BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
template < bool B > struct is_range_impl : boost::mpl::false_ {};
template <> struct is_range_impl< true > : boost::mpl::true_ {};
template < typename R > struct is_range : is_range_impl< has_type< boost::range_iterator< R > >::value > {}; //////////////////////////////////////////////////////////////////////
Which does fine if R is a range (even when you use the non-intrinsic method of defining a custom class as a range), but if R is *not* a range, the compiler complains that "iterator" is not a member of the class that I'm passing as the parameter, because it defaults to using the embedded "iterator" type in the parameter.
Is there a better way to define is_range so that it will work? I imagine that I'd have to use SFINAE somehow, but I can't quite see how to put it together.
Many thanks ahead of time,
--
John Moeller
I figured out how to do it (and it's pretty simple): template < typename R, typename V = void > struct is_range_impl : boost::mpl::false_ {}; template < typename R > struct is_range_impl< R, boost::range_iterator< R > > : boost::mpl::true_ {}; template < typename R > struct is_range : is_range_impl< R > {}; Feel free to pick this apart; I wouldn't mind if it were made better. Thanks, -- John Moeller

AMDG John Moeller wrote:
I figured out how to do it (and it's pretty simple):
template < typename R, typename V = void > struct is_range_impl : boost::mpl::false_ {};
template < typename R > struct is_range_impl< R, boost::range_iterator< R > > : boost::mpl::true_ {};
template < typename R > struct is_range : is_range_impl< R > {};
Feel free to pick this apart; I wouldn't mind if it were made better.
Won't this always be false? In Christ, Steven Watanabe

John Moeller
I figured out how to do it (and it's pretty simple): ...
Feel free to pick this apart; I wouldn't mind if it were made better.
Thanks,
--
John Moeller
This didn't actually work. Sorry for the noise.

John Moeller wrote:
Hello all,
I am trying to make an "is_range" metafunction that (essentially) returns mpl::true_ when the template parameter is a range (as defined by the boost::range library).
I can do this if I create a specialization for every "non-range" type currently specialized by the library (such as built-in arrays, char strings, etc.). However, I'd like to have is_range work for a user-defined range without the user *also* needing to specialize is_range.
Maybe try something like this: http://unitlib.svn.sourceforge.net/viewvc/unitlib/trunk/include/unitlib/meta... Using techniques like that you should be able to generate a metafunction that will check if an object instantiates a concept by checking all it's public interface functions, types, etc...

Noah Roberts
John Moeller wrote:
Hello all,
I am trying to make an "is_range" metafunction that (essentially) returns mpl::true_ when the template parameter is a range (as defined by the boost::range library).
I can do this if I create a specialization for every "non-range" type
specialized by the library (such as built-in arrays, char strings, etc.). However, I'd like to have is_range work for a user-defined range without
currently the
user *also* needing to specialize is_range.
Maybe try something like this: ...
Well, it didn't solve my problem (I don't think there is a solution), but it makes the alternative more compact. Thanks for the advice.
participants (3)
-
John Moeller
-
Noah Roberts
-
Steven Watanabe