Copy constructor and destruct for scalar types

This commit is contained in:
drmortalwombat 2023-08-12 18:19:46 +02:00
parent cb5451b9b9
commit 9d6691cf91
2 changed files with 118 additions and 12 deletions

View File

@ -1,6 +1,8 @@
#ifndef OPP_VECTOR_H #ifndef OPP_VECTOR_H
#define OPP_VECTOR_H #define OPP_VECTOR_H
#include <stdlib.h>
template <class T> template <class T>
class vector class vector
{ {
@ -9,10 +11,16 @@ protected:
int _size, _capacity; int _size, _capacity;
public: public:
vector(void) : _data(nullptr), _size(0), _capacity(0) {} vector(void) : _data(nullptr), _size(0), _capacity(0) {}
vector(int n) : _data(new T[n]), _size(n), _capacity(n) {} vector(int n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n)
{
for(int i=0; i<n; i++)
new (_data + i) T;
}
~vector(void) ~vector(void)
{ {
delete[] _data; for(int i=0; i<_size; i++)
_data[i].~T();
free(_data);
} }
int size(void) const int size(void) const
@ -110,10 +118,13 @@ void vector<T>::reserve(int n)
if (n > _capacity) if (n > _capacity)
{ {
_capacity = n; _capacity = n;
T * d = new T[_capacity]; T * d = (T *)malloc(_capacity * sizeof(T));
for(int i=0; i<_size; i++) for(int i=0; i<_size; i++)
d[i] = _data[i]; {
delete[] _data; new (d + i)T(_data[i]);
_data[i].~T();
}
free(_data);
_data = d; _data = d;
} }
} }
@ -122,9 +133,17 @@ template <class T>
void vector<T>::resize(int n) void vector<T>::resize(int n)
{ {
if (n < _size) if (n < _size)
{
for(int i=n; i<_size; i++)
_data[i].~T();
_size = n; _size = n;
}
else if (n < _capacity) else if (n < _capacity)
{
for(int i=_size; i<n; i++)
new(_data + i)T;
_size = n; _size = n;
}
else else
{ {
reserve(n); reserve(n);
@ -138,10 +157,13 @@ void vector<T>::shrink_to_fit(void)
if (_size < _capacity) if (_size < _capacity)
{ {
_capacity = _size; _capacity = _size;
T * d = new T[_capacity]; T * d = (T *)malloc(_capacity * sizeof(T));
for(int i=0; i<_size; i++) for(int i=0; i<_size; i++)
d[i] = _data[i]; {
delete[] _data; new (d + i)T(_data[i]);
_data[i].~T();
}
free(_data);
_data = d; _data = d;
} }
} }
@ -151,7 +173,7 @@ void vector<T>::push_back(const T & t)
{ {
if (_size == _capacity) if (_size == _capacity)
reserve(_size + 1 + (_size >> 1)); reserve(_size + 1 + (_size >> 1));
_data[_size++] = t; new (_data + _size++)T(t);
} }
template <class T> template <class T>
@ -159,6 +181,7 @@ void vector<T>::insert(int at, const T & t)
{ {
if (_size == _capacity) if (_size == _capacity)
reserve(_size + 1 + (_size >> 1)); reserve(_size + 1 + (_size >> 1));
new (_data + _size)T;
for(int i=_size; i>at; i--) for(int i=_size; i>at; i--)
_data[i] = _data[i - 1]; _data[i] = _data[i - 1];
_data[at] = t; _data[at] = t;
@ -170,6 +193,7 @@ void vector<T>::erase(int at, int n)
_size -= n; _size -= n;
for(int i=at; i<_size; i++) for(int i=at; i<_size; i++)
_data[i] = _data[i + n]; _data[i] = _data[i + n];
_data[_size].~T();
} }
#endif #endif

View File

@ -3301,7 +3301,15 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex
mScanner->NextToken(); mScanner->NextToken();
if (mScanner->mToken == TK_IDENT) if (mScanner->mToken == TK_IDENT)
{ {
if (mScanner->mTokenIdent != pthis->mBase->mIdent) const Ident* ident = mScanner->mTokenIdent;
if (mTemplateScope)
{
Declaration* dec = mTemplateScope->Lookup(ident);
if (dec)
ident = dec->mIdent;
}
if (ident != pthis->mBase->mIdent)
mErrors->Error(mScanner->mLocation, EERR_INVALID_IDENTIFIER, "Wrong class name for destructor", pthis->mBase->mIdent); mErrors->Error(mScanner->mLocation, EERR_INVALID_IDENTIFIER, "Wrong class name for destructor", pthis->mBase->mIdent);
mScanner->NextToken(); mScanner->NextToken();
} }
@ -4662,7 +4670,19 @@ Expression* Parser::ParseQualify(Expression* exp)
{ {
mScanner->NextToken(); mScanner->NextToken();
if (mScanner->mToken == TK_IDENT) if (mScanner->mToken == TK_IDENT)
ident = mScanner->mTokenIdent->PreMangle("~"); {
ident = mScanner->mTokenIdent;
if (mTemplateScope)
{
Declaration* dec = mTemplateScope->Lookup(ident);
if (dec)
ident = dec->mIdent;
}
ident = ident->PreMangle("~");
}
else
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected");
} }
else if (mScanner->mToken == TK_IDENT) else if (mScanner->mToken == TK_IDENT)
ident = mScanner->mTokenIdent; ident = mScanner->mTokenIdent;
@ -4752,6 +4772,40 @@ Expression* Parser::ParseQualify(Expression* exp)
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Struct member identifier expected"); mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Struct member identifier expected");
} }
else if ((mCompilerOptions & COPT_CPLUSPLUS) && mScanner->mToken == TK_BINARY_NOT)
{
mScanner->NextToken();
if (mScanner->mToken == TK_IDENT)
{
const Ident * ident = mScanner->mTokenIdent;
if (mTemplateScope)
{
Declaration* dec = mTemplateScope->Lookup(ident);
if (dec == dtype)
{
mScanner->NextToken();
ConsumeToken(TK_OPEN_PARENTHESIS);
ConsumeToken(TK_CLOSE_PARENTHESIS);
exp = new Expression(mScanner->mLocation, EX_VOID);
exp->mDecType = TheConstVoidTypeDeclaration;
}
}
else if (ident == dtype->mIdent)
{
mScanner->NextToken();
ConsumeToken(TK_OPEN_PARENTHESIS);
ConsumeToken(TK_CLOSE_PARENTHESIS);
exp = new Expression(mScanner->mLocation, EX_VOID);
exp->mDecType = TheConstVoidTypeDeclaration;
}
else
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Destructor identifier expected");
}
else
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected");
}
else else
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Struct expected"); mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Struct expected");
@ -5586,7 +5640,10 @@ Expression* Parser::ParseNewOperator(void)
if (!ConsumeTokenIf(TK_CLOSE_PARENTHESIS)) if (!ConsumeTokenIf(TK_CLOSE_PARENTHESIS))
{ {
plist = true; plist = true;
mdec = dec->mScope->Lookup(dec->mIdent->PreMangle("+")); if (dec->mType == DT_TYPE_STRUCT)
mdec = dec->mScope->Lookup(dec->mIdent->PreMangle("+"));
else
mdec = nullptr;
} }
} }
@ -5654,6 +5711,31 @@ Expression* Parser::ParseNewOperator(void)
nexp->mLeft = iexp; nexp->mLeft = iexp;
nexp->mRight = coexp; nexp->mRight = coexp;
nexp->mDecType = coexp->mDecType; nexp->mDecType = coexp->mDecType;
}
else if (plist && !mdec)
{
Expression * pexp = ParseListExpression(false);
ConsumeToken(TK_CLOSE_PARENTHESIS);
if (pexp && pexp->mType != EX_LIST)
{
Expression* dexp = new Expression(mScanner->mLocation, EX_PREFIX);
dexp->mToken = TK_MUL;
dexp->mLeft = nexp;
dexp->mDecType = nexp->mDecType->mBase;
Expression* iexp = new Expression(mScanner->mLocation, EX_INITIALIZATION);
iexp->mToken = TK_ASSIGN;
iexp->mLeft = dexp;
iexp->mRight = pexp;
iexp->mDecType = nexp->mDecType;
nexp = iexp;
}
else
mErrors->Error(mScanner->mLocation, ERRO_NO_MATCHING_FUNCTION_CALL, "No matching constructor", dec->mIdent);
} }
else if (plist) else if (plist)
{ {