summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '3rdParty/Boost/src/boost/smart_ptr/detail/array_allocator.hpp')
-rw-r--r--3rdParty/Boost/src/boost/smart_ptr/detail/array_allocator.hpp318
1 files changed, 318 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/smart_ptr/detail/array_allocator.hpp b/3rdParty/Boost/src/boost/smart_ptr/detail/array_allocator.hpp
new file mode 100644
index 0000000..4f9dc2b
--- /dev/null
+++ b/3rdParty/Boost/src/boost/smart_ptr/detail/array_allocator.hpp
@@ -0,0 +1,318 @@
+/*
+ * 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_ALLOCATOR_HPP
+#define BOOST_SMART_PTR_DETAIL_ARRAY_ALLOCATOR_HPP
+
+#include <boost/align/align.hpp>
+#include <boost/smart_ptr/detail/array_traits.hpp>
+#include <boost/smart_ptr/detail/array_utility.hpp>
+#include <boost/type_traits/alignment_of.hpp>
+
+namespace boost {
+ namespace detail {
+ struct ms_init_tag { };
+ struct ms_noinit_tag { };
+
+ template<class T>
+ struct ms_allocator_state;
+
+ template<class T>
+ struct ms_allocator_state<T[]> {
+ typedef typename array_base<T>::type type;
+
+ ms_allocator_state(std::size_t size_,
+ type** result_)
+ : size(size_ * array_total<T>::size),
+ result(result_) {
+ }
+
+ std::size_t size;
+
+ union {
+ type** result;
+ type* object;
+ };
+ };
+
+ template<class T, std::size_t N>
+ struct ms_allocator_state<T[N]> {
+ typedef typename array_base<T>::type type;
+
+ ms_allocator_state(type** result_)
+ : result(result_) {
+ }
+
+ enum {
+ size = array_total<T[N]>::size
+ };
+
+ union {
+ type** result;
+ type* object;
+ };
+ };
+
+ template<class A, class T, class R>
+ class as_allocator
+ : public A {
+ template<class A_, class T_, class R_>
+ friend class as_allocator;
+
+#if !defined(BOOST_NO_CXX11_ALLOCATOR)
+ typedef std::allocator_traits<A> AT;
+ typedef typename AT::template rebind_alloc<char> CA;
+ typedef typename AT::template rebind_traits<char> CT;
+#else
+ typedef typename A::template rebind<char>::other CA;
+#endif
+
+ public:
+ typedef A allocator_type;
+
+#if !defined(BOOST_NO_CXX11_ALLOCATOR)
+ typedef typename AT::value_type value_type;
+ typedef typename AT::pointer pointer;
+ typedef typename AT::const_pointer const_pointer;
+ typedef typename AT::void_pointer void_pointer;
+ typedef typename AT::const_void_pointer const_void_pointer;
+ typedef typename AT::size_type size_type;
+ typedef typename AT::difference_type difference_type;
+#else
+ typedef typename A::value_type value_type;
+ typedef typename A::pointer pointer;
+ typedef typename A::const_pointer const_pointer;
+ typedef typename A::size_type size_type;
+ typedef typename A::difference_type difference_type;
+ typedef typename A::reference reference;
+ typedef typename A::const_reference const_reference;
+ typedef void* void_pointer;
+ typedef const void* const_void_pointer;
+#endif
+
+ template<class U>
+ struct rebind {
+#if !defined(BOOST_NO_CXX11_ALLOCATOR)
+ typedef as_allocator<typename AT::
+ template rebind_alloc<U>, T, R> other;
+#else
+ typedef as_allocator<typename A::
+ template rebind<U>::other, T, R> other;
+#endif
+ };
+
+ typedef typename array_base<T>::type type;
+
+ as_allocator(const A& allocator_, type** result)
+ : A(allocator_),
+ data(result) {
+ }
+
+ as_allocator(const A& allocator_, std::size_t size,
+ type** result)
+ : A(allocator_),
+ data(size, result) {
+ }
+
+ template<class U>
+ as_allocator(const as_allocator<U, T, R>& other)
+ : A(other.allocator()),
+ data(other.data) {
+ }
+
+ pointer allocate(size_type count, const_void_pointer = 0) {
+ enum {
+ M = boost::alignment_of<type>::value
+ };
+ std::size_t n1 = count * sizeof(value_type);
+ std::size_t n2 = data.size * sizeof(type);
+ std::size_t n3 = n2 + M;
+ CA ca(allocator());
+ void* p1 = ca.allocate(n1 + n3);
+ void* p2 = static_cast<char*>(p1) + n1;
+ (void)boost::alignment::align(M, n2, p2, n3);
+ *data.result = static_cast<type*>(p2);
+ return static_cast<value_type*>(p1);
+ }
+
+ void deallocate(pointer memory, size_type count) {
+ enum {
+ M = boost::alignment_of<type>::value
+ };
+ std::size_t n1 = count * sizeof(value_type);
+ std::size_t n2 = data.size * sizeof(type) + M;
+ char* p1 = reinterpret_cast<char*>(memory);
+ CA ca(allocator());
+ ca.deallocate(p1, n1 + n2);
+ }
+
+ const A& allocator() const {
+ return static_cast<const A&>(*this);
+ }
+
+ A& allocator() {
+ return static_cast<A&>(*this);
+ }
+
+ void set(type* memory) {
+ data.object = memory;
+ }
+
+ void operator()() {
+ if (data.object) {
+ R tag;
+ release(tag);
+ }
+ }
+
+ private:
+ void release(ms_init_tag) {
+#if !defined(BOOST_NO_CXX11_ALLOCATOR)
+ as_destroy(allocator(), data.object, data.size);
+#else
+ ms_destroy(data.object, data.size);
+#endif
+ }
+
+ void release(ms_noinit_tag) {
+ ms_destroy(data.object, data.size);
+ }
+
+ ms_allocator_state<T> data;
+ };
+
+ template<class A1, class A2, class T, class R>
+ bool operator==(const as_allocator<A1, T, R>& a1,
+ const as_allocator<A2, T, R>& a2) {
+ return a1.allocator() == a2.allocator();
+ }
+
+ template<class A1, class A2, class T, class R>
+ bool operator!=(const as_allocator<A1, T, R>& a1,
+ const as_allocator<A2, T, R>& a2) {
+ return a1.allocator() != a2.allocator();
+ }
+
+ template<class T, class Y = char>
+ class ms_allocator;
+
+ template<class T, class Y>
+ class ms_allocator {
+ template<class T_, class Y_>
+ friend class ms_allocator;
+
+ public:
+ typedef typename array_base<T>::type type;
+
+ typedef Y value_type;
+ typedef Y* pointer;
+ typedef const Y* const_pointer;
+ typedef std::size_t size_type;
+ typedef ptrdiff_t difference_type;
+ typedef Y& reference;
+ typedef const Y& const_reference;
+
+ template<class U>
+ struct rebind {
+ typedef ms_allocator<T, U> other;
+ };
+
+ ms_allocator(type** result)
+ : data(result) {
+ }
+
+ ms_allocator(std::size_t size, type** result)
+ : data(size, result) {
+ }
+
+ template<class U>
+ ms_allocator(const ms_allocator<T, U>& other)
+ : data(other.data) {
+ }
+
+ pointer allocate(size_type count, const void* = 0) {
+ enum {
+ M = boost::alignment_of<type>::value
+ };
+ std::size_t n1 = count * sizeof(Y);
+ std::size_t n2 = data.size * sizeof(type);
+ std::size_t n3 = n2 + M;
+ void* p1 = ::operator new(n1 + n3);
+ void* p2 = static_cast<char*>(p1) + n1;
+ (void)boost::alignment::align(M, n2, p2, n3);
+ *data.result = static_cast<type*>(p2);
+ return static_cast<Y*>(p1);
+ }
+
+ void deallocate(pointer memory, size_type) {
+ void* p1 = memory;
+ ::operator delete(p1);
+ }
+
+#if defined(BOOST_NO_CXX11_ALLOCATOR)
+ pointer address(reference value) const {
+ return &value;
+ }
+
+ const_pointer address(const_reference value) const {
+ return &value;
+ }
+
+ size_type max_size() const {
+ enum {
+ N = static_cast<std::size_t>(-1) / sizeof(Y)
+ };
+ return N;
+ }
+
+ void construct(pointer memory, const_reference value) {
+ void* p1 = memory;
+ ::new(p1) Y(value);
+ }
+
+ void destroy(pointer memory) {
+ (void)memory;
+ memory->~Y();
+ }
+#endif
+
+ void set(type* memory) {
+ data.object = memory;
+ }
+
+ void operator()() {
+ if (data.object) {
+ ms_destroy(data.object, data.size);
+ }
+ }
+
+ private:
+ ms_allocator_state<T> data;
+ };
+
+ template<class T, class Y1, class Y2>
+ bool operator==(const ms_allocator<T, Y1>&,
+ const ms_allocator<T, Y2>&) {
+ return true;
+ }
+
+ template<class T, class Y1, class Y2>
+ bool operator!=(const ms_allocator<T, Y1>&,
+ const ms_allocator<T, Y2>&) {
+ return false;
+ }
+
+ class ms_in_allocator_tag {
+ public:
+ void operator()(const void*) {
+ }
+ };
+ }
+}
+
+#endif