From 5f485c2952af46a7b1f28fc2608facbe94bf7cd9 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Mon, 10 Feb 2014 20:54:48 -0800 Subject: [PATCH 01/55] Spatial optimization for make_shared for arrays Saves up to sizeof(void*) + sizeof(size_t) bytes for make_shared and saves sizeof(void*) + sizeof(size_t) + sizeof(A) bytes for allocate_shared where A is the supplied allocator type. --- .../boost/smart_ptr/allocate_shared_array.hpp | 174 +++++++------ .../boost/smart_ptr/detail/allocator_pair.hpp | 29 --- .../smart_ptr/detail/array_allocator.hpp | 246 ++++++++++++------ .../smart_ptr/detail/array_count_impl.hpp | 68 +++++ .../boost/smart_ptr/detail/array_deleter.hpp | 109 -------- .../boost/smart_ptr/detail/array_traits.hpp | 20 +- .../boost/smart_ptr/detail/array_utility.hpp | 131 ++++------ .../boost/smart_ptr/detail/sp_if_array.hpp | 8 +- include/boost/smart_ptr/make_shared_array.hpp | 140 +++++----- 9 files changed, 460 insertions(+), 465 deletions(-) delete mode 100644 include/boost/smart_ptr/detail/allocator_pair.hpp create mode 100644 include/boost/smart_ptr/detail/array_count_impl.hpp delete mode 100644 include/boost/smart_ptr/detail/array_deleter.hpp diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index a27b99f..aca4920 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -9,152 +9,166 @@ #ifndef BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP #define BOOST_SMART_PTR_ALLOCATE_SHARED_ARRAY_HPP -#include -#include +#include #include -#include namespace boost { - template + template inline typename boost::detail::sp_if_array::type allocate_shared(const A& allocator, std::size_t size) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - typedef typename boost::remove_cv::type T3; - typedef boost::detail::as_allocator A1; - typedef boost::detail::as_deleter D1; - T1* p1 = 0; - T3* p2 = 0; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; std::size_t n1 = size * boost::detail::array_total::size; - D1 d1(allocator, n1); - A1 a1(allocator, n1, &p2); - boost::shared_ptr s1(p1, d1, a1); - p1 = reinterpret_cast(p2); + T1* p1 = 0; + T2* p2 = 0; + D1 d1; + A1 a1(allocator, size, &p2); + shared_ptr s1(p1, d1, a1); +#if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, n1); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); +#else + boost::detail::ms_init(p2, n1); +#endif + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + p1 = reinterpret_cast(p2); + return shared_ptr(s1, p1); } - template + template inline typename boost::detail::sp_if_size_array::type allocate_shared(const A& allocator) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - typedef typename boost::remove_cv::type T3; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { N = boost::detail::array_total::size }; - typedef boost::detail::as_allocator A1; - typedef boost::detail::as_deleter D1; T1* p1 = 0; - T3* p2 = 0; - D1 d1(allocator); + T2* p2 = 0; + D1 d1; A1 a1(allocator, &p2); - boost::shared_ptr s1(p1, d1, a1); - p1 = reinterpret_cast(p2); + shared_ptr s1(p1, d1, a1); +#if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, N); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); +#else + boost::detail::ms_init(p2, N); +#endif + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + p1 = reinterpret_cast(p2); + return shared_ptr(s1, p1); } - template + template inline typename boost::detail::sp_if_array::type allocate_shared(const A& allocator, std::size_t size, const typename boost::detail::array_inner::type& value) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - typedef typename boost::remove_cv::type T3; - typedef const T2 T4; - typedef boost::detail::as_allocator A1; - typedef boost::detail::as_deleter D1; + typedef const T2 T3; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { M = boost::detail::array_total::size }; - T1* p1 = 0; - T3* p2 = 0; - T4* p3 = reinterpret_cast(&value); std::size_t n1 = M * size; - D1 d1(allocator, n1); - A1 a1(allocator, n1, &p2); - boost::shared_ptr s1(p1, d1, a1); + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = reinterpret_cast(&value); + D1 d1; + A1 a1(allocator, size, &p2); + shared_ptr s1(p1, d1, a1); +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + boost::detail::as_init(allocator, p2, n1, p3); +#else + boost::detail::ms_init(p2, n1, p3); +#endif + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); p1 = reinterpret_cast(p2); - boost::detail::as_init(allocator, p2, n1, p3); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + return shared_ptr(s1, p1); } - template + template inline typename boost::detail::sp_if_size_array::type allocate_shared(const A& allocator, const typename boost::detail::array_inner::type& value) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - typedef typename boost::remove_cv::type T3; - typedef const T2 T4; + typedef const T2 T3; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { - M = boost::detail::array_total::size, - N = boost::detail::array_total::size + N = boost::detail::array_total::size, + M = boost::detail::array_total::size }; - typedef boost::detail::as_allocator A1; - typedef boost::detail::as_deleter D1; T1* p1 = 0; - T3* p2 = 0; - T4* p3 = reinterpret_cast(&value); - D1 d1(allocator); + T2* p2 = 0; + T3* p3 = reinterpret_cast(&value); + D1 d1; A1 a1(allocator, &p2); - boost::shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + boost::detail::as_init(allocator, p2, N, p3); +#else + boost::detail::as_init(p2, N, p3); +#endif + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); p1 = reinterpret_cast(p2); - boost::detail::as_init(allocator, p2, N, p3); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + return shared_ptr(s1, p1); } - template + template inline typename boost::detail::sp_if_array::type allocate_shared_noinit(const A& allocator, std::size_t size) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - typedef typename boost::remove_cv::type T3; - typedef boost::detail::as_allocator A1; - typedef boost::detail::ms_deleter D1; - T1* p1 = 0; - T3* p2 = 0; + typedef boost::detail::ms_noinit_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; std::size_t n1 = size * boost::detail::array_total::size; - D1 d1(n1); - A1 a1(allocator, n1, &p2); - boost::shared_ptr s1(p1, d1, a1); - p1 = reinterpret_cast(p2); + T1* p1 = 0; + T2* p2 = 0; + D1 d1; + A1 a1(allocator, size, &p2); + shared_ptr s1(p1, d1, a1); boost::detail::ms_noinit(p2, n1); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + p1 = reinterpret_cast(p2); + return shared_ptr(s1, p1); } - template + template inline typename boost::detail::sp_if_size_array::type allocate_shared_noinit(const A& allocator) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - typedef typename boost::remove_cv::type T3; + typedef boost::detail::ms_noinit_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { N = boost::detail::array_total::size }; - typedef boost::detail::as_allocator A1; - typedef boost::detail::ms_deleter D1; T1* p1 = 0; - T3* p2 = 0; + T2* p2 = 0; D1 d1; A1 a1(allocator, &p2); - boost::shared_ptr s1(p1, d1, a1); - p1 = reinterpret_cast(p2); + shared_ptr s1(p1, d1, a1); boost::detail::ms_noinit(p2, N); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + p1 = reinterpret_cast(p2); + return shared_ptr(s1, p1); } } diff --git a/include/boost/smart_ptr/detail/allocator_pair.hpp b/include/boost/smart_ptr/detail/allocator_pair.hpp deleted file mode 100644 index 8910c90..0000000 --- a/include/boost/smart_ptr/detail/allocator_pair.hpp +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_DETAIL_ALLOCATOR_PAIR_HPP -#define BOOST_SMART_PTR_DETAIL_ALLOCATOR_PAIR_HPP - -#include - -namespace boost { - namespace detail { - template - struct as_pair - : A { - as_pair(const A& allocator, const T& value) - : A(allocator), - data(value) { - } - - T data; - }; - } -} - -#endif diff --git a/include/boost/smart_ptr/detail/array_allocator.hpp b/include/boost/smart_ptr/detail/array_allocator.hpp index cca57b7..fc55504 100644 --- a/include/boost/smart_ptr/detail/array_allocator.hpp +++ b/include/boost/smart_ptr/detail/array_allocator.hpp @@ -9,8 +9,8 @@ #ifndef BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP #define BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP -#include #include +#include #include #if !defined(BOOST_NO_CXX11_ALLOCATOR) #include @@ -18,32 +18,42 @@ namespace boost { namespace detail { - template - struct ms_allocator_base; + template + struct as_size_base; - template - struct ms_allocator_base { - ms_allocator_base(std::size_t size_) - : size(size_ * sizeof(T)) { + template + struct as_size_base + : A { + as_size_base(const A& allocator, std::size_t size_) + : A(allocator), + size(size_ * array_total::size) { } std::size_t size; }; - template - struct ms_allocator_base { + template + struct as_size_base + : A { + as_size_base(const A& allocator) + : A(allocator) { + } + enum { - size = N * sizeof(T) + size = array_total::size }; }; - template - class as_allocator - : ms_allocator_base { - using ms_allocator_base::size; + struct ms_init_tag { }; + struct ms_noinit_tag { }; - template - friend class as_allocator; + template + class ms_allocator + : as_size_base { + using as_size_base::size; + + template + friend class ms_allocator; #if !defined(BOOST_NO_CXX11_ALLOCATOR) typedef typename std::allocator_traits:: @@ -60,7 +70,7 @@ namespace boost { #endif public: - typedef typename array_inner::type type; + typedef typename array_base::type type; #if !defined(BOOST_NO_CXX11_ALLOCATOR) typedef typename YT::value_type value_type; @@ -80,52 +90,62 @@ namespace boost { typedef typename YA::const_reference const_reference; #endif - template + template struct rebind { - typedef as_allocator other; + typedef ms_allocator other; }; - as_allocator(const A& allocator, type** data) - : pair(allocator, data) { + ms_allocator(const A& allocator, type** data_) + : as_size_base(allocator), + data(data_), + object(0) { } - as_allocator(const A& allocator, std::size_t size_, type** data) - : ms_allocator_base(size_), - pair(allocator, data) { + ms_allocator(const A& allocator, std::size_t size_, type** data_) + : as_size_base(allocator, size_), + data(data_), + object(0) { } template - as_allocator(const as_allocator& other) - : ms_allocator_base(other), - pair(other.pair, other.pair.data) { + ms_allocator(const ms_allocator& other) + : as_size_base(other), + data(other.data), + object(other.object) { } pointer address(reference value) const { - return pair.address(value); + YA ya(*this); + return ya.address(value); } const_pointer address(const_reference value) const { - return pair.address(value); + YA ya(*this); + return ya.address(value); } size_type max_size() const { - return pair.max_size(); + YA ya(*this); + return ya.max_size(); } pointer allocate(size_type count, const void* value = 0) { - std::size_t a1 = boost::alignment_of::value; - std::size_t n1 = count * sizeof(value_type) + a1 - 1; - CA ca(pair); + enum { + M = boost::alignment_of::value + }; + std::size_t n1 = count * sizeof(value_type) + M - 1; + std::size_t n2 = size * sizeof(type); + CA ca(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) - char* p1 = CT::allocate(ca, size + n1, value); + char* p1 = CT::allocate(ca, n1 + n2, value); #else - char* p1 = ca.allocate(size + n1, value); + char* p1 = ca.allocate(n1 + n2, value); #endif char* p2 = p1 + n1; - while (std::size_t(p2) % a1 != 0) { + while (std::size_t(p2) % M != 0) { p2--; } - *pair.data = reinterpret_cast(p2); + *data = reinterpret_cast(p2); return reinterpret_cast(p1); } @@ -133,7 +153,7 @@ namespace boost { std::size_t a1 = boost::alignment_of::value; std::size_t n1 = count * sizeof(value_type) + a1 - 1; char* p1 = reinterpret_cast(memory); - CA ca(pair); + CA ca(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) CT::deallocate(ca, p1, size + n1); #else @@ -141,58 +161,105 @@ namespace boost { #endif } - template + template void construct(U* memory, const_reference value) { + YA ya(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) - YT::construct(pair, memory, value); + YT::construct(ya, memory, value); #else - pair.construct(memory, value); + ya.construct(memory, value); #endif } - template + template void destroy(U* memory) { + YA ya(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) - YT::destroy(pair, memory); + YT::destroy(ya, memory); #else - pair.destroy(memory); + ya.destroy(memory); #endif } #if !defined(BOOST_NO_CXX11_ALLOCATOR) && \ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - template + template void construct(U* memory, Args&&... args) { - YT::construct(pair, memory, std::forward(args)...); + YA ya(*this); + YT::construct(ya, memory, std::forward(args)...); } #endif - template - bool operator==(const as_allocator& other) const { - return pair == other.pair; + template + bool operator==(const ms_allocator& other) const { + return true; } - template - bool operator!=(const as_allocator& other) const { - return !(*this == other); + template + bool operator!=(const ms_allocator& other) const { + return !(*this == other); + } + + void set(type* memory) { + object = memory; + } + + void operator()() { + if (object) { + R tag; + free(tag); + } } private: - as_pair pair; + void free(ms_init_tag) { +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + const A& a1(*this); + as_destroy(a1, object, size); +#else + ms_destroy(object, size); +#endif + } + + void free(ms_noinit_tag) { + ms_destroy(object, size); + } + + type** data; + type* object; }; - template - class ms_allocator - : ms_allocator_base { - using ms_allocator_base::size; + template + struct ms_size_base; - template + template + struct ms_size_base { + ms_size_base(std::size_t size_) + : size(size_ * array_total::size) { + } + + std::size_t size; + }; + + template + struct ms_size_base { + enum { + size = array_total::size + }; + }; + + template + class ms_allocator + : ms_size_base { + using ms_size_base::size; + + template friend class ms_allocator; public: - typedef typename array_inner::type type; + typedef typename array_base::type type; typedef Y value_type; typedef Y* pointer; typedef const Y* const_pointer; @@ -201,24 +268,27 @@ namespace boost { typedef Y& reference; typedef const Y& const_reference; - template + template struct rebind { - typedef ms_allocator other; + typedef ms_allocator other; }; ms_allocator(type** data_) - : data(data_) { + : data(data_), + object(0) { } ms_allocator(std::size_t size_, type** data_) - : ms_allocator_base(size_), - data(data_) { + : ms_size_base(size_), + data(data_), + object(0) { } template - ms_allocator(const ms_allocator& other) - : ms_allocator_base(other), - data(other.data) { + ms_allocator(const ms_allocator& other) + : ms_size_base(other), + data(other.data), + object(other.object) { } pointer address(reference value) const { @@ -237,11 +307,14 @@ namespace boost { } pointer allocate(size_type count, const void* = 0) { - std::size_t a1 = boost::alignment_of::value; - std::size_t n1 = count * sizeof(value_type) + a1 - 1; - void* p1 = ::operator new(n1 + size); + enum { + M = boost::alignment_of::value + }; + std::size_t n1 = count * sizeof(value_type) + M - 1; + std::size_t n2 = size * sizeof(type); + void* p1 = ::operator new(n1 + n2); char* p2 = static_cast(p1) + n1; - while (std::size_t(p2) % a1 != 0) { + while (std::size_t(p2) % M != 0) { p2--; } *data = reinterpret_cast(p2); @@ -253,13 +326,13 @@ namespace boost { ::operator delete(p1); } - template + template void construct(U* memory, const_reference value) { void* p1 = memory; ::new(p1) U(value); } - template + template void destroy(U* memory) { memory->~U(); } @@ -267,25 +340,42 @@ namespace boost { #if !defined(BOOST_NO_CXX11_ALLOCATOR) && \ !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) - template + template void construct(U* memory, Args&&... args) { void* p1 = memory; ::new(p1) U(std::forward(args)...); } #endif - template - bool operator==(const ms_allocator&) const { + template + bool operator==(const ms_allocator&) const { return true; } - template - bool operator!=(const ms_allocator& other) const { + template + bool operator!=(const ms_allocator& other) const { return !(*this == other); } + void set(type* memory) { + object = memory; + } + + void operator()() { + if (object) { + ms_destroy(object, size); + } + } + private: type** data; + type* object; + }; + + class ms_noop { + public: + void operator()(const void*) { + } }; } } diff --git a/include/boost/smart_ptr/detail/array_count_impl.hpp b/include/boost/smart_ptr/detail/array_count_impl.hpp new file mode 100644 index 0000000..503947e --- /dev/null +++ b/include/boost/smart_ptr/detail/array_count_impl.hpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2014 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_COUNT_IMPL_HPP +#define BOOST_SMART_PTR_DETAIL_ARRAY_COUNT_IMPL_HPP + +#include +#include + +namespace boost { + namespace detail { + template + class sp_counted_impl_pda > + : public sp_counted_base { + typedef ms_noop D; + typedef ms_allocator A; + typedef sp_counted_impl_pda Y; + public: + sp_counted_impl_pda(const P&, const D&, const A& allocator_) + : allocator(allocator_) { + } + + virtual void dispose() { + allocator(); + } + + virtual void destroy() { +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + typedef typename std::allocator_traits:: + template rebind_alloc YA; + typedef typename std::allocator_traits:: + template rebind_traits YT; +#else + typedef typename A::template rebind::other YA; +#endif + YA a1(allocator); +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + YT::destroy(a1, this); + YT::deallocate(a1, this, 1); +#else + this->~Y(); + a1.deallocate(this, 1); +#endif + } + + virtual void* get_deleter(const sp_typeinfo&) { + return &reinterpret_cast(allocator); + } + + virtual void* get_untyped_deleter() { + return &reinterpret_cast(allocator); + } + + private: + sp_counted_impl_pda(const sp_counted_impl_pda&); + sp_counted_impl_pda& operator=(const sp_counted_impl_pda&); + + A allocator; + }; + } +} + +#endif diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp deleted file mode 100644 index ca320dc..0000000 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 2012-2014 Glen Joseph Fernandes - * glenfe at live dot com - * - * Distributed under the Boost Software License, - * Version 1.0. (See accompanying file LICENSE_1_0.txt - * or copy at http://boost.org/LICENSE_1_0.txt) - */ -#ifndef BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP -#define BOOST_SMART_PTR_DETAIL_ARRAY_DELETER_HPP - -#include -#include -#include - -namespace boost { - namespace detail { - template - struct ms_deleter_base; - - template - struct ms_deleter_base { - ms_deleter_base(std::size_t size_) - : size(size_) { - } - - std::size_t size; - }; - - template - struct ms_deleter_base { - enum { - size = N - }; - }; - - template - class as_deleter - : ms_deleter_base { - using ms_deleter_base::size; - - public: - typedef typename array_inner::type type; - -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - typedef typename std::allocator_traits:: - template rebind_alloc allocator; -#else - typedef typename A:: - template rebind::other allocator; -#endif - - as_deleter(const A& allocator_) - : pair(allocator_, 0) { - } - - as_deleter(const A& allocator_, std::size_t size_) - : ms_deleter_base(size_), - pair(allocator_, 0) { - } - - void set(type* memory) { - pair.data = memory; - } - - void operator()(const void*) { - if (pair.data) { - as_destroy(pair, pair.data, size); - } - } - - private: - as_pair pair; - }; - - template - class ms_deleter - : ms_deleter_base { - using ms_deleter_base::size; - - public: - typedef typename array_inner::type type; - - ms_deleter() - : object(0) { - } - - ms_deleter(std::size_t size_) - : ms_deleter_base(size_), - object(0) { - } - - void set(type* memory) { - object = memory; - } - - void operator()(const void*) { - if (object) { - ms_destroy(object, size); - } - } - - private: - type* object; - }; - } -} - -#endif diff --git a/include/boost/smart_ptr/detail/array_traits.hpp b/include/boost/smart_ptr/detail/array_traits.hpp index e10ef97..819c5ba 100644 --- a/include/boost/smart_ptr/detail/array_traits.hpp +++ b/include/boost/smart_ptr/detail/array_traits.hpp @@ -9,48 +9,48 @@ #ifndef BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP #define BOOST_SMART_PTR_DETAIL_ARRAY_TRAITS_HPP -#include +#include namespace boost { namespace detail { - template + template struct array_base { - typedef T type; + typedef typename boost::remove_cv::type type; }; - template + template struct array_base { typedef typename array_base::type type; }; - template + template struct array_base { typedef typename array_base::type type; }; - template + template struct array_total { enum { size = 1 }; }; - template + template struct array_total { enum { size = N * array_total::size }; }; - template + template struct array_inner; - template + template struct array_inner { typedef T type; }; - template + template struct array_inner { typedef T type; }; diff --git a/include/boost/smart_ptr/detail/array_utility.hpp b/include/boost/smart_ptr/detail/array_utility.hpp index e4b690c..84029a1 100644 --- a/include/boost/smart_ptr/detail/array_utility.hpp +++ b/include/boost/smart_ptr/detail/array_utility.hpp @@ -21,43 +21,24 @@ namespace boost { typedef boost::true_type ms_is_trivial; typedef boost::false_type ms_no_trivial; - template + template inline void ms_destroy(T*, std::size_t, ms_is_trivial) { } - template + template inline void ms_destroy(T* memory, std::size_t size, ms_no_trivial) { for (std::size_t i = size; i > 0;) { memory[--i].~T(); } } - template + template inline void ms_destroy(T* memory, std::size_t size) { boost::has_trivial_destructor trivial; ms_destroy(memory, size, trivial); } -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - template - inline void as_destroy(A& allocator, T* memory, - std::size_t size) { - typedef typename std::allocator_traits:: - template rebind_traits TT; - for (std::size_t i = size; i > 0;) { - TT::destroy(allocator, &memory[--i]); - } - } -#else - template - inline void as_destroy(const A&, T* memory, - std::size_t size) { - boost::has_trivial_destructor trivial; - ms_destroy(memory, size, trivial); - } -#endif - - template + template inline void ms_init(T* memory, std::size_t size, ms_is_trivial) { for (std::size_t i = 0; i < size; i++) { void* p1 = memory + i; @@ -65,7 +46,7 @@ namespace boost { } } - template + template inline void ms_init(T* memory, std::size_t size, ms_no_trivial) { #if !defined(BOOST_NO_EXCEPTIONS) std::size_t i = 0; @@ -86,15 +67,48 @@ namespace boost { #endif } - template + template inline void ms_init(T* memory, std::size_t size) { boost::has_trivial_default_constructor trivial; ms_init(memory, size, trivial); } + template + inline void ms_init(T* memory, std::size_t size, const T* list) { +#if !defined(BOOST_NO_EXCEPTIONS) + std::size_t i = 0; + try { + for (; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(list[i % N]); + } + } catch (...) { + ms_destroy(memory, i); + throw; + } +#else + for (std::size_t i = 0; i < size; i++) { + void* p1 = memory + i; + ::new(p1) T(list[i % N]); + } +#endif + } #if !defined(BOOST_NO_CXX11_ALLOCATOR) - template + template + inline void as_destroy(const A& allocator, T* memory, + std::size_t size) { + typedef typename std::allocator_traits:: + template rebind_alloc TA; + typedef typename std::allocator_traits:: + template rebind_traits TT; + TA a2(allocator); + for (std::size_t i = size; i > 0;) { + TT::destroy(a2, &memory[--i]); + } + } + + template inline void as_init(const A& allocator, T* memory, std::size_t size, ms_is_trivial) { typedef typename std::allocator_traits:: @@ -107,8 +121,8 @@ namespace boost { } } - template - inline void as_init(const A& allocator, T* memory, std::size_t size, + template + inline void as_init(const A& allocator, T* memory, std::size_t size, ms_no_trivial) { typedef typename std::allocator_traits:: template rebind_alloc TA; @@ -132,42 +146,13 @@ namespace boost { #endif } - template + template inline void as_init(const A& allocator, T* memory, std::size_t size) { boost::has_trivial_default_constructor trivial; as_init(allocator, memory, size, trivial); } -#else - template - inline void as_init(const A&, T* memory, std::size_t size) { - boost::has_trivial_default_constructor trivial; - ms_init(memory, size, trivial); - } -#endif - template - inline void ms_init(T* memory, std::size_t size, const T* list) { -#if !defined(BOOST_NO_EXCEPTIONS) - std::size_t i = 0; - try { - for (; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(list[i % N]); - } - } catch (...) { - ms_destroy(memory, i); - throw; - } -#else - for (std::size_t i = 0; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(list[i % N]); - } -#endif - } - -#if !defined(BOOST_NO_CXX11_ALLOCATOR) - template + template inline void as_init(const A& allocator, T* memory, std::size_t size, const T* list) { typedef typename std::allocator_traits:: @@ -191,35 +176,13 @@ namespace boost { } #endif } -#else - template - inline void as_init(const A&, T* memory, std::size_t size, - const T* list) { -#if !defined(BOOST_NO_EXCEPTIONS) - std::size_t i = 0; - try { - for (; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(list[i % N]); - } - } catch (...) { - ms_destroy(memory, i); - throw; - } -#else - for (std::size_t i = 0; i < size; i++) { - void* p1 = memory + i; - ::new(p1) T(list[i % N]); - } -#endif - } #endif - template + template inline void ms_noinit(T*, std::size_t, ms_is_trivial) { } - template + template inline void ms_noinit(T* memory, std::size_t size, ms_no_trivial) { #if !defined(BOOST_NO_EXCEPTIONS) std::size_t i = 0; @@ -240,7 +203,7 @@ namespace boost { #endif } - template + template inline void ms_noinit(T* memory, std::size_t size) { boost::has_trivial_default_constructor trivial; ms_noinit(memory, size, trivial); diff --git a/include/boost/smart_ptr/detail/sp_if_array.hpp b/include/boost/smart_ptr/detail/sp_if_array.hpp index bbd0f3c..9a2c1e0 100644 --- a/include/boost/smart_ptr/detail/sp_if_array.hpp +++ b/include/boost/smart_ptr/detail/sp_if_array.hpp @@ -13,18 +13,18 @@ namespace boost { namespace detail { - template + template struct sp_if_array; - template + template struct sp_if_array { typedef boost::shared_ptr type; }; - template + template struct sp_if_size_array; - template + template struct sp_if_size_array { typedef boost::shared_ptr type; }; diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 50763d8..65eb76f 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -9,151 +9,149 @@ #ifndef BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP #define BOOST_SMART_PTR_MAKE_SHARED_ARRAY_HPP -#include -#include +#include #include -#include namespace boost { - template + template inline typename boost::detail::sp_if_array::type make_shared(std::size_t size) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - typedef typename boost::remove_cv::type T3; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_deleter D1; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; + std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; - T3* p2 = 0; - std::size_t n1 = size * boost::detail::array_total::size; - D1 d1(n1); + T2* p2 = 0; + D1 d1; A1 a1(n1, &p2); - boost::shared_ptr s1(p1, d1, a1); - p1 = reinterpret_cast(p2); + shared_ptr s1(p1, d1, a1); boost::detail::ms_init(p2, n1); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + p1 = reinterpret_cast(p2); + return shared_ptr(s1, p1); } - template + template inline typename boost::detail::sp_if_size_array::type make_shared() { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - typedef typename boost::remove_cv::type T3; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { N = boost::detail::array_total::size }; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_deleter D1; T1* p1 = 0; - T3* p2 = 0; + T2* p2 = 0; D1 d1; A1 a1(&p2); - boost::shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); p1 = reinterpret_cast(p2); boost::detail::ms_init(p2, N); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + return shared_ptr(s1, p1); } - template + template inline typename boost::detail::sp_if_array::type make_shared(std::size_t size, const typename boost::detail::array_inner::type& value) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - typedef typename boost::remove_cv::type T3; - typedef const T2 T4; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_deleter D1; + typedef const T2 T3; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { M = boost::detail::array_total::size }; - T1* p1 = 0; - T3* p2 = 0; - T4* p3 = reinterpret_cast(&value); std::size_t n1 = M * size; - D1 d1(n1); + T1* p1 = 0; + T2* p2 = 0; + T3* p3 = reinterpret_cast(&value); + D1 d1; A1 a1(n1, &p2); - boost::shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); + boost::detail::ms_init(p2, n1, p3); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); p1 = reinterpret_cast(p2); - boost::detail::ms_init(p2, n1, p3); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + return shared_ptr(s1, p1); } - template + template inline typename boost::detail::sp_if_size_array::type make_shared(const typename boost::detail::array_inner::type& value) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - typedef typename boost::remove_cv::type T3; - typedef const T2 T4; + typedef const T2 T3; + typedef boost::detail::ms_init_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { M = boost::detail::array_total::size, N = boost::detail::array_total::size - }; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_deleter D1; + }; T1* p1 = 0; - T3* p2 = 0; - T4* p3 = reinterpret_cast(&value); + T2* p2 = 0; + T3* p3 = reinterpret_cast(&value); D1 d1; A1 a1(&p2); - boost::shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); + boost::detail::ms_init(p2, N, p3); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); p1 = reinterpret_cast(p2); - boost::detail::ms_init(p2, N, p3); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + return shared_ptr(s1, p1); } - template + template inline typename boost::detail::sp_if_array::type make_shared_noinit(std::size_t size) { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - typedef typename boost::remove_cv::type T3; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_deleter D1; + typedef boost::detail::ms_noinit_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; + std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; - T3* p2 = 0; - std::size_t n1 = size * boost::detail::array_total::size; - D1 d1(n1); + T2* p2 = 0; + D1 d1; A1 a1(n1, &p2); - boost::shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); p1 = reinterpret_cast(p2); boost::detail::ms_noinit(p2, n1); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + return shared_ptr(s1, p1); } - template + template inline typename boost::detail::sp_if_size_array::type make_shared_noinit() { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; - typedef typename boost::remove_cv::type T3; + typedef boost::detail::ms_noinit_tag R1; + typedef boost::detail::ms_allocator A1; + typedef boost::detail::ms_noop D1; enum { N = boost::detail::array_total::size }; - typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_deleter D1; T1* p1 = 0; - T3* p2 = 0; + T2* p2 = 0; D1 d1; A1 a1(&p2); - boost::shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); p1 = reinterpret_cast(p2); boost::detail::ms_noinit(p2, N); - D1* d2 = static_cast(s1._internal_get_untyped_deleter()); - d2->set(p2); - return boost::shared_ptr(s1, p1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->set(p2); + return shared_ptr(s1, p1); } } From 57dc400fbfccf31737e92cca8ce1a6e9912c326c Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Mon, 10 Feb 2014 21:04:41 -0800 Subject: [PATCH 02/55] Cosmetic changes in make_shared and make_unique --- include/boost/smart_ptr/allocate_shared_array.hpp | 14 +++++++------- include/boost/smart_ptr/detail/up_if_array.hpp | 4 ++-- include/boost/smart_ptr/detail/up_if_not_array.hpp | 6 +++--- include/boost/smart_ptr/make_shared_array.hpp | 12 ++++++------ include/boost/smart_ptr/make_unique_array.hpp | 4 ++-- include/boost/smart_ptr/make_unique_object.hpp | 8 ++++---- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index aca4920..b260520 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -26,7 +26,7 @@ namespace boost { T2* p2 = 0; D1 d1; A1 a1(allocator, size, &p2); - shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, n1); #else @@ -53,7 +53,7 @@ namespace boost { T2* p2 = 0; D1 d1; A1 a1(allocator, &p2); - shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, N); #else @@ -84,7 +84,7 @@ namespace boost { T3* p3 = reinterpret_cast(&value); D1 d1; A1 a1(allocator, size, &p2); - shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, n1, p3); #else @@ -115,7 +115,7 @@ namespace boost { T3* p3 = reinterpret_cast(&value); D1 d1; A1 a1(allocator, &p2); - shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, N, p3); #else @@ -137,10 +137,10 @@ namespace boost { typedef boost::detail::ms_noop D1; std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; - T2* p2 = 0; + T2* p2 = 0; D1 d1; A1 a1(allocator, size, &p2); - shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); boost::detail::ms_noinit(p2, n1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); a2->set(p2); @@ -163,7 +163,7 @@ namespace boost { T2* p2 = 0; D1 d1; A1 a1(allocator, &p2); - shared_ptr s1(p1, d1, a1); + shared_ptr s1(p1, d1, a1); boost::detail::ms_noinit(p2, N); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); a2->set(p2); diff --git a/include/boost/smart_ptr/detail/up_if_array.hpp b/include/boost/smart_ptr/detail/up_if_array.hpp index d0b197d..7e62d10 100644 --- a/include/boost/smart_ptr/detail/up_if_array.hpp +++ b/include/boost/smart_ptr/detail/up_if_array.hpp @@ -13,10 +13,10 @@ namespace boost { namespace detail { - template + template struct up_if_array; - template + template struct up_if_array { typedef std::unique_ptr type; }; diff --git a/include/boost/smart_ptr/detail/up_if_not_array.hpp b/include/boost/smart_ptr/detail/up_if_not_array.hpp index 7679e61..fd74f25 100644 --- a/include/boost/smart_ptr/detail/up_if_not_array.hpp +++ b/include/boost/smart_ptr/detail/up_if_not_array.hpp @@ -13,16 +13,16 @@ namespace boost { namespace detail { - template + template struct up_if_not_array { typedef std::unique_ptr type; }; - template + template struct up_if_not_array { }; - template + template struct up_if_not_array { }; } diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 65eb76f..cfd390d 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -21,7 +21,7 @@ namespace boost { typedef boost::detail::ms_init_tag R1; typedef boost::detail::ms_allocator A1; typedef boost::detail::ms_noop D1; - std::size_t n1 = size * boost::detail::array_total::size; + std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; T2* p2 = 0; D1 d1; @@ -50,10 +50,10 @@ namespace boost { D1 d1; A1 a1(&p2); shared_ptr s1(p1, d1, a1); - p1 = reinterpret_cast(p2); boost::detail::ms_init(p2, N); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); a2->set(p2); + p1 = reinterpret_cast(p2); return shared_ptr(s1, p1); } @@ -96,7 +96,7 @@ namespace boost { enum { M = boost::detail::array_total::size, N = boost::detail::array_total::size - }; + }; T1* p1 = 0; T2* p2 = 0; T3* p3 = reinterpret_cast(&value); @@ -118,16 +118,16 @@ namespace boost { typedef boost::detail::ms_noinit_tag R1; typedef boost::detail::ms_allocator A1; typedef boost::detail::ms_noop D1; - std::size_t n1 = size * boost::detail::array_total::size; + std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; T2* p2 = 0; D1 d1; A1 a1(n1, &p2); shared_ptr s1(p1, d1, a1); - p1 = reinterpret_cast(p2); boost::detail::ms_noinit(p2, n1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); a2->set(p2); + p1 = reinterpret_cast(p2); return shared_ptr(s1, p1); } @@ -147,10 +147,10 @@ namespace boost { D1 d1; A1 a1(&p2); shared_ptr s1(p1, d1, a1); - p1 = reinterpret_cast(p2); boost::detail::ms_noinit(p2, N); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); a2->set(p2); + p1 = reinterpret_cast(p2); return shared_ptr(s1, p1); } } diff --git a/include/boost/smart_ptr/make_unique_array.hpp b/include/boost/smart_ptr/make_unique_array.hpp index 987c565..eb0528e 100644 --- a/include/boost/smart_ptr/make_unique_array.hpp +++ b/include/boost/smart_ptr/make_unique_array.hpp @@ -13,14 +13,14 @@ #include namespace boost { - template + template inline typename boost::detail::up_if_array::type make_unique(std::size_t size) { typedef typename boost::detail::array_inner::type U; return std::unique_ptr(new U[size]()); } - template + template inline typename boost::detail::up_if_array::type make_unique_noinit(std::size_t size) { typedef typename boost::detail::array_inner::type U; diff --git a/include/boost/smart_ptr/make_unique_object.hpp b/include/boost/smart_ptr/make_unique_object.hpp index 12149c5..c392e24 100644 --- a/include/boost/smart_ptr/make_unique_object.hpp +++ b/include/boost/smart_ptr/make_unique_object.hpp @@ -14,27 +14,27 @@ #include namespace boost { - template + template inline typename boost::detail::up_if_not_array::type make_unique() { return std::unique_ptr(new T()); } #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) - template + template inline typename boost::detail::up_if_not_array::type make_unique(Args&&... args) { return std::unique_ptr(new T(std::forward(args)...)); } #endif - template + template inline typename boost::detail::up_if_not_array::type make_unique(T&& value) { return std::unique_ptr(new T(std::move(value))); } - template + template inline typename boost::detail::up_if_not_array::type make_unique_noinit() { return std::unique_ptr(new T); From 7e3ae44bc28069d2c07d84db899649abf67efbc9 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Mon, 10 Feb 2014 21:08:08 -0800 Subject: [PATCH 03/55] Fix use of size in make_shared for arrays --- include/boost/smart_ptr/make_shared_array.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index cfd390d..f98368a 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -25,7 +25,7 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(n1, &p2); + A1 a1(size, &p2); shared_ptr s1(p1, d1, a1); boost::detail::ms_init(p2, n1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); @@ -75,7 +75,7 @@ namespace boost { T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; - A1 a1(n1, &p2); + A1 a1(size, &p2); shared_ptr s1(p1, d1, a1); boost::detail::ms_init(p2, n1, p3); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); @@ -122,7 +122,7 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(n1, &p2); + A1 a1(size, &p2); shared_ptr s1(p1, d1, a1); boost::detail::ms_noinit(p2, n1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); From 7ce5b6b2a938d4ee949ae529afc0cadcfabbc24d Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Tue, 11 Feb 2014 08:39:52 -0800 Subject: [PATCH 04/55] Fix use of ms_init in no C++11 allocator case --- include/boost/smart_ptr/allocate_shared_array.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index b260520..fdaec42 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -119,7 +119,7 @@ namespace boost { #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, N, p3); #else - boost::detail::as_init(p2, N, p3); + boost::detail::ms_init(p2, N, p3); #endif A1* a2 = static_cast(s1._internal_get_untyped_deleter()); a2->set(p2); From 6b6b63ef377bae28704994022fe3e7e0e60a0127 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 30 Jan 2003 14:20:22 +0000 Subject: [PATCH 05/55] Dave's quick_allocator added, #define BOOST_SP_USE_QUICK_ALLOCATOR to make shared_ptr use it. [SVN r17087] --- include/boost/detail/quick_allocator.hpp | 145 +++++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 include/boost/detail/quick_allocator.hpp diff --git a/include/boost/detail/quick_allocator.hpp b/include/boost/detail/quick_allocator.hpp new file mode 100644 index 0000000..66ba3d8 --- /dev/null +++ b/include/boost/detail/quick_allocator.hpp @@ -0,0 +1,145 @@ +#ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED +#define BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED + +#if _MSC_VER >= 1020 +#pragma once +#endif + +// +// detail/quick_allocator.hpp +// +// Copyright (c) 2003 David Abrahams +// Copyright (c) 2003 Peter Dimov +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +#include + +#include +#include +#include + +#include +#include // ::operator new, ::operator delete +#include // std::size_t + +namespace boost +{ + +namespace detail +{ + +template union freeblock +{ + typedef typename boost::type_with_alignment::type aligner_type; + aligner_type aligner; + char bytes[size]; + freeblock * next; +}; + +template struct allocator_impl +{ + typedef freeblock block; + + static lightweight_mutex mutex; + static std::deque store; + static block * free; + + static inline void * alloc() + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock(mutex); +#endif + if(block * x = free) + { + free = x->next; + return x; + } + else + { + store.resize(store.size() + 1); + return &store.back(); + } + } + + static inline void * alloc(std::size_t n) + { + if(n != size) // class-specific new called for a derived object + { + return ::operator new(n); + } + else + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock(mutex); +#endif + if(block * x = free) + { + free = x->next; + return x; + } + else + { + store.resize(store.size() + 1); + return &store.back(); + } + } + } + + static inline void dealloc(void * pv) + { + if(pv != 0) // 18.4.1.1/13 + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock(mutex); +#endif + block * pb = static_cast(pv); + pb->next = free; + free = pb; + } + } + + static inline void dealloc(void * pv, std::size_t n) + { + if(pv != 0) // 18.4.1.1/13 + { + if(n != size) // class-specific delete called for a derived object + { + ::operator delete(pv); + } + else + { +#ifdef BOOST_HAS_THREADS + lightweight_mutex::scoped_lock lock(mutex); +#endif + block * pb = static_cast(pv); + pb->next = free; + free = pb; + } + } + } +}; + +template + lightweight_mutex allocator_impl::mutex; + +template + std::deque< freeblock > allocator_impl::store; + +template + freeblock * allocator_impl::free = 0; + +template +struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of::value > +{ +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED From 97eed20d9b06cbcc4ac9ba893178069ca9a36324 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 7 Feb 2003 15:08:52 +0000 Subject: [PATCH 06/55] Quick_allocator updates. [SVN r17267] --- include/boost/detail/quick_allocator.hpp | 74 +++++++++++++++++------- 1 file changed, 52 insertions(+), 22 deletions(-) diff --git a/include/boost/detail/quick_allocator.hpp b/include/boost/detail/quick_allocator.hpp index 66ba3d8..2d8d735 100644 --- a/include/boost/detail/quick_allocator.hpp +++ b/include/boost/detail/quick_allocator.hpp @@ -23,7 +23,6 @@ #include #include -#include #include // ::operator new, ::operator delete #include // std::size_t @@ -45,10 +44,27 @@ template struct allocator_impl { typedef freeblock block; + // It may seem odd to use such small pages. + // + // However, on a typical Windows implementation that uses + // the OS allocator, "normal size" pages interact with the + // "ordinary" operator new, slowing it down dramatically. + // + // 512 byte pages are handled by the small object allocator, + // and don't interfere with ::new. + // + // The other alternative is to use much bigger pages (1M.) + + enum { items_per_page = 496 / size }; // 1048560 / size + +#ifdef BOOST_HAS_THREADS static lightweight_mutex mutex; - static std::deque store; +#endif + static block * free; - + static block * page; + static unsigned last; + static inline void * alloc() { #ifdef BOOST_HAS_THREADS @@ -61,8 +77,15 @@ template struct allocator_impl } else { - store.resize(store.size() + 1); - return &store.back(); + if(last == items_per_page) + { + // "Listen to me carefully: there is no memory leak" + // -- Scott Meyers, Eff C++ 2nd Ed Item 10 + page = ::new block[items_per_page]; + last = 0; + } + + return &page[last++]; } } @@ -84,8 +107,13 @@ template struct allocator_impl } else { - store.resize(store.size() + 1); - return &store.back(); + if(last == items_per_page) + { + page = ::new block[items_per_page]; + last = 0; + } + + return &page[last++]; } } } @@ -105,34 +133,36 @@ template struct allocator_impl static inline void dealloc(void * pv, std::size_t n) { - if(pv != 0) // 18.4.1.1/13 + if(n != size) // class-specific delete called for a derived object + { + ::operator delete(pv); + } + else if(pv != 0) // 18.4.1.1/13 { - if(n != size) // class-specific delete called for a derived object - { - ::operator delete(pv); - } - else - { #ifdef BOOST_HAS_THREADS - lightweight_mutex::scoped_lock lock(mutex); + lightweight_mutex::scoped_lock lock(mutex); #endif - block * pb = static_cast(pv); - pb->next = free; - free = pb; - } + block * pb = static_cast(pv); + pb->next = free; + free = pb; } } }; +#ifdef BOOST_HAS_THREADS template lightweight_mutex allocator_impl::mutex; - -template - std::deque< freeblock > allocator_impl::store; +#endif template freeblock * allocator_impl::free = 0; +template + freeblock * allocator_impl::page = 0; + +template + unsigned allocator_impl::last = allocator_impl::items_per_page; + template struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of::value > { From eee70bdcab6f4a0430c29e32242c0dae90783b26 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 7 Feb 2003 18:43:48 +0000 Subject: [PATCH 07/55] Added BOOST_QA_PAGE_SIZE. [SVN r17270] --- include/boost/detail/quick_allocator.hpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/include/boost/detail/quick_allocator.hpp b/include/boost/detail/quick_allocator.hpp index 2d8d735..195e602 100644 --- a/include/boost/detail/quick_allocator.hpp +++ b/include/boost/detail/quick_allocator.hpp @@ -55,8 +55,16 @@ template struct allocator_impl // // The other alternative is to use much bigger pages (1M.) +#if defined(BOOST_QA_PAGE_SIZE) + + enum { items_per_page = BOOST_QA_PAGE_SIZE / size }; + +#else + enum { items_per_page = 496 / size }; // 1048560 / size +#endif + #ifdef BOOST_HAS_THREADS static lightweight_mutex mutex; #endif From ce36b11fd56509a680300156007242c7cedc7faa Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 7 Feb 2003 19:06:28 +0000 Subject: [PATCH 08/55] Made the default page size 512 (g++ 2.96 on Red Hat 7.2 dislikes 496.) [SVN r17272] --- include/boost/detail/quick_allocator.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/boost/detail/quick_allocator.hpp b/include/boost/detail/quick_allocator.hpp index 195e602..f206b79 100644 --- a/include/boost/detail/quick_allocator.hpp +++ b/include/boost/detail/quick_allocator.hpp @@ -54,6 +54,10 @@ template struct allocator_impl // and don't interfere with ::new. // // The other alternative is to use much bigger pages (1M.) + // + // It is surprisingly easy to hit pathological behavior by + // varying the page size. g++ 2.96 on Red Hat Linux 7.2, + // for example, passionately dislikes 496. 512 seems OK. #if defined(BOOST_QA_PAGE_SIZE) @@ -61,7 +65,7 @@ template struct allocator_impl #else - enum { items_per_page = 496 / size }; // 1048560 / size + enum { items_per_page = 512 / size }; // 1048560 / size #endif From ec1c6ed4146c75345e93d1e573b0e89ca1601de8 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 22 Feb 2003 13:40:23 +0000 Subject: [PATCH 09/55] Fixes for Comeau with Borland as backend. [SVN r17588] --- include/boost/detail/quick_allocator.hpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/include/boost/detail/quick_allocator.hpp b/include/boost/detail/quick_allocator.hpp index f206b79..58cc1d8 100644 --- a/include/boost/detail/quick_allocator.hpp +++ b/include/boost/detail/quick_allocator.hpp @@ -32,17 +32,17 @@ namespace boost namespace detail { -template union freeblock +template union freeblock { - typedef typename boost::type_with_alignment::type aligner_type; + typedef typename boost::type_with_alignment::type aligner_type; aligner_type aligner; char bytes[size]; freeblock * next; }; -template struct allocator_impl +template struct allocator_impl { - typedef freeblock block; + typedef freeblock block; // It may seem odd to use such small pages. // @@ -162,18 +162,18 @@ template struct allocator_impl }; #ifdef BOOST_HAS_THREADS -template - lightweight_mutex allocator_impl::mutex; +template + lightweight_mutex allocator_impl::mutex; #endif -template - freeblock * allocator_impl::free = 0; +template + freeblock * allocator_impl::free = 0; -template - freeblock * allocator_impl::page = 0; +template + freeblock * allocator_impl::page = 0; -template - unsigned allocator_impl::last = allocator_impl::items_per_page; +template + unsigned allocator_impl::last = allocator_impl::items_per_page; template struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of::value > From d676bac36aece1f653575501b632c469e6203a1d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 12 Jun 2003 17:09:24 +0000 Subject: [PATCH 10/55] -Wundef fixes. [SVN r18788] --- include/boost/detail/quick_allocator.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/detail/quick_allocator.hpp b/include/boost/detail/quick_allocator.hpp index 58cc1d8..83987d5 100644 --- a/include/boost/detail/quick_allocator.hpp +++ b/include/boost/detail/quick_allocator.hpp @@ -1,8 +1,8 @@ #ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED #define BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED -#if _MSC_VER >= 1020 -#pragma once +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once #endif // From 5320981cbb8876a7231c9b1900505637e30f8c5f Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 28 Nov 2003 15:35:21 +0000 Subject: [PATCH 11/55] _MSC_VER use clarified. [SVN r20992] --- include/boost/detail/quick_allocator.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/boost/detail/quick_allocator.hpp b/include/boost/detail/quick_allocator.hpp index 83987d5..e2b3f57 100644 --- a/include/boost/detail/quick_allocator.hpp +++ b/include/boost/detail/quick_allocator.hpp @@ -1,6 +1,8 @@ #ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED #define BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED +// MS compatible compilers support #pragma once + #if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif From e0ec2a0aaa12d2fe57e3f8e4f2f7d8fd34e674e7 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Mon, 26 Jul 2004 00:32:12 +0000 Subject: [PATCH 12/55] Converted to Boost Software License, Version 1.0 [SVN r24055] --- include/boost/detail/quick_allocator.hpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/boost/detail/quick_allocator.hpp b/include/boost/detail/quick_allocator.hpp index e2b3f57..eb6398c 100644 --- a/include/boost/detail/quick_allocator.hpp +++ b/include/boost/detail/quick_allocator.hpp @@ -13,10 +13,9 @@ // Copyright (c) 2003 David Abrahams // Copyright (c) 2003 Peter Dimov // -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) // #include From 43bc30e5768697b0b1b36b440146d62ed88db659 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 18 Mar 2005 01:27:11 +0000 Subject: [PATCH 13/55] Split sp_counted_base into no threads (nt), win32 lock-free (w32) and pthreads (pt) [SVN r27729] --- include/boost/detail/interlocked.hpp | 78 ++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 include/boost/detail/interlocked.hpp diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp new file mode 100644 index 0000000..efca8e7 --- /dev/null +++ b/include/boost/detail/interlocked.hpp @@ -0,0 +1,78 @@ +#ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED +#define BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/interlocked.hpp +// +// Copyright 2005 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include + +#if defined( BOOST_USE_WINDOWS_H ) + +# include + +# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange + +#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) + +# if defined( BOOST_MSVC ) && ( BOOST_MSVC >= 1400 ) + +# include + +# else + +extern "C" long __cdecl _InterlockedIncrement( long volatile * ); +extern "C" long __cdecl _InterlockedDecrement( long volatile * ); +extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); + +# endif + +# pragma intrinsic( _InterlockedIncrement ) +# pragma intrinsic( _InterlockedDecrement ) +# pragma intrinsic( _InterlockedCompareExchange ) + +# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange + +#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) + +namespace boost +{ + +namespace detail +{ + +extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * ); +extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * ); +extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long ); + +} // namespace detail + +} // namespace boost + +# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange + +#else + +# error "Interlocked intrinsics not available" + +#endif + +#endif // #ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED From 0fd3947e199add52f151e0235fdf0f2a5e0cf726 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Fri, 18 Mar 2005 18:23:59 +0000 Subject: [PATCH 14/55] appears broken. [SVN r27737] --- include/boost/detail/interlocked.hpp | 8 -------- 1 file changed, 8 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index efca8e7..025f3b5 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -29,18 +29,10 @@ #elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) -# if defined( BOOST_MSVC ) && ( BOOST_MSVC >= 1400 ) - -# include - -# else - extern "C" long __cdecl _InterlockedIncrement( long volatile * ); extern "C" long __cdecl _InterlockedDecrement( long volatile * ); extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); -# endif - # pragma intrinsic( _InterlockedIncrement ) # pragma intrinsic( _InterlockedDecrement ) # pragma intrinsic( _InterlockedCompareExchange ) From d9f24f882e2002b2fe51c345056d83f40022ed06 Mon Sep 17 00:00:00 2001 From: Anthony Williams Date: Wed, 7 Sep 2005 15:02:16 +0000 Subject: [PATCH 15/55] New version of call_once for win32 [SVN r30847] --- include/boost/detail/interlocked.hpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 025f3b5..4e497ba 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -23,23 +23,27 @@ # include -# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_INTERLOCKED_INCREMENT ::InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT ::InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE ::InterlockedExchange #elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) extern "C" long __cdecl _InterlockedIncrement( long volatile * ); extern "C" long __cdecl _InterlockedDecrement( long volatile * ); extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __cdecl _InterlockedExchange( long volatile *, long); # pragma intrinsic( _InterlockedIncrement ) # pragma intrinsic( _InterlockedDecrement ) # pragma intrinsic( _InterlockedCompareExchange ) +# pragma intrinsic( _InterlockedExchange ) -# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_INTERLOCKED_INCREMENT ::_InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT ::_InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::_InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE ::_InterlockedExchange #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) @@ -52,14 +56,16 @@ namespace detail extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * ); extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * ); extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long ); +extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long ); } // namespace detail } // namespace boost -# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange #else From 142eb95986b9371e5fc725539e87815b5dd3e4e8 Mon Sep 17 00:00:00 2001 From: Anthony Williams Date: Tue, 13 Sep 2005 09:37:02 +0000 Subject: [PATCH 16/55] Added interlocked compare/exchange for pointers, and interlocked_read for values and pointers [SVN r30941] --- include/boost/detail/interlocked.hpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 4e497ba..0d504f5 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -27,6 +27,7 @@ # define BOOST_INTERLOCKED_DECREMENT ::InterlockedDecrement # define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::InterlockedCompareExchange # define BOOST_INTERLOCKED_EXCHANGE ::InterlockedExchange +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER ::InterlockedCompareExchangePointer #elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) @@ -34,16 +35,19 @@ extern "C" long __cdecl _InterlockedIncrement( long volatile * ); extern "C" long __cdecl _InterlockedDecrement( long volatile * ); extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); extern "C" long __cdecl _InterlockedExchange( long volatile *, long); +extern "C" void* __cdecl _InterlockedCompareExchangePointer( void* volatile *, void*, void* ); # pragma intrinsic( _InterlockedIncrement ) # pragma intrinsic( _InterlockedDecrement ) # pragma intrinsic( _InterlockedCompareExchange ) # pragma intrinsic( _InterlockedExchange ) +# pragma intrinsic( _InterlockedCompareExchangePointer ) # define BOOST_INTERLOCKED_INCREMENT ::_InterlockedIncrement # define BOOST_INTERLOCKED_DECREMENT ::_InterlockedDecrement # define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::_InterlockedCompareExchange # define BOOST_INTERLOCKED_EXCHANGE ::_InterlockedExchange +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER ::_InterlockedCompareExchangePointer #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) @@ -57,6 +61,7 @@ extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volat extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * ); extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long ); extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long ); +extern "C" __declspec(dllimport) void* __stdcall InterlockedCompareExchangePointer( void* volatile *, void*, void* ); } // namespace detail @@ -66,6 +71,7 @@ extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volati # define BOOST_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement # define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange # define BOOST_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER ::boost::detail::InterlockedCompareExchangePointer #else @@ -73,4 +79,8 @@ extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volati #endif +#define BOOST_INTERLOCKED_READ(x) BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,0,0) +#define BOOST_INTERLOCKED_READ_POINTER(x) BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0) + + #endif // #ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED From 7c7250379b3fff11cafb967eae044085ef5f5487 Mon Sep 17 00:00:00 2001 From: Anthony Williams Date: Tue, 13 Sep 2005 14:19:46 +0000 Subject: [PATCH 17/55] InterlockedCompareExchangePointer is only intrinsic on 64 bit platforms, otherwise it's just a synonym for InterlockedCompareExchange [SVN r30951] --- include/boost/detail/interlocked.hpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 0d504f5..49f8da4 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -35,19 +35,24 @@ extern "C" long __cdecl _InterlockedIncrement( long volatile * ); extern "C" long __cdecl _InterlockedDecrement( long volatile * ); extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); extern "C" long __cdecl _InterlockedExchange( long volatile *, long); -extern "C" void* __cdecl _InterlockedCompareExchangePointer( void* volatile *, void*, void* ); # pragma intrinsic( _InterlockedIncrement ) # pragma intrinsic( _InterlockedDecrement ) # pragma intrinsic( _InterlockedCompareExchange ) # pragma intrinsic( _InterlockedExchange ) -# pragma intrinsic( _InterlockedCompareExchangePointer ) +# if defined(_M_IA64) || defined(_M_AMD64) +extern "C" void* __cdecl _InterlockedCompareExchangePointer( void* volatile *, void*, void* ); +# pragma intrinsic( _InterlockedCompareExchangePointer ) +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER ::_InterlockedCompareExchangePointer +# else +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# endif # define BOOST_INTERLOCKED_INCREMENT ::_InterlockedIncrement # define BOOST_INTERLOCKED_DECREMENT ::_InterlockedDecrement # define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::_InterlockedCompareExchange # define BOOST_INTERLOCKED_EXCHANGE ::_InterlockedExchange -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER ::_InterlockedCompareExchangePointer #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) @@ -61,8 +66,6 @@ extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volat extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * ); extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long ); extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long ); -extern "C" __declspec(dllimport) void* __stdcall InterlockedCompareExchangePointer( void* volatile *, void*, void* ); - } // namespace detail } // namespace boost @@ -71,7 +74,8 @@ extern "C" __declspec(dllimport) void* __stdcall InterlockedCompareExchangePoint # define BOOST_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement # define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange # define BOOST_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER ::boost::detail::InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) #else From 677a0777d2c58ed2656ea0d04bdd51d11c1dfc48 Mon Sep 17 00:00:00 2001 From: Anthony Williams Date: Fri, 16 Sep 2005 13:57:44 +0000 Subject: [PATCH 18/55] Added InterlockedExchangePointer [SVN r31010] --- include/boost/detail/interlocked.hpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 49f8da4..3150642 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -23,11 +23,12 @@ # include -# define BOOST_INTERLOCKED_INCREMENT ::InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT ::InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE ::InterlockedExchange -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER ::InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER InterlockedExchangePointer #elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) @@ -42,11 +43,16 @@ extern "C" long __cdecl _InterlockedExchange( long volatile *, long); # pragma intrinsic( _InterlockedExchange ) # if defined(_M_IA64) || defined(_M_AMD64) extern "C" void* __cdecl _InterlockedCompareExchangePointer( void* volatile *, void*, void* ); +extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); # pragma intrinsic( _InterlockedCompareExchangePointer ) +# pragma intrinsic( _InterlockedExchangePointer ) # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER ::_InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER ::_InterlockedExchangePointer # else # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) # endif # define BOOST_INTERLOCKED_INCREMENT ::_InterlockedIncrement From 77aeaee7a7a581d5bca833096d0580637c5d5a51 Mon Sep 17 00:00:00 2001 From: Anthony Williams Date: Fri, 16 Sep 2005 14:05:33 +0000 Subject: [PATCH 19/55] Added BOOST_INTERLOCKED_EXCHANGE_POINTER in all branches of the #if [SVN r31012] --- include/boost/detail/interlocked.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 3150642..1771eb7 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -82,6 +82,8 @@ extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volati # define BOOST_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) #else From b4c8cf3958b4f814545612afdc020895d4276d73 Mon Sep 17 00:00:00 2001 From: Anthony Williams Date: Fri, 23 Sep 2005 16:56:09 +0000 Subject: [PATCH 20/55] Removed :: qualification on _Interlocked functions [SVN r31097] --- include/boost/detail/interlocked.hpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 1771eb7..3f66152 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -46,8 +46,8 @@ extern "C" void* __cdecl _InterlockedCompareExchangePointer( void* volatile *, v extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); # pragma intrinsic( _InterlockedCompareExchangePointer ) # pragma intrinsic( _InterlockedExchangePointer ) -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER ::_InterlockedCompareExchangePointer -# define BOOST_INTERLOCKED_EXCHANGE_POINTER ::_InterlockedExchangePointer +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer # else # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) @@ -55,10 +55,10 @@ extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) # endif -# define BOOST_INTERLOCKED_INCREMENT ::_InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT ::_InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::_InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE ::_InterlockedExchange +# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) From 21198d07fd0d197d189bc05464fc83ee3af9baaf Mon Sep 17 00:00:00 2001 From: Anthony Williams Date: Fri, 23 Sep 2005 17:24:29 +0000 Subject: [PATCH 21/55] Moved BOOST_INTERLOCKED_READ stuff into its own header [SVN r31098] --- include/boost/detail/interlocked.hpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 3f66152..1b88382 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -91,8 +91,4 @@ extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volati #endif -#define BOOST_INTERLOCKED_READ(x) BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,0,0) -#define BOOST_INTERLOCKED_READ_POINTER(x) BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0) - - #endif // #ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED From 8c50214e3f2a8e2744aababe347e0712582ea678 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Tue, 6 Dec 2005 12:24:40 +0000 Subject: [PATCH 22/55] Fixed bug #1370716, static shared_ptr instances not working w/ quick_allocator [SVN r31931] --- include/boost/detail/quick_allocator.hpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/include/boost/detail/quick_allocator.hpp b/include/boost/detail/quick_allocator.hpp index eb6398c..7c19d0f 100644 --- a/include/boost/detail/quick_allocator.hpp +++ b/include/boost/detail/quick_allocator.hpp @@ -71,7 +71,15 @@ template struct allocator_impl #endif #ifdef BOOST_HAS_THREADS - static lightweight_mutex mutex; + + static lightweight_mutex & mutex() + { + static lightweight_mutex m; + return m; + } + + static lightweight_mutex * mutex_init; + #endif static block * free; @@ -81,7 +89,7 @@ template struct allocator_impl static inline void * alloc() { #ifdef BOOST_HAS_THREADS - lightweight_mutex::scoped_lock lock(mutex); + lightweight_mutex::scoped_lock lock( mutex() ); #endif if(block * x = free) { @@ -111,7 +119,7 @@ template struct allocator_impl else { #ifdef BOOST_HAS_THREADS - lightweight_mutex::scoped_lock lock(mutex); + lightweight_mutex::scoped_lock lock( mutex() ); #endif if(block * x = free) { @@ -136,7 +144,7 @@ template struct allocator_impl if(pv != 0) // 18.4.1.1/13 { #ifdef BOOST_HAS_THREADS - lightweight_mutex::scoped_lock lock(mutex); + lightweight_mutex::scoped_lock lock( mutex() ); #endif block * pb = static_cast(pv); pb->next = free; @@ -153,7 +161,7 @@ template struct allocator_impl else if(pv != 0) // 18.4.1.1/13 { #ifdef BOOST_HAS_THREADS - lightweight_mutex::scoped_lock lock(mutex); + lightweight_mutex::scoped_lock lock( mutex() ); #endif block * pb = static_cast(pv); pb->next = free; @@ -163,8 +171,10 @@ template struct allocator_impl }; #ifdef BOOST_HAS_THREADS + template - lightweight_mutex allocator_impl::mutex; + lightweight_mutex allocator_impl::mutex_init = &lightweight_mutex allocator_impl::mutex(); + #endif template From 82fe5f5095f71c4a30a051d3f420a5b665b90a4c Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 7 Dec 2005 20:41:11 +0000 Subject: [PATCH 23/55] Fixed a couple of syntax errors (reported by Juergen Hunold) [SVN r31946] --- include/boost/detail/quick_allocator.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/detail/quick_allocator.hpp b/include/boost/detail/quick_allocator.hpp index 7c19d0f..ddb0a76 100644 --- a/include/boost/detail/quick_allocator.hpp +++ b/include/boost/detail/quick_allocator.hpp @@ -173,7 +173,7 @@ template struct allocator_impl #ifdef BOOST_HAS_THREADS template - lightweight_mutex allocator_impl::mutex_init = &lightweight_mutex allocator_impl::mutex(); + lightweight_mutex * allocator_impl::mutex_init = &allocator_impl::mutex(); #endif From e274885fd2bfae4c369418b69835b04721a30726 Mon Sep 17 00:00:00 2001 From: Anthony Williams Date: Wed, 8 Mar 2006 22:24:52 +0000 Subject: [PATCH 24/55] Win32 implementation of boost::timed_mutex [SVN r33272] --- include/boost/detail/interlocked.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 1b88382..3149319 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -27,6 +27,7 @@ # define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement # define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange # define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER InterlockedCompareExchangePointer # define BOOST_INTERLOCKED_EXCHANGE_POINTER InterlockedExchangePointer @@ -36,11 +37,13 @@ extern "C" long __cdecl _InterlockedIncrement( long volatile * ); extern "C" long __cdecl _InterlockedDecrement( long volatile * ); extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); extern "C" long __cdecl _InterlockedExchange( long volatile *, long); +extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long); # pragma intrinsic( _InterlockedIncrement ) # pragma intrinsic( _InterlockedDecrement ) # pragma intrinsic( _InterlockedCompareExchange ) # pragma intrinsic( _InterlockedExchange ) +# pragma intrinsic( _InterlockedExchangeAdd ) # if defined(_M_IA64) || defined(_M_AMD64) extern "C" void* __cdecl _InterlockedCompareExchangePointer( void* volatile *, void*, void* ); extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); @@ -59,6 +62,7 @@ extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); # define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement # define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange # define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) @@ -72,6 +76,7 @@ extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volat extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * ); extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long ); extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long ); +extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long ); } // namespace detail } // namespace boost @@ -80,6 +85,7 @@ extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volati # define BOOST_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement # define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange # define BOOST_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) # define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ From 6341b8802a0c98c79b8a36c52955590c26a3cd8c Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 17 May 2006 22:33:47 +0000 Subject: [PATCH 25/55] Windows CE patch by Michael Fink [SVN r33986] --- include/boost/detail/interlocked.hpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 3149319..76a24c3 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -31,6 +31,22 @@ # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER InterlockedCompareExchangePointer # define BOOST_INTERLOCKED_EXCHANGE_POINTER InterlockedExchangePointer +#elif defined(_WIN32_WCE) + +// under Windows CE we still have old-style Interlocked* functions + +extern "C" long __cdecl InterlockedIncrement( long* ); +extern "C" long __cdecl InterlockedDecrement( long* ); +extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); +extern "C" long __cdecl InterlockedExchange( long*, long ); +extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); + +# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd + #elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) extern "C" long __cdecl _InterlockedIncrement( long volatile * ); @@ -44,18 +60,25 @@ extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long); # pragma intrinsic( _InterlockedCompareExchange ) # pragma intrinsic( _InterlockedExchange ) # pragma intrinsic( _InterlockedExchangeAdd ) + # if defined(_M_IA64) || defined(_M_AMD64) + extern "C" void* __cdecl _InterlockedCompareExchangePointer( void* volatile *, void*, void* ); extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); + # pragma intrinsic( _InterlockedCompareExchangePointer ) # pragma intrinsic( _InterlockedExchangePointer ) + # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer # define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer + # else + # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) # define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) + # endif # define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement @@ -77,6 +100,7 @@ extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volat extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long ); extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long ); extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long ); + } // namespace detail } // namespace boost @@ -86,6 +110,7 @@ extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long vol # define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange # define BOOST_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange # define BOOST_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd + # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) # define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ From 451c71c1bd4e3d855a64ae32251a9bfb092a7280 Mon Sep 17 00:00:00 2001 From: Anthony Williams Date: Fri, 2 Nov 2007 09:17:02 +0000 Subject: [PATCH 26/55] Added changes from David Deakins to enable compilation on Windows CE [SVN r40679] --- include/boost/detail/interlocked.hpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 76a24c3..258320c 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -47,6 +47,11 @@ extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); # define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange # define BOOST_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long*)(dest),(long)(exchange))) + #elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) extern "C" long __cdecl _InterlockedIncrement( long volatile * ); From aab1328e060b2c661ddb8d672733f29a6eae6965 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sat, 5 Apr 2008 15:06:31 +0000 Subject: [PATCH 27/55] spinlock_nt.hpp added, Cygwin fixes. [SVN r44055] --- include/boost/detail/interlocked.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 258320c..b6c8d75 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -92,7 +92,7 @@ extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); # define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange # define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd -#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) +#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) namespace boost { From 6ede4ec4c69b142b5d6bf2820150f44c1e083d89 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 20 Apr 2008 15:37:08 +0000 Subject: [PATCH 28/55] Factored out boost/detail/lightweight_thread.hpp. [SVN r44638] --- include/boost/detail/lightweight_thread.hpp | 135 ++++++++++++++++++++ 1 file changed, 135 insertions(+) create mode 100644 include/boost/detail/lightweight_thread.hpp diff --git a/include/boost/detail/lightweight_thread.hpp b/include/boost/detail/lightweight_thread.hpp new file mode 100644 index 0000000..6fe70a6 --- /dev/null +++ b/include/boost/detail/lightweight_thread.hpp @@ -0,0 +1,135 @@ +#ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED +#define BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/detail/lightweight_thread.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// Copyright (c) 2008 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include + +// pthread_create, pthread_join + +#if defined( BOOST_HAS_PTHREADS ) + +#include + +#else + +#include +#include + +typedef HANDLE pthread_t; + +int pthread_create( pthread_t * thread, void const *, unsigned (__stdcall * start_routine) (void*), void* arg ) +{ + HANDLE h = (HANDLE)_beginthreadex( 0, 0, start_routine, arg, 0, 0 ); + + if( h != 0 ) + { + *thread = h; + return 0; + } + else + { + return EAGAIN; + } +} + +int pthread_join( pthread_t thread, void ** /*value_ptr*/ ) +{ + ::WaitForSingleObject( thread, INFINITE ); + ::CloseHandle( thread ); + return 0; +} + +#endif + +// template int lw_thread_create( pthread_t & pt, F f ); + +namespace boost +{ + +namespace detail +{ + +class lw_abstract_thread +{ +public: + + virtual ~lw_abstract_thread() {} + virtual void run() = 0; +}; + +#if defined( BOOST_HAS_PTHREADS ) + +extern "C" void * lw_thread_routine( void * pv ) +{ + std::auto_ptr pt( static_cast( pv ) ); + + pt->run(); + + return 0; +} + +#else + +unsigned __stdcall lw_thread_routine( void * pv ) +{ + std::auto_ptr pt( static_cast( pv ) ); + + pt->run(); + + return 0; +} + +#endif + +template class lw_thread_impl: public lw_abstract_thread +{ +public: + + explicit lw_thread_impl( F f ): f_( f ) + { + } + + void run() + { + f_(); + } + +private: + + F f_; +}; + +template int lw_thread_create( pthread_t & pt, F f ) +{ + std::auto_ptr p( new lw_thread_impl( f ) ); + + int r = pthread_create( &pt, 0, lw_thread_routine, p.get() ); + + if( r == 0 ) + { + p.release(); + } + + return r; +} + +} // namespace detail +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_THREAD_HPP_INCLUDED From bd5b684fd3ea5ff82ccf9f9033b9f5a93bec5a01 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 1 Mar 2009 16:00:42 +0000 Subject: [PATCH 29/55] Move smart_ptr into boost/smart_ptr/*.hpp (refs #2239). [SVN r51509] --- include/boost/detail/quick_allocator.hpp | 183 +---------------------- 1 file changed, 4 insertions(+), 179 deletions(-) diff --git a/include/boost/detail/quick_allocator.hpp b/include/boost/detail/quick_allocator.hpp index ddb0a76..d54b3a7 100644 --- a/include/boost/detail/quick_allocator.hpp +++ b/include/boost/detail/quick_allocator.hpp @@ -13,186 +13,11 @@ // Copyright (c) 2003 David Abrahams // Copyright (c) 2003 Peter Dimov // -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt // -#include - -#include -#include -#include - -#include // ::operator new, ::operator delete -#include // std::size_t - -namespace boost -{ - -namespace detail -{ - -template union freeblock -{ - typedef typename boost::type_with_alignment::type aligner_type; - aligner_type aligner; - char bytes[size]; - freeblock * next; -}; - -template struct allocator_impl -{ - typedef freeblock block; - - // It may seem odd to use such small pages. - // - // However, on a typical Windows implementation that uses - // the OS allocator, "normal size" pages interact with the - // "ordinary" operator new, slowing it down dramatically. - // - // 512 byte pages are handled by the small object allocator, - // and don't interfere with ::new. - // - // The other alternative is to use much bigger pages (1M.) - // - // It is surprisingly easy to hit pathological behavior by - // varying the page size. g++ 2.96 on Red Hat Linux 7.2, - // for example, passionately dislikes 496. 512 seems OK. - -#if defined(BOOST_QA_PAGE_SIZE) - - enum { items_per_page = BOOST_QA_PAGE_SIZE / size }; - -#else - - enum { items_per_page = 512 / size }; // 1048560 / size - -#endif - -#ifdef BOOST_HAS_THREADS - - static lightweight_mutex & mutex() - { - static lightweight_mutex m; - return m; - } - - static lightweight_mutex * mutex_init; - -#endif - - static block * free; - static block * page; - static unsigned last; - - static inline void * alloc() - { -#ifdef BOOST_HAS_THREADS - lightweight_mutex::scoped_lock lock( mutex() ); -#endif - if(block * x = free) - { - free = x->next; - return x; - } - else - { - if(last == items_per_page) - { - // "Listen to me carefully: there is no memory leak" - // -- Scott Meyers, Eff C++ 2nd Ed Item 10 - page = ::new block[items_per_page]; - last = 0; - } - - return &page[last++]; - } - } - - static inline void * alloc(std::size_t n) - { - if(n != size) // class-specific new called for a derived object - { - return ::operator new(n); - } - else - { -#ifdef BOOST_HAS_THREADS - lightweight_mutex::scoped_lock lock( mutex() ); -#endif - if(block * x = free) - { - free = x->next; - return x; - } - else - { - if(last == items_per_page) - { - page = ::new block[items_per_page]; - last = 0; - } - - return &page[last++]; - } - } - } - - static inline void dealloc(void * pv) - { - if(pv != 0) // 18.4.1.1/13 - { -#ifdef BOOST_HAS_THREADS - lightweight_mutex::scoped_lock lock( mutex() ); -#endif - block * pb = static_cast(pv); - pb->next = free; - free = pb; - } - } - - static inline void dealloc(void * pv, std::size_t n) - { - if(n != size) // class-specific delete called for a derived object - { - ::operator delete(pv); - } - else if(pv != 0) // 18.4.1.1/13 - { -#ifdef BOOST_HAS_THREADS - lightweight_mutex::scoped_lock lock( mutex() ); -#endif - block * pb = static_cast(pv); - pb->next = free; - free = pb; - } - } -}; - -#ifdef BOOST_HAS_THREADS - -template - lightweight_mutex * allocator_impl::mutex_init = &allocator_impl::mutex(); - -#endif - -template - freeblock * allocator_impl::free = 0; - -template - freeblock * allocator_impl::page = 0; - -template - unsigned allocator_impl::last = allocator_impl::items_per_page; - -template -struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of::value > -{ -}; - -} // namespace detail - -} // namespace boost +#include #endif // #ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED From 97a9aac5f083bd2ebbf38f7126178073f1b80858 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 26 Nov 2009 21:40:50 +0000 Subject: [PATCH 30/55] Fix interlocked.hpp to compile under /clr:pure. Refs #3378. [SVN r57958] --- include/boost/detail/interlocked.hpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index b6c8d75..fccebc3 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -54,11 +54,23 @@ extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); #elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) +#if defined( __CLRCALL_PURE_OR_CDECL ) + +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long ); + +#else + extern "C" long __cdecl _InterlockedIncrement( long volatile * ); extern "C" long __cdecl _InterlockedDecrement( long volatile * ); extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); -extern "C" long __cdecl _InterlockedExchange( long volatile *, long); -extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long); +extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); +extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); + +#endif # pragma intrinsic( _InterlockedIncrement ) # pragma intrinsic( _InterlockedDecrement ) From 3dbde36076d39a440cab9374ef862249849bf750 Mon Sep 17 00:00:00 2001 From: Anthony Williams Date: Mon, 7 Jun 2010 15:44:32 +0000 Subject: [PATCH 31/55] Applied patch from issue #3377 [SVN r62509] --- include/boost/detail/interlocked.hpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index fccebc3..c88d326 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -118,6 +118,11 @@ extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long ); extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long ); +# if defined(_M_IA64) || defined(_M_AMD64) +extern "C" __declspec(dllimport) void* __stdcall InterlockedCompareExchangePointer( void* volatile *, void*, void* ); +extern "C" __declspec(dllimport) void* __stdcall InterlockedExchangePointer( void* volatile *, void* ); +# endif + } // namespace detail } // namespace boost @@ -128,10 +133,15 @@ extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long vol # define BOOST_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange # define BOOST_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ +# if defined(_M_IA64) || defined(_M_AMD64) +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER ::boost::detail::InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER ::boost::detail::InterlockedExchangePointer +# else +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) -# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) +# endif #else From 5dabdf635c9a880b7b8aaab44fd122054b5f5cfd Mon Sep 17 00:00:00 2001 From: Anthony Williams Date: Mon, 21 Mar 2011 23:09:07 +0000 Subject: [PATCH 32/55] Applied patch from issue #4849 [SVN r70383] --- include/boost/detail/interlocked.hpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index c88d326..5889ccb 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -106,21 +106,28 @@ extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) +#if defined(__MINGW64__) +#define BOOST_INTERLOCKED_IMPORT +#else +#define BOOST_INTERLOCKED_IMPORT __declspec(dllimport) +#endif + + namespace boost { namespace detail { -extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * ); -extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * ); -extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long ); -extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long ); -extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long ); +extern "C"BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedIncrement( long volatile * ); +extern "C"BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedDecrement( long volatile * ); +extern "C"BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedCompareExchange( long volatile *, long, long ); +extern "C"BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedExchange( long volatile *, long ); +extern "C"BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedExchangeAdd( long volatile *, long ); # if defined(_M_IA64) || defined(_M_AMD64) -extern "C" __declspec(dllimport) void* __stdcall InterlockedCompareExchangePointer( void* volatile *, void*, void* ); -extern "C" __declspec(dllimport) void* __stdcall InterlockedExchangePointer( void* volatile *, void* ); +extern "C"BOOST_INTERLOCKED_IMPORT void* __stdcall InterlockedCompareExchangePointer( void* volatile *, void*, void* ); +extern "C"BOOST_INTERLOCKED_IMPORT void* __stdcall InterlockedExchangePointer( void* volatile *, void* ); # endif } // namespace detail From dffbf7c9310266ab30b948c2b8109da5946090d5 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Mon, 7 Nov 2011 23:08:53 +0000 Subject: [PATCH 33/55] Use for VS2010+. Refs #4678. [SVN r75396] --- include/boost/detail/interlocked.hpp | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 5889ccb..1802e34 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -54,7 +54,11 @@ extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); #elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) -#if defined( __CLRCALL_PURE_OR_CDECL ) +#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1600 + +#include + +#elif defined( __CLRCALL_PURE_OR_CDECL ) extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * ); extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * ); @@ -119,15 +123,15 @@ namespace boost namespace detail { -extern "C"BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedIncrement( long volatile * ); -extern "C"BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedDecrement( long volatile * ); -extern "C"BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedCompareExchange( long volatile *, long, long ); -extern "C"BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedExchange( long volatile *, long ); -extern "C"BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedExchangeAdd( long volatile *, long ); +extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedIncrement( long volatile * ); +extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedDecrement( long volatile * ); +extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedCompareExchange( long volatile *, long, long ); +extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedExchange( long volatile *, long ); +extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedExchangeAdd( long volatile *, long ); # if defined(_M_IA64) || defined(_M_AMD64) -extern "C"BOOST_INTERLOCKED_IMPORT void* __stdcall InterlockedCompareExchangePointer( void* volatile *, void*, void* ); -extern "C"BOOST_INTERLOCKED_IMPORT void* __stdcall InterlockedExchangePointer( void* volatile *, void* ); +extern "C" BOOST_INTERLOCKED_IMPORT void* __stdcall InterlockedCompareExchangePointer( void* volatile *, void*, void* ); +extern "C" BOOST_INTERLOCKED_IMPORT void* __stdcall InterlockedExchangePointer( void* volatile *, void* ); # endif } // namespace detail From b69ca7aaa59e9ba8000c7d017eb9986a711d0823 Mon Sep 17 00:00:00 2001 From: "Vicente J. Botet Escriba" Date: Wed, 15 Aug 2012 10:02:09 +0000 Subject: [PATCH 34/55] Thread: Try to fix 5431 [SVN r80042] --- include/boost/detail/interlocked.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 1802e34..4c87e6e 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -35,11 +35,11 @@ // under Windows CE we still have old-style Interlocked* functions -extern "C" long __cdecl InterlockedIncrement( long* ); -extern "C" long __cdecl InterlockedDecrement( long* ); -extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); -extern "C" long __cdecl InterlockedExchange( long*, long ); -extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); +extern "C" long __cdecl InterlockedIncrement( long volatile * ); +extern "C" long __cdecl InterlockedDecrement( long volatile * ); +extern "C" long __cdecl InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __cdecl InterlockedExchange( long volatile *, long ); +extern "C" long __cdecl InterlockedExchangeAdd( long volatile *, long ); # define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement # define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement From 0401afc106d0da5f2b373c4365f730a46935abfb Mon Sep 17 00:00:00 2001 From: "Vicente J. Botet Escriba" Date: Fri, 17 Aug 2012 15:27:56 +0000 Subject: [PATCH 35/55] Thread: Rollback last modification as it breaks regression test VeecoFTC/msvc-9.0~wm5~stlport5.2 [SVN r80067] --- include/boost/detail/interlocked.hpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 4c87e6e..1802e34 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -35,11 +35,11 @@ // under Windows CE we still have old-style Interlocked* functions -extern "C" long __cdecl InterlockedIncrement( long volatile * ); -extern "C" long __cdecl InterlockedDecrement( long volatile * ); -extern "C" long __cdecl InterlockedCompareExchange( long volatile *, long, long ); -extern "C" long __cdecl InterlockedExchange( long volatile *, long ); -extern "C" long __cdecl InterlockedExchangeAdd( long volatile *, long ); +extern "C" long __cdecl InterlockedIncrement( long* ); +extern "C" long __cdecl InterlockedDecrement( long* ); +extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); +extern "C" long __cdecl InterlockedExchange( long*, long ); +extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); # define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement # define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement From 8fbb5e9e7f41a6fd846a649fb2e65d68ba7be042 Mon Sep 17 00:00:00 2001 From: "Vicente J. Botet Escriba" Date: Tue, 21 Aug 2012 21:36:12 +0000 Subject: [PATCH 36/55] Thread: Try again to fix 5431 [SVN r80127] --- include/boost/detail/interlocked.hpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 1802e34..916db81 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -33,6 +33,15 @@ #elif defined(_WIN32_WCE) +#if _WIN32_WCE >= 0x600 + +extern "C" long __cdecl _InterlockedIncrement( long volatile * ); +extern "C" long __cdecl _InterlockedDecrement( long volatile * ); +extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); +extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); + +#else // under Windows CE we still have old-style Interlocked* functions extern "C" long __cdecl InterlockedIncrement( long* ); @@ -41,6 +50,8 @@ extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); extern "C" long __cdecl InterlockedExchange( long*, long ); extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); +#endif + # define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement # define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement # define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange From fe04bea979b47542de8b104e485d9900c7cd3279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Hunold?= Date: Sat, 22 Sep 2012 15:35:41 +0000 Subject: [PATCH 37/55] Fix: intrin.h is available in msvc-9.0 (_MSC_VER 1500) [SVN r80626] --- include/boost/detail/interlocked.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 916db81..6434cb8 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -65,7 +65,7 @@ extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); #elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) -#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1600 +#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1500 #include From f5402a937e7f5eed41bd7077dfbe8c6046f086df Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 10 Oct 2012 13:11:38 +0000 Subject: [PATCH 38/55] Fix the _WIN32_WCE >= 0x600 case. [SVN r80935] --- include/boost/detail/interlocked.hpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 6434cb8..c8870d9 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -41,6 +41,12 @@ extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); +# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + #else // under Windows CE we still have old-style Interlocked* functions @@ -50,14 +56,14 @@ extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); extern "C" long __cdecl InterlockedExchange( long*, long ); extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); -#endif - # define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement # define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement # define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange # define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange # define BOOST_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd +#endif + # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest),(long)(exchange),(long)(compare))) # define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ From 443302306edcf6b098cbcdfa2dbec1aab448beb8 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Tue, 24 Sep 2013 12:49:46 +0000 Subject: [PATCH 39/55] Fixed compilation problems with MinGW-w64. [SVN r85865] --- include/boost/detail/interlocked.hpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index c8870d9..5130259 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -125,14 +125,30 @@ extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); # define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange # define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd +// Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets. +#elif defined(__MINGW64_VERSION_MAJOR) + +// MinGW-w64 provides intrin.h for both 32 and 64-bit targets. +#include + +# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd +# if defined(__x86_64__) || defined(__x86_64) +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer +# else +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) +# endif + #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) -#if defined(__MINGW64__) -#define BOOST_INTERLOCKED_IMPORT -#else #define BOOST_INTERLOCKED_IMPORT __declspec(dllimport) -#endif - namespace boost { From a56378ee3508b17b28b47199756768fd99935607 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Tue, 24 Sep 2013 12:56:50 +0000 Subject: [PATCH 40/55] Enabled #pragma once for all compilers that support it, not only MSVC. [SVN r85866] --- include/boost/detail/interlocked.hpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index 5130259..c2b3d2e 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -1,12 +1,6 @@ #ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED #define BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED -// MS compatible compilers support #pragma once - -#if defined(_MSC_VER) && (_MSC_VER >= 1020) -# pragma once -#endif - // // boost/detail/interlocked.hpp // @@ -19,6 +13,11 @@ #include +// MS compatible compilers support #pragma once +#ifdef BOOST_HAS_PRAGMA_ONCE +#pragma once +#endif + #if defined( BOOST_USE_WINDOWS_H ) # include From b7ee78884538a79e4767f29ddb87e09a752667d8 Mon Sep 17 00:00:00 2001 From: Stephen Kelly Date: Thu, 26 Sep 2013 13:02:51 +0000 Subject: [PATCH 41/55] Remove obsolete MSVC check from pragma guard git grep -h -B1 "^#\s*pragma once" | grep -v pragma | sort | uniq is now clean. [SVN r85952] --- include/boost/detail/lightweight_thread.hpp | 2 +- include/boost/detail/quick_allocator.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/detail/lightweight_thread.hpp b/include/boost/detail/lightweight_thread.hpp index 6fe70a6..8eba1f8 100644 --- a/include/boost/detail/lightweight_thread.hpp +++ b/include/boost/detail/lightweight_thread.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif diff --git a/include/boost/detail/quick_allocator.hpp b/include/boost/detail/quick_allocator.hpp index d54b3a7..ba048e0 100644 --- a/include/boost/detail/quick_allocator.hpp +++ b/include/boost/detail/quick_allocator.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) && (_MSC_VER >= 1020) +#if defined(_MSC_VER) # pragma once #endif From 2c32bf91b7d3232743190065206a3d88d3e7f036 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Sun, 29 Sep 2013 11:04:37 +0000 Subject: [PATCH 42/55] Add BOOST_USE_INTRIN_H support; remove #pragma intrinsic, not needed and not supported on Intel. [SVN r85994] --- include/boost/detail/interlocked.hpp | 33 ++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/detail/interlocked.hpp index c2b3d2e..1152f71 100644 --- a/include/boost/detail/interlocked.hpp +++ b/include/boost/detail/interlocked.hpp @@ -30,6 +30,30 @@ # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER InterlockedCompareExchangePointer # define BOOST_INTERLOCKED_EXCHANGE_POINTER InterlockedExchangePointer +#elif defined( BOOST_USE_INTRIN_H ) + +#include + +# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +# if defined(_M_IA64) || defined(_M_AMD64) || defined(__x86_64__) || defined(__x86_64) + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer +# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer + +# else + +# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ + ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) +# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ + ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) + +# endif + #elif defined(_WIN32_WCE) #if _WIN32_WCE >= 0x600 @@ -92,20 +116,11 @@ extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); #endif -# pragma intrinsic( _InterlockedIncrement ) -# pragma intrinsic( _InterlockedDecrement ) -# pragma intrinsic( _InterlockedCompareExchange ) -# pragma intrinsic( _InterlockedExchange ) -# pragma intrinsic( _InterlockedExchangeAdd ) - # if defined(_M_IA64) || defined(_M_AMD64) extern "C" void* __cdecl _InterlockedCompareExchangePointer( void* volatile *, void*, void* ); extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); -# pragma intrinsic( _InterlockedCompareExchangePointer ) -# pragma intrinsic( _InterlockedExchangePointer ) - # define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer # define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer From 208bfd78f9ab4baf24688e0ef92e50b26faf55ac Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 12 Feb 2014 16:39:56 +0200 Subject: [PATCH 43/55] Move interlocked.hpp to smart_ptr/detail --- include/boost/{ => smart_ptr}/detail/interlocked.hpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename include/boost/{ => smart_ptr}/detail/interlocked.hpp (100%) diff --git a/include/boost/detail/interlocked.hpp b/include/boost/smart_ptr/detail/interlocked.hpp similarity index 100% rename from include/boost/detail/interlocked.hpp rename to include/boost/smart_ptr/detail/interlocked.hpp From 0337743c8cb457de765fd3ef06e708b30b9aad9a Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 12 Feb 2014 16:57:45 +0200 Subject: [PATCH 44/55] Revert "Remove obsolete MSVC check from pragma guard" This reverts commit b7ee78884538a79e4767f29ddb87e09a752667d8. --- include/boost/detail/lightweight_thread.hpp | 2 +- include/boost/detail/quick_allocator.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/detail/lightweight_thread.hpp b/include/boost/detail/lightweight_thread.hpp index 8eba1f8..6fe70a6 100644 --- a/include/boost/detail/lightweight_thread.hpp +++ b/include/boost/detail/lightweight_thread.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif diff --git a/include/boost/detail/quick_allocator.hpp b/include/boost/detail/quick_allocator.hpp index ba048e0..d54b3a7 100644 --- a/include/boost/detail/quick_allocator.hpp +++ b/include/boost/detail/quick_allocator.hpp @@ -3,7 +3,7 @@ // MS compatible compilers support #pragma once -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (_MSC_VER >= 1020) # pragma once #endif From 016af907bdccc61e3415828c4efeeeb38765b36f Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 12 Feb 2014 08:46:59 -0800 Subject: [PATCH 45/55] Make sp_counted_impl_ specialization more generic --- include/boost/smart_ptr/allocate_shared_array.hpp | 12 ++++++------ include/boost/smart_ptr/detail/array_allocator.hpp | 2 +- include/boost/smart_ptr/detail/array_count_impl.hpp | 9 ++++----- include/boost/smart_ptr/make_shared_array.hpp | 12 ++++++------ 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index fdaec42..e64047f 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -20,7 +20,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; typedef boost::detail::ms_init_tag R1; typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_noop D1; + typedef boost::detail::ms_in_allocator_tag D1; std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; T2* p2 = 0; @@ -45,7 +45,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; typedef boost::detail::ms_init_tag R1; typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_noop D1; + typedef boost::detail::ms_in_allocator_tag D1; enum { N = boost::detail::array_total::size }; @@ -74,7 +74,7 @@ namespace boost { typedef const T2 T3; typedef boost::detail::ms_init_tag R1; typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_noop D1; + typedef boost::detail::ms_in_allocator_tag D1; enum { M = boost::detail::array_total::size }; @@ -105,7 +105,7 @@ namespace boost { typedef const T2 T3; typedef boost::detail::ms_init_tag R1; typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_noop D1; + typedef boost::detail::ms_in_allocator_tag D1; enum { N = boost::detail::array_total::size, M = boost::detail::array_total::size @@ -134,7 +134,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; typedef boost::detail::ms_noinit_tag R1; typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_noop D1; + typedef boost::detail::ms_in_allocator_tag D1; std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; T2* p2 = 0; @@ -155,7 +155,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; typedef boost::detail::ms_noinit_tag R1; typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_noop D1; + typedef boost::detail::ms_in_allocator_tag D1; enum { N = boost::detail::array_total::size }; diff --git a/include/boost/smart_ptr/detail/array_allocator.hpp b/include/boost/smart_ptr/detail/array_allocator.hpp index fc55504..ce918b9 100644 --- a/include/boost/smart_ptr/detail/array_allocator.hpp +++ b/include/boost/smart_ptr/detail/array_allocator.hpp @@ -372,7 +372,7 @@ namespace boost { type* object; }; - class ms_noop { + class ms_in_allocator_tag { public: void operator()(const void*) { } diff --git a/include/boost/smart_ptr/detail/array_count_impl.hpp b/include/boost/smart_ptr/detail/array_count_impl.hpp index 503947e..f81954d 100644 --- a/include/boost/smart_ptr/detail/array_count_impl.hpp +++ b/include/boost/smart_ptr/detail/array_count_impl.hpp @@ -14,14 +14,13 @@ namespace boost { namespace detail { - template - class sp_counted_impl_pda > + template + class sp_counted_impl_pda : public sp_counted_base { - typedef ms_noop D; - typedef ms_allocator A; + typedef ms_in_allocator_tag D; typedef sp_counted_impl_pda Y; public: - sp_counted_impl_pda(const P&, const D&, const A& allocator_) + sp_counted_impl_pda(P, const D&, const A& allocator_) : allocator(allocator_) { } diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index f98368a..362c3f8 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -20,7 +20,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; typedef boost::detail::ms_init_tag R1; typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_noop D1; + typedef boost::detail::ms_in_allocator_tag D1; std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; T2* p2 = 0; @@ -41,7 +41,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; typedef boost::detail::ms_init_tag R1; typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_noop D1; + typedef boost::detail::ms_in_allocator_tag D1; enum { N = boost::detail::array_total::size }; @@ -66,7 +66,7 @@ namespace boost { typedef const T2 T3; typedef boost::detail::ms_init_tag R1; typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_noop D1; + typedef boost::detail::ms_in_allocator_tag D1; enum { M = boost::detail::array_total::size }; @@ -92,7 +92,7 @@ namespace boost { typedef const T2 T3; typedef boost::detail::ms_init_tag R1; typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_noop D1; + typedef boost::detail::ms_in_allocator_tag D1; enum { M = boost::detail::array_total::size, N = boost::detail::array_total::size @@ -117,7 +117,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; typedef boost::detail::ms_noinit_tag R1; typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_noop D1; + typedef boost::detail::ms_in_allocator_tag D1; std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; T2* p2 = 0; @@ -138,7 +138,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; typedef boost::detail::ms_noinit_tag R1; typedef boost::detail::ms_allocator A1; - typedef boost::detail::ms_noop D1; + typedef boost::detail::ms_in_allocator_tag D1; enum { N = boost::detail::array_total::size }; From 0c29e86728713873868305af30497116f88e8635 Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 12 Feb 2014 20:20:56 +0200 Subject: [PATCH 46/55] Add spinlock_std_atomic.hpp --- include/boost/smart_ptr/detail/spinlock.hpp | 5 +- .../smart_ptr/detail/spinlock_std_atomic.hpp | 83 +++++++++++++++++++ 2 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 include/boost/smart_ptr/detail/spinlock_std_atomic.hpp diff --git a/include/boost/smart_ptr/detail/spinlock.hpp b/include/boost/smart_ptr/detail/spinlock.hpp index 88d7ad6..deffb67 100644 --- a/include/boost/smart_ptr/detail/spinlock.hpp +++ b/include/boost/smart_ptr/detail/spinlock.hpp @@ -31,7 +31,10 @@ #include #include -#if defined( BOOST_SP_USE_PTHREADS ) +#if defined( BOOST_SP_USE_STD_ATOMIC ) +# include + +#elif defined( BOOST_SP_USE_PTHREADS ) # include #elif defined(__GNUC__) && defined( __arm__ ) && !defined( __thumb__ ) diff --git a/include/boost/smart_ptr/detail/spinlock_std_atomic.hpp b/include/boost/smart_ptr/detail/spinlock_std_atomic.hpp new file mode 100644 index 0000000..a61c1cd --- /dev/null +++ b/include/boost/smart_ptr/detail/spinlock_std_atomic.hpp @@ -0,0 +1,83 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// Copyright (c) 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt) +// + +#include +#include + +namespace boost +{ + +namespace detail +{ + +class spinlock +{ +public: + + std::atomic_flag v_; + +public: + + bool try_lock() + { + return !v_.test_and_set( std::memory_order_acquire ); + } + + void lock() + { + for( unsigned k = 0; !try_lock(); ++k ) + { + boost::detail::yield( k ); + } + } + + void unlock() + { + v_ .clear( std::memory_order_release ); + } + +public: + + class scoped_lock + { + private: + + spinlock & sp_; + + scoped_lock( scoped_lock const & ); + scoped_lock & operator=( scoped_lock const & ); + + public: + + explicit scoped_lock( spinlock & sp ): sp_( sp ) + { + sp.lock(); + } + + ~scoped_lock() + { + sp_.unlock(); + } + }; +}; + +} // namespace detail +} // namespace boost + +#define BOOST_DETAIL_SPINLOCK_INIT { ATOMIC_FLAG_INIT } + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SPINLOCK_STD_ATOMIC_HPP_INCLUDED From c003fba3a0b051a20a085c7a98389086a79faaed Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Wed, 12 Feb 2014 20:48:35 +0200 Subject: [PATCH 47/55] Renamed, cleaned up interlocked.hpp; added test --- .../boost/smart_ptr/detail/interlocked.hpp | 210 ------------------ .../boost/smart_ptr/detail/sp_interlocked.hpp | 152 +++++++++++++ test/Jamfile.v2 | 1 + test/sp_interlocked_test.cpp | 60 +++++ 4 files changed, 213 insertions(+), 210 deletions(-) delete mode 100644 include/boost/smart_ptr/detail/interlocked.hpp create mode 100644 include/boost/smart_ptr/detail/sp_interlocked.hpp create mode 100644 test/sp_interlocked_test.cpp diff --git a/include/boost/smart_ptr/detail/interlocked.hpp b/include/boost/smart_ptr/detail/interlocked.hpp deleted file mode 100644 index 1152f71..0000000 --- a/include/boost/smart_ptr/detail/interlocked.hpp +++ /dev/null @@ -1,210 +0,0 @@ -#ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED -#define BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED - -// -// boost/detail/interlocked.hpp -// -// Copyright 2005 Peter Dimov -// -// Distributed under the Boost Software License, Version 1.0. (See -// accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) -// - -#include - -// MS compatible compilers support #pragma once -#ifdef BOOST_HAS_PRAGMA_ONCE -#pragma once -#endif - -#if defined( BOOST_USE_WINDOWS_H ) - -# include - -# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange -# define BOOST_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER InterlockedCompareExchangePointer -# define BOOST_INTERLOCKED_EXCHANGE_POINTER InterlockedExchangePointer - -#elif defined( BOOST_USE_INTRIN_H ) - -#include - -# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange -# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd - -# if defined(_M_IA64) || defined(_M_AMD64) || defined(__x86_64__) || defined(__x86_64) - -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer -# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer - -# else - -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ - ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) -# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ - ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) - -# endif - -#elif defined(_WIN32_WCE) - -#if _WIN32_WCE >= 0x600 - -extern "C" long __cdecl _InterlockedIncrement( long volatile * ); -extern "C" long __cdecl _InterlockedDecrement( long volatile * ); -extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); -extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); -extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); - -# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange -# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd - -#else -// under Windows CE we still have old-style Interlocked* functions - -extern "C" long __cdecl InterlockedIncrement( long* ); -extern "C" long __cdecl InterlockedDecrement( long* ); -extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); -extern "C" long __cdecl InterlockedExchange( long*, long ); -extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); - -# define BOOST_INTERLOCKED_INCREMENT InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE InterlockedExchange -# define BOOST_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd - -#endif - -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ - ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long*)(dest),(long)(exchange),(long)(compare))) -# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ - ((void*)BOOST_INTERLOCKED_EXCHANGE((long*)(dest),(long)(exchange))) - -#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) - -#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1500 - -#include - -#elif defined( __CLRCALL_PURE_OR_CDECL ) - -extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * ); -extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * ); -extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long ); -extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long ); -extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long ); - -#else - -extern "C" long __cdecl _InterlockedIncrement( long volatile * ); -extern "C" long __cdecl _InterlockedDecrement( long volatile * ); -extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); -extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); -extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); - -#endif - -# if defined(_M_IA64) || defined(_M_AMD64) - -extern "C" void* __cdecl _InterlockedCompareExchangePointer( void* volatile *, void*, void* ); -extern "C" void* __cdecl _InterlockedExchangePointer( void* volatile *, void* ); - -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer -# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer - -# else - -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ - ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) -# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ - ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) - -# endif - -# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange -# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd - -// Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets. -#elif defined(__MINGW64_VERSION_MAJOR) - -// MinGW-w64 provides intrin.h for both 32 and 64-bit targets. -#include - -# define BOOST_INTERLOCKED_INCREMENT _InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT _InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE _InterlockedExchange -# define BOOST_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd -# if defined(__x86_64__) || defined(__x86_64) -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER _InterlockedCompareExchangePointer -# define BOOST_INTERLOCKED_EXCHANGE_POINTER _InterlockedExchangePointer -# else -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ - ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) -# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ - ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) -# endif - -#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) - -#define BOOST_INTERLOCKED_IMPORT __declspec(dllimport) - -namespace boost -{ - -namespace detail -{ - -extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedIncrement( long volatile * ); -extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedDecrement( long volatile * ); -extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedCompareExchange( long volatile *, long, long ); -extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedExchange( long volatile *, long ); -extern "C" BOOST_INTERLOCKED_IMPORT long __stdcall InterlockedExchangeAdd( long volatile *, long ); - -# if defined(_M_IA64) || defined(_M_AMD64) -extern "C" BOOST_INTERLOCKED_IMPORT void* __stdcall InterlockedCompareExchangePointer( void* volatile *, void*, void* ); -extern "C" BOOST_INTERLOCKED_IMPORT void* __stdcall InterlockedExchangePointer( void* volatile *, void* ); -# endif - -} // namespace detail - -} // namespace boost - -# define BOOST_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement -# define BOOST_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange -# define BOOST_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange -# define BOOST_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd - -# if defined(_M_IA64) || defined(_M_AMD64) -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER ::boost::detail::InterlockedCompareExchangePointer -# define BOOST_INTERLOCKED_EXCHANGE_POINTER ::boost::detail::InterlockedExchangePointer -# else -# define BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(dest,exchange,compare) \ - ((void*)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long volatile*)(dest),(long)(exchange),(long)(compare))) -# define BOOST_INTERLOCKED_EXCHANGE_POINTER(dest,exchange) \ - ((void*)BOOST_INTERLOCKED_EXCHANGE((long volatile*)(dest),(long)(exchange))) -# endif - -#else - -# error "Interlocked intrinsics not available" - -#endif - -#endif // #ifndef BOOST_DETAIL_INTERLOCKED_HPP_INCLUDED diff --git a/include/boost/smart_ptr/detail/sp_interlocked.hpp b/include/boost/smart_ptr/detail/sp_interlocked.hpp new file mode 100644 index 0000000..814b0c2 --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_interlocked.hpp @@ -0,0 +1,152 @@ +#ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED +#define BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// +// boost/detail/sp_interlocked.hpp +// +// Copyright 2005, 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include + +// BOOST_SP_HAS_INTRIN_H + +// VC9 has intrin.h, but it collides with +#if defined( BOOST_MSVC ) && BOOST_MSVC >= 1600 + +# define BOOST_SP_HAS_INTRIN_H + +// Unlike __MINGW64__, __MINGW64_VERSION_MAJOR is defined by MinGW-w64 for both 32 and 64-bit targets. +#elif defined( __MINGW64_VERSION_MAJOR ) + +// MinGW-w64 provides intrin.h for both 32 and 64-bit targets. +# define BOOST_SP_HAS_INTRIN_H + +// Intel C++ on Windows on VC10+ stdlib +#elif defined( BOOST_INTEL_WIN ) && defined( _CPPLIB_VER ) && _CPPLIB_VER >= 520 + +# define BOOST_SP_HAS_INTRIN_H + +#endif + +#if defined( BOOST_USE_WINDOWS_H ) + +# include + +# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd + +#elif defined( BOOST_USE_INTRIN_H ) || defined( BOOST_SP_HAS_INTRIN_H ) + +#include + +# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +#elif defined( _WIN32_WCE ) + +#if _WIN32_WCE >= 0x600 + +extern "C" long __cdecl _InterlockedIncrement( long volatile * ); +extern "C" long __cdecl _InterlockedDecrement( long volatile * ); +extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); +extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); + +# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +#else + +// under Windows CE we still have old-style Interlocked* functions + +extern "C" long __cdecl InterlockedIncrement( long* ); +extern "C" long __cdecl InterlockedDecrement( long* ); +extern "C" long __cdecl InterlockedCompareExchange( long*, long, long ); +extern "C" long __cdecl InterlockedExchange( long*, long ); +extern "C" long __cdecl InterlockedExchangeAdd( long*, long ); + +# define BOOST_SP_INTERLOCKED_INCREMENT InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD InterlockedExchangeAdd + +#endif + +#elif defined( BOOST_MSVC ) || defined( BOOST_INTEL_WIN ) + +#if defined( __CLRCALL_PURE_OR_CDECL ) + +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedIncrement( long volatile * ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedDecrement( long volatile * ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchange( long volatile *, long ); +extern "C" long __CLRCALL_PURE_OR_CDECL _InterlockedExchangeAdd( long volatile *, long ); + +#else + +extern "C" long __cdecl _InterlockedIncrement( long volatile * ); +extern "C" long __cdecl _InterlockedDecrement( long volatile * ); +extern "C" long __cdecl _InterlockedCompareExchange( long volatile *, long, long ); +extern "C" long __cdecl _InterlockedExchange( long volatile *, long ); +extern "C" long __cdecl _InterlockedExchangeAdd( long volatile *, long ); + +#endif + +# define BOOST_SP_INTERLOCKED_INCREMENT _InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT _InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE _InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE _InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD _InterlockedExchangeAdd + +#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) + +namespace boost +{ + +namespace detail +{ + +extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement( long volatile * ); +extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement( long volatile * ); +extern "C" __declspec(dllimport) long __stdcall InterlockedCompareExchange( long volatile *, long, long ); +extern "C" __declspec(dllimport) long __stdcall InterlockedExchange( long volatile *, long ); +extern "C" __declspec(dllimport) long __stdcall InterlockedExchangeAdd( long volatile *, long ); + +} // namespace detail + +} // namespace boost + +# define BOOST_SP_INTERLOCKED_INCREMENT ::boost::detail::InterlockedIncrement +# define BOOST_SP_INTERLOCKED_DECREMENT ::boost::detail::InterlockedDecrement +# define BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE ::boost::detail::InterlockedCompareExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE ::boost::detail::InterlockedExchange +# define BOOST_SP_INTERLOCKED_EXCHANGE_ADD ::boost::detail::InterlockedExchangeAdd + +#else + +# error "Interlocked intrinsics not available" + +#endif + +#endif // #ifndef BOOST_SMART_PTR_DETAIL_SP_INTERLOCKED_HPP_INCLUDED diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index fc95688..19520c2 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -83,6 +83,7 @@ import testing ; [ run shared_ptr_alloc11_test.cpp ] [ run allocate_shared_alloc11_test.cpp ] [ run allocate_shared_construct11_test.cpp ] + [ run sp_interlocked_test.cpp ] [ compile-fail array_fail_spa_sp_c.cpp ] [ compile-fail array_fail_sp_spa_c.cpp ] diff --git a/test/sp_interlocked_test.cpp b/test/sp_interlocked_test.cpp new file mode 100644 index 0000000..d02bac7 --- /dev/null +++ b/test/sp_interlocked_test.cpp @@ -0,0 +1,60 @@ +// +// sp_interlocked_test.cpp +// +// Copyright 2014 Peter Dimov +// +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE_1_0.txt or copy at +// http://www.boost.org/LICENSE_1_0.txt +// + +#include +#include + +#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) + +int main() +{ + long x = 0, r; + + r = BOOST_SP_INTERLOCKED_INCREMENT( &x ); + + BOOST_TEST( x == 1 ); + BOOST_TEST( r == 1 ); + + r = BOOST_SP_INTERLOCKED_DECREMENT( &x ); + + BOOST_TEST( x == 0 ); + BOOST_TEST( r == 0 ); + + r = BOOST_SP_INTERLOCKED_EXCHANGE( &x, 3 ); + + BOOST_TEST( x == 3 ); + BOOST_TEST( r == 0 ); + + r = BOOST_SP_INTERLOCKED_EXCHANGE_ADD( &x, 2 ); + + BOOST_TEST( x == 5 ); + BOOST_TEST( r == 3 ); + + r = BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &x, 0, 3 ); + + BOOST_TEST( x == 5 ); + BOOST_TEST( r == 5 ); + + r = BOOST_SP_INTERLOCKED_COMPARE_EXCHANGE( &x, 0, 5 ); + + BOOST_TEST( x == 0 ); + BOOST_TEST( r == 5 ); + + return boost::report_errors(); +} + +#else + +int main() +{ + return 0; +} + +#endif From 3d279e6c6d668d56db4722618ebc78580c542e71 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 12 Feb 2014 13:45:28 -0800 Subject: [PATCH 48/55] Save additional sizeof(void*) bytes for arrays --- .../boost/smart_ptr/allocate_shared_array.hpp | 54 ++++---- .../smart_ptr/detail/array_allocator.hpp | 120 ++++++++++-------- .../smart_ptr/detail/array_count_impl.hpp | 2 +- include/boost/smart_ptr/make_shared_array.hpp | 42 +++--- 4 files changed, 120 insertions(+), 98 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index e64047f..c91d4da 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -19,22 +19,23 @@ namespace boost { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef boost::detail::ms_init_tag R1; - typedef boost::detail::ms_allocator A1; + typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(allocator, size, &p2); + A1 a1(allocator, size); shared_ptr s1(p1, d1, a1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->swap(p2); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, n1); #else boost::detail::ms_init(p2, n1); #endif - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -44,7 +45,7 @@ namespace boost { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef boost::detail::ms_init_tag R1; - typedef boost::detail::ms_allocator A1; + typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; enum { N = boost::detail::array_total::size @@ -52,16 +53,17 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(allocator, &p2); + A1 a1(allocator); shared_ptr s1(p1, d1, a1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->swap(p2); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, N); #else boost::detail::ms_init(p2, N); #endif - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -73,7 +75,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; typedef const T2 T3; typedef boost::detail::ms_init_tag R1; - typedef boost::detail::ms_allocator A1; + typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; enum { M = boost::detail::array_total::size @@ -83,16 +85,17 @@ namespace boost { T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; - A1 a1(allocator, size, &p2); + A1 a1(allocator, size); shared_ptr s1(p1, d1, a1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->swap(p2); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, n1, p3); #else boost::detail::ms_init(p2, n1, p3); #endif - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -104,7 +107,7 @@ namespace boost { typedef typename boost::detail::array_base::type T2; typedef const T2 T3; typedef boost::detail::ms_init_tag R1; - typedef boost::detail::ms_allocator A1; + typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; enum { N = boost::detail::array_total::size, @@ -114,16 +117,17 @@ namespace boost { T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; - A1 a1(allocator, &p2); + A1 a1(allocator); shared_ptr s1(p1, d1, a1); + A1* a2 = static_cast(s1._internal_get_untyped_deleter()); + a2->swap(p2); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, N, p3); #else boost::detail::ms_init(p2, N, p3); #endif - A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -133,18 +137,19 @@ namespace boost { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef boost::detail::ms_noinit_tag R1; - typedef boost::detail::ms_allocator A1; + typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; std::size_t n1 = size * boost::detail::array_total::size; T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(allocator, size, &p2); + A1 a1(allocator, size); shared_ptr s1(p1, d1, a1); - boost::detail::ms_noinit(p2, n1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); + a2->swap(p2); + boost::detail::ms_noinit(p2, n1); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -154,7 +159,7 @@ namespace boost { typedef typename boost::detail::array_inner::type T1; typedef typename boost::detail::array_base::type T2; typedef boost::detail::ms_noinit_tag R1; - typedef boost::detail::ms_allocator A1; + typedef boost::detail::as_allocator A1; typedef boost::detail::ms_in_allocator_tag D1; enum { N = boost::detail::array_total::size @@ -162,12 +167,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(allocator, &p2); + A1 a1(allocator); shared_ptr s1(p1, d1, a1); - boost::detail::ms_noinit(p2, N); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); + a2->swap(p2); + boost::detail::ms_noinit(p2, N); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } } diff --git a/include/boost/smart_ptr/detail/array_allocator.hpp b/include/boost/smart_ptr/detail/array_allocator.hpp index ce918b9..2289084 100644 --- a/include/boost/smart_ptr/detail/array_allocator.hpp +++ b/include/boost/smart_ptr/detail/array_allocator.hpp @@ -12,9 +12,7 @@ #include #include #include -#if !defined(BOOST_NO_CXX11_ALLOCATOR) -#include -#endif +#include namespace boost { namespace detail { @@ -47,13 +45,13 @@ namespace boost { struct ms_init_tag { }; struct ms_noinit_tag { }; - template - class ms_allocator + template + class as_allocator : as_size_base { using as_size_base::size; template - friend class ms_allocator; + friend class as_allocator; #if !defined(BOOST_NO_CXX11_ALLOCATOR) typedef typename std::allocator_traits:: @@ -92,25 +90,36 @@ namespace boost { template struct rebind { - typedef ms_allocator other; + typedef as_allocator other; }; - ms_allocator(const A& allocator, type** data_) + as_allocator(const A& allocator) : as_size_base(allocator), - data(data_), object(0) { } - ms_allocator(const A& allocator, std::size_t size_, type** data_) + as_allocator(const A& allocator, std::size_t size_) : as_size_base(allocator, size_), - data(data_), object(0) { } template - ms_allocator(const ms_allocator& other) + as_allocator(const as_allocator& other, U* memory) + : as_size_base(other) { + enum { + M = boost::alignment_of::value + }; + std::size_t n1 = sizeof(U) + M - 1; + char* p1 = reinterpret_cast(memory) + n1; + while (std::size_t(p1) % M != 0) { + p1--; + } + object = reinterpret_cast(p1); + } + + template + as_allocator(const as_allocator& other) : as_size_base(other), - data(other.data), object(other.object) { } @@ -129,29 +138,26 @@ namespace boost { return ya.max_size(); } - pointer allocate(size_type count, const void* value = 0) { + pointer allocate(size_type, const void* value = 0) { enum { M = boost::alignment_of::value }; - std::size_t n1 = count * sizeof(value_type) + M - 1; + std::size_t n1 = sizeof(value_type) + M - 1; std::size_t n2 = size * sizeof(type); CA ca(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) - char* p1 = CT::allocate(ca, n1 + n2, value); + void* p1 = CT::allocate(ca, n1 + n2, value); #else - char* p1 = ca.allocate(n1 + n2, value); + void* p1 = ca.allocate(n1 + n2, value); #endif - char* p2 = p1 + n1; - while (std::size_t(p2) % M != 0) { - p2--; - } - *data = reinterpret_cast(p2); - return reinterpret_cast(p1); + return static_cast(p1); } - void deallocate(pointer memory, size_type count) { - std::size_t a1 = boost::alignment_of::value; - std::size_t n1 = count * sizeof(value_type) + a1 - 1; + void deallocate(pointer memory, size_type) { + enum { + M = boost::alignment_of::value + }; + std::size_t n1 = sizeof(value_type) + M - 1; char* p1 = reinterpret_cast(memory); CA ca(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) @@ -193,17 +199,17 @@ namespace boost { #endif template - bool operator==(const ms_allocator& other) const { + bool operator==(const as_allocator& other) const { return true; } template - bool operator!=(const ms_allocator& other) const { + bool operator!=(const as_allocator& other) const { return !(*this == other); } - void set(type* memory) { - object = memory; + void swap(type*& other) { + std::swap(object, other); } void operator()() { @@ -227,7 +233,6 @@ namespace boost { ms_destroy(object, size); } - type** data; type* object; }; @@ -250,12 +255,12 @@ namespace boost { }; }; - template - class ms_allocator + template + class ms_allocator : ms_size_base { using ms_size_base::size; - template + template friend class ms_allocator; public: @@ -270,24 +275,35 @@ namespace boost { template struct rebind { - typedef ms_allocator other; + typedef ms_allocator other; }; - ms_allocator(type** data_) - : data(data_), - object(0) { + ms_allocator() + : object(0) { } - ms_allocator(std::size_t size_, type** data_) + ms_allocator(std::size_t size_) : ms_size_base(size_), - data(data_), object(0) { } template - ms_allocator(const ms_allocator& other) + ms_allocator(const ms_allocator& other, U* memory) + : ms_size_base(other) { + enum { + M = boost::alignment_of::value + }; + std::size_t n1 = sizeof(U) + M - 1; + char* p1 = reinterpret_cast(memory) + n1; + while (std::size_t(p1) % M != 0) { + p1--; + } + object = reinterpret_cast(p1); + } + + template + ms_allocator(const ms_allocator& other) : ms_size_base(other), - data(other.data), object(other.object) { } @@ -306,19 +322,14 @@ namespace boost { return N; } - pointer allocate(size_type count, const void* = 0) { + pointer allocate(size_type, const void* = 0) { enum { M = boost::alignment_of::value }; - std::size_t n1 = count * sizeof(value_type) + M - 1; + std::size_t n1 = sizeof(value_type) + M - 1; std::size_t n2 = size * sizeof(type); void* p1 = ::operator new(n1 + n2); - char* p2 = static_cast(p1) + n1; - while (std::size_t(p2) % M != 0) { - p2--; - } - *data = reinterpret_cast(p2); - return reinterpret_cast(p1); + return static_cast(p1); } void deallocate(pointer memory, size_type) { @@ -348,17 +359,17 @@ namespace boost { #endif template - bool operator==(const ms_allocator&) const { + bool operator==(const ms_allocator&) const { return true; } template - bool operator!=(const ms_allocator& other) const { + bool operator!=(const ms_allocator& other) const { return !(*this == other); } - void set(type* memory) { - object = memory; + void swap(type*& other) { + std::swap(object, other); } void operator()() { @@ -368,7 +379,6 @@ namespace boost { } private: - type** data; type* object; }; diff --git a/include/boost/smart_ptr/detail/array_count_impl.hpp b/include/boost/smart_ptr/detail/array_count_impl.hpp index f81954d..da2d9dd 100644 --- a/include/boost/smart_ptr/detail/array_count_impl.hpp +++ b/include/boost/smart_ptr/detail/array_count_impl.hpp @@ -21,7 +21,7 @@ namespace boost { typedef sp_counted_impl_pda Y; public: sp_counted_impl_pda(P, const D&, const A& allocator_) - : allocator(allocator_) { + : allocator(allocator_, this) { } virtual void dispose() { diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 362c3f8..96a45dc 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -25,12 +25,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(size, &p2); + A1 a1(size); shared_ptr s1(p1, d1, a1); - boost::detail::ms_init(p2, n1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); + a2->swap(p2); + boost::detail::ms_init(p2, n1); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -48,12 +49,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(&p2); + A1 a1; shared_ptr s1(p1, d1, a1); - boost::detail::ms_init(p2, N); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); + a2->swap(p2); + boost::detail::ms_init(p2, N); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -75,12 +77,13 @@ namespace boost { T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; - A1 a1(size, &p2); + A1 a1(size); shared_ptr s1(p1, d1, a1); - boost::detail::ms_init(p2, n1, p3); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); + a2->swap(p2); + boost::detail::ms_init(p2, n1, p3); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -101,12 +104,13 @@ namespace boost { T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; - A1 a1(&p2); + A1 a1; shared_ptr s1(p1, d1, a1); - boost::detail::ms_init(p2, N, p3); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); + a2->swap(p2); + boost::detail::ms_init(p2, N, p3); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -122,12 +126,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(size, &p2); + A1 a1(size); shared_ptr s1(p1, d1, a1); - boost::detail::ms_noinit(p2, n1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); + a2->swap(p2); + boost::detail::ms_noinit(p2, n1); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } @@ -145,12 +150,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(&p2); + A1 a1; shared_ptr s1(p1, d1, a1); - boost::detail::ms_noinit(p2, N); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->set(p2); + a2->swap(p2); + boost::detail::ms_noinit(p2, N); p1 = reinterpret_cast(p2); + a2->swap(p2); return shared_ptr(s1, p1); } } From d9333e537579bed09ea1cfd0be08f7ed6c27f6a4 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 12 Feb 2014 19:19:02 -0800 Subject: [PATCH 49/55] Simplify array_allocator; update documentation --- .../smart_ptr/detail/array_allocator.hpp | 29 +++++++++---------- .../smart_ptr/detail/array_count_impl.hpp | 2 +- make_shared_array.html | 5 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/include/boost/smart_ptr/detail/array_allocator.hpp b/include/boost/smart_ptr/detail/array_allocator.hpp index 2289084..8a408e2 100644 --- a/include/boost/smart_ptr/detail/array_allocator.hpp +++ b/include/boost/smart_ptr/detail/array_allocator.hpp @@ -103,14 +103,14 @@ namespace boost { object(0) { } - template - as_allocator(const as_allocator& other, U* memory) + as_allocator(const as_allocator& other, void* memory, + std::size_t offset) : as_size_base(other) { enum { M = boost::alignment_of::value }; - std::size_t n1 = sizeof(U) + M - 1; - char* p1 = reinterpret_cast(memory) + n1; + std::size_t n1 = offset + M - 1; + char* p1 = static_cast(memory) + n1; while (std::size_t(p1) % M != 0) { p1--; } @@ -138,11 +138,11 @@ namespace boost { return ya.max_size(); } - pointer allocate(size_type, const void* value = 0) { + pointer allocate(size_type count, const void* value = 0) { enum { M = boost::alignment_of::value }; - std::size_t n1 = sizeof(value_type) + M - 1; + std::size_t n1 = count * sizeof(value_type) + M - 1; std::size_t n2 = size * sizeof(type); CA ca(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) @@ -153,11 +153,11 @@ namespace boost { return static_cast(p1); } - void deallocate(pointer memory, size_type) { + void deallocate(pointer memory, size_type count) { enum { M = boost::alignment_of::value }; - std::size_t n1 = sizeof(value_type) + M - 1; + std::size_t n1 = count * sizeof(value_type) + M - 1; char* p1 = reinterpret_cast(memory); CA ca(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) @@ -172,7 +172,6 @@ namespace boost { YA ya(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) YT::construct(ya, memory, value); - #else ya.construct(memory, value); #endif @@ -287,14 +286,14 @@ namespace boost { object(0) { } - template - ms_allocator(const ms_allocator& other, U* memory) + ms_allocator(const ms_allocator& other, void* memory, + std::size_t offset) : ms_size_base(other) { enum { M = boost::alignment_of::value }; - std::size_t n1 = sizeof(U) + M - 1; - char* p1 = reinterpret_cast(memory) + n1; + std::size_t n1 = offset + M - 1; + char* p1 = static_cast(memory) + n1; while (std::size_t(p1) % M != 0) { p1--; } @@ -322,11 +321,11 @@ namespace boost { return N; } - pointer allocate(size_type, const void* = 0) { + pointer allocate(size_type count, const void* = 0) { enum { M = boost::alignment_of::value }; - std::size_t n1 = sizeof(value_type) + M - 1; + std::size_t n1 = count * sizeof(value_type) + M - 1; std::size_t n2 = size * sizeof(type); void* p1 = ::operator new(n1 + n2); return static_cast(p1); diff --git a/include/boost/smart_ptr/detail/array_count_impl.hpp b/include/boost/smart_ptr/detail/array_count_impl.hpp index da2d9dd..6a6a2a9 100644 --- a/include/boost/smart_ptr/detail/array_count_impl.hpp +++ b/include/boost/smart_ptr/detail/array_count_impl.hpp @@ -21,7 +21,7 @@ namespace boost { typedef sp_counted_impl_pda Y; public: sp_counted_impl_pda(P, const D&, const A& allocator_) - : allocator(allocator_, this) { + : allocator(allocator_, this, sizeof(Y)) { } virtual void dispose() { diff --git a/make_shared_array.html b/make_shared_array.html index 6c323b8..56341cd 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -252,8 +252,9 @@ boost::shared_ptr<int[4][2]> a2 = boost::make_shared_noinit<int[4][2]&g

History

February 2014. Glen Fernandes updated overloads of make_shared and allocate_shared to conform to the specification in C++ standard paper - N3870 including resolving C++ standard library - defect report 2070.

+ N3870, including resolving C++ standard library + defect report 2070, and reduced the spatial overhead of the internal + bookkeeping structures.

November 2012. Glen Fernandes contributed implementations of make_shared and allocate_shared for arrays.

References

From 8c9e8b55566cb1ebd1d77d906176aa3b5d6eda35 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Wed, 12 Feb 2014 22:12:04 -0800 Subject: [PATCH 50/55] Further simplification of ms_allocator --- .../boost/smart_ptr/allocate_shared_array.hpp | 36 +++---- .../smart_ptr/detail/array_allocator.hpp | 94 +++++++++---------- .../smart_ptr/detail/array_count_impl.hpp | 2 +- include/boost/smart_ptr/make_shared_array.hpp | 36 +++---- 4 files changed, 81 insertions(+), 87 deletions(-) diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index c91d4da..bdd8b1f 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -25,17 +25,17 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(allocator, size); + A1 a1(allocator, size, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->swap(p2); + a2->set(0); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, n1); #else boost::detail::ms_init(p2, n1); #endif + a2->set(p2); p1 = reinterpret_cast(p2); - a2->swap(p2); return shared_ptr(s1, p1); } @@ -53,17 +53,17 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(allocator); + A1 a1(allocator, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->swap(p2); + a2->set(0); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, N); #else boost::detail::ms_init(p2, N); #endif + a2->set(p2); p1 = reinterpret_cast(p2); - a2->swap(p2); return shared_ptr(s1, p1); } @@ -85,17 +85,17 @@ namespace boost { T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; - A1 a1(allocator, size); + A1 a1(allocator, size, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->swap(p2); + a2->set(0); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, n1, p3); #else boost::detail::ms_init(p2, n1, p3); #endif + a2->set(p2); p1 = reinterpret_cast(p2); - a2->swap(p2); return shared_ptr(s1, p1); } @@ -117,17 +117,17 @@ namespace boost { T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; - A1 a1(allocator); + A1 a1(allocator, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->swap(p2); + a2->set(0); #if !defined(BOOST_NO_CXX11_ALLOCATOR) boost::detail::as_init(allocator, p2, N, p3); #else boost::detail::ms_init(p2, N, p3); #endif + a2->set(p2); p1 = reinterpret_cast(p2); - a2->swap(p2); return shared_ptr(s1, p1); } @@ -143,13 +143,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(allocator, size); + A1 a1(allocator, size, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->swap(p2); + a2->set(0); boost::detail::ms_noinit(p2, n1); + a2->set(p2); p1 = reinterpret_cast(p2); - a2->swap(p2); return shared_ptr(s1, p1); } @@ -167,13 +167,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(allocator); + A1 a1(allocator, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->swap(p2); + a2->set(0); boost::detail::ms_noinit(p2, N); + a2->set(p2); p1 = reinterpret_cast(p2); - a2->swap(p2); return shared_ptr(s1, p1); } } diff --git a/include/boost/smart_ptr/detail/array_allocator.hpp b/include/boost/smart_ptr/detail/array_allocator.hpp index 8a408e2..a5a2d61 100644 --- a/include/boost/smart_ptr/detail/array_allocator.hpp +++ b/include/boost/smart_ptr/detail/array_allocator.hpp @@ -45,6 +45,16 @@ namespace boost { struct ms_init_tag { }; struct ms_noinit_tag { }; + template + union ms_allocator_state { + ms_allocator_state(T** result_) + : result(result_) { + } + + T** result; + T* object; + }; + template class as_allocator : as_size_base { @@ -93,34 +103,21 @@ namespace boost { typedef as_allocator other; }; - as_allocator(const A& allocator) + as_allocator(const A& allocator, type** result) : as_size_base(allocator), - object(0) { + data(result) { } - as_allocator(const A& allocator, std::size_t size_) + as_allocator(const A& allocator, std::size_t size_, + type** result) : as_size_base(allocator, size_), - object(0) { - } - - as_allocator(const as_allocator& other, void* memory, - std::size_t offset) - : as_size_base(other) { - enum { - M = boost::alignment_of::value - }; - std::size_t n1 = offset + M - 1; - char* p1 = static_cast(memory) + n1; - while (std::size_t(p1) % M != 0) { - p1--; - } - object = reinterpret_cast(p1); + data(result) { } template as_allocator(const as_allocator& other) : as_size_base(other), - object(other.object) { + data(other.data) { } pointer address(reference value) const { @@ -150,6 +147,11 @@ namespace boost { #else void* p1 = ca.allocate(n1 + n2, value); #endif + char* p2 = static_cast(p1) + n1; + while (std::size_t(p2) % M != 0) { + p2--; + } + *data.result = reinterpret_cast(p2); return static_cast(p1); } @@ -207,12 +209,12 @@ namespace boost { return !(*this == other); } - void swap(type*& other) { - std::swap(object, other); + void set(type* memory) { + data.object = memory; } void operator()() { - if (object) { + if (data.object) { R tag; free(tag); } @@ -222,17 +224,17 @@ namespace boost { void free(ms_init_tag) { #if !defined(BOOST_NO_CXX11_ALLOCATOR) const A& a1(*this); - as_destroy(a1, object, size); + as_destroy(a1, data.object, size); #else - ms_destroy(object, size); + ms_destroy(data.object, size); #endif } void free(ms_noinit_tag) { - ms_destroy(object, size); + ms_destroy(data.object, size); } - type* object; + ms_allocator_state data; }; template @@ -264,6 +266,7 @@ namespace boost { public: typedef typename array_base::type type; + typedef Y value_type; typedef Y* pointer; typedef const Y* const_pointer; @@ -277,33 +280,19 @@ namespace boost { typedef ms_allocator other; }; - ms_allocator() - : object(0) { + ms_allocator(type** result) + : data(result) { } - ms_allocator(std::size_t size_) + ms_allocator(std::size_t size_, type** result) : ms_size_base(size_), - object(0) { - } - - ms_allocator(const ms_allocator& other, void* memory, - std::size_t offset) - : ms_size_base(other) { - enum { - M = boost::alignment_of::value - }; - std::size_t n1 = offset + M - 1; - char* p1 = static_cast(memory) + n1; - while (std::size_t(p1) % M != 0) { - p1--; - } - object = reinterpret_cast(p1); + data(result) { } template ms_allocator(const ms_allocator& other) : ms_size_base(other), - object(other.object) { + data(other.data) { } pointer address(reference value) const { @@ -328,6 +317,11 @@ namespace boost { std::size_t n1 = count * sizeof(value_type) + M - 1; std::size_t n2 = size * sizeof(type); void* p1 = ::operator new(n1 + n2); + char* p2 = static_cast(p1) + n1; + while (std::size_t(p2) % M != 0) { + p2--; + } + *data.result = reinterpret_cast(p2); return static_cast(p1); } @@ -367,18 +361,18 @@ namespace boost { return !(*this == other); } - void swap(type*& other) { - std::swap(object, other); + void set(type* memory) { + data.object = memory; } void operator()() { - if (object) { - ms_destroy(object, size); + if (data.object) { + ms_destroy(data.object, size); } } private: - type* object; + ms_allocator_state data; }; class ms_in_allocator_tag { diff --git a/include/boost/smart_ptr/detail/array_count_impl.hpp b/include/boost/smart_ptr/detail/array_count_impl.hpp index 6a6a2a9..f81954d 100644 --- a/include/boost/smart_ptr/detail/array_count_impl.hpp +++ b/include/boost/smart_ptr/detail/array_count_impl.hpp @@ -21,7 +21,7 @@ namespace boost { typedef sp_counted_impl_pda Y; public: sp_counted_impl_pda(P, const D&, const A& allocator_) - : allocator(allocator_, this, sizeof(Y)) { + : allocator(allocator_) { } virtual void dispose() { diff --git a/include/boost/smart_ptr/make_shared_array.hpp b/include/boost/smart_ptr/make_shared_array.hpp index 96a45dc..8c2c5d0 100644 --- a/include/boost/smart_ptr/make_shared_array.hpp +++ b/include/boost/smart_ptr/make_shared_array.hpp @@ -25,13 +25,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(size); + A1 a1(size, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->swap(p2); + a2->set(0); boost::detail::ms_init(p2, n1); + a2->set(p2); p1 = reinterpret_cast(p2); - a2->swap(p2); return shared_ptr(s1, p1); } @@ -49,13 +49,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1; + A1 a1(&p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->swap(p2); + a2->set(0); boost::detail::ms_init(p2, N); + a2->set(p2); p1 = reinterpret_cast(p2); - a2->swap(p2); return shared_ptr(s1, p1); } @@ -77,13 +77,13 @@ namespace boost { T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; - A1 a1(size); + A1 a1(size, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->swap(p2); + a2->set(0); boost::detail::ms_init(p2, n1, p3); + a2->set(p2); p1 = reinterpret_cast(p2); - a2->swap(p2); return shared_ptr(s1, p1); } @@ -104,13 +104,13 @@ namespace boost { T2* p2 = 0; T3* p3 = reinterpret_cast(&value); D1 d1; - A1 a1; + A1 a1(&p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->swap(p2); + a2->set(0); boost::detail::ms_init(p2, N, p3); + a2->set(p2); p1 = reinterpret_cast(p2); - a2->swap(p2); return shared_ptr(s1, p1); } @@ -126,13 +126,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1(size); + A1 a1(size, &p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->swap(p2); + a2->set(0); boost::detail::ms_noinit(p2, n1); + a2->set(p2); p1 = reinterpret_cast(p2); - a2->swap(p2); return shared_ptr(s1, p1); } @@ -150,13 +150,13 @@ namespace boost { T1* p1 = 0; T2* p2 = 0; D1 d1; - A1 a1; + A1 a1(&p2); shared_ptr s1(p1, d1, a1); A1* a2 = static_cast(s1._internal_get_untyped_deleter()); - a2->swap(p2); + a2->set(0); boost::detail::ms_noinit(p2, N); + a2->set(p2); p1 = reinterpret_cast(p2); - a2->swap(p2); return shared_ptr(s1, p1); } } From dcfa031de7991baafd96f3dace866e342795bf7d Mon Sep 17 00:00:00 2001 From: Peter Dimov Date: Thu, 13 Feb 2014 12:51:23 +0200 Subject: [PATCH 51/55] Do not include sp_interlocked.hpp when not on Windows --- test/sp_interlocked_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/sp_interlocked_test.cpp b/test/sp_interlocked_test.cpp index d02bac7..1b075b4 100644 --- a/test/sp_interlocked_test.cpp +++ b/test/sp_interlocked_test.cpp @@ -8,11 +8,11 @@ // http://www.boost.org/LICENSE_1_0.txt // +#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) + #include #include -#if defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) || defined( __CYGWIN__ ) - int main() { long x = 0, r; From adc0cdddff785ab85e61eabcad63f0d32f3f990a Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Fri, 14 Feb 2014 18:31:52 -0800 Subject: [PATCH 52/55] Make as_allocator::deallocate consistent --- include/boost/smart_ptr/detail/array_allocator.hpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/boost/smart_ptr/detail/array_allocator.hpp b/include/boost/smart_ptr/detail/array_allocator.hpp index a5a2d61..2a60528 100644 --- a/include/boost/smart_ptr/detail/array_allocator.hpp +++ b/include/boost/smart_ptr/detail/array_allocator.hpp @@ -160,12 +160,13 @@ namespace boost { M = boost::alignment_of::value }; std::size_t n1 = count * sizeof(value_type) + M - 1; + std::size_t n2 = size * sizeof(type); char* p1 = reinterpret_cast(memory); CA ca(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) - CT::deallocate(ca, p1, size + n1); + CT::deallocate(ca, p1, n1 + n2); #else - ca.deallocate(p1, size + n1); + ca.deallocate(p1, n1 + n2); #endif } From 5f1d4eae4f4984a8ac0b2501df7d2e062610a1c1 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Sun, 16 Feb 2014 11:02:37 -0800 Subject: [PATCH 53/55] Factor out alignment code into sp_align --- .../smart_ptr/detail/array_allocator.hpp | 29 +++++++-------- include/boost/smart_ptr/detail/sp_align.hpp | 37 +++++++++++++++++++ 2 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 include/boost/smart_ptr/detail/sp_align.hpp diff --git a/include/boost/smart_ptr/detail/array_allocator.hpp b/include/boost/smart_ptr/detail/array_allocator.hpp index 2a60528..8f1e632 100644 --- a/include/boost/smart_ptr/detail/array_allocator.hpp +++ b/include/boost/smart_ptr/detail/array_allocator.hpp @@ -11,6 +11,7 @@ #include #include +#include #include #include @@ -139,19 +140,17 @@ namespace boost { enum { M = boost::alignment_of::value }; - std::size_t n1 = count * sizeof(value_type) + M - 1; - std::size_t n2 = size * sizeof(type); + std::size_t n1 = count * sizeof(value_type); + std::size_t n2 = size * sizeof(type) + M - 1; CA ca(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) void* p1 = CT::allocate(ca, n1 + n2, value); #else void* p1 = ca.allocate(n1 + n2, value); #endif - char* p2 = static_cast(p1) + n1; - while (std::size_t(p2) % M != 0) { - p2--; - } - *data.result = reinterpret_cast(p2); + void* p2 = static_cast(p1) + n1; + p2 = sp_align(M, p2); + *data.result = static_cast(p2); return static_cast(p1); } @@ -159,8 +158,8 @@ namespace boost { enum { M = boost::alignment_of::value }; - std::size_t n1 = count * sizeof(value_type) + M - 1; - std::size_t n2 = size * sizeof(type); + std::size_t n1 = count * sizeof(value_type); + std::size_t n2 = size * sizeof(type) + M - 1; char* p1 = reinterpret_cast(memory); CA ca(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) @@ -315,14 +314,12 @@ namespace boost { enum { M = boost::alignment_of::value }; - std::size_t n1 = count * sizeof(value_type) + M - 1; - std::size_t n2 = size * sizeof(type); + std::size_t n1 = count * sizeof(value_type); + std::size_t n2 = size * sizeof(type) + M - 1; void* p1 = ::operator new(n1 + n2); - char* p2 = static_cast(p1) + n1; - while (std::size_t(p2) % M != 0) { - p2--; - } - *data.result = reinterpret_cast(p2); + void* p2 = static_cast(p1) + n1; + p2 = sp_align(M, p2); + *data.result = static_cast(p2); return static_cast(p1); } diff --git a/include/boost/smart_ptr/detail/sp_align.hpp b/include/boost/smart_ptr/detail/sp_align.hpp new file mode 100644 index 0000000..b78bdc0 --- /dev/null +++ b/include/boost/smart_ptr/detail/sp_align.hpp @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014 Glen Joseph Fernandes + * glenfe at live dot com + * + * Distributed under the Boost Software License, + * Version 1.0. (See accompanying file LICENSE_1_0.txt + * or copy at http://boost.org/LICENSE_1_0.txt) + */ +#ifndef BOOST_SMART_PTR_DETAIL_SP_ALIGN_HPP +#define BOOST_SMART_PTR_DETAIL_SP_ALIGN_HPP + +#include +#if !defined(BOOST_NO_CXX11_STD_ALIGN) +#include +#endif + +namespace boost { + namespace detail { +#if !defined(BOOST_NO_CXX11_STD_ALIGN) + inline void* sp_align(std::size_t alignment, void* ptr) { + std::size_t n1 = alignment - 1; + std::align(alignment, 0, ptr, n1); + return ptr; + } +#else + inline void* sp_align(std::size_t alignment, void* ptr) { + std::size_t n1 = (std::size_t)ptr % alignment; + if (n1 != 0) { + ptr = (char*)ptr + alignment - n1; + } + return ptr; + } +#endif + } +} + +#endif From 38cb5237131c6aadb853931d9c87237375f1f7f4 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Tue, 18 Feb 2014 00:14:31 -0800 Subject: [PATCH 54/55] Derive empty base optimization from rebound allocator --- .../smart_ptr/detail/array_allocator.hpp | 65 +++++++++++-------- .../smart_ptr/detail/array_count_impl.hpp | 2 +- make_shared_array.html | 56 ++++++++-------- make_unique.html | 26 ++++---- 4 files changed, 79 insertions(+), 70 deletions(-) diff --git a/include/boost/smart_ptr/detail/array_allocator.hpp b/include/boost/smart_ptr/detail/array_allocator.hpp index 8f1e632..79bae59 100644 --- a/include/boost/smart_ptr/detail/array_allocator.hpp +++ b/include/boost/smart_ptr/detail/array_allocator.hpp @@ -28,6 +28,12 @@ namespace boost { size(size_ * array_total::size) { } + template + as_size_base(const as_size_base& other) + : A(other), + size(other.size) { + } + std::size_t size; }; @@ -38,6 +44,11 @@ namespace boost { : A(allocator) { } + template + as_size_base(const as_size_base& other) + : A(other) { + } + enum { size = array_total::size }; @@ -58,9 +69,13 @@ namespace boost { template class as_allocator - : as_size_base { - using as_size_base::size; - +#if !defined(BOOST_NO_CXX11_ALLOCATOR) + : as_size_base:: + template rebind_alloc > { +#else + : as_size_base::other> { +#endif template friend class as_allocator; @@ -78,6 +93,8 @@ namespace boost { typedef typename A::template rebind::other CA; #endif + using as_size_base::size; + public: typedef typename array_base::type type; @@ -105,36 +122,30 @@ namespace boost { }; as_allocator(const A& allocator, type** result) - : as_size_base(allocator), + : as_size_base(allocator), data(result) { } as_allocator(const A& allocator, std::size_t size_, type** result) - : as_size_base(allocator, size_), + : as_size_base(allocator, size_), data(result) { } template as_allocator(const as_allocator& other) - : as_size_base(other), + : as_size_base(other), data(other.data) { } - pointer address(reference value) const { - YA ya(*this); - return ya.address(value); - } - - const_pointer address(const_reference value) const { - YA ya(*this); - return ya.address(value); - } - +#if !defined(BOOST_NO_CXX11_ALLOCATOR) size_type max_size() const { - YA ya(*this); - return ya.max_size(); + return YT::max_size(*this); } +#else + using YA::address; + using YA::max_size; +#endif pointer allocate(size_type count, const void* value = 0) { enum { @@ -171,21 +182,19 @@ namespace boost { template void construct(U* memory, const_reference value) { - YA ya(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) - YT::construct(ya, memory, value); + YT::construct(*this, memory, value); #else - ya.construct(memory, value); + YA::construct(memory, value); #endif } template void destroy(U* memory) { - YA ya(*this); #if !defined(BOOST_NO_CXX11_ALLOCATOR) - YT::destroy(ya, memory); + YT::destroy(*this, memory); #else - ya.destroy(memory); + YA::destroy(memory); #endif } @@ -194,8 +203,7 @@ namespace boost { !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) template void construct(U* memory, Args&&... args) { - YA ya(*this); - YT::construct(ya, memory, std::forward(args)...); + YT::construct(*this, memory, std::forward(args)...); } #endif @@ -223,8 +231,7 @@ namespace boost { private: void free(ms_init_tag) { #if !defined(BOOST_NO_CXX11_ALLOCATOR) - const A& a1(*this); - as_destroy(a1, data.object, size); + as_destroy(*this, data.object, size); #else ms_destroy(data.object, size); #endif @@ -295,6 +302,7 @@ namespace boost { data(other.data) { } +#if defined(BOOST_NO_CXX11_ALLOCATOR) pointer address(reference value) const { return &value; } @@ -302,6 +310,7 @@ namespace boost { const_pointer address(const_reference value) const { return &value; } +#endif size_type max_size() const { enum { diff --git a/include/boost/smart_ptr/detail/array_count_impl.hpp b/include/boost/smart_ptr/detail/array_count_impl.hpp index f81954d..b7c9617 100644 --- a/include/boost/smart_ptr/detail/array_count_impl.hpp +++ b/include/boost/smart_ptr/detail/array_count_impl.hpp @@ -20,7 +20,7 @@ namespace boost { typedef ms_in_allocator_tag D; typedef sp_counted_impl_pda Y; public: - sp_counted_impl_pda(P, const D&, const A& allocator_) + sp_counted_impl_pda(P, D, const A& allocator_) : allocator(allocator_) { } diff --git a/make_shared_array.html b/make_shared_array.html index 56341cd..ebfaeda 100644 --- a/make_shared_array.html +++ b/make_shared_array.html @@ -30,50 +30,50 @@ user-supplied allocator, allowing finer control.

Synopsis

namespace boost {
-    template<typename U> // U is T[]
+    template<class U> // U is T[]
     shared_ptr<U> make_shared(size_t size);
 
-    template<typename U, typename A> // U is T[]
+    template<class U, class A> // U is T[]
     shared_ptr<U> allocate_shared(const A& allocator, size_t size);
 
-    template<typename U> // U is T[N]
+    template<class U> // U is T[N]
     shared_ptr<U> make_shared();
 
-    template<typename U, typename A> // U is T[N]
+    template<class U, class A> // U is T[N]
     shared_ptr<U> allocate_shared(const A& allocator);
 
-    template<typename U> // U is T[]
+    template<class U> // U is T[]
     shared_ptr<U> make_shared(size_t size, const T& value);
 
-    template<typename U, typename A>  // U is T[]
+    template<class U, class A>  // U is T[]
     shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T& value);
 
-    template<typename U> // U is T[N]
+    template<class U> // U is T[N]
     shared_ptr<U> make_shared(const T& value);
 
-    template<typename U, typename A> // U is T[N]
+    template<class U, class A> // U is T[N]
     shared_ptr<U> allocate_shared(const A& allocator, const T& value);
 
-    template<typename U> // U is T[]
+    template<class U> // U is T[]
     shared_ptr<U> make_shared_noinit(size_t size);
 
-    template<typename U, typename A> // U is T[]
+    template<class U, class A> // U is T[]
     shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);
 
-    template<typename U> // U is T[N]
+    template<class U> // U is T[N]
     shared_ptr<U> make_shared_noinit();
 
-    template<typename U, typename A> // U is T[N]
+    template<class U, class A> // U is T[N]
     shared_ptr<U> allocate_shared_noinit(const A& allocator);
 }

Common Requirements

-
template<typename U>
+    
template<class U>
     shared_ptr<U> make_shared(args);
-template<typename U, typename A>
+template<class U, class A>
     shared_ptr<U> allocate_shared(const A& allocator, args);
-template<typename U>
+template<class U>
     shared_ptr<U> make_shared_noinit(args);
-template<typename U, typename A>
+template<class U, class A>
     shared_ptr<U> allocate_shared_noinit(const A& allocator, args);

Requires: U is of the form T[] or @@ -157,9 +157,9 @@ template<typename U, typename A> structures such as the reference counts.

Free Functions

-
template<typename U> 
+    
template<class U> 
     shared_ptr<U> make_shared(size_t size);
-template<typename U, typename A> 
+template<class U, class A> 
     shared_ptr<U> allocate_shared(const A& allocator, size_t size);

Returns: A shared_ptr to a value-initialized @@ -172,9 +172,9 @@ template<typename U, typename A> boost::shared_ptr<int[][2]> a2 = boost::make_shared<int[][2]>(size);

-
template<typename U> 
+    
template<class U> 
     shared_ptr<U> make_shared();
-template<typename U, typename A> 
+template<class U, class A> 
     shared_ptr<U> allocate_shared(const A& allocator);

Returns: A shared_ptr to a value-initialized @@ -187,9 +187,9 @@ template<typename U, typename A> boost::shared_ptr<int[4][2]> a2 = boost::make_shared<int[4][2]>();

-
template<typename U> 
+    
template<class U> 
     shared_ptr<U> make_shared(size_t size, const T& value);
-template<typename U, typename A> 
+template<class U, class A> 
     shared_ptr<U> allocate_shared(const A& allocator, size_t size, const T& value);

Returns: A shared_ptr to an object of type @@ -203,9 +203,9 @@ template<typename U, typename A> boost::shared_ptr<int[][2]> a2 = boost::make_shared<int[][2]>(size, {1, 2});

-
template<typename U> 
+    
template<class U> 
     shared_ptr<U> make_shared(const T& value);
-template<typename U, typename A> 
+template<class U, class A> 
     shared_ptr<U> allocate_shared(const A& allocator, const T& value);

Returns: A shared_ptr to an object of type @@ -219,9 +219,9 @@ template<typename U, typename A> boost::shared_ptr<int[4][2]> a2 = boost::make_shared<int[4][2]>({1, 2});

-
template<typename U> 
+    
template<class U> 
     shared_ptr<U> make_shared_noinit(size_t size);
-template<typename U, typename A> 
+template<class U, class A> 
     shared_ptr<U> allocate_shared_noinit(const A& allocator, size_t size);

Returns: A shared_ptr to a default-initialized @@ -234,9 +234,9 @@ template<typename U, typename A> boost::shared_ptr<int[][2]> a2 = boost::make_shared_noinit<int[][2]>(size);

-
template<typename U> 
+    
template<class U> 
     shared_ptr<U> make_shared_noinit();
-template<typename U, typename A> 
+template<class U, class A> 
     shared_ptr<U> allocate_shared_noinit(const A& allocator);

Returns: A shared_ptr to a default-initialized diff --git a/make_unique.html b/make_unique.html index c3e6ab8..5b414e8 100644 --- a/make_unique.html +++ b/make_unique.html @@ -18,30 +18,30 @@ unique_ptr objects.

Synopsis

namespace boost {
-    template<typename U> // U is not array
+    template<class U> // U is not array
     unique_ptr<U> make_unique();
 
 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
-    template<typename U, typename... Args> // U is not array
+    template<class U, class... Args> // U is not array
     unique_ptr<U> make_unique(Args&&... args);
 #endif
 
-    template<typename U> // U is not array
+    template<class U> // U is not array
     unique_ptr<U> make_unique(U&& value);
 
-    template<typename U> // U is T[]
+    template<class U> // U is T[]
     unique_ptr<U> make_unique(size_t size);
 
-    template<typename U> // U is not array
+    template<class U> // U is not array
     unique_ptr<U> make_unique_noinit();
 
-    template<typename U> // U is T[]
+    template<class U> // U is T[]
     unique_ptr<U> make_unique_noinit(size_t size);
 }

Common Requirements

-
template<typename U>
+    
template<class U>
     unique_ptr<U> make_unique(args);
-template<typename U>
+template<class U>
     unique_ptr<U> make_unique_noinit(args);

Effects: Allocates memory for an object of type U @@ -73,7 +73,7 @@ template<typename U>

Free Functions

-
template<typename U, typename... Args>
+    
template<class U, class... Args>
 unique_ptr<U> make_unique(Args&&... args);

Returns: A unique_ptr to an object of type U, @@ -86,7 +86,7 @@ unique_ptr<U> make_unique(Args&&... args);

unique_ptr<point> p2 = boost::make_unique<point>(x, y);
-
template<typename U>
+    
template<class U>
 unique_ptr<U> make_unique(U&& value);

Returns: A unique_ptr to an object of type U, @@ -99,7 +99,7 @@ unique_ptr<U> make_unique(U&& value);

unique_ptr<point> p2 = boost::make_unique<point>({-10, 25});
-
template<typename U>
+    
template<class U>
 unique_ptr<U> make_unique(size_t size);

Returns: A unique_ptr to a value-initialized object of type @@ -112,7 +112,7 @@ unique_ptr<U> make_unique(size_t size);

unique_ptr<int[][2]> p2 = boost::make_unique<int[][2]>(2); -
template<typename U>
+    
template<class U>
 unique_ptr<U> make_unique_noinit();

Returns: A unique_ptr to a default-initialized object of @@ -125,7 +125,7 @@ unique_ptr<U> make_unique_noinit();

unique_ptr<point> p2 = boost::make_unique_noinit<point>(); -
template<typename U>
+    
template<class U>
 unique_ptr<U> make_unique_noinit(size_t size);

Returns: A unique_ptr to a default-initialized object of From 75cab39801206f6d898943b85f3896f01ecf0068 Mon Sep 17 00:00:00 2001 From: Glen Fernandes Date: Mon, 24 Feb 2014 08:35:59 -0800 Subject: [PATCH 55/55] Drop the BOOST_NO_CXX11_STD_ALIGN-undefined path Until the merge of Boost.Config develop to master --- include/boost/smart_ptr/detail/sp_align.hpp | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/include/boost/smart_ptr/detail/sp_align.hpp b/include/boost/smart_ptr/detail/sp_align.hpp index b78bdc0..5a616ee 100644 --- a/include/boost/smart_ptr/detail/sp_align.hpp +++ b/include/boost/smart_ptr/detail/sp_align.hpp @@ -9,20 +9,10 @@ #ifndef BOOST_SMART_PTR_DETAIL_SP_ALIGN_HPP #define BOOST_SMART_PTR_DETAIL_SP_ALIGN_HPP -#include -#if !defined(BOOST_NO_CXX11_STD_ALIGN) -#include -#endif +#include namespace boost { namespace detail { -#if !defined(BOOST_NO_CXX11_STD_ALIGN) - inline void* sp_align(std::size_t alignment, void* ptr) { - std::size_t n1 = alignment - 1; - std::align(alignment, 0, ptr, n1); - return ptr; - } -#else inline void* sp_align(std::size_t alignment, void* ptr) { std::size_t n1 = (std::size_t)ptr % alignment; if (n1 != 0) { @@ -30,7 +20,6 @@ namespace boost { } return ptr; } -#endif } }