is_virtual_base_of ?

Is there an implementation of the type trait is_virtual_base_of<D, B> anywhere? If not is there a way to make such a thing? Robert Ramey

On 08.03.2009, at 11:02, John Maddock wrote:
If not is there a way to make such a thing? Can't think of a method off the top of my head, but Boosters are a clever lot so you never know....!
One can check if the size changes when creating another class: template< typename D, typename B > struct is_virtual_base_of { struct X : D, virtual B {}; enum { value = sizeof(X)==sizeof(D) }; }; template< typename T > struct is_virtual_base_of< T, T > { enum { value = false }; }; it triggers some warnings with GCC in my experiments when a base class is *not* virtual, but it seems to detect virtual bases just fine. Disclaimer: It's a start, nothing more. I have no idea how other compilers (even other compiler versions of GCC other than 4.3.2) will react on it, etc. Regards, Daniel

I have checked in a boostification/typetraitification of this idea. It can be found in boost/serialization/is_virtual_base_of.hpp I have tested it as used in the serialization library with MSVC compilers and gcc. With gcc it doesn't indeed create an annoying warning. I would like to see the type_trait gurus to: a) look at this b) see if this gcc warning can be suppressed c) if its OK move it to the type_traits library and out of the serialization librar d) maybe add a separate test. e) and promote to the next release branch since I prefer to run my local tests against the next release branch. Thank you very much. Robert Ramey Daniel Frey wrote:
On 08.03.2009, at 11:02, John Maddock wrote:
If not is there a way to make such a thing? Can't think of a method off the top of my head, but Boosters are a clever lot so you never know....!
One can check if the size changes when creating another class:
template< typename D, typename B > struct is_virtual_base_of { struct X : D, virtual B {}; enum { value = sizeof(X)==sizeof(D) }; };
template< typename T > struct is_virtual_base_of< T, T > { enum { value = false }; };
it triggers some warnings with GCC in my experiments when a base class is *not* virtual, but it seems to detect virtual bases just fine. Disclaimer: It's a start, nothing more. I have no idea how other compilers (even other compiler versions of GCC other than 4.3.2) will react on it, etc.
Regards, Daniel
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Hi Robert, On 10.03.2009, at 01:49, Robert Ramey wrote:
b) see if this gcc warning can be suppressed
for GCC, you can suppress warnings by declaring your header as a system header, GCC has a pragma for this purpose: #pragma GCC system_header Just add it at the top of the is_virtual_base_of.hpp. It's kind of overkill, but I don't see any other way... Regards, Daniel

Robert Ramey wrote: I'm still having some problems with this. Some compilers are flaging as an error the case where B doesn't have a default constructor. Robert Ramey
template< typename D, typename B > struct is_virtual_base_of { struct X : D, virtual B {}; enum { value = sizeof(X)==sizeof(D) }; };
template< typename T > struct is_virtual_base_of< T, T > { enum { value = false }; };

I'm still having some problems with this. Some compilers are flaging as an error the case where B doesn't have a default constructor.
Rightly too I suspect :-( What happens if you give class X an explicit default constructor that is declared but not implemented? Maybe copy constructor, and assignment ops too in case the compiler tries to automatically create those? HTH, John.

On Wed, Mar 11, 2009 at 12:22 PM, John Maddock <john@johnmaddock.co.uk>wrote:
I'm still having some problems with this. Some compilers are flaging as an
error the case where B doesn't have a default constructor.
Rightly too I suspect :-(
I don't think that should be an error -- a warning, maybe, but not an error. We are never actually creating an instance of X anywhere so there is no actual problem. Another thing that should probably be handled is yielding false when D and/or B is not a class type rather than error. Also, it might be better to reorder the template arguments so that it is "Base, Derived" not "Derived, Base" as the name suggests and to be consistent with is_base_of. -- -Matt Calabrese

My current version - checked into the trunk at boost/serialization/is_virtual_base_of.hpp is attached. I think it addresses the points mentioned here. I can fix the case that causes me problems by adding a default constructor which is never called. That doesn't help for the generic case though. I'm guessing that type traits has lots of situations where members are declared and never called. FWIW - the reason I really need this is that I've implemented a much needed improvement in the speed of void_cast. But it can't be applied to void_casts to virtual base classes so I need to use another method. So I need this to invoke the proper method. Robert Ramey Matt Calabrese wrote:
On Wed, Mar 11, 2009 at 12:22 PM, John Maddock <john@johnmaddock.co.uk>wrote:
I'm still having some problems with this. Some compilers are flaging as an
error the case where B doesn't have a default constructor.
Rightly too I suspect :-(
I don't think that should be an error -- a warning, maybe, but not an error. We are never actually creating an instance of X anywhere so there is no actual problem.
Another thing that should probably be handled is yielding false when D and/or B is not a class type rather than error. Also, it might be better to reorder the template arguments so that it is "Base, Derived" not "Derived, Base" as the name suggests and to be consistent with is_base_of.
begin 666 is_virtual_base_of.hpp M+R\@("A#*2!#;W!Y<FEG:'0@1&%N:65L($9R97D@86YD(%)O8F5R="!286UE M>2 R,# Y+@T*+R\@(%5S92P@;6]D:69I8V%T:6]N(&%N9"!D:7-T<FEB=71I M;VX@87)E('-U8FIE8W0@=&\@=&AE($)O;W-T(%-O9G1W87)E($QI8V5N<V4L M#0HO+R @5F5R<VEO;B Q+C N("A3964@86-C;VUP86YY:6YG(&9I;&4@3$E# M14Y315\Q7S N='AT(&]R(&-O<'D@870-"B\O("!H='1P.B\O=W=W+F)O;W-T M+F]R9R],24-%3E-%7S%?,"YT>'0I+@T*+R\-"B\O("!3964@:'1T<#HO+W=W M=RYB;V]S="YO<F<O;&EB<R]T>7!E7W1R86ET<R!F;W(@;6]S="!R96-E;G0@ M=F5R<VEO;B!I;F-L=61I;F<@9&]C=6UE;G1A=&EO;BX-"B -"B-I9FYD968@ M0D]/4U1?5%1?25-?5DE25%5!3%]"05-%7T]&7TA04%])3D-,541%1 T*(V1E M9FEN92!"3T]35%]45%])4U]625)454%,7T)!4T5?3T9?2%!07TE.0TQ51$5$ M#0H-"B-I;F-L=61E(#QB;V]S="]T>7!E7W1R86ET<R]I<U]S86UE+FAP<#X- M"B-I;F-L=61E(#QB;V]S="]T>7!E7W1R86ET<R]D971A:6PO:6-E7VYO="YH M<' ^#0HC:6YC;'5D92 \8F]O<W0O='EP95]T<F%I=',O9&5T86EL+VEC95]A M;F0N:'!P/@T*#0HO+R!S:&]U;&0@8F4@=&AE(&QA<W0@(VEN8VQU9&4-"B-I M;F-L=61E(#QB;V]S="]T>7!E7W1R86ET<R]D971A:6PO8F]O;%]T<F%I=%]D M968N:'!P/@T*#0IN86UE<W!A8V4@8F]O<W0@>PT*;F%M97-P86-E(&1E=&%I M;"![#0H-"@T*(VEF9&5F($)/3U-47TU35D,-"B-P<F%G;6$@=V%R;FEN9R@@ M<'5S:" I#0HC<')A9VUA('=A<FYI;F<H(&1I<V%B;&4@.B T-3@T("D-"B-E M;&EF(&1E9FEN960@7U]'3E5#7U\-"B-P<F%G;6$@1T-#('-Y<W1E;5]H96%D M97(-"B-E;F1I9@T*#0IT96UP;&%T93QT>7!E;F%M92!"87-E+"!T>7!E;F%M M92!$97)I=F5D/@T*<W1R=6-T(&ES7W9I<G1U86Q?8F%S95]O9E]I;7!L#0I[ M#0H@(" @<W1R=6-T(%@@.B!$97)I=F5D+"!V:7)T=6%L($)A<V4@>WT[#0H@ M(" @0D]/4U1?4U1!5$E#7T-/3E-404Y4*&)O;VPL('9A;'5E(#T@<VEZ96]F M*%@I/3US:7IE;V8H1&5R:79E9"DI.PT*?3L-"@T*(VEF9&5F($)/3U-47TU3 M5D,-"B-P<F%G;6$@=V%R;FEN9R@@<&]P("D-"B-E;F1I9@T*#0I]("\O(&YA M;65S<&%C92!D971A:6P-"@T*0D]/4U1?5%1?05587T)/3TQ?5%)!251?1$5& M,B@-"B @(" @(&ES7W9I<G1U86Q?8F%S95]O9@T*(" @("P@0F%S90T*(" @ M("P@1&5R:79E9 T*(" @("P@*#HZ8F]O<W0Z.G1Y<&5?=')A:71S.CII8V5? M86YD/" @(" @( T*(" @(" @(" @*#HZ8F]O<W0Z.F1E=&%I;#HZ:7-?=FER M='5A;%]B87-E7V]F7VEM<&P\0F%S92Q$97)I=F5D/CHZ=F%L=64I+ T*(" @ M(" @(" @*#HZ8F]O<W0Z.G1Y<&5?=')A:71S.CII8V5?;F]T/ T*(" @(" @ M(" @(" @*#HZ8F]O<W0Z.FES7W-A;64\0F%S92Q$97)I=F5D/CHZ=F%L=64I M#0H@(" @(" @(" ^.CIV86QU92D-"B @(" ^.CIV86QU92D-"BD-"@T*(VEF M;F1E9B!"3T]35%].3U]414U03$%415]005)424%,7U-014-)04Q)6D%424]. M#0I"3T]35%]45%]!55A?0D]/3%]44D%)5%]005)424%,7U-014,R7S(H='EP M96YA;64@0F%S92QT>7!E;F%M92!$97)I=F5D+&ES7W9I<G1U86Q?8F%S95]O M9BQ"87-E)BQ$97)I=F5D+&9A;'-E*0T*0D]/4U1?5%1?05587T)/3TQ?5%)! M251?4$%25$E!3%]34$5#,E\R*'1Y<&5N86UE($)A<V4L='EP96YA;64@1&5R M:79E9"QI<U]V:7)T=6%L7V)A<V5?;V8L0F%S92Q$97)I=F5D)BQF86QS92D- M"D)/3U-47U147T%56%]"3T],7U1204E47U!!4E1)04Q?4U!%0S)?,BAT>7!E M;F%M92!"87-E+'1Y<&5N86UE($1E<FEV960L:7-?=FER='5A;%]B87-E7V]F M+$)A<V4F+$1E<FEV960F+&9A;'-E*0T*(V5N9&EF#0H-"GT@+R\@;F%M97-P M86-E(&)O;W-T#0H-"B-I;F-L=61E(#QB;V]S="]T>7!E7W1R86ET<R]D971A D:6PO8F]O;%]T<F%I=%]U;F1E9BYH<' ^#0H-"B-E;F1I9@T* ` end

On 11.03.2009, at 19:18, Robert Ramey wrote:
My current version - checked into the trunk at boost/serialization/is_virtual_base_of.hpp is attached. I think it addresses the points mentioned here.
I can fix the case that causes me problems by adding a default constructor which is never called. That doesn't help for the generic case though. I'm guessing that type traits has lots of situations where members are declared and never called.
You probably misunderstood the idea, as it is really generic. The idea is to add a declaration (without a definition) of X's ctor (or any other generated methods that cause you trouble). To be more precise: Index: boost/serialization/is_virtual_base_of.hpp =================================================================== --- boost/serialization/is_virtual_base_of.hpp (revision 51709) +++ boost/serialization/is_virtual_base_of.hpp (working copy) @@ -29,7 +29,7 @@ template<typename Base, typename Derived> struct is_virtual_base_of_impl { - struct X : Derived, virtual Base {}; + struct X : Derived, virtual Base { X(); }; BOOST_STATIC_CONSTANT(bool, value = sizeof(X)==sizeof(Derived)); }; HTH, Daniel

The problem is that Base needs the default constructor Daniel Frey wrote:
On 11.03.2009, at 19:18, Robert Ramey wrote:
My current version - checked into the trunk at boost/serialization/is_virtual_base_of.hpp is attached. I think it addresses the points mentioned here.
I can fix the case that causes me problems by adding a default constructor which is never called. That doesn't help for the generic case though. I'm guessing that type traits has lots of situations where members are declared and never called.
You probably misunderstood the idea, as it is really generic. The idea is to add a declaration (without a definition) of X's ctor (or any other generated methods that cause you trouble). To be more precise:
Index: boost/serialization/is_virtual_base_of.hpp =================================================================== --- boost/serialization/is_virtual_base_of.hpp (revision 51709) +++ boost/serialization/is_virtual_base_of.hpp (working copy) @@ -29,7 +29,7 @@ template<typename Base, typename Derived> struct is_virtual_base_of_impl { - struct X : Derived, virtual Base {}; + struct X : Derived, virtual Base { X(); }; BOOST_STATIC_CONSTANT(bool, value = sizeof(X)==sizeof(Derived)); };
HTH, Daniel
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

On 11.03.2009, at 21:58, Robert Ramey wrote:
The problem is that Base needs the default constructor
Sound weird to me, so I am probably the one who is missing something. Could you please post a testcase and the exact output of the compiler? Regards, Daniel
Daniel Frey wrote:
You probably misunderstood the idea, as it is really generic. The idea is to add a declaration (without a definition) of X's ctor (or any other generated methods that cause you trouble).

Robert Ramey wrote:
My current version - checked into the trunk at boost/serialization/is_virtual_base_of.hpp is attached. I think it addresses the points mentioned here.
Please see attached test (against trunk r51712). Either I'm missing something very obvious... or is_virtual_base_of reports a completely unrelated struct Z as being a virtual base of struct B, where it is clearly not. Regards, François

On 11.03.2009, at 19:47, Francois Barel wrote:
Please see attached test (against trunk r51712). Either I'm missing something very obvious... or is_virtual_base_of reports a completely unrelated struct Z as being a virtual base of struct B, where it is clearly not.
That's probably because the classes are empty, is_virtual_base_of might not be able to work in such a situation. One might check for is_empty and static_assert on it as a protection, but that is not a solution... Regards, Daniel

Daniel Frey:
On 11.03.2009, at 19:47, Francois Barel wrote:
Please see attached test (against trunk r51712). Either I'm missing something very obvious... or is_virtual_base_of reports a completely unrelated struct Z as being a virtual base of struct B, where it is clearly not.
That's probably because the classes are empty, is_virtual_base_of might not be able to work in such a situation. One might check for is_empty and static_assert on it as a protection, but that is not a solution...
It should be possible to check is_base_of first, then check whether the B base of D resides at the same address as the B virtual base of X?

On Mar 9, 2009, at 5:49 PM, Robert Ramey wrote:
I have checked in a boostification/typetraitification of this idea. It can be found in boost/serialization/is_virtual_base_of.hpp
I have tested it as used in the serialization library with MSVC compilers and gcc.
With gcc it doesn't indeed create an annoying warning.
I would like to see the type_trait gurus to:
a) look at this b) see if this gcc warning can be suppressed c) if its OK move it to the type_traits library and out of the serialization librar d) maybe add a separate test. e) and promote to the next release branch since I prefer to run my local tests against the next release branch.
The best way to get the maintainer to look at it is to submit it as a patch attached to a Trac ticket. -- David Abrahams BoostPro Computing http://boostpro.com

I would like to see the type_trait gurus to:
a) look at this b) see if this gcc warning can be suppressed c) if its OK move it to the type_traits library and out of the serialization librar d) maybe add a separate test. e) and promote to the next release branch since I prefer to run my local tests against the next release branch.
The best way to get the maintainer to look at it is to submit it as a patch attached to a Trac ticket.
Indeed, but in this case the maintainer has just added is_virtual_base_of to type_traits Trunk: no docs yet, lets see how the regression tests work out first. Robert, can you see if this version meets your needs? It passes all tests for me with gcc, msvc, intel and sun, but you never know what may happen with other compilers. Also I was unable to create a test case for the situation where the Base has no default constructor leading to a compiler error - do you have a test case for this? Cheers, John.

On Mar 9, 2009, at 5:49 PM, Robert Ramey wrote:
I have checked in a boostification/typetraitification of this idea. It can be found in boost/serialization/is_virtual_base_of.hpp
I have tested it as used in the serialization library with MSVC compilers and gcc.
With gcc it doesn't indeed create an annoying warning.
I would like to see the type_trait gurus to:
a) look at this b) see if this gcc warning can be suppressed c) if its OK move it to the type_traits library and out of the serialization librar d) maybe add a separate test. e) and promote to the next release branch since I prefer to run my local tests against the next release branch.
The best way to get the maintainer to look at it is to submit it as a patch attached to a Trac -- David Abrahams BoostPro Computing http://boostpro.com
participants (7)
-
Daniel Frey
-
David Abrahams
-
Francois Barel
-
John Maddock
-
Matt Calabrese
-
Peter Dimov
-
Robert Ramey