From 2027ac5d4c8b234577f6774c6d79a6d261af4c4f Mon Sep 17 00:00:00 2001 From: drmortalwombat <90205530+drmortalwombat@users.noreply.github.com> Date: Thu, 12 Oct 2023 14:10:34 +0200 Subject: [PATCH] Fix template expansion in multiple cpp --- autotest/opp_vector.cpp | 41 ++++++++++++++++ include/opp/algorithm.h | 19 +++++--- include/opp/utility.h | 8 +++- include/opp/vector.h | 101 ++++++++++++++++++++++++++++++---------- oscar64/Declaration.cpp | 2 + oscar64/InterCode.cpp | 6 +-- oscar64/Parser.cpp | 44 ++++++++--------- 7 files changed, 166 insertions(+), 55 deletions(-) diff --git a/autotest/opp_vector.cpp b/autotest/opp_vector.cpp index 5e82699..f2d56a1 100644 --- a/autotest/opp_vector.cpp +++ b/autotest/opp_vector.cpp @@ -1,5 +1,7 @@ #include +#include #include +#include int main(void) { @@ -23,5 +25,44 @@ int main(void) assert(s == 1 + 3 + 5 + 7 + 9); + opp::vector v; + + for(int i=0; i<10; i++) + v.push_back(i); + + assert(v.size() == 10); + v.insert(0, 20); + assert(v.size() == 11); + v.insert(6, 21); + assert(v.size() == 12); + v.insert(12, 22); + + int * fi = opp::find(v.begin(), v.end(), 21); + + fi = v.insert(fi, 30); + fi = v.insert(fi, 31); + fi = v.insert(fi, 32); + + assert(v.size() == 16); + assert(v[0] == 20); + assert(v[15] == 22); + assert(v[8] == 32); + + fi = opp::find(v.begin(), v.end(), 32); + + for(int i=0; i<30; i++) + { + fi = v.insert(fi, i + 40); + } + + assert(v.size() == 46); + assert(v[28] == 60); + + v.erase(10, 10); + + for(int i : v) + opp::cout << i << ", "; + opp::cout << "\n"; + return 0; } diff --git a/include/opp/algorithm.h b/include/opp/algorithm.h index b1d8807..a6f5a19 100644 --- a/include/opp/algorithm.h +++ b/include/opp/algorithm.h @@ -1,14 +1,9 @@ #ifndef OPP_ALGORITHM_H #define OPP_ALGORITHM_H +#include "utility.h" namespace opp { -template -inline void swap(T & x, T & y) -{ - T t(x); x = y; y = t; -} - template void sort(T s, T e) { @@ -72,6 +67,18 @@ OI copy(II first, II last, OI result) return result; } + +template +II find (II first, II last, const T& val) +{ + while (first != last) + { + if (*first == val) return first; + ++first; + } + return last; +} + } #endif diff --git a/include/opp/utility.h b/include/opp/utility.h index b09c0aa..503aa8d 100644 --- a/include/opp/utility.h +++ b/include/opp/utility.h @@ -4,11 +4,17 @@ namespace opp { template -T && move(T & m) +inline T && move(T & m) { return (T &&)m; } +template +inline void swap(T & x, T & y) +{ + T t(x); x = y; y = move(t); +} + template struct pair diff --git a/include/opp/vector.h b/include/opp/vector.h index 57f07d8..c18c96c 100644 --- a/include/opp/vector.h +++ b/include/opp/vector.h @@ -12,22 +12,22 @@ class vector { protected: T * _data; - int _size, _capacity; + size_t _size, _capacity; public: typedef T element_type; vector(void) : _data(nullptr), _size(0), _capacity(0) {} - vector(int n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n) + vector(size_t n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n) { - for(int i=0; i void emplace_back(const P&... p); @@ -174,13 +204,13 @@ protected: template -void vector::reserve(int n) +void vector::reserve(size_t n) { if (n > _capacity) { _capacity = n; T * d = (T *)malloc(_capacity * sizeof(T)); - for(int i=0; i<_size; i++) + for(size_t i=0; i<_size; i++) { new (d + i)T(move(_data[i])); _data[i].~T(); @@ -191,17 +221,17 @@ void vector::reserve(int n) } template -void vector::resize(int n) +void vector::resize(size_t n) { if (n < _size) { - for(int i=n; i<_size; i++) + for(size_t i=n; i<_size; i++) _data[i].~T(); _size = n; } else if (n < _capacity) { - for(int i=_size; i::shrink_to_fit(void) { _capacity = _size; T * d = (T *)malloc(_capacity * sizeof(T)); - for(int i=0; i<_size; i++) + for(size_t i=0; i<_size; i++) { new (d + i)T(move(_data[i])); _data[i].~T(); @@ -257,23 +287,46 @@ void vector::emplace_back(const P&... p) } template -void vector::insert(int at, const T & t) +void vector::insert(size_t at, const T & t) { if (_size == _capacity) reserve(_size + 1 + (_size >> 1)); new (_data + _size)T; - for(int i=_size; i>at; i--) + for(size_t i=_size; i>at; i--) _data[i] = move(_data[i - 1]); _data[at] = t; + _size++; } template -void vector::erase(int at, int n) +void vector::erase(size_t at, size_t n) { _size -= n; - for(int i=at; i<_size; i++) + for(size_t i=at; i<_size; i++) _data[i] = move(_data[i + n]); - _data[_size].~T(); + for(size_t i=0; i +T * vector::insert(T * at, const T & t) +{ + if (_size == _capacity) + { + unsigned f = unsigned(at) - unsigned(_data); + reserve(_size + 1 + (_size >> 1)); + at = (T *)(f + unsigned(_data)); + } + T * dp = _data + _size; + new (dp)T; + while (dp != at) + { + dp--; + dp[1] = move(dp[0]); + } + dp[0] = t; + _size++; + return dp + 1; } } diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index a24e0bc..24a399a 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -2221,6 +2221,8 @@ bool Declaration::IsTemplateSame(const Declaration* dec, const Declaration * tde else return false; } + else if (dec->mBase->mType == DT_TYPE_TEMPLATE) + return mBase->IsTemplateSame(dec->mBase, tdec); else return this->Stride() == dec->Stride() && mBase->IsTemplateSame(dec->mBase, tdec); } diff --git a/oscar64/InterCode.cpp b/oscar64/InterCode.cpp index 98b702b..87e17d8 100644 --- a/oscar64/InterCode.cpp +++ b/oscar64/InterCode.cpp @@ -7631,9 +7631,9 @@ void InterCodeBasicBlock::UpdateLocalIntegerRangeSets(const GrowingVariableArray else { if (mLocalValueRange[s0].mMaxState == IntegerValueRange::S_BOUND) - mTrueValueRange[s1].LimitMax(mLocalValueRange[s0].mMaxValue - 1); + mTrueValueRange[s1].LimitMaxWeak(mLocalValueRange[s0].mMaxValue - 1); if (mLocalValueRange[s0].mMinState == IntegerValueRange::S_BOUND) - mFalseValueRange[s1].LimitMin(mLocalValueRange[s0].mMinValue); + mFalseValueRange[s1].LimitMinWeak(mLocalValueRange[s0].mMinValue); } break; case IA_CMPLES: @@ -17434,7 +17434,7 @@ void InterCodeProcedure::Close(void) { GrowingTypeArray tstack(IT_NONE); - CheckFunc = !strcmp(mIdent->mString, "mod"); + CheckFunc = !strcmp(mIdent->mString, "main"); mEntryBlock = mBlocks[0]; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 5005ce4..84e7f75 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -1620,27 +1620,29 @@ Expression* Parser::ParseInitExpression(Declaration* dtype) mErrors->Error(mScanner->mLocation, EERR_CONSTANT_INITIALIZER, "Identifier expected"); } - if (!mdec) + if (mdec) + { + Expression* texp = ParseInitExpression(mdec->mBase); + + Declaration* cdec = CopyConstantInitializer(mdec->mOffset, mdec->mBase, texp); + cdec->mBits = mdec->mBits; + cdec->mShift = mdec->mShift; + + if (last) + last->mNext = cdec; + else + dec->mParams = cdec; + last = cdec; + + if (!ConsumeTokenIf(TK_COMMA)) + break; + + mdec = mdec->mNext; + while (!mdec && path.Size()) + mdec = path.Pop()->mParams; + } + else if (!ConsumeTokenIf(TK_COMMA)) break; - - Expression* texp = ParseInitExpression(mdec->mBase); - - Declaration* cdec = CopyConstantInitializer(mdec->mOffset, mdec->mBase, texp); - cdec->mBits = mdec->mBits; - cdec->mShift = mdec->mShift; - - if (last) - last->mNext = cdec; - else - dec->mParams = cdec; - last = cdec; - - if (!ConsumeTokenIf(TK_COMMA)) - break; - - mdec = mdec->mNext; - while (!mdec && path.Size()) - mdec = path.Pop()->mParams; } } @@ -4555,7 +4557,7 @@ Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool ex { if (ndec->mBase->mType == DT_TYPE_FUNCTION) { - if (ndec->mFlags & DTF_DEFINED) + if ((ndec->mFlags & DTF_DEFINED) && !(ndec->mFlags & DTF_REQUEST_INLINE)) mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate function definition", ndec->mQualIdent); ndec->mCompilerOptions = mCompilerOptions;