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 cmemlink
l (*this);
116 /// Copies data from \p p, \p n.
117 void memblock::assign (const void* p
, size_type n
)
119 assert ((p
!= (const void*) cdata() || size() == n
) && "Self-assignment can not resize");
124 /// \brief Reallocates internal block to hold at least \p newSize bytes.
126 /// Additional memory may be allocated, but for efficiency it is a very
127 /// good idea to call reserve before doing byte-by-byte edit operations.
128 /// The block size as returned by size() is not altered. reserve will not
129 /// reduce allocated memory. If you think you are wasting space, call
130 /// deallocate and start over. To avoid wasting space, use the block for
131 /// only one purpose, and try to get that purpose to use similar amounts
132 /// of memory on each iteration.
134 void memblock::reserve (size_type newSize
, bool bExact
)
136 if ((newSize
+= minimumFreeCapacity()) <= m_Capacity
)
138 pointer
oldBlock (is_linked() ? NULL
: data());
139 const size_t alignedSize (Align (newSize
, c_PageSize
));
141 newSize
= alignedSize
;
142 pointer newBlock
= (pointer
) realloc (oldBlock
, newSize
);
144 throw bad_alloc (newSize
);
145 if (!oldBlock
& (cdata() != NULL
))
146 copy_n (cdata(), min (size() + 1, newSize
), newBlock
);
147 link (newBlock
, size());
148 m_Capacity
= newSize
;
151 /// Swaps the contents with \p l
152 void memblock::swap (memblock
& l
)
155 ::ustl::swap (m_Capacity
, l
.m_Capacity
);
158 /// Shifts the data in the linked block from \p start to \p start + \p n.
159 memblock::iterator
memblock::insert (iterator start
, size_type n
)
161 const uoff_t ip
= start
- begin();
162 assert (ip
<= size());
163 resize (size() + n
, false);
164 memlink::insert (iat(ip
), n
);
168 /// Shifts the data in the linked block from \p start + \p n to \p start.
169 memblock::iterator
memblock::erase (iterator start
, size_type n
)
171 const uoff_t ep
= start
- begin();
172 assert (ep
+ n
<= size());
173 memlink::erase (start
, n
);
174 memlink::resize (size() - n
);
179 void memblock::unlink (void)
185 /// Reads the object from stream \p s
186 void memblock::read (istream
& is
)
190 is
.verify_remaining ("read", "ustl::memblock", n
);
192 is
.read (data(), writable_size());
193 is
.align (alignof (n
));
196 /// Reads the entire file \p "filename".
197 void memblock::read_file (const char* filename
)
200 f
.exceptions (fstream::allbadbits
);
201 f
.open (filename
, fstream::in
);
202 const off_t
fsize (f
.size());
204 f
.read (data(), fsize
);