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