3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-07 18:05:21 +00:00
z3/lib/buffer.h
Leonardo de Moura e9eab22e5c Z3 sources
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
2012-10-02 11:35:25 -07:00

257 lines
5.1 KiB
C++

/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
buffer.h
Abstract:
<abstract>
Author:
Leonardo de Moura (leonardo) 2006-10-16.
Revision History:
--*/
#ifndef _BUFFER_H_
#define _BUFFER_H_
#include<string.h>
#include"memory_manager.h"
template<typename T, bool CallDestructors=true, unsigned INITIAL_SIZE=16>
class buffer {
protected:
T * m_buffer;
unsigned m_pos;
unsigned m_capacity;
char m_initial_buffer[INITIAL_SIZE * sizeof(T)];
void free_memory() {
if (m_buffer != reinterpret_cast<T*>(m_initial_buffer)) {
memory::deallocate(m_buffer);
}
}
void expand() {
unsigned new_capacity = m_capacity << 1;
T * new_buffer = reinterpret_cast<T*>(memory::allocate(sizeof(T) * new_capacity));
memcpy(new_buffer, m_buffer, m_pos * sizeof(T));
free_memory();
m_buffer = new_buffer;
m_capacity = new_capacity;
}
void destroy_elements() {
iterator it = begin();
iterator e = end();
for (; it != e; ++it) {
it->~T();
}
}
void destroy() {
if (CallDestructors) {
destroy_elements();
}
free_memory();
}
public:
typedef T data;
typedef T * iterator;
typedef const T * const_iterator;
buffer():
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
m_pos(0),
m_capacity(INITIAL_SIZE) {
}
buffer(const buffer & source):
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
m_pos(0),
m_capacity(INITIAL_SIZE) {
unsigned sz = source.size();
for(unsigned i = 0; i < sz; i++) {
push_back(source.m_buffer[i]);
}
}
buffer(unsigned sz, const T & elem):
m_buffer(reinterpret_cast<T *>(m_initial_buffer)),
m_pos(0),
m_capacity(INITIAL_SIZE) {
for (unsigned i = 0; i < sz; i++) {
push_back(elem);
}
SASSERT(size() == sz);
}
~buffer() {
destroy();
}
void reset() {
if (CallDestructors) {
destroy_elements();
}
m_pos = 0;
}
void finalize() {
destroy();
m_buffer = reinterpret_cast<T *>(m_initial_buffer);
m_pos = 0;
m_capacity = INITIAL_SIZE;
}
unsigned size() const {
return m_pos;
}
bool empty() const {
return m_pos == 0;
}
iterator begin() {
return m_buffer;
}
iterator end() {
return m_buffer + size();
}
void set_end(iterator it) {
m_pos = static_cast<unsigned>(it - m_buffer);
if (CallDestructors) {
iterator e = end();
for (; it != e; ++it) {
it->~T();
}
}
}
const_iterator begin() const {
return m_buffer;
}
const_iterator end() const {
return m_buffer + size();
}
void push_back(const T & elem) {
if (m_pos >= m_capacity)
expand();
new (m_buffer + m_pos) T(elem);
m_pos++;
}
void pop_back() {
if (CallDestructors) {
back().~T();
}
m_pos--;
}
const T & back() const {
SASSERT(!empty());
SASSERT(m_pos > 0);
return m_buffer[m_pos - 1];
}
T & back() {
SASSERT(!empty());
SASSERT(m_pos > 0);
return m_buffer[m_pos - 1];
}
T * c_ptr() const {
return m_buffer;
}
void append(unsigned n, T const * elems) {
for (unsigned i = 0; i < n; i++) {
push_back(elems[i]);
}
}
void append(const buffer& source) {
append(source.size(), source.c_ptr());
}
T & operator[](unsigned idx) {
SASSERT(idx < size());
return m_buffer[idx];
}
const T & operator[](unsigned idx) const {
SASSERT(idx < size());
return m_buffer[idx];
}
T & get(unsigned idx) {
SASSERT(idx < size());
return m_buffer[idx];
}
const T & get(unsigned idx) const {
SASSERT(idx < size());
return m_buffer[idx];
}
void set(unsigned idx, T const & val) {
SASSERT(idx < size());
m_buffer[idx] = val;
}
void resize(unsigned nsz, const T & elem=T()) {
unsigned sz = size();
if (nsz > sz) {
for (unsigned i = sz; i < nsz; i++) {
push_back(elem);
}
}
else if (nsz < sz) {
for (unsigned i = nsz; i < sz; i++) {
pop_back();
}
}
SASSERT(size() == nsz);
}
void shrink(unsigned nsz) {
unsigned sz = size();
SASSERT(nsz <= sz);
for (unsigned i = nsz; i < sz; i++)
pop_back();
SASSERT(size() == nsz);
}
private:
buffer& operator=(buffer const&);
};
template<typename T, unsigned INITIAL_SIZE=16>
class ptr_buffer : public buffer<T *, false, INITIAL_SIZE> {
public:
void append(unsigned n, T * const * elems) {
for (unsigned i = 0; i < n; i++) {
push_back(elems[i]);
}
}
};
template<typename T, unsigned INITIAL_SIZE=16>
class sbuffer : public buffer<T, false, INITIAL_SIZE> {
public:
sbuffer(): buffer<T, false, INITIAL_SIZE>() {}
sbuffer(unsigned sz, const T& elem) : buffer<T, false, INITIAL_SIZE>(sz,elem) {}
};
#endif /* _BUFFER_H_ */