From 6d73b4aa5441875a158ea3dcfcff5cd712cf552a Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Tue, 4 Feb 2014 23:36:04 -0800 Subject: [PATCH] Work around VC11 which has broken rebind_traits VC11 has only partial support for C++11 allocators. For example it has a non-conforming rebind_alloc and rebind_traits in std::allocator_traits because it does not support C++11 template aliases. --- .../smart_ptr/detail/array_allocator.hpp | 20 +- .../boost/smart_ptr/detail/array_deleter.hpp | 9 +- test/allocate_shared_array_construct_test.cpp | 191 ++++++++++++++---- 3 files changed, 167 insertions(+), 53 deletions(-) diff --git a/include/boost/smart_ptr/detail/array_allocator.hpp b/include/boost/smart_ptr/detail/array_allocator.hpp index 5c6baf4..f085523 100644 --- a/include/boost/smart_ptr/detail/array_allocator.hpp +++ b/include/boost/smart_ptr/detail/array_allocator.hpp @@ -12,7 +12,7 @@ #include #include #include -#if !defined(BOOST_NO_CXX11_ALLOCATOR) +#if !defined(BOOST_NO_CXX11_ALLOCATOR) #include #endif @@ -45,20 +45,20 @@ namespace boost { template friend class as_allocator; -#if !defined(BOOST_NO_CXX11_ALLOCATOR) +#if !defined(BOOST_NO_CXX11_ALLOCATOR) && \ + !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) typedef typename std::allocator_traits:: template rebind_alloc YA; typedef typename std::allocator_traits:: template rebind_alloc CA; - typedef typename std::allocator_traits:: - template rebind_traits YT; - typedef typename std::allocator_traits:: - template rebind_traits CT; #else - typedef typename A:: - template rebind::other YA; - typedef typename A:: - template rebind::other CA; + typedef typename A::template rebind::other YA; + typedef typename A::template rebind::other CA; +#endif + +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + typedef std::allocator_traits YT; + typedef std::allocator_traits CT; #endif public: diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 5fd7e43..bf967a0 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -74,16 +74,19 @@ namespace boost { } private: -#if !defined(BOOST_NO_CXX11_ALLOCATOR) +#if !defined(BOOST_NO_CXX11_ALLOCATOR) && \ + !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) typedef typename std::allocator_traits:: template rebind_alloc TA; - typedef typename std::allocator_traits:: - template rebind_traits TT; #else typedef typename A:: template rebind::other TA; #endif +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + typedef std::allocator_traits TT; +#endif + void destroy(type*, std::size_t, boost::true_type) { } diff --git a/test/allocate_shared_array_construct_test.cpp b/test/allocate_shared_array_construct_test.cpp index 623aa65..6501fa0 100644 --- a/test/allocate_shared_array_construct_test.cpp +++ b/test/allocate_shared_array_construct_test.cpp @@ -10,11 +10,42 @@ #if !defined(BOOST_NO_CXX11_ALLOCATOR) #include +class type1 { + friend class std::allocator; + +public: + static unsigned int instances; + static const type1 object; + +protected: + explicit type1() { + instances++; + } + + type1(const type1&) { + instances++; + } + + ~type1() { + instances--; + } +}; + +unsigned int type1::instances; +const type1 type1::object; + template class creator { public: typedef T value_type; +#if defined(BOOST_NO_CXX11_TEMPLATE_ALIASES) + template + struct rebind { + typedef creator other; + }; +#endif + creator() { } @@ -44,109 +75,189 @@ public: } }; -class type { - friend class creator; +class type2 { + friend class creator; public: static unsigned int instances; - static type object; + static const type2 object; protected: - explicit type() { + explicit type2() { instances++; } - type(const type&) { + type2(const type2&) { instances++; } - ~type() { + ~type2() { instances--; } }; -unsigned int type::instances; -type type::object; +unsigned int type2::instances; +const type2 type2::object; int main() { - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); { - boost::shared_ptr a1 = boost::allocate_shared(creator(), 3); + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3); BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1.get() != 0); - BOOST_TEST(type::instances == 4); + BOOST_TEST(type1::instances == 4); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); } - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); { - boost::shared_ptr a1 = boost::allocate_shared(creator()); + boost::shared_ptr a1 = boost::allocate_shared(std::allocator()); BOOST_TEST(a1.use_count() == 1); BOOST_TEST(a1.get() != 0); - BOOST_TEST(type::instances == 4); + BOOST_TEST(type1::instances == 4); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); } - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); { - boost::shared_ptr a1 = boost::allocate_shared(creator(), 2); + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); - BOOST_TEST(type::instances == 5); + BOOST_TEST(type1::instances == 5); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); } - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); { - boost::shared_ptr a1 = boost::allocate_shared(creator()); + boost::shared_ptr a1 = boost::allocate_shared(std::allocator()); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); - BOOST_TEST(type::instances == 5); + BOOST_TEST(type1::instances == 5); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); } - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); { - boost::shared_ptr a1 = boost::allocate_shared(creator(), 3); + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 3); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); - BOOST_TEST(type::instances == 4); + BOOST_TEST(type1::instances == 4); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); } - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); { - boost::shared_ptr a1 = boost::allocate_shared(creator()); + boost::shared_ptr a1 = boost::allocate_shared(std::allocator()); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); - BOOST_TEST(type::instances == 4); + BOOST_TEST(type1::instances == 4); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); } - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); { - boost::shared_ptr a1 = boost::allocate_shared(creator(), 2); + boost::shared_ptr a1 = boost::allocate_shared(std::allocator(), 2); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); - BOOST_TEST(type::instances == 5); + BOOST_TEST(type1::instances == 5); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); } - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); { - boost::shared_ptr a1 = boost::allocate_shared(creator()); + boost::shared_ptr a1 = boost::allocate_shared(std::allocator()); BOOST_TEST(a1.get() != 0); BOOST_TEST(a1.use_count() == 1); - BOOST_TEST(type::instances == 5); + BOOST_TEST(type1::instances == 5); a1.reset(); - BOOST_TEST(type::instances == 1); + BOOST_TEST(type1::instances == 1); + } + + BOOST_TEST(type2::instances == 1); + { + boost::shared_ptr a1 = boost::allocate_shared(creator(), 3); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(type2::instances == 4); + a1.reset(); + BOOST_TEST(type2::instances == 1); + } + + BOOST_TEST(type2::instances == 1); + { + boost::shared_ptr a1 = boost::allocate_shared(creator()); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(type2::instances == 4); + a1.reset(); + BOOST_TEST(type2::instances == 1); + } + + BOOST_TEST(type2::instances == 1); + { + boost::shared_ptr a1 = boost::allocate_shared(creator(), 2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type2::instances == 5); + a1.reset(); + BOOST_TEST(type2::instances == 1); + } + + BOOST_TEST(type2::instances == 1); + { + boost::shared_ptr a1 = boost::allocate_shared(creator()); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type2::instances == 5); + a1.reset(); + BOOST_TEST(type2::instances == 1); + } + + BOOST_TEST(type2::instances == 1); + { + boost::shared_ptr a1 = boost::allocate_shared(creator(), 3); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type2::instances == 4); + a1.reset(); + BOOST_TEST(type2::instances == 1); + } + + BOOST_TEST(type2::instances == 1); + { + boost::shared_ptr a1 = boost::allocate_shared(creator()); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type2::instances == 4); + a1.reset(); + BOOST_TEST(type2::instances == 1); + } + + BOOST_TEST(type2::instances == 1); + { + boost::shared_ptr a1 = boost::allocate_shared(creator(), 2); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type2::instances == 5); + a1.reset(); + BOOST_TEST(type2::instances == 1); + } + + BOOST_TEST(type2::instances == 1); + { + boost::shared_ptr a1 = boost::allocate_shared(creator()); + BOOST_TEST(a1.get() != 0); + BOOST_TEST(a1.use_count() == 1); + BOOST_TEST(type2::instances == 5); + a1.reset(); + BOOST_TEST(type2::instances == 1); } return boost::report_errors();