1 // This file is part of the ustl library, an STL implementation.
3 // Copyright (C) 2005 by Mike Sharov <msharov@users.sourceforge.net>
4 // This file is free software, distributed under the MIT License.
8 // Allocated memory block.
20 /// Allocates 0 bytes for the internal block.
21 memblock::memblock (void)
27 /// Allocates \p n bytes for the internal block.
28 memblock::memblock (size_type n
)
35 /// links to \p p, \p n. Data can not be modified and will not be freed.
36 memblock::memblock (const void* p
, size_type n
)
43 /// Links to what \p b is linked to.
44 memblock::memblock (const cmemlink
& b
)
51 /// Links to what \p b is linked to.
52 memblock::memblock (const memlink
& b
)
59 /// Links to what \p b is linked to.
60 memblock::memblock (const memblock
& b
)
67 /// Frees internal data, if appropriate
68 /// Only if the block was allocated using resize, or linked to using Manage,
69 /// will it be freed. Also, Derived classes should call DestructBlock from
70 /// their destructor, because upstream virtual functions are unavailable at
71 /// this point and will not be called automatically.
73 memblock::~memblock (void)
78 /// resizes the block to \p newSize bytes, reallocating if necessary.
79 void memblock::resize (size_type newSize
, bool bExact
)
81 if (m_Capacity
< newSize
+ minimumFreeCapacity())
82 reserve (newSize
, bExact
);
83 memlink::resize (newSize
);
86 /// Frees internal data.
87 void memblock::deallocate (void) throw()
90 assert (cdata() && "Internal error: space allocated, but the pointer is NULL");
91 assert (data() && "Internal error: read-only block is marked as allocated space");
97 /// Assumes control of the memory block \p p of size \p n.
98 /// The block assigned using this function will be freed in the destructor.
99 void memblock::manage (void* p
, size_type n
)
102 assert (!m_Capacity
&& "Already managing something. deallocate or unlink first.");
107 /// "Instantiate" a linked block by allocating and copying the linked data.
108 void memblock::copy_link (void)
110 const pointer
p (begin());
111 const size_t sz (size());
117 /// Copies data from \p p, \p n.
118 void memblock::assign (const void* p
, size_type n
)
120 assert ((p
!= (const void*) cdata() || size() == n
) && "Self-assignment can not resize");
125 /// \brief Reallocates internal block to hold at least \p newSize bytes.
127 /// Additional memory may be allocated, but for efficiency it is a very
128 /// good idea to call reserve before doing byte-by-byte edit operations.
129 /// The block size as returned by size() is not altered. reserve will not
130 /// reduce allocated memory. If you think you are wasting space, call
131 /// deallocate and start over. To avoid wasting space, use the block for
132 /// only one purpose, and try to get that purpose to use similar amounts
133 /// of memory on each iteration.
135 void memblock::reserve (size_type newSize
, bool bExact
)
137 if ((newSize
+= minimumFreeCapacity()) <= m_Capacity
)
139 pointer
oldBlock (is_linked() ? NULL
: data());
140 const size_t alignedSize (Align (newSize
, c_PageSize
));
142 newSize
= alignedSize
;
143 pointer newBlock
= (pointer
) realloc (oldBlock
, newSize
);
145 throw bad_alloc (newSize
);
146 if (!oldBlock
& (cdata() != NULL
))
147 copy_n (cdata(), min (size() + 1, newSize
), newBlock
);
148 link (newBlock
, size());
149 m_Capacity
= newSize
;
152 /// Swaps the contents with \p l
153 void memblock::swap (memblock
& l
)
156 ::ustl::swap (m_Capacity
, l
.m_Capacity
);
159 /// Shifts the data in the linked block from \p start to \p start + \p n.
160 memblock::iterator
memblock::insert (iterator start
, size_type n
)
162 const uoff_t ip
= start
- begin();
163 assert (ip
<= size());
164 resize (size() + n
, false);
165 memlink::insert (iat(ip
), n
);
169 /// Shifts the data in the linked block from \p start + \p n to \p start.
170 memblock::iterator
memblock::erase (iterator start
, size_type n
)
172 const uoff_t ep
= start
- begin();
173 assert (ep
+ n
<= size());
174 memlink::erase (start
, n
);
175 memlink::resize (size() - n
);
180 void memblock::unlink (void) throw()
186 /// Reads the object from stream \p s
187 void memblock::read (istream
& is
)
191 is
.verify_remaining ("read", "ustl::memblock", n
);
193 is
.read (data(), writable_size());
194 is
.align (alignof (n
));
197 /// Reads the entire file \p "filename".
198 void memblock::read_file (const char* filename
)
201 f
.exceptions (fstream::allbadbits
);
202 f
.open (filename
, fstream::in
);
203 const off_t
fsize (f
.size());
205 f
.read (data(), fsize
);