[any] Divergence between Boost.Any and standard library proposal
A fresh draft of the proposal is up at http://beman.github.com/dot16/any-proposal.html In testing new any_cast examples, Boost.Any is handling one case differently from the proposal: any x; ... x = "Meow"; // x holds const char* This works fine with the Adobe implementation, but with the Boost implementation g++ 4.7.0 -std=c++11 reports: In file included from any_cast_test.cpp:5:0: c:\boost\trunk/boost/any.hpp: In instantiation of 'boost::any::holder<ValueType>::holder(c onst ValueType&) [with ValueType = char [5]]': c:\boost\trunk/boost/any.hpp:52:49: required from 'boost::any::any(const ValueType&) [wi th ValueType = char [5]]' c:\boost\trunk/boost/any.hpp:124:13: required from 'boost::any& boost::any::operator=(Va lueType&&) [with ValueType = const char (&)[5]; boost::any = boost::any]' any_cast_test.cpp:79:7: required from here c:\boost\trunk/boost/any.hpp:169:27: error: array used as initializer VC++ 2012 gets the same error, albeit with a much longer set of messages. AFAICS, the Adobe (and the proposed standard) behavior is preferred. The type does need to decay. Comments? --Beman
2013/5/3 Beman Dawes
A fresh draft of the proposal is up at http://beman.github.com/dot16/any-proposal.html
In testing new any_cast examples, Boost.Any is handling one case differently from the proposal:
any x; ... x = "Meow"; // x holds const char*
This works fine with the Adobe implementation, but with the Boost implementation g++ 4.7.0 -std=c++11 reports:
In file included from any_cast_test.cpp:5:0: c:\boost\trunk/boost/any.hpp: In instantiation of 'boost::any::holder<ValueType>::holder(c onst ValueType&) [with ValueType = char [5]]': c:\boost\trunk/boost/any.hpp:52:49: required from 'boost::any::any(const ValueType&) [wi th ValueType = char [5]]' c:\boost\trunk/boost/any.hpp:124:13: required from 'boost::any& boost::any::operator=(Va lueType&&) [with ValueType = const char (&)[5]; boost::any = boost::any]' any_cast_test.cpp:79:7: required from here c:\boost\trunk/boost/any.hpp:169:27: error: array used as initializer
VC++ 2012 gets the same error, albeit with a much longer set of messages.
AFAICS, the Adobe (and the proposed standard) behavior is preferred. The type does need to decay.
Comments?
Looks like I broke it in https://svn.boost.org/trac/boost/ticket/6999 . There are also some other differences: * boost implementation has perfect forwarding of ValueType (constructor and operator=) * ValueType requirement is MoveConstructible or CopyConstructible (it can be used with move only types) * ~any() is noexcept * proposal misses noexcept in for bad_any_cast: virtual const char* what() const; * Boosts version does not accept Allocator A few things that I think would be helpful: * clear() method * ??? assign() method with Allocator -- Best regards, Antony Polukhin
Le 03/05/13 18:30, Antony Polukhin a écrit : > 2013/5/3 Beman Dawes: >> A fresh draft of the proposal is up at >> http://beman.github.com/dot16/any-proposal.html >> >> There are also some other differences: >> * boost implementation has perfect forwarding of ValueType >> (constructor and operator=) +1 > * ValueType requirement is MoveConstructible or CopyConstructible (it > can be used with move only types) +1 > * proposal misses noexcept in for bad_any_cast: virtual const char* > what() const; What about adding to Boost.Config helpers #if ! defined BOOST_NOEXCEPT_OR_THROW #ifdef BOOST_NO_CXX11_NOEXCEPT # define BOOST_NOEXCEPT_OR_THROW throw() #else # define BOOST_NOEXCEPT_OR_THROW noexcept #endif #endif Vicente
On Friday 03 May 2013 23:07:42 Vicente J. Botet Escriba wrote:
What about adding to Boost.Config helpers
#if ! defined BOOST_NOEXCEPT_OR_THROW #ifdef BOOST_NO_CXX11_NOEXCEPT # define BOOST_NOEXCEPT_OR_THROW throw() #else # define BOOST_NOEXCEPT_OR_THROW noexcept #endif #endif
There is already BOOST_NOEXCEPT_OR_NOTHROW.
Le 03/05/13 23:13, Andrey Semashev a écrit :
On Friday 03 May 2013 23:07:42 Vicente J. Botet Escriba wrote:
What about adding to Boost.Config helpers
#if ! defined BOOST_NOEXCEPT_OR_THROW #ifdef BOOST_NO_CXX11_NOEXCEPT # define BOOST_NOEXCEPT_OR_THROW throw() #else # define BOOST_NOEXCEPT_OR_THROW noexcept #endif #endif There is already BOOST_NOEXCEPT_OR_NOTHROW.
Ups! Vicente
On Fri, May 3, 2013 at 12:30 PM, Antony Polukhin
2013/5/3 Beman Dawes
: ...
AFAICS, the Adobe (and the proposed standard) behavior is preferred. The type does need to decay.
Comments?
Looks like I broke it in https://svn.boost.org/trac/boost/ticket/6999 .
Should I create a new ticket:-)
There are also some other differences: * boost implementation has perfect forwarding of ValueType (constructor and operator=)
I created the attached little test program to see the effects of that. For both VC++ 2012 and GCC 4.7.0 -std=c++11, your implementation is more efficient: Adobe: copy construct any copy ctor move ctor move ctor move construct any move ctor move ctor move ctor copy assign to any copy ctor move ctor move ctor move assign to any move ctor move ctor move ctor Boost: copy construct any copy ctor move construct any move ctor copy assign to any copy ctor move assign to any move ctor Only the tests with differences are shown. The results are the same for both debug and release builds for both compilers. Please look at the test program and verify the tests are OK. I'll email Sean Parent to see what he has to say about those test results:-)
* ValueType requirement is MoveConstructible or CopyConstructible (it can be used with move only types)
Interesting point. IIRC, there has been some discussion in the LWG about such types, but I can't remember the conclusions. I'll check with Daniel Krügler.
* ~any() is noexcept
By convention, the standard library doesn't add noexcept to destructors. I've forgotten the rationale for that.
* proposal misses noexcept in for bad_any_cast: virtual const char* what() const;
Ha! Thanks for spotting that. Proposal fixed.
* Boosts version does not accept Allocator
The standard library is tentatively planning to add type erased allocator support to vocabulary types like any if they typically allocate heap memory, so it was added at the request of the LWG.
A few things that I think would be helpful: * clear() method
Interesting. I'll give it some thought for the proposal.
* ??? assign() method with Allocator
I'll do whatever the committee wants on that one. Thanks for your comments! Much appreciated! --Beman
2013/5/4 Beman Dawes
On Fri, May 3, 2013 at 12:30 PM, Antony Polukhin
wrote: 2013/5/3 Beman Dawes
: ...
AFAICS, the Adobe (and the proposed standard) behavior is preferred. The type does need to decay.
Comments?
Looks like I broke it in https://svn.boost.org/trac/boost/ticket/6999 .
Should I create a new ticket:-)
I'll fix it in #6999 and add some tests for that case. I'll need a day or two.
There are also some other differences: * boost implementation has perfect forwarding of ValueType (constructor and operator=)
I created the attached little test program to see the effects of that. For both VC++ 2012 and GCC 4.7.0 -std=c++11, your implementation is more efficient:
Adobe:
copy construct any copy ctor move ctor move ctor move construct any move ctor move ctor move ctor copy assign to any copy ctor move ctor move ctor move assign to any move ctor move ctor move ctor
Boost:
copy construct any copy ctor move construct any move ctor copy assign to any copy ctor move assign to any move ctor
Only the tests with differences are shown. The results are the same for both debug and release builds for both compilers.
Please look at the test program and verify the tests are OK.
They are OK, almost the same tests are part of Boost.Any test case: http://svn.boost.org/svn/boost/trunk/libs/any/test/any_test_rv.cpp
I'll email Sean Parent to see what he has to say about those test results:-)
* ValueType requirement is MoveConstructible or CopyConstructible (it can be used with move only types)
Interesting point. IIRC, there has been some discussion in the LWG about such types, but I can't remember the conclusions. I'll check with Daniel Krügler.
Idea was to allow usage with unique_ptr. Something like: boost:any a = std::unique_ptr<Handle>(ConstructWindowHndle(params), [](Handle* p){ FreeHandle(p); });
* ~any() is noexcept
By convention, the standard library doesn't add noexcept to destructors. I've forgotten the rationale for that.
* proposal misses noexcept in for bad_any_cast: virtual const char* what() const;
Ha! Thanks for spotting that. Proposal fixed.
* Boosts version does not accept Allocator
The standard library is tentatively planning to add type erased allocator support to vocabulary types like any if they typically allocate heap memory, so it was added at the request of the LWG.
I may patch Boost.Any to work with type erased allocators. This shall not break users code.
A few things that I think would be helpful: * clear() method
Interesting. I'll give it some thought for the proposal.
* ??? assign() method with Allocator
I'll do whatever the committee wants on that one.
Thanks for your comments! Much appreciated!
I'll need your help later with Boost.LexicalCast proposal. It requires some updates and C++14 Concepts for better detection of character types. -- Best regards, Antony Polukhin
On Sat, May 4, 2013 at 12:38 PM, Antony Polukhin
2013/5/4 Beman Dawes
: * ~any() is noexcept
By convention, the standard library doesn't add noexcept to destructors. I've forgotten the rationale for that.
Isn't the rationale that the language defines all destructors are noexcept by default? (I recall that at least being discussed, I think it was accepted?) Tony
On 6 May 2013 18:38, Gottlob Frege wrote:
Isn't the rationale that the language defines all destructors are noexcept by default? (I recall that at least being discussed, I think it was accepted?)
Yes, see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1147 and http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2010/n3204.htm
2013/5/4 Beman Dawes
On Fri, May 3, 2013 at 12:30 PM, Antony Polukhin
wrote: 2013/5/3 Beman Dawes
: ...
AFAICS, the Adobe (and the proposed standard) behavior is preferred. The type does need to decay.
Comments?
Looks like I broke it in https://svn.boost.org/trac/boost/ticket/6999 .
Should I create a new ticket:-)
Fixed in trunk.
BTW, draft tells nothing about any_cast
On Sat, May 4, 2013 at 3:09 PM, Antony Polukhin
Looks like I broke it in https://svn.boost.org/trac/boost/ticket/6999 .
Should I create a new ticket:-)
Fixed in trunk.
Great!
BTW, draft tells nothing about any_cast
(instance_of_any). Current Boost version will return rvalue if `instance_of_any` is not const and fail to compile other way.
Interesting!
To movable_test.cpp, I added:
std::cout << "move assign from any contents by rvalue reference"
<< std::endl;
m = any_cast
participants (6)
-
Andrey Semashev
-
Antony Polukhin
-
Beman Dawes
-
Gottlob Frege
-
Jonathan Wakely
-
Vicente J. Botet Escriba