You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
825 lines
19 KiB
825 lines
19 KiB
/* |
|
* This file is a part of PikoTools |
|
* and is distributed under the (new) BSD licence. |
|
* Author: Tomasz Sowa <t.sowa@ttmath.org> |
|
*/ |
|
|
|
/* |
|
* Copyright (c) 2012-2021, Tomasz Sowa |
|
* All rights reserved. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions are met: |
|
* |
|
* * Redistributions of source code must retain the above copyright notice, |
|
* this list of conditions and the following disclaimer. |
|
* |
|
* * Redistributions in binary form must reproduce the above copyright |
|
* notice, this list of conditions and the following disclaimer in the |
|
* documentation and/or other materials provided with the distribution. |
|
* |
|
* * Neither the name Tomasz Sowa nor the names of contributors to this |
|
* project may be used to endorse or promote products derived |
|
* from this software without specific prior written permission. |
|
* |
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
|
* THE POSSIBILITY OF SUCH DAMAGE. |
|
*/ |
|
|
|
#ifndef headerfile_picotools_membuffer_membuffer |
|
#define headerfile_picotools_membuffer_membuffer |
|
|
|
|
|
#include <iostream> |
|
|
|
namespace pt |
|
{ |
|
|
|
/* |
|
|
|
|
|
stack_size and heap_block_size have to be *greater* than zero |
|
*/ |
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
class MemBuffer |
|
{ |
|
public: |
|
|
|
class iterator |
|
{ |
|
public: |
|
|
|
bool operator==(const iterator & i) const; |
|
bool operator!=(const iterator & i) const; |
|
|
|
iterator & operator++(); // prefix ++ |
|
iterator operator++(int); // postfix ++ |
|
|
|
iterator & operator--(); // prefix -- |
|
iterator operator--(int); // postfix -- |
|
|
|
item_type & operator*(); |
|
|
|
private: |
|
|
|
MemBuffer * mem_buffer; |
|
size_t dynamic_array_index; |
|
size_t index; |
|
|
|
friend class MemBuffer; |
|
}; |
|
|
|
|
|
class const_iterator |
|
{ |
|
public: |
|
|
|
const_iterator(); |
|
const_iterator(const const_iterator & i); |
|
const_iterator(const iterator & i); |
|
const_iterator & operator=(const const_iterator & i); |
|
const_iterator & operator=(const iterator & i); |
|
|
|
bool operator==(const const_iterator & i) const; |
|
bool operator!=(const const_iterator & i) const; |
|
|
|
const_iterator & operator++(); // prefix ++ |
|
const_iterator operator++(int); // postfix ++ |
|
|
|
const_iterator & operator--(); // prefix -- |
|
const_iterator operator--(int); // postfix -- |
|
|
|
item_type operator*(); |
|
|
|
private: |
|
|
|
const MemBuffer * mem_buffer; |
|
size_t dynamic_array_index; |
|
size_t index; |
|
|
|
friend class MemBuffer; |
|
}; |
|
|
|
|
|
|
|
MemBuffer(); |
|
~MemBuffer(); |
|
MemBuffer(const MemBuffer<item_type, stack_size, heap_block_size> & arg); |
|
MemBuffer & operator=(const MemBuffer<item_type, stack_size, heap_block_size> & arg); |
|
|
|
void append(item_type item); |
|
void append(const item_type * item_array, size_t len); |
|
|
|
template<typename in_item_type> |
|
void append(const in_item_type * item_array, size_t len); |
|
|
|
template<typename arg_item_type, size_t arg_stack_size, size_t arg_heap_block_size> |
|
void append(const MemBuffer<arg_item_type, arg_stack_size, arg_heap_block_size> & arg); |
|
|
|
size_t size() const; |
|
bool empty() const; |
|
|
|
void reserve(size_t len); |
|
size_t capacity() const; |
|
void clear(); // frees memory but only to capacity() |
|
|
|
iterator begin(); |
|
iterator end(); |
|
|
|
const_iterator begin() const; |
|
const_iterator end() const; |
|
|
|
item_type & operator[](size_t i); |
|
const item_type operator[](size_t i) const; |
|
|
|
|
|
private: |
|
|
|
struct MemArray |
|
{ |
|
size_t size_used; |
|
item_type * buf; |
|
}; |
|
|
|
item_type stack_array[stack_size]; |
|
MemArray * dynamic_array; // dynamic array of MemArray descriptors |
|
size_t dynamic_array_index; // index of a MemArray to which the last insertion was made |
|
// size_t(-1) means the stack_array |
|
size_t dynamic_array_used; // how many MemArray-s have been inited in dynamic_array |
|
size_t dynamic_array_size; // the size of the dynamic_array |
|
|
|
size_t size_used; // the size of all valid items |
|
size_t size_allocated; // how many memory is reserved |
|
size_t size_reserved; // memory reserved by reserve(), it is used by clear() |
|
|
|
// used by ctors |
|
void Initialize(); |
|
|
|
void add_dynamic_node(); |
|
}; |
|
|
|
|
|
|
|
/* |
|
iterator |
|
*/ |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
typename MemBuffer<item_type, stack_size, heap_block_size>::iterator & |
|
MemBuffer<item_type, stack_size, heap_block_size>::iterator::operator++() |
|
{ |
|
if( dynamic_array_index == size_t(-1) ) |
|
{ |
|
index += 1; |
|
|
|
if( index >= stack_size ) |
|
{ |
|
index = 0; |
|
dynamic_array_index = 0; |
|
} |
|
} |
|
else |
|
{ |
|
index += 1; |
|
|
|
if( index >= heap_block_size ) |
|
{ |
|
dynamic_array_index += 1; |
|
index = 0; |
|
} |
|
} |
|
|
|
return *this; |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
typename MemBuffer<item_type, stack_size, heap_block_size>::iterator |
|
MemBuffer<item_type, stack_size, heap_block_size>::iterator::operator++(int) |
|
{ |
|
iterator old(*this); |
|
operator++(); |
|
|
|
return old; |
|
} |
|
|
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
typename MemBuffer<item_type, stack_size, heap_block_size>::iterator & |
|
MemBuffer<item_type, stack_size, heap_block_size>::iterator::operator--() |
|
{ |
|
if( index == 0 ) |
|
{ |
|
dynamic_array_index -= 1; |
|
|
|
if( dynamic_array_index == size_t(-1) ) |
|
index = stack_size - 1; |
|
else |
|
index = heap_block_size - 1; |
|
} |
|
else |
|
{ |
|
index -= 1; |
|
} |
|
|
|
return *this; |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
typename MemBuffer<item_type, stack_size, heap_block_size>::iterator |
|
MemBuffer<item_type, stack_size, heap_block_size>::iterator::operator--(int) |
|
{ |
|
iterator old(*this); |
|
operator++(); |
|
|
|
return old; |
|
} |
|
|
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
item_type & MemBuffer<item_type, stack_size, heap_block_size>::iterator::operator*() |
|
{ |
|
if( dynamic_array_index == size_t(-1) ) |
|
{ |
|
return mem_buffer->stack_array[index]; |
|
} |
|
else |
|
{ |
|
return mem_buffer->dynamic_array[dynamic_array_index].buf[index]; |
|
} |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
bool MemBuffer<item_type, stack_size, heap_block_size>::iterator::operator==(const iterator & i) const |
|
{ |
|
return mem_buffer == i.mem_buffer && |
|
dynamic_array_index == i.dynamic_array_index && |
|
index == i.index; |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
bool MemBuffer<item_type, stack_size, heap_block_size>::iterator::operator!=(const iterator & i) const |
|
{ |
|
return mem_buffer != i.mem_buffer || |
|
dynamic_array_index != i.dynamic_array_index || |
|
index != i.index; |
|
} |
|
|
|
|
|
|
|
/* |
|
const_iterator |
|
*/ |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
MemBuffer<item_type, stack_size, heap_block_size>::const_iterator::const_iterator() |
|
{ |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
MemBuffer<item_type, stack_size, heap_block_size>::const_iterator::const_iterator(const const_iterator & i) |
|
{ |
|
operator=(i); |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
MemBuffer<item_type, stack_size, heap_block_size>::const_iterator::const_iterator(const iterator & i) |
|
{ |
|
operator=(i); |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
typename MemBuffer<item_type, stack_size, heap_block_size>::const_iterator & |
|
MemBuffer<item_type, stack_size, heap_block_size>::const_iterator::operator=(const const_iterator & i) |
|
{ |
|
mem_buffer = i.mem_buffer; |
|
dynamic_array_index = i.dynamic_array_index; |
|
index = i.index; |
|
|
|
return *this; |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
typename MemBuffer<item_type, stack_size, heap_block_size>::const_iterator & |
|
MemBuffer<item_type, stack_size, heap_block_size>::const_iterator::operator=(const iterator & i) |
|
{ |
|
mem_buffer = i.mem_buffer; |
|
dynamic_array_index = i.dynamic_array_index; |
|
index = i.index; |
|
|
|
return *this; |
|
} |
|
|
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
typename MemBuffer<item_type, stack_size, heap_block_size>::const_iterator & |
|
MemBuffer<item_type, stack_size, heap_block_size>::const_iterator::operator++() |
|
{ |
|
if( dynamic_array_index == size_t(-1) ) |
|
{ |
|
index += 1; |
|
|
|
if( index >= stack_size ) |
|
{ |
|
index = 0; |
|
dynamic_array_index = 0; |
|
} |
|
} |
|
else |
|
{ |
|
index += 1; |
|
|
|
if( index >= heap_block_size ) |
|
{ |
|
dynamic_array_index += 1; |
|
index = 0; |
|
} |
|
} |
|
|
|
return *this; |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
typename MemBuffer<item_type, stack_size, heap_block_size>::const_iterator |
|
MemBuffer<item_type, stack_size, heap_block_size>::const_iterator::operator++(int) |
|
{ |
|
const_iterator old(*this); |
|
operator++(); |
|
|
|
return old; |
|
} |
|
|
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
typename MemBuffer<item_type, stack_size, heap_block_size>::const_iterator & |
|
MemBuffer<item_type, stack_size, heap_block_size>::const_iterator::operator--() |
|
{ |
|
if( index == 0 ) |
|
{ |
|
dynamic_array_index -= 1; |
|
|
|
if( dynamic_array_index == size_t(-1) ) |
|
index = stack_size - 1; |
|
else |
|
index = heap_block_size - 1; |
|
} |
|
else |
|
{ |
|
index -= 1; |
|
} |
|
|
|
return *this; |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
typename MemBuffer<item_type, stack_size, heap_block_size>::const_iterator |
|
MemBuffer<item_type, stack_size, heap_block_size>::const_iterator::operator--(int) |
|
{ |
|
const_iterator old(*this); |
|
operator++(); |
|
|
|
return old; |
|
} |
|
|
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
item_type MemBuffer<item_type, stack_size, heap_block_size>::const_iterator::operator*() |
|
{ |
|
if( dynamic_array_index == size_t(-1) ) |
|
{ |
|
return mem_buffer->stack_array[index]; |
|
} |
|
else |
|
{ |
|
return mem_buffer->dynamic_array[dynamic_array_index].buf[index]; |
|
} |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
bool MemBuffer<item_type, stack_size, heap_block_size>::const_iterator::operator==(const const_iterator & i) const |
|
{ |
|
return mem_buffer == i.mem_buffer && |
|
dynamic_array_index == i.dynamic_array_index && |
|
index == i.index; |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
bool MemBuffer<item_type, stack_size, heap_block_size>::const_iterator::operator!=(const const_iterator & i) const |
|
{ |
|
return mem_buffer != i.mem_buffer || |
|
dynamic_array_index != i.dynamic_array_index || |
|
index != i.index; |
|
} |
|
|
|
|
|
|
|
/* |
|
|
|
MemBuffer |
|
|
|
*/ |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
void MemBuffer<item_type, stack_size, heap_block_size>::Initialize() |
|
{ |
|
size_reserved = 0; |
|
size_used = 0; |
|
size_allocated = stack_size; |
|
dynamic_array = 0; |
|
dynamic_array_index = size_t(-1); |
|
dynamic_array_used = 0; |
|
dynamic_array_size = 0; |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
MemBuffer<item_type, stack_size, heap_block_size>::MemBuffer() |
|
{ |
|
Initialize(); |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
MemBuffer<item_type, stack_size, heap_block_size>::~MemBuffer() |
|
{ |
|
if( dynamic_array ) |
|
{ |
|
for(size_t i=0 ; i<dynamic_array_used ; ++i) |
|
delete [] dynamic_array[i].buf; |
|
|
|
delete [] dynamic_array; |
|
} |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
MemBuffer<item_type, stack_size, heap_block_size>::MemBuffer(const MemBuffer<item_type, stack_size, heap_block_size> & arg) |
|
{ |
|
Initialize(); |
|
operator=(arg); |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
MemBuffer<item_type, stack_size, heap_block_size> & |
|
MemBuffer<item_type, stack_size, heap_block_size>::operator=(const MemBuffer<item_type, stack_size, heap_block_size> & arg) |
|
{ |
|
if( size_used > 0 ) |
|
clear(); |
|
|
|
const_iterator i = arg.begin(); |
|
|
|
for( ; i != arg.end() ; ++i) |
|
append(*i); |
|
|
|
return *this; |
|
} |
|
|
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
void MemBuffer<item_type, stack_size, heap_block_size>::add_dynamic_node() |
|
{ |
|
if( dynamic_array_used >= dynamic_array_size ) |
|
{ |
|
// reallocating |
|
dynamic_array_size += 2; // 64; |
|
MemArray * new_array = new MemArray[dynamic_array_size]; |
|
|
|
for(size_t i=0 ; i<dynamic_array_used ; ++i) |
|
new_array[i] = dynamic_array[i]; |
|
|
|
delete [] dynamic_array; |
|
dynamic_array = new_array; |
|
} |
|
|
|
dynamic_array[dynamic_array_used].size_used = 0; |
|
dynamic_array[dynamic_array_used].buf = new item_type[heap_block_size]; |
|
|
|
dynamic_array_used += 1; |
|
size_allocated += heap_block_size; |
|
} |
|
|
|
|
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
void MemBuffer<item_type, stack_size, heap_block_size>::append(item_type item) |
|
{ |
|
if( size_used < stack_size ) |
|
{ |
|
stack_array[size_used] = item; |
|
} |
|
else |
|
{ |
|
if( dynamic_array_index == size_t(-1) ) |
|
{ |
|
dynamic_array_index = 0; |
|
|
|
if( dynamic_array_index >= dynamic_array_used ) |
|
add_dynamic_node(); |
|
|
|
dynamic_array[dynamic_array_index].size_used = 0; |
|
} |
|
else |
|
if( dynamic_array[dynamic_array_index].size_used >= heap_block_size ) |
|
{ |
|
dynamic_array_index += 1; |
|
|
|
if( dynamic_array_index >= dynamic_array_used ) |
|
add_dynamic_node(); |
|
|
|
dynamic_array[dynamic_array_index].size_used = 0; |
|
} |
|
|
|
dynamic_array[dynamic_array_index].buf[dynamic_array[dynamic_array_index].size_used] = item; |
|
dynamic_array[dynamic_array_index].size_used += 1; |
|
} |
|
|
|
size_used += 1; |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
void MemBuffer<item_type, stack_size, heap_block_size>::append(const item_type * item_array, size_t len) |
|
{ |
|
if( size_used + len <= stack_size ) |
|
{ |
|
for(size_t i=0 ; i<len ; ++i) |
|
stack_array[size_used++] = item_array[i]; |
|
|
|
return; |
|
} |
|
|
|
if( dynamic_array_index != size_t(-1) && |
|
dynamic_array[dynamic_array_index].size_used + len <= heap_block_size ) |
|
{ |
|
item_type * buf = dynamic_array[dynamic_array_index].buf; |
|
size_t bufsize = dynamic_array[dynamic_array_index].size_used; |
|
|
|
for(size_t i=0 ; i<len ; ++i) |
|
buf[bufsize++] = item_array[i]; |
|
|
|
dynamic_array[dynamic_array_index].size_used += len; |
|
size_used += len; |
|
|
|
return; |
|
} |
|
|
|
for(size_t i=0 ; i<len ; ++i) |
|
append(item_array[i]); |
|
} |
|
|
|
|
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
template<typename in_item_type> |
|
void MemBuffer<item_type, stack_size, heap_block_size>::append(const in_item_type * item_array, size_t len) |
|
{ |
|
for(size_t i=0 ; i<len ; ++i) |
|
append(static_cast<item_type>(item_array[i])); |
|
} |
|
|
|
|
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
template<typename arg_item_type, size_t arg_stack_size, size_t arg_heap_block_size> |
|
void MemBuffer<item_type, stack_size, heap_block_size>::append( |
|
const MemBuffer<arg_item_type, arg_stack_size, arg_heap_block_size> & arg) |
|
{ |
|
typename MemBuffer<arg_item_type, arg_stack_size, arg_heap_block_size>::const_iterator i = arg.begin(); |
|
|
|
for( ; i != arg.end() ; ++i) |
|
append(static_cast<item_type>(*i)); |
|
} |
|
|
|
|
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
item_type & MemBuffer<item_type, stack_size, heap_block_size>::operator[](size_t i) |
|
{ |
|
if( i < stack_size ) |
|
{ |
|
return stack_array[i]; |
|
} |
|
else |
|
{ |
|
i -= stack_size; |
|
size_t index = i / heap_block_size; |
|
size_t offset = i % heap_block_size; |
|
|
|
return dynamic_array[index].buf[offset]; |
|
} |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
const item_type MemBuffer<item_type, stack_size, heap_block_size>::operator[](size_t i) const |
|
{ |
|
if( i < stack_size ) |
|
{ |
|
return stack_array[i]; |
|
} |
|
else |
|
{ |
|
i -= stack_size; |
|
size_t index = i / heap_block_size; |
|
size_t offset = i % heap_block_size; |
|
|
|
return dynamic_array[index].buf[offset]; |
|
} |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
size_t MemBuffer<item_type, stack_size, heap_block_size>::size() const |
|
{ |
|
return size_used; |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
bool MemBuffer<item_type, stack_size, heap_block_size>::empty() const |
|
{ |
|
return size_used == 0; |
|
} |
|
|
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
typename MemBuffer<item_type, stack_size, heap_block_size>::iterator |
|
MemBuffer<item_type, stack_size, heap_block_size>::begin() |
|
{ |
|
iterator i; |
|
|
|
i.mem_buffer = this; |
|
i.dynamic_array_index = size_t(-1); |
|
i.index = 0; |
|
|
|
return i; |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
typename MemBuffer<item_type, stack_size, heap_block_size>::iterator |
|
MemBuffer<item_type, stack_size, heap_block_size>::end() |
|
{ |
|
iterator i; |
|
|
|
i.mem_buffer = this; |
|
|
|
if( size_used <= stack_size ) |
|
{ |
|
i.dynamic_array_index = size_t(-1); |
|
i.index = size_used; |
|
|
|
if( i.index >= stack_size ) |
|
{ |
|
i.dynamic_array_index = 0; |
|
i.index = 0; |
|
} |
|
} |
|
else |
|
{ |
|
i.dynamic_array_index = dynamic_array_index; |
|
i.index = dynamic_array[dynamic_array_index].size_used; |
|
|
|
if( i.index >= heap_block_size ) |
|
{ |
|
i.dynamic_array_index += 1; |
|
i.index = 0; |
|
} |
|
} |
|
|
|
return i; |
|
} |
|
|
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
typename MemBuffer<item_type, stack_size, heap_block_size>::const_iterator |
|
MemBuffer<item_type, stack_size, heap_block_size>::begin() const |
|
{ |
|
const_iterator i; |
|
|
|
i.mem_buffer = this; |
|
i.dynamic_array_index = size_t(-1); |
|
i.index = 0; |
|
|
|
return i; |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
typename MemBuffer<item_type, stack_size, heap_block_size>::const_iterator |
|
MemBuffer<item_type, stack_size, heap_block_size>::end() const |
|
{ |
|
const_iterator i; |
|
|
|
i.mem_buffer = this; |
|
|
|
if( size_used <= stack_size ) |
|
{ |
|
i.dynamic_array_index = size_t(-1); |
|
i.index = size_used; |
|
|
|
if( i.index >= stack_size ) |
|
{ |
|
i.dynamic_array_index = 0; |
|
i.index = 0; |
|
} |
|
} |
|
else |
|
{ |
|
i.dynamic_array_index = dynamic_array_index; |
|
i.index = dynamic_array[dynamic_array_index].size_used; |
|
|
|
if( i.index >= heap_block_size ) |
|
{ |
|
i.dynamic_array_index += 1; |
|
i.index = 0; |
|
} |
|
} |
|
|
|
return i; |
|
} |
|
|
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
void MemBuffer<item_type, stack_size, heap_block_size>::reserve(size_t len) |
|
{ |
|
size_reserved = len; |
|
|
|
while( size_allocated < size_reserved ) |
|
add_dynamic_node(); |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
size_t MemBuffer<item_type, stack_size, heap_block_size>::capacity() const |
|
{ |
|
return size_allocated; |
|
} |
|
|
|
|
|
template<typename item_type, size_t stack_size, size_t heap_block_size> |
|
void MemBuffer<item_type, stack_size, heap_block_size>::clear() |
|
{ |
|
size_t index = 0; |
|
|
|
if( size_reserved > stack_size ) |
|
{ |
|
index = (size_reserved - stack_size) / heap_block_size + 1; |
|
size_t old_index = index; |
|
|
|
for(; index < dynamic_array_used ; ++index) |
|
{ |
|
size_allocated -= heap_block_size; |
|
delete [] dynamic_array[index].buf; |
|
} |
|
|
|
dynamic_array_used = old_index; |
|
} |
|
|
|
size_used = 0; |
|
dynamic_array_index = size_t(-1); |
|
} |
|
|
|
|
|
} // namespace |
|
|
|
|
|
#endif |
|
|
|
|