Remove placement-new in RecastRegion.cpp in favor of rcTempVector. (#326)

This commit is contained in:
mbabinski-at-google 2018-05-18 06:50:42 -05:00 committed by Jakob Botsch Nielsen
parent 3ddb9ba074
commit 1284a2b191
2 changed files with 20 additions and 25 deletions

View File

@ -73,7 +73,7 @@ typedef intptr_t rcSizeType;
#define RC_SIZE_MAX INTPTR_MAX #define RC_SIZE_MAX INTPTR_MAX
/// Macros to hint to the compiler about the likeliest branch. Please add a benchmark that demonstrates a performance /// Macros to hint to the compiler about the likeliest branch. Please add a benchmark that demonstrates a performance
/// improvement before intrudcing use cases. /// improvement before introducing use cases.
#if defined(__GNUC__) || defined(__clang__) #if defined(__GNUC__) || defined(__clang__)
#define rcLikely(x) __builtin_expect((x), true) #define rcLikely(x) __builtin_expect((x), true)
#define rcUnlikely(x) __builtin_expect((x), false) #define rcUnlikely(x) __builtin_expect((x), false)
@ -116,7 +116,8 @@ class rcVectorBase {
rcVectorBase(const T* begin, const T* end) : m_size(0), m_cap(0), m_data(0) { assign(begin, end); } rcVectorBase(const T* begin, const T* end) : m_size(0), m_cap(0), m_data(0) { assign(begin, end); }
~rcVectorBase() { destroy_range(0, m_size); rcFree(m_data); } ~rcVectorBase() { destroy_range(0, m_size); rcFree(m_data); }
void reserve(rcSizeType size); // Unlike in std::vector, we return a bool to indicate whether the alloc was successful.
bool reserve(rcSizeType size);
void assign(rcSizeType count, const T& value) { clear(); resize(count, value); } void assign(rcSizeType count, const T& value) { clear(); resize(count, value); }
void assign(const T* begin, const T* end); void assign(const T* begin, const T* end);
@ -155,21 +156,27 @@ class rcVectorBase {
}; };
template<typename T, rcAllocHint H> template<typename T, rcAllocHint H>
void rcVectorBase<T, H>::reserve(rcSizeType count) { bool rcVectorBase<T, H>::reserve(rcSizeType count) {
if (count <= m_cap) { if (count <= m_cap) {
return; return true;
} }
T* new_data = allocate_and_copy(count); T* new_data = allocate_and_copy(count);
if (!new_data) {
return false;
}
destroy_range(0, m_size); destroy_range(0, m_size);
rcFree(m_data); rcFree(m_data);
m_data = new_data; m_data = new_data;
m_cap = count; m_cap = count;
return true;
} }
template <typename T, rcAllocHint H> template <typename T, rcAllocHint H>
T* rcVectorBase<T, H>::allocate_and_copy(rcSizeType size) { T* rcVectorBase<T, H>::allocate_and_copy(rcSizeType size) {
rcAssert(RC_SIZE_MAX / sizeof(T) >= size); rcAssert(RC_SIZE_MAX / sizeof(T) >= size);
T* new_data = static_cast<T*>(rcAlloc(sizeof(T) * size, H)); T* new_data = static_cast<T*>(rcAlloc(sizeof(T) * size, H));
if (new_data) {
copy_range(new_data, m_data, m_data + m_size); copy_range(new_data, m_data, m_data + m_size);
}
return new_data; return new_data;
} }
template <typename T, rcAllocHint H> template <typename T, rcAllocHint H>

View File

@ -25,7 +25,6 @@
#include "Recast.h" #include "Recast.h"
#include "RecastAlloc.h" #include "RecastAlloc.h"
#include "RecastAssert.h" #include "RecastAssert.h"
#include <new>
namespace namespace
{ {
@ -796,16 +795,15 @@ static bool mergeAndFilterRegions(rcContext* ctx, int minRegionArea, int mergeRe
const int h = chf.height; const int h = chf.height;
const int nreg = maxRegionId+1; const int nreg = maxRegionId+1;
rcRegion* regions = (rcRegion*)rcAlloc(sizeof(rcRegion)*nreg, RC_ALLOC_TEMP); rcTempVector<rcRegion> regions;
if (!regions) if (!regions.reserve(nreg)) {
{
ctx->log(RC_LOG_ERROR, "mergeAndFilterRegions: Out of memory 'regions' (%d).", nreg); ctx->log(RC_LOG_ERROR, "mergeAndFilterRegions: Out of memory 'regions' (%d).", nreg);
return false; return false;
} }
// Construct regions // Construct regions
for (int i = 0; i < nreg; ++i) for (int i = 0; i < nreg; ++i)
new(&regions[i]) rcRegion((unsigned short)i); regions.push_back(rcRegion((unsigned short) i));
// Find edge of a region and find connections around the contour. // Find edge of a region and find connections around the contour.
for (int y = 0; y < h; ++y) for (int y = 0; y < h; ++y)
@ -1031,11 +1029,6 @@ static bool mergeAndFilterRegions(rcContext* ctx, int minRegionArea, int mergeRe
if (regions[i].overlap) if (regions[i].overlap)
overlaps.push(regions[i].id); overlaps.push(regions[i].id);
for (int i = 0; i < nreg; ++i)
regions[i].~rcRegion();
rcFree(regions);
return true; return true;
} }
@ -1057,16 +1050,15 @@ static bool mergeAndFilterLayerRegions(rcContext* ctx, int minRegionArea,
const int h = chf.height; const int h = chf.height;
const int nreg = maxRegionId+1; const int nreg = maxRegionId+1;
rcRegion* regions = (rcRegion*)rcAlloc(sizeof(rcRegion)*nreg, RC_ALLOC_TEMP); rcTempVector<rcRegion> regions;
if (!regions)
{ // Construct regions
if (!regions.reserve(nreg)) {
ctx->log(RC_LOG_ERROR, "mergeAndFilterLayerRegions: Out of memory 'regions' (%d).", nreg); ctx->log(RC_LOG_ERROR, "mergeAndFilterLayerRegions: Out of memory 'regions' (%d).", nreg);
return false; return false;
} }
// Construct regions
for (int i = 0; i < nreg; ++i) for (int i = 0; i < nreg; ++i)
new(&regions[i]) rcRegion((unsigned short)i); regions.push_back(rcRegion((unsigned short) i));
// Find region neighbours and overlapping regions. // Find region neighbours and overlapping regions.
rcIntArray lregs(32); rcIntArray lregs(32);
@ -1244,10 +1236,6 @@ static bool mergeAndFilterLayerRegions(rcContext* ctx, int minRegionArea,
srcReg[i] = regions[srcReg[i]].id; srcReg[i] = regions[srcReg[i]].id;
} }
for (int i = 0; i < nreg; ++i)
regions[i].~rcRegion();
rcFree(regions);
return true; return true;
} }