Boost logo

Boost :

Subject: Re: [boost] [Opaque] Request for interest in Opaque typedefs library emulation
From: vicente.botet (vicente.botet_at_[hidden])
Date: 2010-05-07 14:29:25


----- Original Message -----
From: "Stewart, Robert" <Robert.Stewart_at_[hidden]>
To: <boost_at_[hidden]>
Sent: Friday, May 07, 2010 7:54 PM
Subject: Re: [boost] [Opaque] Request for interest in Opaque typedefs library emulation

>
> vicente.botet wrote:
>>
>> The library include two class templates (CRTP) to define opaque types:
>> * public_opaque_type<OT,UT> : implicit conversion from OT to UT
>> * private_opaque_type<OT,UT> : no conversion from OT to UT
>
> Why not name them typedef_public and typedef_private to correlate with the proposed syntax?

No problem, if this is clearer.

>> To define a new OT with this mixin classes
>>
>> struct serial_number: public_opaque_type<serial_number, unsigned>
>> {
>> BOOST_OPAQUE_PUPLIC_FORWARD_CONSTRUCTORS(serial_number,unsigned);
>> };
>>
>> struct game_score: private_opaque_type<game_score, unsigned>
>> {
>> BOOST_OPAQUE_PRIVATE_FORWARD_CONSTRUCTORS(game_score,unsigned);
>> };
>
> Can you imagine any use case in which someone would want to add anything else to such a type? They won't be able to if opaque types ever become part of the standard, will they?

I have surely misunderstood the text in N1891 §7 "Since only the provider of the opaque-type is in a position to know the desired behavior, we now propose that the function's result in every case be returned as the type originally specified by the function selected by overload resolution, and that any other desired return type be specifically provided by a suitably overloaded version of the function."

This let me think that the user could overload the a funtion to change the return type. But it is also thru that the syntax doesn't allows this overloading. So if present they will be in a class inheriting from the opaque typedef, and then the macros will be enough.

>> In addition, defines macros that make this simpler
>>
>> BOOST_OPAQUE_PUBLIC_TYPEDEF(unsigned, serial_number);
>> BOOST_OPAQUE_PRIVATE_TYPEDEF(unsigned, game_score);
>
> BOOST_TYPEDEF_PUBLIC
> BOOST_TYPEDEF_PRIVATE

OK.
 
>> Next follows the definition of the public_opaque_type
>>
>> template <typename Final, typename T>
>> class public_opaque_type
>> : boost::totally_ordered< Final
>> , boost::integer_arithmetic< Final
>> , boost::bitwise< Final
>> , boost::unit_steppable< Final
>> , boost::totally_ordered< T, Final // public
>> specific conversions
>> , boost::integer_arithmetic< T, Final // public
>> specific conversions
>> , boost::bitwise< T, Final // public specific conversions
>> > > > > > > >
>
> That's quite a collection of mixins!

Yes, in order to overload all the operators this was the short way. If the class public_typedef is not needed, I can add all the operator overloadings on the macro directly. Even if this is verbose, it could be a solution to aboid inheritance, if this was a problem.
 
>> Please, let me know if you see an error on the design.
>
> At first blush, it seems reasonable, but you'll need to test a great variety of use cases to make sure they do only what they should and in many contexts.

Yes, I know that a lot od cases can broke.
 
> Here are a few questions that spring to mind:
>
> Can you declare such types local to a function?
Yes, I think. I will add a test.

> Can you declare such types nested within a UDT?
Yes, I think. I will add a test.
 
> Can you declare such types with others as the underlying type?
Yes, and as defined in N1891, only the implicit conversion to the UT is ensured for public typedefs.

BOOST_OPAQUE_PUBLIC_TYPEDEF(A, B);
BOOST_OPAQUE_PUBLIC_TYPEDEF(B, C);

B is convertible to A, C is convertible to B, but C is not convertible to A.
 
Thanks Rob for your comments, I will comeback after BoostCon with the suggested modifications and tests.
Vicente


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk