[C++-sig] Re: is_polymorphic and unions

David Abrahams dave at boost-consulting.com
Wed Jul 23 02:17:31 CEST 2003


spex66 at gmx.net writes:

> Hi Dave,
>
> thanks for your fast helping hand :)
> (don't know how to respond in thread from a mail-client?!?)

Are you asking me if I know how?  I use GNUs; it seems to be working.

>>> solution to (1) is obviously splitting... sigh -> any chance to got this as
>>> a feature from pyste, Nicodemus?
>>
>>The current CVS includes support for "--multiple":
>>http://tinyurl.com/hp3j
>
> as far as I could see, its a splitting at header-file
> level... that's not enough in my case. Maybe a hardcore classlevel
> would be a nice option, too?

Pyste stuff is up to Nicodemus.

>>> This conversion requires a reinterpret_cast, a C-style cast or
>>> function-style cast
>>
>>This is an msvc bug which preserves top-level constness of arguments
>>in function (pointer) types.  If you can redeclare the offending
>>function as:
>>
>>  short SRM_ChangeCoordinateSRF(SRM_SRF_Parameters_Pair, const
> SRM_Coordinate *,SRM_Coordinate *);
>
> I'm a little bit challenged with C++ actually :/
> Do you mean 'redeclare' in its original position in the header-file (srm.h
> in this case)?

Yes, I mean modify the declaration, if the code is under your control.

> If so... in exactly the way you give the example, or the original
>
> EXPORT_DLL extern SRM_Status_Code
> SRM_ChangeCoordinateSRF
> (
>     const SRM_SRF_Parameters_Pair  coord_op_params_ptr,
>     const SRM_Coordinate          *source_coord_ptr,
>           SRM_Coordinate          *dest_coord_ptr
> );
>
> style (deleting first occur of const)?

The latter sounds good.

> Or have I to redeclare it in the mSedris.cpp

Nope.

>>I suppose Pyste could be patched to do this for you...
>
> This would be great :)

Note that I am not volunteering this feature.  As ever, it's up to
Nicodemus.

>>> :::::::::::::::::::::::::::::::::::
>>> ERROR::>>
>>> error C2504: in ..../type_traits/is_polymorphic.hpp (79) ---> problem of a
>>> union
>>
>>What's the complete error message for that line?
>
> here it comes (followed by matching pyste-result, and original
> header-file-snippets) parts translated from german VC6 messages into matching english one:
>
> ..\..\..\boost/type_traits/is_polymorphic.hpp(26) : error C2569: 'type' :
> enum/union cannot be used as a base class
> C:\arwa\dev\sedris_sdk_3.1.2\include\srm_types.h(5165) : see reference to
> class template instantiation 'type' being compiled
>         ..\..\..\boost/type_traits/is_polymorphic.hpp(79) : see reference to
> class template instantiation 'boost::detail::is_polymorphic_imp1<union
> SRM_SRF_Parameters::type>' being compiled
>         ..\..\..\boost/type_traits/is_polymorphic.hpp(84) : see reference to
> class template instantiation  'boost::detail::is_polymorphic_imp<union
> SRM_SRF_Parameters::type>' being compiled

OK, the easy solution is to specialize is_polymorphic for your union
type:

#include <boost/mpl/bool.hpp>

namespace boost
{
  template <> struct is_polymorphic<union SRM_SRF_Parameters::type>
    : mpl::false_
  {};
}

>         ..\..\..\boost/python/object/make_ptr_instance.hpp(37) : see
> reference to class template instantiation 'boost::is_polymorphic<union
> SRM_SRF_Parameters::type>' being compiled
>         ..\..\..\boost/python/object/make_ptr_instance.hpp(30) : see
> reference to class template instantiation 'struct _typeobject *__cdecl
> boost::python::objects::make_ptr_instance<union SRM_SRF_Parameters::type,struct
> boost::python::objects::pointer_holder<union SRM_SRF_Parameters::type *,union
> SRM_SRF_Parameters::type> >::get_class_object_impl(volatile const
> SRM_SRF_Parameters::type *)' being compiled
>
> PYSTE-AGAIN::>>
> class_< SRM_SRF_Parameters >("SRM_SRF_Parameters", init<  >())
> 	.def(init< const SRM_SRF_Parameters & >())
> 	.def_readwrite("dimensionality", &SRM_SRF_Parameters::dimensionality)
> 	.def_readwrite("parameters", &SRM_SRF_Parameters::parameters)
> ;
>
>
> SOURCE-AGAIN::>>
> typedef struct
> {
>     SRM_Dimensionality dimensionality;
>     union
>     {
>         SRM_SRF_Parameters_2D two_d;
>         SRM_SRF_Parameters_3D three_d;
>     } parameters;
> } SRM_SRF_Parameters;


This doesn't quite add up.  According to your declaration of
SRM_SRF_Parameters, there is no nested member called 'type'.  Is
there perhaps

#define parameters type

somewhere in your source code?

> I have not reproduce the 
>>>          mpl::and_<is_class<T>, is_polymorphic<T> >
> stuff. But from my memory, trying this last time... do you mean to
> replace occurences only from is_polymorphic<T> or also
> is_polymorphic<Target> // is_polymorphic<Source> //
> is_polymorphic<Base> in the same style? Thats what I have tried last
> time (plus # include <boost/mpl/and.hpp>)

No, it won't work, sorry.  Try the specialization.


> ::::::::::::::::::::
> And a new kind of compiler-error, maybe time to use boost.array?
>
>
> ::::::::::::::::::::::::::::::::::
> PYSTE::>>
>
> class_< SRM_Matrix_3x3 >("SRM_Matrix_3x3", init<  >())
> 	.def(init< const SRM_Matrix_3x3 & >())
> 	.def_readwrite("mat", &SRM_Matrix_3x3::mat)
> ;
>
> ::::::::::::::::::::::::::::::::::
> ERROR::>>
> ..\..\..\boost/python/data_members.hpp(68) : 
> error C2440: '=' : 'const double [3][3]' cannot convert in 'double [3][3]'
>         Es gibt keinen Kontext, in dem diese Konvertierung moeglich ist
>         ..\..\..\boost/python/data_members.hpp(55) : 
>         	Bei der Kompilierung der Member-Funktion 
> 'struct _object *__cdecl boost::python::detail::member<
> 			double [3][3],
> 			struct SRM_Matrix_3x3,
> 			struct boost::python::default_call_policies
> 			>::set(double (SRM_Matrix_3x3::*)[3][3],
> 				   struct _object *,
> 				   struct _object *,
> 				   const struct boost::python::default_call_policies &)'
> der Klassenvorlage
>
> ::::::::::::::::::::::::::::::::::
> SOURCE::>>
> typedef struct
> {
>     SRM_Long_Float mat[3][3];
> } SRM_Matrix_3x3;
>

Boost.Python doesn't convert builtin arrays to/from python
automatically.  You'll have to decide how you want to represent
them.  I suggest something like:

boost::python::tuple getter(SRM_Matrix_3x3& m)
{
    return boost::python::make_tuple(
        boost::python::make_tuple(m.mat[0][0], m.mat[0][1], m.mat[0][2])
      , boost::python::make_tuple(m.mat[1][0], m.mat[1][1], m.mat[1][2])
      , boost::python::make_tuple(m.mat[1][0], m.mat[1][1], m.mat[1][2]));
}

void setter(SRM_Matrix_3x3& m, boost::python::tuple x)
{
    for (int i = 0; i < 3; ++i)
        for (int j = 0; i < 3; ++j)
            m.mat[i][j] = extract<SRM_Long_Float>(x[i][j]);
}

 class_< SRM_Matrix_3x3 >("SRM_Matrix_3x3", init<  >())
 	.def(init< const SRM_Matrix_3x3 & >())
 	.add_property("mat", getter, setter)
    ;

> thanks again for your help and your time, but as it is in
> software-project life... time is the REAL bottleneck, *sigh*

That's why *I* can't afford to do much more as a volunteer ;-)

> but building wonders and miracles in zero-time is the real thrill :)

Always glad to offer a little thrill... ;->

-- 
Dave Abrahams
Boost Consulting
www.boost-consulting.com





More information about the Cplusplus-sig mailing list