]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // | |
3 | // (C) Copyright Ion Gaztanaga 2005-2012. Distributed under the Boost | |
4 | // Software License, Version 1.0. (See accompanying file | |
5 | // LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | |
6 | // | |
7 | // See http://www.boost.org/libs/interprocess for documentation. | |
8 | // | |
9 | /////////////////////////////////////////////////////////////////////////////// | |
10 | ||
11 | #ifndef BOOST_INTERPROCESS_HEAP_ALLOCATOR_V1_HPP | |
12 | #define BOOST_INTERPROCESS_HEAP_ALLOCATOR_V1_HPP | |
13 | ||
14 | #if defined (_MSC_VER) | |
15 | # pragma once | |
16 | #endif | |
17 | ||
18 | #include <boost/interprocess/detail/config_begin.hpp> | |
19 | #include <boost/interprocess/detail/workaround.hpp> | |
20 | ||
21 | #include <boost/intrusive/pointer_traits.hpp> | |
22 | ||
23 | #include <boost/interprocess/interprocess_fwd.hpp> | |
24 | #include <boost/interprocess/containers/allocation_type.hpp> | |
25 | #include <boost/interprocess/detail/utilities.hpp> | |
26 | #include <boost/interprocess/containers/version_type.hpp> | |
27 | #include <boost/interprocess/exceptions.hpp> | |
28 | #include <boost/move/adl_move_swap.hpp> | |
29 | ||
30 | //!\file | |
31 | //!Describes an heap_allocator_v1 that allocates portions of fixed size | |
32 | //!memory buffer (shared memory, mapped file...) | |
33 | ||
34 | namespace boost { | |
35 | namespace interprocess { | |
36 | namespace test { | |
37 | ||
38 | //!An STL compatible heap_allocator_v1 that uses a segment manager as | |
39 | //!memory source. The internal pointer type will of the same type (raw, smart) as | |
40 | //!"typename SegmentManager::void_pointer" type. This allows | |
41 | //!placing the heap_allocator_v1 in shared memory, memory mapped-files, etc...*/ | |
42 | template<class T, class SegmentManager> | |
43 | class heap_allocator_v1 | |
44 | { | |
45 | private: | |
46 | typedef heap_allocator_v1<T, SegmentManager> self_t; | |
47 | typedef SegmentManager segment_manager; | |
48 | typedef typename segment_manager::void_pointer aux_pointer_t; | |
49 | ||
50 | typedef typename boost::intrusive:: | |
51 | pointer_traits<aux_pointer_t>::template | |
52 | rebind_pointer<const void>::type cvoid_ptr; | |
53 | ||
54 | typedef typename boost::intrusive:: | |
55 | pointer_traits<cvoid_ptr>::template | |
56 | rebind_pointer<segment_manager>::type alloc_ptr_t; | |
57 | ||
58 | template<class T2, class SegmentManager2> | |
59 | heap_allocator_v1& operator=(const heap_allocator_v1<T2, SegmentManager2>&); | |
60 | ||
61 | heap_allocator_v1& operator=(const heap_allocator_v1&); | |
62 | ||
63 | alloc_ptr_t mp_mngr; | |
64 | ||
65 | public: | |
66 | typedef T value_type; | |
67 | typedef typename boost::intrusive:: | |
68 | pointer_traits<cvoid_ptr>::template | |
69 | rebind_pointer<T>::type pointer; | |
70 | typedef typename boost::intrusive:: | |
71 | pointer_traits<cvoid_ptr>::template | |
72 | rebind_pointer<const T>::type const_pointer; | |
73 | typedef typename ipcdetail::add_reference | |
74 | <value_type>::type reference; | |
75 | typedef typename ipcdetail::add_reference | |
76 | <const value_type>::type const_reference; | |
77 | typedef typename SegmentManager::size_type size_type; | |
78 | typedef typename SegmentManager::difference_type difference_type; | |
79 | ||
80 | //!Obtains an heap_allocator_v1 of other type | |
81 | template<class T2> | |
82 | struct rebind | |
83 | { | |
84 | typedef heap_allocator_v1<T2, SegmentManager> other; | |
85 | }; | |
86 | ||
87 | //!Returns the segment manager. Never throws | |
88 | segment_manager* get_segment_manager()const | |
89 | { return ipcdetail::to_raw_pointer(mp_mngr); } | |
90 | ||
91 | //!Returns address of mutable object. Never throws | |
92 | pointer address(reference value) const | |
93 | { return pointer(addressof(value)); } | |
94 | ||
95 | //!Returns address of non mutable object. Never throws | |
96 | const_pointer address(const_reference value) const | |
97 | { return const_pointer(addressof(value)); } | |
98 | ||
99 | //!Constructor from the segment manager. Never throws | |
100 | heap_allocator_v1(segment_manager *segment_mngr) | |
101 | : mp_mngr(segment_mngr) { } | |
102 | ||
103 | //!Constructor from other heap_allocator_v1. Never throws | |
104 | heap_allocator_v1(const heap_allocator_v1 &other) | |
105 | : mp_mngr(other.get_segment_manager()){ } | |
106 | ||
107 | //!Constructor from related heap_allocator_v1. Never throws | |
108 | template<class T2> | |
109 | heap_allocator_v1(const heap_allocator_v1<T2, SegmentManager> &other) | |
110 | : mp_mngr(other.get_segment_manager()){} | |
111 | ||
112 | //!Allocates memory for an array of count elements. | |
113 | //!Throws boost::interprocess::bad_alloc if there is no enough memory | |
114 | pointer allocate(size_type count, cvoid_ptr hint = 0) | |
115 | { | |
116 | (void)hint; | |
117 | char *raw_mem = ::new char[sizeof(value_type)*count]; | |
1e59de90 | 118 | return boost::intrusive::pointer_traits<pointer>::pointer_to(*reinterpret_cast<value_type *>((void*)raw_mem)); |
7c673cae FG |
119 | } |
120 | ||
121 | //!Deallocates memory previously allocated. Never throws | |
122 | void deallocate(const pointer &ptr, size_type) | |
92f5a8d4 TL |
123 | { |
124 | char *ptr_raw = (char*)ipcdetail::to_raw_pointer(ptr); | |
125 | ::delete[] ptr_raw; | |
126 | } | |
7c673cae FG |
127 | |
128 | //!Construct object, calling constructor. | |
129 | //!Throws if T(const T&) throws | |
130 | void construct(const pointer &ptr, const_reference value) | |
131 | { new((void*)ipcdetail::to_raw_pointer(ptr)) value_type(value); } | |
132 | ||
133 | //!Destroys object. Throws if object's destructor throws | |
134 | void destroy(const pointer &ptr) | |
135 | { BOOST_ASSERT(ptr != 0); (*ptr).~value_type(); } | |
136 | ||
137 | //!Returns the number of elements that could be allocated. Never throws | |
138 | size_type max_size() const | |
139 | { return mp_mngr->get_size(); } | |
140 | ||
141 | //!Swap segment manager. Does not throw. If each heap_allocator_v1 is placed in | |
142 | //!different memory segments, the result is undefined. | |
143 | friend void swap(self_t &alloc1, self_t &alloc2) | |
144 | { ::boost::adl_move_swap(alloc1.mp_mngr, alloc2.mp_mngr); } | |
145 | }; | |
146 | ||
147 | //!Equality test for same type of heap_allocator_v1 | |
148 | template<class T, class SegmentManager> inline | |
149 | bool operator==(const heap_allocator_v1<T , SegmentManager> &alloc1, | |
150 | const heap_allocator_v1<T, SegmentManager> &alloc2) | |
151 | { return alloc1.get_segment_manager() == alloc2.get_segment_manager(); } | |
152 | ||
153 | //!Inequality test for same type of heap_allocator_v1 | |
154 | template<class T, class SegmentManager> inline | |
155 | bool operator!=(const heap_allocator_v1<T, SegmentManager> &alloc1, | |
156 | const heap_allocator_v1<T, SegmentManager> &alloc2) | |
157 | { return alloc1.get_segment_manager() != alloc2.get_segment_manager(); } | |
158 | ||
159 | } //namespace test { | |
160 | } //namespace interprocess { | |
161 | } //namespace boost { | |
162 | ||
163 | #include <boost/interprocess/detail/config_end.hpp> | |
164 | ||
165 | #endif //BOOST_INTERPROCESS_HEAP_ALLOCATOR_V1_HPP | |
166 |