Merge pull request #1269 from KhronosGroup/fix-1267

Make SmallVector noexcept.
This commit is contained in:
Hans-Kristian Arntzen 2020-01-23 12:23:13 +01:00 committed by GitHub
commit f9376058ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 34 deletions

View File

@ -75,11 +75,14 @@ endif()
string(TIMESTAMP spirv-cross-timestamp)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake/gitversion.in.h ${CMAKE_CURRENT_BINARY_DIR}/gitversion.h @ONLY)
if(SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS)
if (SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS)
set(spirv-compiler-defines ${spirv-compiler-defines} SPIRV_CROSS_EXCEPTIONS_TO_ASSERTIONS)
if (NOT MSVC)
set(spirv-compiler-options ${spirv-compiler-options} -fno-exceptions)
endif()
endif()
if(SPIRV_CROSS_FORCE_STL_TYPES)
if (SPIRV_CROSS_FORCE_STL_TYPES)
set(spirv-compiler-defines ${spirv-compiler-defines} SPIRV_CROSS_FORCE_STL_TYPES)
endif()

View File

@ -85,72 +85,72 @@ template <typename T>
class VectorView
{
public:
T &operator[](size_t i)
T &operator[](size_t i) SPIRV_CROSS_NOEXCEPT
{
return ptr[i];
}
const T &operator[](size_t i) const
const T &operator[](size_t i) const SPIRV_CROSS_NOEXCEPT
{
return ptr[i];
}
bool empty() const
bool empty() const SPIRV_CROSS_NOEXCEPT
{
return buffer_size == 0;
}
size_t size() const
size_t size() const SPIRV_CROSS_NOEXCEPT
{
return buffer_size;
}
T *data()
T *data() SPIRV_CROSS_NOEXCEPT
{
return ptr;
}
const T *data() const
const T *data() const SPIRV_CROSS_NOEXCEPT
{
return ptr;
}
T *begin()
T *begin() SPIRV_CROSS_NOEXCEPT
{
return ptr;
}
T *end()
T *end() SPIRV_CROSS_NOEXCEPT
{
return ptr + buffer_size;
}
const T *begin() const
const T *begin() const SPIRV_CROSS_NOEXCEPT
{
return ptr;
}
const T *end() const
const T *end() const SPIRV_CROSS_NOEXCEPT
{
return ptr + buffer_size;
}
T &front()
T &front() SPIRV_CROSS_NOEXCEPT
{
return ptr[0];
}
const T &front() const
const T &front() const SPIRV_CROSS_NOEXCEPT
{
return ptr[0];
}
T &back()
T &back() SPIRV_CROSS_NOEXCEPT
{
return ptr[buffer_size - 1];
}
const T &back() const
const T &back() const SPIRV_CROSS_NOEXCEPT
{
return ptr[buffer_size - 1];
}
@ -194,13 +194,13 @@ template <typename T, size_t N = 8>
class SmallVector : public VectorView<T>
{
public:
SmallVector()
SmallVector() SPIRV_CROSS_NOEXCEPT
{
this->ptr = stack_storage.data();
buffer_capacity = N;
}
SmallVector(const T *arg_list_begin, const T *arg_list_end)
SmallVector(const T *arg_list_begin, const T *arg_list_end) SPIRV_CROSS_NOEXCEPT
: SmallVector()
{
auto count = size_t(arg_list_end - arg_list_begin);
@ -245,14 +245,17 @@ public:
return *this;
}
SmallVector(const SmallVector &other)
SmallVector(const SmallVector &other) SPIRV_CROSS_NOEXCEPT
: SmallVector()
{
*this = other;
}
SmallVector &operator=(const SmallVector &other)
SmallVector &operator=(const SmallVector &other) SPIRV_CROSS_NOEXCEPT
{
if (this == &other)
return *this;
clear();
reserve(other.buffer_size);
for (size_t i = 0; i < other.buffer_size; i++)
@ -261,7 +264,7 @@ public:
return *this;
}
explicit SmallVector(size_t count)
explicit SmallVector(size_t count) SPIRV_CROSS_NOEXCEPT
: SmallVector()
{
resize(count);
@ -274,28 +277,28 @@ public:
free(this->ptr);
}
void clear()
void clear() SPIRV_CROSS_NOEXCEPT
{
for (size_t i = 0; i < this->buffer_size; i++)
this->ptr[i].~T();
this->buffer_size = 0;
}
void push_back(const T &t)
void push_back(const T &t) SPIRV_CROSS_NOEXCEPT
{
reserve(this->buffer_size + 1);
new (&this->ptr[this->buffer_size]) T(t);
this->buffer_size++;
}
void push_back(T &&t)
void push_back(T &&t) SPIRV_CROSS_NOEXCEPT
{
reserve(this->buffer_size + 1);
new (&this->ptr[this->buffer_size]) T(std::move(t));
this->buffer_size++;
}
void pop_back()
void pop_back() SPIRV_CROSS_NOEXCEPT
{
// Work around false positive warning on GCC 8.3.
// Calling pop_back on empty vector is undefined.
@ -304,14 +307,14 @@ public:
}
template <typename... Ts>
void emplace_back(Ts &&... ts)
void emplace_back(Ts &&... ts) SPIRV_CROSS_NOEXCEPT
{
reserve(this->buffer_size + 1);
new (&this->ptr[this->buffer_size]) T(std::forward<Ts>(ts)...);
this->buffer_size++;
}
void reserve(size_t count)
void reserve(size_t count) SPIRV_CROSS_NOEXCEPT
{
if (count > buffer_capacity)
{
@ -327,8 +330,9 @@ public:
T *new_buffer =
target_capacity > N ? static_cast<T *>(malloc(target_capacity * sizeof(T))) : stack_storage.data();
// If we actually fail this malloc, we are hosed anyways, there is no reason to attempt recovery.
if (!new_buffer)
SPIRV_CROSS_THROW("Out of memory.");
std::terminate();
// In case for some reason two allocations both come from same stack.
if (new_buffer != this->ptr)
@ -348,7 +352,7 @@ public:
}
}
void insert(T *itr, const T *insert_begin, const T *insert_end)
void insert(T *itr, const T *insert_begin, const T *insert_end) SPIRV_CROSS_NOEXCEPT
{
auto count = size_t(insert_end - insert_begin);
if (itr == this->end())
@ -374,8 +378,10 @@ public:
// Need to allocate new buffer. Move everything to a new buffer.
T *new_buffer =
target_capacity > N ? static_cast<T *>(malloc(target_capacity * sizeof(T))) : stack_storage.data();
// If we actually fail this malloc, we are hosed anyways, there is no reason to attempt recovery.
if (!new_buffer)
SPIRV_CROSS_THROW("Out of memory.");
std::terminate();
// First, move elements from source buffer to new buffer.
// We don't deal with types which can throw in move constructor.
@ -447,19 +453,19 @@ public:
}
}
void insert(T *itr, const T &value)
void insert(T *itr, const T &value) SPIRV_CROSS_NOEXCEPT
{
insert(itr, &value, &value + 1);
}
T *erase(T *itr)
T *erase(T *itr) SPIRV_CROSS_NOEXCEPT
{
std::move(itr + 1, this->end(), itr);
this->ptr[--this->buffer_size].~T();
return itr;
}
void erase(T *start_erase, T *end_erase)
void erase(T *start_erase, T *end_erase) SPIRV_CROSS_NOEXCEPT
{
if (end_erase == this->end())
{
@ -473,7 +479,7 @@ public:
}
}
void resize(size_t new_size)
void resize(size_t new_size) SPIRV_CROSS_NOEXCEPT
{
if (new_size < this->buffer_size)
{