
On Jan 6, 2009, at 12:37 PM, David Abrahams wrote:
on Tue Jan 06 2009, Howard Hinnant <hinnant-AT-twcny.rr.com> wrote:
On Jan 6, 2009, at 10:45 AM, David Abrahams wrote:
on Mon Jan 05 2009, Howard Hinnant <hinnant-AT-twcny.rr.com> wrote:
I'm continuing to refine a boost::unique_ptr emulation and testsuite.
Howard, can you put this in the sandbox? I know there are a number of us who would like very much to collaborate on it.
I will make it available as soon as I can at http://home.roadrunner.com/~hinnant/unique_ptr03.html
There will be plenty of room for collaboration. Indeed I feel like that is already happening with the discussion in this thread.
For optimal collaboration you need source control. That's why I suggest the sandbox. That's probably the only way I'd be able to afford to work on it.
Understood. I'm a boost sandbox newbie and am juggling too many things today to even learn how to get boost sandbox access. For now I have a better, but still incomplete, tests and source up at: http://home.roadrunner.com/~hinnant/unique_ptr03.html The tests are hierarchical, organized according to N2800's [unique.ptr]. One can: $ export CC=g++ $ export BOOST_INCLUDE="-I/<path-to>/boost-trunk" $ export SOURCE_INCLUDE="-I/<path-to>/unique_ptr" And then cd into any directory under unique.ptr and: $ ./test 6 of the tests currently fail for me. 2 of them are fixed by changing boost::is_convertible's From to an rvalue. The other 4 I currently don't know how to fix. They involve unique_ptr's converting ctor. My current fear is that our generalized move library won't handle this, but I hope I'm wrong. $ ./test ... failed 6 tests in /Users/hinnant/Development/unique_ptr/unique.ptr/ unique.ptr.single/unique.ptr.single.ctor ... failed 6 tests in /Users/hinnant/Development/unique_ptr/unique.ptr/ unique.ptr.single failed 6 tests in /Users/hinnant/Development/unique_ptr/unique.ptr
I've modified my copy of is_convertible (without really knowing what I'm doing) like so:
Index: is_convertible.hpp =================================================================== --- is_convertible.hpp (revision 50433) +++ is_convertible.hpp (working copy) @@ -119,6 +119,8 @@ struct any_conversion { template <typename T> any_conversion(const volatile T&); + template <typename T> any_conversion(volatile T&); + template <typename T> any_conversion(const T&); template <typename T> any_conversion(T&); };
@@ -131,8 +133,8 @@ template <typename From, typename To> struct is_convertible_basic_impl { - static From _m_from; - static bool const value = sizeof( detail::checker<To>::_m_check(_m_from, 0) ) + static From _m_from(); + static bool const value = sizeof( detail::checker<To>::_m_check(_m_from(), 0) ) == sizeof(::boost::type_traits::yes_type); };
Note the From above is not the same as the one below at least in the current code.
I ran svn update on the boost-trunk before creating this diff.
You miss my point. I'm just pointing out that in the current code, the
From above is always a reference type and the From below is not necessarily a reference type.
I know that. I did that on purpose. I'm still missing your point.
@@ -291,7 +293,8 @@ template <typename From, typename To> struct is_convertible_impl { - typedef typename add_reference<From>::type ref_type; +// typedef typename add_reference<From>::type ref_type; + typedef From ref_type; BOOST_STATIC_CONSTANT(bool, value = (::boost::type_traits::ice_and< ::boost::type_traits::ice_or<
So it used to pass an lvalue of type _m_from, and after your change it passes an rvalue. Of course, your change now assumes that From can be returned from a function. I think you'll have a problem if you try this with From being a noncopyable non-movable type.
Did you overlook this remark completely?
No, I commented on it below.
This hits just the part targeting gcc.
(and old Borland compilers).
The intent is that in boost::is_convertible<From, To> From is now considered an rvalue (unless From is a (lvalue) reference type). This makes my test case happy. I can now move construct a unique_ptr with a move-only deleter.
Fwiw, this definition of is_convertible is consistent with std::is_convertible in N2800:
I was just going to ask that.
To emulate the N2800 definition in C++03 one must treat void, array and function types specially in the implementation (arrays and functions can't be returned from functions and void can't be a function parameter). Even so, a C++03 library emulation will get noncopyable non-movable types wrong (as will the current boost::is_convertible).
I'm claiming that your emulation gives a compile-time error in that case.
I'm claiming that so does boost: Compiled against revision 50433: $ cat test.cpp #include <boost/type_traits.hpp> class non_copyable_non_movable { int data_; non_copyable_non_movable(const non_copyable_non_movable&); non_copyable_non_movable& operator=(const non_copyable_non_movable&); public: non_copyable_non_movable() : data_(0) {} }; int main() { bool b = boost::is_convertible<non_copyable_non_movable, non_copyable_non_movable>::value; } $ g++ g++ -I/Users/hinnant/Development/boost-dev/boost-trunk test.cpp /Users/hinnant/Development/boost-dev/boost-trunk/boost/type_traits/ is_convertible.hpp: In instantiation of ‘boost::detail::is_convertible_basic_impl<non_copyable_non_movable&, non_copyable_non_movable>’: /Users/hinnant/Development/boost-dev/boost-trunk/boost/type_traits/ is_convertible.hpp:295: instantiated from ‘boost::detail::is_convertible_impl<non_copyable_non_movable, non_copyable_non_movable>’ /Users/hinnant/Development/boost-dev/boost-trunk/boost/type_traits/ is_convertible.hpp:372: instantiated from ‘boost::detail::is_convertible_impl_dispatch<non_copyable_non_movable, non_copyable_non_movable>’ /Users/hinnant/Development/boost-dev/boost-trunk/boost/type_traits/ is_convertible.hpp:418: instantiated from ‘boost::is_convertible<non_copyable_non_movable, non_copyable_non_movable>’ test.cpp:18: instantiated from here test.cpp:7: error: ‘non_copyable_non_movable::non_copyable_non_movable(const non_copyable_non_movable&)’ is private /Users/hinnant/Development/boost-dev/boost-trunk/boost/type_traits/ is_convertible.hpp:136: error: within this context /Users/hinnant/Development/boost-dev/boost-trunk/boost/type_traits/ is_convertible.hpp:136: error: initializing argument 1 of ‘static boost::type_traits::yes_type boost::detail::checker<T>::_m_check(T, int) [with T = non_copyable_non_movable]’ I know of no way to fix this in C++03. I strongly suspect it will take C++0X std::Convertible to get this one right (or compiler support such as __is_convertible(T,U)). Correct handling of noncopyable nonmovable types has no bearing on this discussion. We are *not* going to get it right. However we *can* get noncopyable movable types right if we choose to. Currently boost handles only copyable types. -Howard