Index: boost/ptr_container/detail/reversible_ptr_container.hpp =================================================================== --- boost/ptr_container/detail/reversible_ptr_container.hpp (revision 60445) +++ boost/ptr_container/detail/reversible_ptr_container.hpp (working copy) @@ -35,6 +35,11 @@ #include #include #include +#include +#include +#include +#include +#include #include #include #include @@ -48,6 +53,9 @@ namespace boost { +// minimum declaration required by propagate_noncopyable_for_foreach +namespace foreach { template< class T > struct is_noncopyable; } + namespace ptr_container_detail { template< class Container > @@ -93,15 +101,31 @@ struct associative_container_tag {}; struct ordered_associative_container_tag : associative_container_tag {}; struct unordered_associative_container_tag : associative_container_tag {}; - + // Mark the ptr_container with boost::noncopyable as appropreate to + // enable use of BOOST_FOREACH over const reference of ptr_container + // of which value_type is noncopyable. + // See: http://www.boost.org/doc/html/foreach/extensibility.html#id862475 + struct copyable {}; // dummy + template + struct propagate_noncopyable_for_foreach + : mpl::if_< + mpl::and_< + mpl::not_ >, + boost::foreach::is_noncopyable + >, + boost::noncopyable, + copyable + >::type {}; template < class Config, class CloneAllocator > - class reversible_ptr_container : CloneAllocator + class reversible_ptr_container : CloneAllocator, + private propagate_noncopyable_for_foreach< + BOOST_DEDUCED_TYPENAME Config::value_type, CloneAllocator> { private: BOOST_STATIC_CONSTANT( bool, allow_null = Config::allow_null ); Index: libs/ptr_container/test/foreach_noncopyable_detection.cpp =================================================================== --- libs/ptr_container/test/foreach_noncopyable_detection.cpp (revision 0) +++ libs/ptr_container/test/foreach_noncopyable_detection.cpp (revision 0) @@ -0,0 +1,48 @@ +#include "boost/ptr_container/ptr_vector.hpp" +#include "boost/ptr_container/ptr_map.hpp" +#include "boost/ptr_container/ptr_set.hpp" +#include "boost/foreach.hpp" + +struct normal {}; +bool operator < (normal const&, normal const&); + +struct abstract { virtual void f() const = 0; }; +bool operator < (abstract const&, abstract const&); + +struct noncopyable : boost::noncopyable {}; +bool operator < (noncopyable const&, noncopyable const&); + + +using boost::foreach::is_noncopyable; + +template +struct test_noncopyable +{ + typedef boost::ptr_vector sequence; + BOOST_STATIC_ASSERT(is_noncopyable::value == ExpectedNoncopyable); + + typedef boost::ptr_set, CloneAllocator> set; + BOOST_STATIC_ASSERT(is_noncopyable::value == ExpectedNoncopyable); + + typedef boost::ptr_map, CloneAllocator> map; + BOOST_STATIC_ASSERT(is_noncopyable::value == ExpectedNoncopyable); +}; + + +test_noncopyable +normal_container_should_be_copyable; + +test_noncopyable +normal_view_should_be_copyable; + +test_noncopyable +abstract_container_should_be_noncopyable; + +test_noncopyable +abstract_view_should_be_copyable; + +test_noncopyable +noncopyable_container_should_be_noncopyable; + +test_noncopyable +noncopyable_view_should_be_copyable;