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_EXPAND_BWD_TEST_ALLOCATOR_HPP
12#define BOOST_INTERPROCESS_EXPAND_BWD_TEST_ALLOCATOR_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/interprocess/interprocess_fwd.hpp>
22#include <boost/interprocess/containers/allocation_type.hpp>
23#include <boost/assert.hpp>
24#include <boost/interprocess/detail/utilities.hpp>
25#include <boost/interprocess/containers/version_type.hpp>
26#include <boost/interprocess/exceptions.hpp>
27#include <boost/move/adl_move_swap.hpp>
28#include <memory>
29#include <cstddef>
30#include <cassert>
31#include <new>
32
33//!\file
34//!Describes an allocator to test expand capabilities
35
36namespace boost {
37namespace interprocess {
38namespace test {
39
40//This allocator just allows two allocations. The first one will return
41//mp_buffer + m_offset configured in the constructor. The second one
42//will return mp_buffer.
43template<class T>
44class expand_bwd_test_allocator
45{
46 private:
47 typedef expand_bwd_test_allocator<T> self_t;
48 typedef void * aux_pointer_t;
49 typedef const void * cvoid_ptr;
50
51 template<class T2>
52 expand_bwd_test_allocator& operator=(const expand_bwd_test_allocator<T2>&);
53
54 expand_bwd_test_allocator& operator=(const expand_bwd_test_allocator&);
55
56 public:
57 typedef T value_type;
58 typedef T * pointer;
59 typedef const T * const_pointer;
60 typedef typename ipcdetail::add_reference
61 <value_type>::type reference;
62 typedef typename ipcdetail::add_reference
63 <const value_type>::type const_reference;
64 typedef std::size_t size_type;
65
66 typedef boost::interprocess::version_type<expand_bwd_test_allocator, 2> version;
67
68 //Dummy multiallocation chain
69 struct multiallocation_chain{};
70
71 template<class T2>
72 struct rebind
73 { typedef expand_bwd_test_allocator<T2> other; };
74
75 //!Constructor from the segment manager. Never throws
76 expand_bwd_test_allocator(T *buf, size_type sz, size_type offset)
77 : mp_buffer(buf), m_size(sz)
78 , m_offset(offset), m_allocations(0){ }
79
80 //!Constructor from other expand_bwd_test_allocator. Never throws
81 expand_bwd_test_allocator(const expand_bwd_test_allocator &other)
82 : mp_buffer(other.mp_buffer), m_size(other.m_size)
83 , m_offset(other.m_offset), m_allocations(0){ }
84
85 //!Constructor from related expand_bwd_test_allocator. Never throws
86 template<class T2>
87 expand_bwd_test_allocator(const expand_bwd_test_allocator<T2> &other)
88 : mp_buffer(other.mp_buffer), m_size(other.m_size)
89 , m_offset(other.m_offset), m_allocations(0){ }
90
91 pointer address(reference value)
92 { return pointer(addressof(value)); }
93
94 const_pointer address(const_reference value) const
95 { return const_pointer(addressof(value)); }
96
97 pointer allocate(size_type , cvoid_ptr hint = 0)
98 { (void)hint; return 0; }
99
100 void deallocate(const pointer &, size_type)
101 {}
102
103 template<class Convertible>
104 void construct(pointer ptr, const Convertible &value)
105 { new((void*)ptr) value_type(value); }
106
107 void destroy(pointer ptr)
108 { (*ptr).~value_type(); }
109
110 size_type max_size() const
111 { return m_size; }
112
113 friend void swap(self_t &alloc1, self_t &alloc2)
114 {
115 ::boost::adl_move_swap(alloc1.mp_buffer, alloc2.mp_buffer);
116 ::boost::adl_move_swap(alloc1.m_size, alloc2.m_size);
117 ::boost::adl_move_swap(alloc1.m_offset, alloc2.m_offset);
118 }
119
120 //Experimental version 2 expand_bwd_test_allocator functions
121
122 pointer allocation_command(boost::interprocess::allocation_type command,
123 size_type limit_size, size_type &prefer_in_recvd_out_size, pointer &reuse)
124 {
125 (void)reuse; (void)command;
126 //This allocator only expands backwards!
127 assert(m_allocations == 0 || (command & boost::interprocess::expand_bwd));
128 prefer_in_recvd_out_size = limit_size;
129
130 if(m_allocations == 0){
131 if((m_offset + limit_size) > m_size){
132 assert(0);
133 }
134 ++m_allocations;
135 return mp_buffer + std::ptrdiff_t(m_offset);
136 }
137 else if(m_allocations == 1){
138 if(limit_size > m_size){
139 assert(0);
140 }
141 ++m_allocations;
142 return mp_buffer;
143 }
144 else{
145 assert(0);
146 throw std::bad_alloc();
147 }
148 }
149
150 //!Returns maximum the number of objects the previously allocated memory
151 //!pointed by p can hold.
152 size_type size(const pointer &p) const
153 { (void)p; return m_size; }
154
155 //!Allocates just one object. Memory allocated with this function
156 //!must be deallocated only with deallocate_one().
157 //!Throws boost::interprocess::bad_alloc if there is no enough memory
158 pointer allocate_one()
159 { return this->allocate(1); }
160
161 //!Deallocates memory previously allocated with allocate_one().
162 //!You should never use deallocate_one to deallocate memory allocated
163 //!with other functions different from allocate_one(). Never throws
164 void deallocate_one(const pointer &p)
165 { return this->deallocate(p, 1); }
166
167 pointer mp_buffer;
168 size_type m_size;
169 size_type m_offset;
170 char m_allocations;
171};
172
173//!Equality test for same type of expand_bwd_test_allocator
174template<class T> inline
175bool operator==(const expand_bwd_test_allocator<T> &,
176 const expand_bwd_test_allocator<T> &)
177{ return false; }
178
179//!Inequality test for same type of expand_bwd_test_allocator
180template<class T> inline
181bool operator!=(const expand_bwd_test_allocator<T> &,
182 const expand_bwd_test_allocator<T> &)
183{ return true; }
184
185} //namespace test {
186} //namespace interprocess {
187} //namespace boost {
188
189#include <boost/interprocess/detail/config_end.hpp>
190
191#endif //BOOST_INTERPROCESS_EXPAND_BWD_TEST_ALLOCATOR_HPP
192
193

source code of boost/libs/interprocess/test/expand_bwd_test_allocator.hpp