[range] Trying to make an "is_range" metafunction

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

[range] Trying to make an "is_range" metafunction

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

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [range] Trying to make an "is_range" metafunction

John Moeller
John Moeller <fishcorn <at> gmail.com> writes:

>
> 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

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [range] Trying to make an "is_range" metafunction

Noah Roberts
In reply to this post by John Moeller
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/metafunc/is_quantity_operand.hpp?view=markup

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...

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [range] Trying to make an "is_range" metafunction

Steven Watanabe-4
In reply to this post by 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

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [range] Trying to make an "is_range" metafunction

John Moeller
In reply to this post by John Moeller
John Moeller <fishcorn <at> gmail.com> writes:

> 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.

_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Reply | Threaded
Open this post in threaded view
|

Re: [range] Trying to make an

John Moeller
In reply to this post by Noah Roberts
Noah Roberts <roberts.noah <at> gmail.com> writes:

>
> 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:
> ...

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.


_______________________________________________
Boost-users mailing list
[hidden email]
http://lists.boost.org/mailman/listinfo.cgi/boost-users