1 ///////////////////////////////////////////////////////////////////////////////
3 // (C) Copyright Ion Gaztanaga 2005-2011. 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)
7 // See http://www.boost.org/libs/container for documentation.
9 ///////////////////////////////////////////////////////////////////////////////
11 #ifndef BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP
12 #define BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP
14 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
18 #include <boost/container/detail/config_begin.hpp>
19 #include <boost/container/detail/workaround.hpp>
21 #include <boost/container/container_fwd.hpp>
22 #include <boost/container/detail/allocation_type.hpp>
23 #include <boost/assert.hpp>
24 #include <boost/container/detail/utilities.hpp>
25 #include <boost/container/detail/version_type.hpp>
33 //!Describes an allocator to test expand capabilities
39 //This allocator just allows two allocations. The first one will return
40 //mp_buffer + m_offset configured in the constructor. The second one
41 //will return mp_buffer.
43 class expand_bwd_test_allocator
46 typedef expand_bwd_test_allocator<T> self_t;
47 typedef void * aux_pointer_t;
48 typedef const void * cvoid_ptr;
51 expand_bwd_test_allocator& operator=(const expand_bwd_test_allocator<T2>&);
53 expand_bwd_test_allocator& operator=(const expand_bwd_test_allocator&);
58 typedef const T * const_pointer;
59 typedef typename container_detail::add_reference
60 <value_type>::type reference;
61 typedef typename container_detail::add_reference
62 <const value_type>::type const_reference;
63 typedef std::size_t size_type;
64 typedef std::ptrdiff_t difference_type;
66 typedef boost::container::container_detail::version_type<expand_bwd_test_allocator, 2> version;
70 { typedef expand_bwd_test_allocator<T2> other; };
72 //!Constructor from the segment manager. Never throws
73 expand_bwd_test_allocator(T *buffer, size_type size, difference_type offset)
74 : mp_buffer(buffer), m_size(size)
75 , m_offset(offset), m_allocations(0){ }
77 //!Constructor from other expand_bwd_test_allocator. Never throws
78 expand_bwd_test_allocator(const expand_bwd_test_allocator &other)
79 : mp_buffer(other.mp_buffer), m_size(other.m_size)
80 , m_offset(other.m_offset), m_allocations(0){ }
82 //!Constructor from related expand_bwd_test_allocator. Never throws
84 expand_bwd_test_allocator(const expand_bwd_test_allocator<T2> &other)
85 : mp_buffer(other.mp_buffer), m_size(other.m_size)
86 , m_offset(other.m_offset), m_allocations(0){ }
88 pointer address(reference value)
89 { return pointer(addressof(value)); }
91 const_pointer address(const_reference value) const
92 { return const_pointer(addressof(value)); }
94 pointer allocate(size_type , cvoid_ptr hint = 0)
95 { (void)hint; return 0; }
97 void deallocate(const pointer &, size_type)
100 template<class Convertible>
101 void construct(pointer ptr, const Convertible &value)
102 { new((void*)ptr) value_type(value); }
104 void destroy(pointer ptr)
105 { (*ptr).~value_type(); }
107 size_type max_size() const
110 friend void swap(self_t &alloc1, self_t &alloc2)
112 container_detail::do_swap(alloc1.mp_buffer, alloc2.mp_buffer);
113 container_detail::do_swap(alloc1.m_size, alloc2.m_size);
114 container_detail::do_swap(alloc1.m_offset, alloc2.m_offset);
117 //Experimental version 2 expand_bwd_test_allocator functions
119 std::pair<pointer, bool>
120 allocation_command(boost::container::allocation_type command,
121 size_type limit_size,
122 size_type preferred_size,
123 size_type &received_size, const pointer &reuse = 0)
125 (void)preferred_size; (void)reuse; (void)command;
126 //This allocator only expands backwards!
127 assert(m_allocations == 0 || (command & boost::container::expand_bwd));
129 received_size = limit_size;
131 if(m_allocations == 0){
132 if((m_offset + limit_size) > m_size){
136 return std::pair<pointer, bool>(mp_buffer + m_offset, false);
138 else if(m_allocations == 1){
139 if(limit_size > m_size){
143 return std::pair<pointer, bool>(mp_buffer, true);
147 throw std::bad_alloc();
151 //!Returns maximum the number of objects the previously allocated memory
152 //!pointed by p can hold.
153 size_type size(const pointer &p) const
154 { (void)p; return m_size; }
156 //!Allocates just one object. Memory allocated with this function
157 //!must be deallocated only with deallocate_one().
158 //!Throws boost::container::bad_alloc if there is no enough memory
159 pointer allocate_one()
160 { return this->allocate(1); }
162 //!Deallocates memory previously allocated with allocate_one().
163 //!You should never use deallocate_one to deallocate memory allocated
164 //!with other functions different from allocate_one(). Never throws
165 void deallocate_one(const pointer &p)
166 { return this->deallocate(p, 1); }
170 difference_type m_offset;
174 //!Equality test for same type of expand_bwd_test_allocator
175 template<class T> inline
176 bool operator==(const expand_bwd_test_allocator<T> &alloc1,
177 const expand_bwd_test_allocator<T> &alloc2)
180 //!Inequality test for same type of expand_bwd_test_allocator
181 template<class T> inline
182 bool operator!=(const expand_bwd_test_allocator<T> &alloc1,
183 const expand_bwd_test_allocator<T> &alloc2)
187 } //namespace container {
188 } //namespace boost {
190 #include <boost/container/detail/config_end.hpp>
192 #endif //BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP