diff --git a/include/boost/smart_ptr/allocate_shared_array.hpp b/include/boost/smart_ptr/allocate_shared_array.hpp index 905d311..bac8cef 100644 --- a/include/boost/smart_ptr/allocate_shared_array.hpp +++ b/include/boost/smart_ptr/allocate_shared_array.hpp @@ -11,7 +11,6 @@ #include #include -#include #include #include diff --git a/include/boost/smart_ptr/detail/allocate_array_helper.hpp b/include/boost/smart_ptr/detail/allocate_array_helper.hpp index 1f358e7..de43c76 100644 --- a/include/boost/smart_ptr/detail/allocate_array_helper.hpp +++ b/include/boost/smart_ptr/detail/allocate_array_helper.hpp @@ -9,45 +9,53 @@ #ifndef BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP #define BOOST_SMART_PTR_DETAIL_ALLOCATE_ARRAY_HELPER_HPP +#include +#include #include namespace boost { namespace detail { template - class allocate_array_helper; + class allocate_array_helper + : array_size_base { + using array_size_base::size; - template - class allocate_array_helper { - template + template friend class allocate_array_helper; typedef typename A::template rebind ::other A2; - typedef typename A::template rebind::other A3; + typedef typename A::template rebind::other A3; public: - typedef typename A2::value_type value_type; - typedef typename A2::pointer pointer; - typedef typename A2::const_pointer const_pointer; - typedef typename A2::reference reference; + typedef typename array_inner::type type; + typedef typename A2::value_type value_type; + typedef typename A2::pointer pointer; + typedef typename A2::const_pointer const_pointer; + typedef typename A2::reference reference; typedef typename A2::const_reference const_reference; - typedef typename A2::size_type size_type; + typedef typename A2::size_type size_type; typedef typename A2::difference_type difference_type; template struct rebind { - typedef allocate_array_helper other; + typedef allocate_array_helper other; }; - allocate_array_helper(const A& allocator_, std::size_t size_, T** data_) + allocate_array_helper(const A& allocator_, type** data_) : allocator(allocator_), - size(sizeof(T) * size_), + data(data_) { + } + + allocate_array_helper(const A& allocator_, std::size_t size_, type** data_) + : array_size_base(size_), + allocator(allocator_), data(data_) { } template - allocate_array_helper(const allocate_array_helper& other) - : allocator(other.allocator), - size(other.size), + allocate_array_helper(const allocate_array_helper& other) + : array_size_base(other), + allocator(other.allocator), data(other.data) { } @@ -64,22 +72,22 @@ namespace boost { } pointer allocate(size_type count, const void* value = 0) { - std::size_t a1 = boost::alignment_of::value; + std::size_t a1 = boost::alignment_of::value; std::size_t n1 = count * sizeof(Y) + a1 - 1; - char* p1 = A3(allocator).allocate(n1 + size, value); - char* p2 = p1 + n1; + char* p1 = A3(allocator).allocate(size + n1, value); + char* p2 = p1 + n1; while (std::size_t(p2) % a1 != 0) { p2--; } - *data = reinterpret_cast(p2); - return reinterpret_cast(p1); + *data = reinterpret_cast(p2); + return reinterpret_cast(p1); } void deallocate(pointer memory, size_type count) { - std::size_t a1 = boost::alignment_of::value; + std::size_t a1 = boost::alignment_of::value; std::size_t n1 = count * sizeof(Y) + a1 - 1; - char* p1 = reinterpret_cast(memory); - A3(allocator).deallocate(p1, n1 + size); + char* p1 = reinterpret_cast(memory); + A3(allocator).deallocate(p1, size + n1); } void construct(pointer memory, const Y& value) { @@ -91,110 +99,18 @@ namespace boost { } template - bool operator==(const allocate_array_helper& other) const { + bool operator==(const allocate_array_helper& other) const { return allocator == other.allocator; } template - bool operator!=(const allocate_array_helper& other) const { + bool operator!=(const allocate_array_helper& other) const { return !(*this == other); } private: A2 allocator; - std::size_t size; - T** data; - }; - - template - class allocate_array_helper { - template - friend class allocate_array_helper; - - typedef typename A::template rebind ::other A2; - typedef typename A::template rebind::other A3; - - public: - typedef typename A2::value_type value_type; - typedef typename A2::pointer pointer; - typedef typename A2::const_pointer const_pointer; - typedef typename A2::reference reference; - typedef typename A2::const_reference const_reference; - typedef typename A2::size_type size_type; - typedef typename A2::difference_type difference_type; - - template - struct rebind { - typedef allocate_array_helper other; - }; - - allocate_array_helper(const A& allocator_, T** data_) - : allocator(allocator_), - data(data_) { - } - - template - allocate_array_helper(const allocate_array_helper& other) - : allocator(other.allocator), - data(other.data) { - } - - pointer address(reference value) const { - return allocator.address(value); - } - - const_pointer address(const_reference value) const { - return allocator.address(value); - } - - size_type max_size() const { - return allocator.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(Y) + a1 - 1; - char* p1 = A3(allocator).allocate(n1 + N1, value); - char* p2 = p1 + n1; - while (std::size_t(p2) % a1 != 0) { - p2--; - } - *data = reinterpret_cast(p2); - return reinterpret_cast(p1); - } - - void deallocate(pointer memory, size_type count) { - std::size_t a1 = boost::alignment_of::value; - std::size_t n1 = count * sizeof(Y) + a1 - 1; - char* p1 = reinterpret_cast(memory); - A3(allocator).deallocate(p1, n1 + N1); - } - - void construct(pointer memory, const Y& value) { - allocator.construct(memory, value); - } - - void destroy(pointer memory) { - allocator.destroy(memory); - } - - template - bool operator==(const allocate_array_helper& other) const { - return allocator == other.allocator; - } - - template - bool operator!=(const allocate_array_helper& other) const { - return !(*this == other); - } - - private: - enum { - N1 = N * sizeof(T) - }; - - A2 allocator; - T** data; + type** data; }; } } diff --git a/include/boost/smart_ptr/detail/array_deleter.hpp b/include/boost/smart_ptr/detail/array_deleter.hpp index 9d7f970..58adbbc 100644 --- a/include/boost/smart_ptr/detail/array_deleter.hpp +++ b/include/boost/smart_ptr/detail/array_deleter.hpp @@ -15,13 +15,38 @@ namespace boost { namespace detail { template - class array_deleter; + struct array_count_base; template - class array_deleter { + struct array_count_base { + array_count_base(std::size_t size_) + : size(size_) { + } + + std::size_t size; + }; + + template + struct array_count_base { + enum { + size = N + }; + }; + + template + class array_deleter + : array_count_base { + using array_count_base::size; + public: + typedef typename array_inner::type type; + + array_deleter() + : object(0) { + } + array_deleter(std::size_t size_) - : size(size_), + : array_count_base(size_), object(0) { } @@ -31,18 +56,18 @@ namespace boost { } } - void init(T* memory) { + void init(type* memory) { array_init(memory, size); object = memory; } template - void init(T* memory, const T* value) { - array_init(memory, size, value); + void init(type* memory, const type* value) { + array_init(memory, size, value); object = memory; } - void noinit(T* memory) { + void noinit(type* memory) { array_noinit(memory, size); object = memory; } @@ -55,49 +80,8 @@ namespace boost { } private: - std::size_t size; - T* object; - }; - - template - class array_deleter { - public: - array_deleter() - : object(0) { - } - - ~array_deleter() { - if (object) { - array_destroy(object, N); - } - } - - void init(T* memory) { - array_init(memory, N); - object = memory; - } - - template - void init(T* memory, const T* value) { - array_init(memory, N, value); - object = memory; - } - - void noinit(T* memory) { - array_noinit(memory, N); - object = memory; - } - - void operator()(const void*) { - if (object) { - array_destroy(object, N); - object = 0; - } - } - - private: - T* object; - }; + type* object; + }; } } diff --git a/include/boost/smart_ptr/detail/array_size_base.hpp b/include/boost/smart_ptr/detail/array_size_base.hpp new file mode 100644 index 0000000..df5aab2 --- /dev/null +++ b/include/boost/smart_ptr/detail/array_size_base.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_ARRAY_SIZE_BASE_HPP +#define BOOST_SMART_PTR_DETAIL_ARRAY_SIZE_BASE_HPP + +#include + +namespace boost { + namespace detail { + template + struct array_size_base; + + template + struct array_size_base { + array_size_base(std::size_t size_) + : size(size_ * sizeof(T)) { + } + + std::size_t size; + }; + + template + struct array_size_base { + enum { + size = N * sizeof(T) + }; + }; + } +} + +#endif diff --git a/include/boost/smart_ptr/detail/make_array_helper.hpp b/include/boost/smart_ptr/detail/make_array_helper.hpp index cc1fc44..3aebb6d 100644 --- a/include/boost/smart_ptr/detail/make_array_helper.hpp +++ b/include/boost/smart_ptr/detail/make_array_helper.hpp @@ -9,40 +9,47 @@ #ifndef BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP #define BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP +#include +#include #include namespace boost { namespace detail { template - class make_array_helper; + class make_array_helper + : array_size_base { + using array_size_base::size; - template - class make_array_helper { template friend class make_array_helper; public: - typedef Y value_type; - typedef Y* pointer; - typedef const Y* const_pointer; - typedef Y& reference; - typedef const Y& const_reference; + typedef typename array_inner::type type; + typedef Y value_type; + typedef Y* pointer; + typedef const Y* const_pointer; + typedef Y& reference; + typedef const Y& const_reference; typedef std::size_t size_type; - typedef ptrdiff_t difference_type; + typedef ptrdiff_t difference_type; template struct rebind { - typedef make_array_helper other; + typedef make_array_helper other; }; - make_array_helper(std::size_t size_, T** data_) - : size(sizeof(T) * size_), + make_array_helper(type** data_) + : data(data_) { + } + + make_array_helper(std::size_t size_, type** data_) + : array_size_base(size_), data(data_) { } template - make_array_helper(const make_array_helper& other) - : size(other.size), + make_array_helper(const make_array_helper& other) + : array_size_base(other), data(other.data) { } @@ -59,15 +66,15 @@ namespace boost { } pointer allocate(size_type count, const void* = 0) { - std::size_t a1 = boost::alignment_of::value; + std::size_t a1 = boost::alignment_of::value; std::size_t n1 = count * sizeof(Y) + a1 - 1; - void* p1 = ::operator new(n1 + size); - char* p2 = static_cast(p1) + n1; + void* p1 = ::operator new(n1 + size); + char* p2 = static_cast(p1) + n1; while (std::size_t(p2) % a1 != 0) { p2--; } - *data = reinterpret_cast(p2); - return reinterpret_cast(p1); + *data = reinterpret_cast(p2); + return reinterpret_cast(p1); } void deallocate(pointer memory, size_type) { @@ -85,102 +92,17 @@ namespace boost { } template - bool operator==(const make_array_helper&) const { + bool operator==(const make_array_helper&) const { return true; } template - bool operator!=(const make_array_helper& other) const { + bool operator!=(const make_array_helper& other) const { return !(*this == other); } private: - std::size_t size; - T** data; - }; - - template - class make_array_helper { - template - friend class make_array_helper; - - public: - typedef Y value_type; - typedef Y* pointer; - typedef const Y* const_pointer; - typedef Y& reference; - typedef const Y& const_reference; - typedef std::size_t size_type; - typedef ptrdiff_t difference_type; - - template - struct rebind { - typedef make_array_helper other; - }; - - make_array_helper(T** data_) - : data(data_) { - } - - template - make_array_helper(const make_array_helper& other) - : data(other.data) { - } - - pointer address(reference value) const { - return &value; - } - - const_pointer address(const_reference value) const { - return &value; - } - - size_type max_size() const { - return static_cast(-1) / sizeof(Y); - } - - pointer allocate(size_type count, const void* = 0) { - std::size_t a1 = boost::alignment_of::value; - std::size_t n1 = count * sizeof(Y) + a1 - 1; - void* p1 = ::operator new(n1 + N1); - char* p2 = static_cast(p1) + n1; - while (std::size_t(p2) % a1 != 0) { - p2--; - } - *data = reinterpret_cast(p2); - return reinterpret_cast(p1); - } - - void deallocate(pointer memory, size_type) { - void* p1 = memory; - ::operator delete(p1); - } - - void construct(pointer memory, const Y& value) { - void* p1 = memory; - ::new(p1) Y(value); - } - - void destroy(pointer memory) { - memory->~Y(); - } - - template - bool operator==(const make_array_helper&) const { - return true; - } - - template - bool operator!=(const make_array_helper& other) const { - return !(*this == other); - } - - private: - enum { - N1 = N * sizeof(T) - }; - - T** data; + type** data; }; } }