[mpl] Is it possible to mpl_assert depending on the derivation of a class

Hello all, I want some template code to assert if the passed in template type is NOT derived from a particular base class. I've looked through the Template Metaprogamming book, but haven't seen anything that can do this, but I seem to remember something along those lines. Can anyone help? James This message (including any attachments) contains confidential and/or proprietary information intended only for the addressee. Any unauthorized disclosure, copying, distribution or reliance on the contents of this information is strictly prohibited and may constitute a violation of law. If you are not the intended recipient, please notify the sender immediately by responding to this e-mail, and delete the message from your system. If you have any questions about this e-mail please notify the sender immediately.

Hughes, James wrote:
Hello all,
I want some template code to assert if the passed in template type is NOT derived from a particular base class.
I've looked through the Template Metaprogamming book, but haven't seen anything that can do this, but I seem to remember something along those lines.
Can anyone help?
James
Hi James, the easiest way is something like the following: #include <boost/type_traits.hpp> #include <boost/static_assert.hpp> BOOST_STATIC_ASSERT (boost::is_base_of<Base, Derived>::value); Hope this helps, Martin

Hughes, James wrote:
Hello all,
I want some template code to assert if the passed in template type is NOT derived from a particular base class.
I've looked through the Template Metaprogamming book, but haven't seen anything that can do this, but I seem to remember something along those lines.
Can anyone help?
James
Hi James,
the easiest way is something like the following:
#include <boost/type_traits.hpp> #include <boost/static_assert.hpp>
BOOST_STATIC_ASSERT (boost::is_base_of<Base, Derived>::value);
Hope this helps,
Martin
Thanks Martin - I knew I had seen it somewhere. That covers the first point, but I've just realised I need to be a bit cleverer. The incoming type can either be the type itself or a pointer to the type, or a boost::shared_ptr to the type, and the type must be derived as the original question. Depending on which it is I need to do slightly different things, so I need to, effectively, conditionally compile a bit of code depending on the results of the tests, or assert if the type (after getting rid of the pointer/shared point bit) isn't derived from my base class. Basically I'm iterating through a vector of the incoming type and calling a function in the type stored. That function comes from the base class, but in order to be really generic I need to handle the shared_ptr and pointer cases. I think I need mpl for that, but I only get to chapter three of the book before my head starts to hurt. Any ideas/hints/places I can look? James This message (including any attachments) contains confidential and/or proprietary information intended only for the addressee. Any unauthorized disclosure, copying, distribution or reliance on the contents of this information is strictly prohibited and may constitute a violation of law. If you are not the intended recipient, please notify the sender immediately by responding to this e-mail, and delete the message from your system. If you have any questions about this e-mail please notify the sender immediately.

Hi James,
the easiest way is something like the following:
#include <boost/type_traits.hpp> #include <boost/static_assert.hpp>
BOOST_STATIC_ASSERT (boost::is_base_of<Base, Derived>::value);
Hope this helps,
Martin
Thanks Martin - I knew I had seen it somewhere.
That covers the first point, but I've just realised I need to be a bit cleverer. The incoming type can either be the type itself or a pointer to the type, or a boost::shared_ptr to the type, and the type must be derived as the original question. Depending on which it is I need to do slightly different things, so I need to, effectively, conditionally compile a bit of code depending on the results of the tests, or assert if the type (after getting rid of the pointer/shared point bit) isn't derived from my base class.
Basically I'm iterating through a vector of the incoming type and calling a function in the type stored. That function comes from the base class, but in order to be really generic I need to handle the shared_ptr and pointer cases.
I think I need mpl for that, but I only get to chapter three of the book before my head starts to hurt. Any ideas/hints/places I can look?
I'm not sure if you really need mpl to do this. To me it looks as if you need one template and multiple partial specialization, something like the following: template<typename T> class Handler { public: void doIt (T val) { .... // default implementation } }; template<typename T> class Handler<boost::shared_ptr<T> > { public: void doIt (boost::shared_ptr<T> val) { ... // Impl for shared_ptr } template <typename T> class Handler<T*> .... Hope this helps, Martin

On 8/21/07, Martin Apel <martin.apel@simpack.de> wrote:
Hi James,
the easiest way is something like the following:
#include <boost/type_traits.hpp> #include <boost/static_assert.hpp>
BOOST_STATIC_ASSERT (boost::is_base_of<Base, Derived>::value);
Hope this helps,
Martin
Thanks Martin - I knew I had seen it somewhere.
That covers the first point, but I've just realised I need to be a bit cleverer. The incoming type can either be the type itself or a pointer to the type, or a boost::shared_ptr to the type, and the type must be derived as the original question. Depending on which it is I need to do slightly different things, so I need to, effectively, conditionally compile a bit of code depending on the results of the tests, or assert if the type (after getting rid of the pointer/shared point bit) isn't derived from my base class.
Basically I'm iterating through a vector of the incoming type and calling a function in the type stored. That function comes from the base class, but in order to be really generic I need to handle the shared_ptr and pointer cases.
I think I need mpl for that, but I only get to chapter three of the book before my head starts to hurt. Any ideas/hints/places I can look?
I'm not sure if you really need mpl to do this. To me it looks as if you need one template and multiple partial specialization, something like the following:
template<typename T> class Handler { public: void doIt (T val) { .... // default implementation } };
template<typename T> class Handler<boost::shared_ptr<T> > { public: void doIt (boost::shared_ptr<T> val) { ... // Impl for shared_ptr }
template <typename T> class Handler<T*> ....
Hope this helps,
Martin
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Actually you can use only one Handler class and some templated function overloads: template<class Base> class Hanlder { template<class Derived> void do_it(T const& t, typename boost::enable_if< boost::is_base_of<Base, T> >::type*=0) { //do smth. } template<class Derived> void do_it(boost::shared_ptr<T> t, typename boost::enable_if< boost::is_base_of<Base, T> >::type*=0) { //do smth. } .... };

Hi James, >> the easiest way is something like the following: >> >> #include <boost/type_traits.hpp> >> #include <boost/static_assert.hpp> >> >> BOOST_STATIC_ASSERT (boost::is_base_of<Base, Derived>::value); >> >> Hope this helps, >> >> Martin >> > > Thanks Martin - I knew I had seen it somewhere. > > That covers the first point, but I've just realised I need to be a bit > cleverer. The incoming type can either be the type itself or a pointer > to the type, or a boost::shared_ptr to the type, and the type must be > derived as the original question. Depending on which it is I need to do > slightly different things, so I need to, effectively, conditionally > compile a bit of code depending on the results of the tests, or assert > if the type (after getting rid of the pointer/shared point bit) isn't > derived from my base class. > > Basically I'm iterating through a vector of the incoming type and > calling a function in the type stored. That function comes from the base > class, but in order to be really generic I need to handle the shared_ptr > and pointer cases. > > I think I need mpl for that, but I only get to chapter three of the book > before my head starts to hurt. Any ideas/hints/places I can look? > > I'm not sure if you really need mpl to do this. To me it looks as if you need one template and multiple partial specialization, something like the following: template<typename T> class Handler { public: void doIt (T val) { .... // default implementation } }; template<typename T> class Handler<boost::shared_ptr<T> > { public: void doIt (boost::shared_ptr<T> val) { ... // Impl for shared_ptr } template <typename T> class Handler<T*> .... Hope this helps, Martin _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users Actually you can use only one Handler class and some templated function overloads: template<class Base> class Hanlder { template<class Derived> void do_it(T const& t, typename boost::enable_if< boost::is_base_of<Base, T> >::type*=0) { //do smth. } template<class Derived> void do_it(boost::shared_ptr<T> t, typename boost::enable_if< boost::is_base_of<Base, T> >::type*=0) { //do smth. } .... }; Thanks Martin and Ovanes, I think you have put me on the right track there. Much appreciated. James This message (including any attachments) contains confidential and/or proprietary information intended only for the addressee. Any unauthorized disclosure, copying, distribution or reliance on the contents of this information is strictly prohibited and may constitute a violation of law. If you are not the intended recipient, please notify the sender immediately by responding to this e-mail, and delete the message from your system. If you have any questions about this e-mail please notify the sender immediately.

Actually you can use only one Handler class and some templated function overloads: template<class Base> class Hanlder { template<class Derived> void do_it(T const& t, typename boost::enable_if< boost::is_base_of<Base, T> >::type*=0) { //do smth. } template<class Derived> void do_it(boost::shared_ptr<T> t, typename boost::enable_if< boost::is_base_of<Base, T> >::type*=0) { //do smth. } .... }; Thanks Martin and Ovanes, I think you have put me on the right track there. Much appreciated. James Just a quick addendum to this. I tried out a combination of the two - using a BOOST_STATIC_ASSERT((boost::is_base_of<Base, T> >::value)) inside the do_it function described above, and found what I thought was odd behaviour with is_base_of. The following excerpt shows the behaviour class A {}; class B : public A {}; typedef A C; BOOST_STATIC_ASSERT((boost::is_base_of<A,B> >::value)) // this passes BOOST_STATIC_ASSERT((boost::is_base_of<A,C> >::value)) // this fails I would expect both to pass, as is_base_of should return true when both parameters are the same, and I thought that typedef did make classes the same/equivalent http://www.boost.org/doc/html/boost_typetraits/reference.html#boost_type traits.is_base_of Is there something I am missing about typedef? Or is boost::is_base_of unable to handles the aliasing? James This message (including any attachments) contains confidential and/or proprietary information intended only for the addressee. Any unauthorized disclosure, copying, distribution or reliance on the contents of this information is strictly prohibited and may constitute a violation of law. If you are not the intended recipient, please notify the sender immediately by responding to this e-mail, and delete the message from your system. If you have any questions about this e-mail please notify the sender immediately.

Hughes, James wrote:
Just a quick addendum to this. I tried out a combination of the two - using a BOOST_STATIC_ASSERT((boost::is_base_of<Base, T> >::value)) inside the do_it function described above, and found what I thought was odd behaviour with is_base_of.
The following excerpt shows the behaviour
class A {};
class B : public A {};
typedef A C;
BOOST_STATIC_ASSERT((boost::is_base_of<A,B> >::value)) // this passes
BOOST_STATIC_ASSERT((boost::is_base_of<A,C> >::value)) // this fails
I would expect both to pass, as is_base_of should return true when both parameters are the same, and I thought that typedef did make classes the same/equivalent
http://www.boost.org/doc/html/boost_typetraits/reference.html#boost_typetrai...
Is there something I am missing about typedef? Or is boost::is_base_of unable to handles the aliasing?
James
Hi James, I tried this with GCC 4.2 and 3.4.6 under Linux. It passes for both cases. So it might be your compiler, which is doing something wrong. Martin

-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Martin Apel Sent: 21 August 2007 15:00 To: boost-users@lists.boost.org Subject: Re: [Boost-users] [mpl] Is it possible to mpl_assert dependingonthe derivation of a class
Hughes, James wrote:
Just a quick addendum to this. I tried out a combination of the two - using a BOOST_STATIC_ASSERT((boost::is_base_of<Base, T> >::value)) inside the do_it function described above, and found what I thought was odd behaviour with is_base_of.
The following excerpt shows the behaviour
class A {};
class B : public A {};
typedef A C;
BOOST_STATIC_ASSERT((boost::is_base_of<A,B> >::value))
// this
passes
BOOST_STATIC_ASSERT((boost::is_base_of<A,C> >::value))
// this
fails
I would expect both to pass, as is_base_of should
return true when
both parameters are the same, and I thought that
typedef did make
classes the same/equivalent
http://www.boost.org/doc/html/boost_typetraits/reference.html#boost_ty
petraits.is_base_of
Is there something I am missing about typedef? Or is boost::is_base_of unable to handles the aliasing?
James
Hi James,
I tried this with GCC 4.2 and 3.4.6 under Linux. It passes for both cases. So it might be your compiler, which is doing something wrong.
Martin
_______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
I'm using gcc 3.4.3 (Cross compiler to Arm). I had a thought it might be down to having some pure virtual functions in A, which meant that my typedef resulting in an incomplete type, but I removed those as a test and still got the same error. But that wouldn't explain why changing from a typedef to a derivation fixed the problem. Using boost 1.33.1 btw. I'll assume it's the compiler for now!! James This message (including any attachments) contains confidential and/or proprietary information intended only for the addressee. Any unauthorized disclosure, copying, distribution or reliance on the contents of this information is strictly prohibited and may constitute a violation of law. If you are not the intended recipient, please notify the sender immediately by responding to this e-mail, and delete the message from your system. If you have any questions about this e-mail please notify the sender immediately.

on Tue Aug 21 2007, Martin Apel <martin.apel-AT-simpack.de> wrote:
Hughes, James wrote:
Hello all,
I want some template code to assert if the passed in template type is NOT derived from a particular base class.
I've looked through the Template Metaprogamming book, but haven't seen anything that can do this, but I seem to remember something along those lines.
Can anyone help?
James
Hi James,
the easiest way is something like the following:
#include <boost/type_traits.hpp> #include <boost/static_assert.hpp>
BOOST_STATIC_ASSERT (boost::is_base_of<Base, Derived>::value);
BOOST_MPL_ASSERT((boost::is_base_of<Base,Derived>)) Don't use BOOST_STATIC_ASSERT if you can help it. It gives far inferior results when assertions fail. -- Dave Abrahams Boost Consulting http://www.boost-consulting.com The Astoria Seminar ==> http://www.astoriaseminar.com
participants (4)
-
David Abrahams
-
Hughes, James
-
Martin Apel
-
Ovanes Markarian