nestopia/source/win32/NstCollectionVector.cpp

193 lines
4.5 KiB
C++

////////////////////////////////////////////////////////////////////////////////////////
//
// Nestopia - NES/Famicom emulator written in C++
//
// Copyright (C) 2003-2008 Martin Freij
//
// This file is part of Nestopia.
//
// Nestopia 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.
//
// Nestopia 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 Nestopia; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
////////////////////////////////////////////////////////////////////////////////////////
#include <cstring>
#include "NstCollectionVector.hpp"
#ifdef NST_MSVC_OPTIMIZE
#pragma optimize("t", on)
#endif
namespace Nestopia
{
namespace Collection
{
Vector<void>::Vector(const uint inSize)
:
data (inSize ? std::malloc( inSize ) : NULL),
capacity (inSize),
size (inSize)
{}
Vector<void>::Vector(const void* const NST_RESTRICT inData,const uint inSize)
:
data (inSize ? std::memcpy( std::malloc( inSize ), inData, inSize ) : NULL),
capacity (inSize),
size (inSize)
{
NST_ASSERT( bool(inData) >= bool(inSize) );
}
Vector<void>::Vector(const Vector<void>& base)
:
data (base.size ? std::memcpy( std::malloc( base.size ), base.data, base.size ) : NULL),
capacity (base.size),
size (base.size)
{
}
bool Vector<void>::Valid(const void* const it) const
{
return it >= bytes && it <= bytes + size;
}
bool Vector<void>::InBound(const void* const it) const
{
return it >= bytes && it < bytes + size;
}
void Vector<void>::Assign(const void* const NST_RESTRICT inData,const uint inSize)
{
size = inSize;
if (capacity < inSize)
data = std::realloc( data, capacity = inSize );
std::memcpy( data, inData, inSize );
}
void Vector<void>::Append(const void* const NST_RESTRICT inData,const uint inSize)
{
size += inSize;
if (capacity < size)
data = std::realloc( data, capacity = size * 2 );
std::memcpy( bytes + (size - inSize), inData, inSize );
}
void Vector<void>::Insert(void* const offset,const void* const NST_RESTRICT inData,const uint inSize)
{
NST_ASSERT( Valid(offset) );
if (inSize)
{
const uint pos = static_cast<uchar*>(offset) - bytes;
const uint end = size - pos;
size += inSize;
if (capacity >= size)
{
std::memmove( static_cast<uchar*>(offset) + inSize, offset, end );
if (inData)
std::memcpy( offset, inData, inSize );
}
else
{
capacity = size * 2;
void* const NST_RESTRICT next = std::malloc( capacity );
std::memcpy( next, data, pos );
if (inData)
std::memcpy( static_cast<uchar*>(next) + pos, inData, inSize );
std::memcpy( static_cast<uchar*>(next) + pos + inSize, offset, end );
void* tmp = data;
data = next;
std::free( tmp );
}
}
}
void Vector<void>::Erase(void* const begin,void* const end)
{
NST_ASSERT( end >= begin && begin >= bytes && end <= bytes + size );
const uint back = (bytes + size) - static_cast<uchar*>(end);
size -= static_cast<uchar*>(end) - static_cast<uchar*>(begin);
std::memmove( begin, end, back );
}
void Vector<void>::Destroy()
{
if (void* tmp = data)
{
data = NULL;
capacity = 0;
size = 0;
std::free( tmp );
}
}
void Vector<void>::operator = (const Vector<void>& base)
{
Assign( base.data, base.size );
}
void Vector<void>::Reserve(const uint inSize)
{
if (capacity < inSize)
data = std::realloc( data, capacity = inSize );
}
void Vector<void>::Resize(const uint inSize)
{
size = inSize;
Reserve( inSize );
}
void Vector<void>::Grow(const uint inSize)
{
Resize( size + inSize );
}
void Vector<void>::Defrag()
{
if (capacity != size)
data = std::realloc( data, capacity = size );
}
void Vector<void>::Import(Vector<void>& base)
{
void* tmp = data;
data = base.data;
base.data = NULL;
size = base.size;
base.size = 0;
capacity = base.capacity;
base.capacity = 0;
std::free( tmp );
}
}
}
#ifdef NST_MSVC_OPTIMIZE
#pragma optimize("", on)
#endif