/*
* tarrayobj.h
*
* This file is part of NEST.
*
* Copyright (C) 2004 The NEST Initiative
*
* NEST is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* NEST is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with NEST. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef TARRAYOBJ_H
#define TARRAYOBJ_H
/*
Array of Tokens
*/
#include <typeinfo>
#include <cstddef>
#include "token.h"
#define ARRAY_ALLOC_SIZE 64
class Token;
class TokenArrayObj
{
private:
Token* p;
Token* begin_of_free_storage;
Token* end_of_free_storage;
unsigned int alloc_block_size;
unsigned int refs_;
// bool homogeneous;
void allocate(size_t, size_t, size_t, const Token & = Token());
static size_t allocations;
public:
TokenArrayObj(void)
:p(NULL),begin_of_free_storage(NULL),
end_of_free_storage(NULL),
alloc_block_size(ARRAY_ALLOC_SIZE),
refs_(1)
{};
TokenArrayObj(size_t , const Token & = Token(), size_t = 0);
TokenArrayObj(const TokenArrayObj &);
virtual ~TokenArrayObj();
Token * begin() const
{
return p;
}
Token * end() const
{
return begin_of_free_storage;
}
size_t size(void) const
{
return (size_t)(begin_of_free_storage-p);
}
size_t capacity(void) const
{
return (size_t)(end_of_free_storage - p);
}
Token & operator[](size_t i) { return p[i]; }
const Token & operator[](size_t i) const
{ return p[i]; }
const Token & get(long i) const
{
return *(p+i);
// return p[i];
}
bool index_is_valid(long i) const
{
return (p+i) < begin_of_free_storage;
}
void rotate(Token *, Token *, Token *);
// Memory allocation
bool shrink(void);
bool reserve(size_t);
unsigned int references(void)
{
return refs_;
}
unsigned int remove_reference()
{
--refs_;
if(refs_==0)
{
delete this;
return 0;
}
return refs_;
}
unsigned int add_reference()
{
return ++refs_;
}
void resize(size_t, size_t, const Token & = Token());
void resize(size_t, const Token & = Token());
void reserve_token(size_t n)
{
if(capacity()<size()+1+n)
reserve(size()+n);
}
// Insertion, deletion
void push_back(const Token &t)
{
if(capacity()<size()+1)
reserve(size()+alloc_block_size);
(begin_of_free_storage++)->init_by_copy(t);
}
void push_back_move(Token &t)
{
if(capacity()<size()+1)
reserve(size()+alloc_block_size);
(begin_of_free_storage++)->init_move(t);
// ++begin_of_free_storage;
}
/**
* Push back a reference. This function expects that enough space
* on the stack has been reserved and that the token points to a
* valid datum object.
*/
void push_back_by_ref(const Token &t)
{
if(capacity()<size()+1)
reserve(size()+alloc_block_size);
(begin_of_free_storage++)->init_by_ref(t);
}
/**
* Push back a datum pointer. This function assumes that enough
* space on the stack has been reserved. This function expects a
* valid datum pointer and increases the reference count of the
* datum.
*/
void push_back_by_pointer(Datum *rhs)
{
if(capacity()<size()+1)
reserve(size()+alloc_block_size);
begin_of_free_storage->init_by_pointer(rhs);
++begin_of_free_storage;
}
void assign_move(Token *tp, Token &t)
{
tp->move(t);
}
void pop_back(void)
{
(--begin_of_free_storage)->clear();
}
// Erase the range given by the iterators.
void erase(size_t , size_t);
void erase(Token *, Token *);
void erase(Token *tp)
{
erase(tp,tp+1);
}
// Reduce the array to the range given by the iterators
void reduce(Token *, Token *);
void reduce(size_t, size_t);
void insert(size_t, size_t = 1, const Token& = Token());
void insert(size_t i, const Token& t)
{
insert(i,1,t);
}
void insert_move(size_t, TokenArrayObj &);
void insert_move(size_t, Token &);
void assign_move(TokenArrayObj &, size_t, size_t);
void assign(const TokenArrayObj &, size_t, size_t);
void replace_move(size_t, size_t, TokenArrayObj &);
void append_move(TokenArrayObj &);
void clear(void);
const TokenArrayObj & operator=(const TokenArrayObj &);
bool operator==(const TokenArrayObj &) const;
bool empty(void) const
{
return size()==0;
}
void info(std::ostream &) const;
static size_t getallocations(void)
{ return allocations;}
bool valid(void) const; // check integrity
};
std::ostream & operator<<(std::ostream& , const TokenArrayObj&);
#endif