Imported Upstream version 1.49.0
[platform/upstream/boost.git] / libs / container / test / expand_bwd_test_allocator.hpp
1 ///////////////////////////////////////////////////////////////////////////////
2 //
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)
6 //
7 // See http://www.boost.org/libs/container for documentation.
8 //
9 ///////////////////////////////////////////////////////////////////////////////
10
11 #ifndef BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP
12 #define BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP
13
14 #if (defined _MSC_VER) && (_MSC_VER >= 1200)
15 #  pragma once
16 #endif
17
18 #include <boost/container/detail/config_begin.hpp>
19 #include <boost/container/detail/workaround.hpp>
20
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>
26 #include <memory>
27 #include <algorithm>
28 #include <cstddef>
29 #include <stdexcept>
30 #include <cassert>
31
32 //!\file
33 //!Describes an allocator to test expand capabilities
34
35 namespace boost {
36 namespace container {
37 namespace test {
38
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.
42 template<class T>
43 class expand_bwd_test_allocator 
44 {
45  private:
46    typedef expand_bwd_test_allocator<T> self_t;
47    typedef void *                   aux_pointer_t;
48    typedef const void *             cvoid_ptr;
49
50    template<class T2>
51    expand_bwd_test_allocator& operator=(const expand_bwd_test_allocator<T2>&);
52
53    expand_bwd_test_allocator& operator=(const expand_bwd_test_allocator&);
54
55    public:
56    typedef T                                    value_type;
57    typedef T *                                  pointer;
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;
65
66    typedef boost::container::container_detail::version_type<expand_bwd_test_allocator, 2>   version;
67
68    template<class T2>
69    struct rebind
70    {  typedef expand_bwd_test_allocator<T2>   other;   };
71
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){ }
76
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){ }
81
82    //!Constructor from related expand_bwd_test_allocator. Never throws
83    template<class T2>
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){ }
87
88    pointer address(reference value)
89    {  return pointer(addressof(value));  }
90
91    const_pointer address(const_reference value) const
92    {  return const_pointer(addressof(value));  }
93
94    pointer allocate(size_type , cvoid_ptr hint = 0)
95    {  (void)hint; return 0; }
96
97    void deallocate(const pointer &, size_type)
98    {}
99
100    template<class Convertible>
101    void construct(pointer ptr, const Convertible &value)
102    {  new((void*)ptr) value_type(value);  }
103
104    void destroy(pointer ptr)
105    {  (*ptr).~value_type();  }
106
107    size_type max_size() const
108    {  return m_size;   }
109
110    friend void swap(self_t &alloc1, self_t &alloc2)
111    {  
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);
115    }
116
117    //Experimental version 2 expand_bwd_test_allocator functions
118
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)
124    {
125       (void)preferred_size;   (void)reuse;   (void)command;
126       //This allocator only expands backwards!
127       assert(m_allocations == 0 || (command & boost::container::expand_bwd));
128       
129       received_size = limit_size;
130
131       if(m_allocations == 0){
132          if((m_offset + limit_size) > m_size){
133             assert(0);
134          }
135          ++m_allocations;
136          return std::pair<pointer, bool>(mp_buffer + m_offset, false);
137       }
138       else if(m_allocations == 1){
139          if(limit_size > m_size){
140             assert(0);
141          }
142          ++m_allocations;
143          return std::pair<pointer, bool>(mp_buffer, true);
144       }
145       else{
146          assert(0);
147          throw std::bad_alloc();
148       }
149    }
150
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; }
155
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);  }
161
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);  }
167
168    pointer           mp_buffer;
169    size_type         m_size;
170    difference_type   m_offset;
171    char              m_allocations;
172 };
173
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)
178 {  return false; }
179
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)
184 {  return true; }
185
186 }  //namespace test {
187 }  //namespace container {
188 }  //namespace boost {
189
190 #include <boost/container/detail/config_end.hpp>
191
192 #endif   //BOOST_CONTAINER_EXPAND_BWD_TEST_ALLOCATOR_HPP
193