Ticket #3996: ptr_container_propagate_noncopyable_for_foreach.3.patch

File ptr_container_propagate_noncopyable_for_foreach.3.patch, 11.3 KB (added by Kazutoshi Satoda <k_satoda@…>, 12 years ago)

svn diff for trunk r70851

  • boost/ptr_container/ptr_list.hpp

     
    107107    }
    108108}
    109109
     110BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH(boost::ptr_list, 3)
    110111
    111112#endif
  • boost/ptr_container/ptr_map.hpp

     
    164164
    165165}
    166166
     167BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH(boost::ptr_map, 5)
     168BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH(boost::ptr_multimap, 5)
     169
    167170#endif
  • boost/ptr_container/ptr_array.hpp

     
    231231    }
    232232}
    233233
     234BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH_TUPLE(boost::ptr_array, 3, \
     235  (typename T, size_t size, typename CA), \
     236  (T,size,CA))
     237
    234238#endif
  • boost/ptr_container/ptr_unordered_map.hpp

     
    248248
    249249}
    250250
     251BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH(boost::ptr_unordered_map, 6)
     252BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH(boost::ptr_unordered_multimap, 6)
     253
    251254#endif
  • boost/ptr_container/detail/reversible_ptr_container.hpp

     
    3939#include <typeinfo>
    4040#include <memory>
    4141
     42#include <boost/foreach_fwd.hpp>
     43#include <boost/type_traits/is_same.hpp>
     44#include <boost/mpl/if.hpp>
     45#include <boost/mpl/and.hpp>
     46#include <boost/mpl/not.hpp>
     47#include <boost/preprocessor/seq/enum.hpp>
     48#include <boost/preprocessor/tuple/to_seq.hpp>
     49#include <boost/preprocessor/tuple/to_seq.hpp>
     50#include <boost/preprocessor/repetition/enum_params.hpp>
     51
    4252#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 
    4353#pragma warning(push) 
    4454#pragma warning(disable:4127)
     
    674684        {
    675685            return replace( idx, x.release() );
    676686        }
    677                
     687
     688    public:
     689        // This needs to be a template to avoid ODR violation happens when
     690        // instantiated in two different translation units; one which
     691        // contains specialization of foreach::is_noncopyable<T>, and
     692        // another which doesn't.
     693        // Being a template, this is instantiated only in translation units
     694        // where BOOST_FOREACH is actually used. Such translation units
     695        // are already mandated to contain the specialization of
     696        // foreach::is_noncopyable<T> not to cause ODR violation in the
     697        // implementation of BOOST_FOREACH.
     698        template<bool DummyToDelayInstantiation = false>
     699        struct boost_foreach_is_noncopyable_impl
     700          : mpl::and_<
     701              mpl::not_<is_same<CloneAllocator, view_clone_allocator> >,
     702              foreach::is_noncopyable<typename Config::value_type>
     703            > {};
    678704    }; // 'reversible_ptr_container'
    679705
    680706
     
    762788
    763789} // namespace 'boost' 
    764790
     791// Enable use of BOOST_FOREACH over const reference of ptr_container
     792// of which value_type is noncopyable.
     793// See: http://www.boost.org/doc/html/foreach/extensibility.html#id862475
     794#define BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH_SEQ(template_name, parameters_seq, arguments_seq) \
     795  namespace boost { namespace foreach { \
     796    template<BOOST_PP_SEQ_ENUM(parameters_seq)> \
     797    struct is_noncopyable<template_name<BOOST_PP_SEQ_ENUM(arguments_seq)> > \
     798      : template_name<BOOST_PP_SEQ_ENUM(arguments_seq)>::template boost_foreach_is_noncopyable_impl<> {}; \
     799  }}
     800#define BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH_TUPLE(template_name, num_params, parameters_tuple, arguments_tuple) \
     801  BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH_SEQ(template_name, \
     802    BOOST_PP_TUPLE_TO_SEQ(num_params, parameters_tuple), \
     803    BOOST_PP_TUPLE_TO_SEQ(num_params, arguments_tuple))
     804#define BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH(template_name, num_params) \
     805  BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH_TUPLE(template_name, num_params, \
     806    (BOOST_PP_ENUM_PARAMS(num_params, class T)), \
     807    (BOOST_PP_ENUM_PARAMS(num_params, T)))
     808// Use this way for each public derived ptr_container ...
     809// BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH(ptr_container_detail::reversible_ptr_container, 2)
     810
    765811#if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) 
    766812#pragma warning(pop) 
    767813#endif 
  • boost/ptr_container/ptr_set.hpp

     
    155155
    156156}
    157157
     158BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH(boost::ptr_set, 4)
     159BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH(boost::ptr_multiset, 4)
     160
    158161#endif
  • boost/ptr_container/ptr_circular_buffer.hpp

     
    529529   
    530530}
    531531
     532BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH(boost::ptr_circular_buffer, 3)
     533
    532534#endif
  • boost/ptr_container/ptr_vector.hpp

     
    7474   
    7575}
    7676
     77BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH(boost::ptr_vector, 3)
     78
    7779#endif
  • boost/ptr_container/ptr_unordered_set.hpp

     
    239239
    240240}
    241241
     242BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH(boost::ptr_unordered_set, 5)
     243BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH(boost::ptr_unordered_multiset, 5)
     244
    242245#endif
  • boost/ptr_container/ptr_deque.hpp

     
    6666    }
    6767}
    6868
     69BOOST_PTR_CONTAINER_CUSTOMIZE_FOREACH(boost::ptr_deque, 3)
     70
    6971#endif
  • libs/ptr_container/test/foreach_noncopyable_detection.cpp

     
     1#include <boost/foreach.hpp>
     2#include <boost/noncopyable.hpp>
     3#include <boost/ptr_container/ptr_array.hpp>
     4#include <boost/ptr_container/ptr_deque.hpp>
     5#include <boost/ptr_container/ptr_list.hpp>
     6#include <boost/ptr_container/ptr_map.hpp>
     7#include <boost/ptr_container/ptr_set.hpp>
     8#include <boost/ptr_container/ptr_vector.hpp>
     9#include <boost/ptr_container/ptr_unordered_map.hpp>
     10#include <boost/ptr_container/ptr_unordered_set.hpp>
     11#include <boost/ptr_container/ptr_circular_buffer.hpp>
     12
     13struct normal {};
     14bool operator < (normal const&, normal const&);
     15bool operator == (normal const&, normal const&);
     16std::size_t hash_value(normal const&);
     17
     18struct abstract { virtual void f() const = 0; };
     19bool operator < (abstract const&, abstract const&);
     20bool operator == (abstract const&, abstract const&);
     21std::size_t hash_value(abstract const&);
     22
     23struct noncopyable : boost::noncopyable {};
     24bool operator < (noncopyable const&, noncopyable const&);
     25bool operator == (noncopyable const&, noncopyable const&);
     26std::size_t hash_value(noncopyable const&);
     27
     28using boost::foreach::is_noncopyable;
     29
     30template<typename T, typename CloneAllocator, bool ExpectedNoncopyable>
     31struct test_noncopyable
     32{
     33    typedef boost::ptr_array<T, 10, CloneAllocator> ptr_array;
     34    BOOST_STATIC_ASSERT(is_noncopyable<ptr_array>::value == ExpectedNoncopyable);
     35
     36    typedef boost::ptr_deque<T, CloneAllocator> ptr_deque;
     37    BOOST_STATIC_ASSERT(is_noncopyable<ptr_deque>::value == ExpectedNoncopyable);
     38
     39    typedef boost::ptr_list<T, CloneAllocator> ptr_list;
     40    BOOST_STATIC_ASSERT(is_noncopyable<ptr_list>::value == ExpectedNoncopyable);
     41
     42    typedef boost::ptr_map<int, T, std::less<int>, CloneAllocator> ptr_map;
     43    BOOST_STATIC_ASSERT(is_noncopyable<ptr_map>::value == ExpectedNoncopyable);
     44
     45    typedef boost::ptr_multimap<int, T, std::less<int>, CloneAllocator> ptr_multimap;
     46    BOOST_STATIC_ASSERT(is_noncopyable<ptr_multimap>::value == ExpectedNoncopyable);
     47
     48    typedef boost::ptr_set<T, std::less<T>, CloneAllocator> ptr_set;
     49    BOOST_STATIC_ASSERT(is_noncopyable<ptr_set>::value == ExpectedNoncopyable);
     50
     51    typedef boost::ptr_multiset<T, std::less<T>, CloneAllocator> ptr_multiset;
     52    BOOST_STATIC_ASSERT(is_noncopyable<ptr_multiset>::value == ExpectedNoncopyable);
     53
     54    typedef boost::ptr_vector<T, CloneAllocator> ptr_vector;
     55    BOOST_STATIC_ASSERT(is_noncopyable<ptr_vector>::value == ExpectedNoncopyable);
     56
     57    typedef boost::ptr_unordered_map<int, T, boost::hash<int>, std::equal_to<int>, CloneAllocator> ptr_unordered_map;
     58    BOOST_STATIC_ASSERT(is_noncopyable<ptr_unordered_map>::value == ExpectedNoncopyable);
     59
     60    typedef boost::ptr_unordered_multimap<int, T, boost::hash<int>, std::equal_to<int>, CloneAllocator> ptr_unordered_multimap;
     61    BOOST_STATIC_ASSERT(is_noncopyable<ptr_unordered_multimap>::value == ExpectedNoncopyable);
     62
     63    typedef boost::ptr_unordered_set<T, boost::hash<T>, std::equal_to<T>, CloneAllocator> ptr_unordered_set;
     64    BOOST_STATIC_ASSERT(is_noncopyable<ptr_unordered_set>::value == ExpectedNoncopyable);
     65
     66    typedef boost::ptr_unordered_multiset<T, boost::hash<T>, std::equal_to<T>, CloneAllocator> ptr_unordered_multiset;
     67    BOOST_STATIC_ASSERT(is_noncopyable<ptr_unordered_multiset>::value == ExpectedNoncopyable);
     68
     69    typedef boost::ptr_circular_buffer<T, CloneAllocator> ptr_circular_buffer;
     70    BOOST_STATIC_ASSERT(is_noncopyable<ptr_circular_buffer>::value == ExpectedNoncopyable);
     71};
     72
     73test_noncopyable<normal, boost::heap_clone_allocator, false>
     74normal_container_should_be_copyable;
     75
     76test_noncopyable<normal, boost::view_clone_allocator, false>
     77normal_view_should_be_copyable;
     78
     79test_noncopyable<abstract, boost::heap_clone_allocator, true>
     80abstract_container_should_be_noncopyable;
     81
     82test_noncopyable<abstract, boost::view_clone_allocator, false>
     83abstract_view_should_be_copyable;
     84
     85test_noncopyable<noncopyable, boost::heap_clone_allocator, true>
     86noncopyable_container_should_be_noncopyable;
     87
     88test_noncopyable<noncopyable, boost::view_clone_allocator, false>
     89noncopyable_view_should_be_copyable;
  • libs/ptr_container/test/Jamfile.v2

     
    4040    [ sc-test ptr_circular_buffer ]   
    4141    [ sc-test const_element_containers ]   
    4242 #   [ sc-test null_filter_iterator ]   
    43  
     43    [ compile foreach_noncopyable_detection.cpp ]
    4444    ;