/* * Copyright (c) 2012 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_MAKE_ARRAY_HELPER_HPP #define BOOST_SMART_PTR_DETAIL_MAKE_ARRAY_HELPER_HPP #include namespace boost { namespace detail { template class make_array_helper; 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(std::size_t size_, T** data_) : size(sizeof(T) * size_), data(data_) { } template make_array_helper(const make_array_helper& other) : size(other.size), 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 + size); 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: 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; }; } } #endif