
Alexander Nasonov wrote:
Vladimir Prus wrote:
Alexander Nasonov wrote: I think you're right, and trying gcc + BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION confirms that. I've committed this part of the patch.
Great!
One question. How to make sure that we don't break existing code on broken compilers?
To clarify: the change I've committed only adds cast to reference. I postponed the other parts until we finish our discussion. So for now, all old code still works.
My plan is to extend existing testcase with more exotic use of _old_ functionality (details below) and to put _new_ functionality into separate testcase. Does it sound good to you?
The only new functionality that won't work on broken compilers is cast to reference of user-defined type for which remove_reference was not specified. Do you think we need to test for this explicitly?
const is already stripped because ctor's argument is 'const ValueType & value'. So, it's only for volatile. remove_cv is used only to avoid inclusion of remove_volatile.hpp.
Does this use case matters, btw?
I don't know. Even if it matters to some, I never saw their complains.
Neither did I.
Presumably, because this code snipset compiles and runs nicely:
// candidate for inclusion into _old_ test int volatile i = 0; any a_i(i); any_cast<int>(a_i); int r = any_cast<int>(a_i); r = any_cast<int const>(a_i); r = any_cast<int volatile>(a_i); r = any_cast<int const volatile>(a_i);
If not patched, it has a suble bug. a_i owns holder<int volatile> but any_cast function treats it as holder<int>, holder<int const>, holder<int volatile> and holder<int const volatile>, respectively.
Yea. I think it will never bite in practice, though, because 'const' or 'volatile' won't affect the object layout and IIRC, 'typeid' strips top-level cv qualifiers.
If you're going to fix this, please do it on both ends: in ctor and in any_cast. If you fix only any_cast end, you may end up with unsafe down cast over base pointer from holder<int volatile> to holder<int>. If you disable volatile at ctor end, some users (better if tests) will complain.
Correct type for storing 'int cv' value in a_i is holder<int> (without cv!).
Yes, that's true.
What about declaring that 'T' in all variants should have *no* cv-qualification? It's a bit strange that the user can cast to volatile type, and the any_cast will just throw that away. And cast *from* volalite any does not work, i.e.
volatile boost::any a = 1; volatile int& i = boost::any_cast<volatile int&>(a);
does not compile. So what's the point of allowing volatile type at all?
Why do you need volatile any? Safe casts to cv types and proper construction from volatile variable are things I was trying to fix.
I don't need volatile any, that's the point. I find it clearer if docs say 'You can pass cv-qualified types to 'any_cast'', then if they say 'you can cast to volatile type but you can't cast from volatile any'. - Volodya