227 lines
5.5 KiB
C++
227 lines
5.5 KiB
C++
/*
|
|
* Copyright 2019-2021 Hans-Kristian Arntzen
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "spirv_cross.hpp"
|
|
#include <memory>
|
|
|
|
using namespace spirv_cross;
|
|
|
|
// Test the tricky bits of the implementation.
|
|
// Running the entire test suite on this implementation should find all other potential issues.
|
|
|
|
static int allocations = 0;
|
|
static int deallocations = 0;
|
|
|
|
#define SPVC_ASSERT(x) do { \
|
|
if (!(x)) SPIRV_CROSS_THROW("Assert: " #x " failed!"); \
|
|
} while(0)
|
|
|
|
struct RAIIInt
|
|
{
|
|
RAIIInt(int v_) : v(v_) { allocations++; }
|
|
~RAIIInt() { deallocations++; }
|
|
RAIIInt() { allocations++; }
|
|
RAIIInt(const RAIIInt &other) { v = other.v; allocations++; }
|
|
RAIIInt(RAIIInt &&other) SPIRV_CROSS_NOEXCEPT { v = other.v; allocations++; }
|
|
RAIIInt &operator=(RAIIInt &&) = default;
|
|
RAIIInt &operator=(const RAIIInt &) = default;
|
|
|
|
int v = 0;
|
|
};
|
|
|
|
static void propagate_stack_to_heap()
|
|
{
|
|
SmallVector<RAIIInt, 2> ints;
|
|
ints.emplace_back(1);
|
|
ints.emplace_back(2);
|
|
auto *old_data = ints.data();
|
|
SPVC_ASSERT(ints[0].v == 1);
|
|
SPVC_ASSERT(ints[1].v == 2);
|
|
ints.emplace_back(3);
|
|
SPVC_ASSERT(old_data != ints.data());
|
|
SPVC_ASSERT(ints[0].v == 1);
|
|
SPVC_ASSERT(ints[1].v == 2);
|
|
SPVC_ASSERT(ints[2].v == 3);
|
|
SPVC_ASSERT(ints.size() == 3);
|
|
}
|
|
|
|
static void insert_end()
|
|
{
|
|
SmallVector<RAIIInt, 2> ints;
|
|
ints.emplace_back(1);
|
|
ints.emplace_back(2);
|
|
|
|
const RAIIInt new_ints[3] = { 10, 20, 30 };
|
|
ints.insert(ints.end(), new_ints, new_ints + 3);
|
|
SPVC_ASSERT(ints.size() == 5);
|
|
|
|
SPVC_ASSERT(ints[0].v == 1);
|
|
SPVC_ASSERT(ints[1].v == 2);
|
|
SPVC_ASSERT(ints[2].v == 10);
|
|
SPVC_ASSERT(ints[3].v == 20);
|
|
SPVC_ASSERT(ints[4].v == 30);
|
|
}
|
|
|
|
static void insert_begin_realloc()
|
|
{
|
|
SmallVector<RAIIInt, 2> ints;
|
|
ints.emplace_back(1);
|
|
ints.emplace_back(2);
|
|
|
|
const RAIIInt new_ints[3] = { 10, 20, 30 };
|
|
ints.insert(ints.begin(), new_ints, new_ints + 3);
|
|
SPVC_ASSERT(ints.size() == 5);
|
|
|
|
SPVC_ASSERT(ints[0].v == 10);
|
|
SPVC_ASSERT(ints[1].v == 20);
|
|
SPVC_ASSERT(ints[2].v == 30);
|
|
SPVC_ASSERT(ints[3].v == 1);
|
|
SPVC_ASSERT(ints[4].v == 2);
|
|
}
|
|
|
|
static void insert_middle_realloc()
|
|
{
|
|
SmallVector<RAIIInt, 2> ints;
|
|
ints.emplace_back(1);
|
|
ints.emplace_back(2);
|
|
|
|
const RAIIInt new_ints[3] = { 10, 20, 30 };
|
|
ints.insert(ints.begin() + 1, new_ints, new_ints + 3);
|
|
SPVC_ASSERT(ints.size() == 5);
|
|
|
|
SPVC_ASSERT(ints[0].v == 1);
|
|
SPVC_ASSERT(ints[1].v == 10);
|
|
SPVC_ASSERT(ints[2].v == 20);
|
|
SPVC_ASSERT(ints[3].v == 30);
|
|
SPVC_ASSERT(ints[4].v == 2);
|
|
}
|
|
|
|
static void insert_begin_no_realloc()
|
|
{
|
|
SmallVector<RAIIInt, 2> ints;
|
|
ints.reserve(10);
|
|
ints.emplace_back(1);
|
|
ints.emplace_back(2);
|
|
|
|
const RAIIInt new_ints[3] = { 10, 20, 30 };
|
|
ints.insert(ints.begin(), new_ints, new_ints + 3);
|
|
SPVC_ASSERT(ints.size() == 5);
|
|
|
|
SPVC_ASSERT(ints[0].v == 10);
|
|
SPVC_ASSERT(ints[1].v == 20);
|
|
SPVC_ASSERT(ints[2].v == 30);
|
|
SPVC_ASSERT(ints[3].v == 1);
|
|
SPVC_ASSERT(ints[4].v == 2);
|
|
}
|
|
|
|
static void insert_middle_no_realloc()
|
|
{
|
|
SmallVector<RAIIInt, 2> ints;
|
|
ints.reserve(10);
|
|
ints.emplace_back(1);
|
|
ints.emplace_back(2);
|
|
|
|
const RAIIInt new_ints[3] = { 10, 20, 30 };
|
|
ints.insert(ints.begin() + 1, new_ints, new_ints + 3);
|
|
SPVC_ASSERT(ints.size() == 5);
|
|
|
|
SPVC_ASSERT(ints[0].v == 1);
|
|
SPVC_ASSERT(ints[1].v == 10);
|
|
SPVC_ASSERT(ints[2].v == 20);
|
|
SPVC_ASSERT(ints[3].v == 30);
|
|
SPVC_ASSERT(ints[4].v == 2);
|
|
}
|
|
|
|
static void erase_end()
|
|
{
|
|
SmallVector<RAIIInt, 2> ints;
|
|
ints.emplace_back(1);
|
|
ints.emplace_back(2);
|
|
ints.emplace_back(3);
|
|
ints.emplace_back(4);
|
|
ints.erase(ints.begin() + 1, ints.end());
|
|
|
|
SPVC_ASSERT(ints.size() == 1);
|
|
SPVC_ASSERT(ints[0].v == 1);
|
|
}
|
|
|
|
static void erase_middle()
|
|
{
|
|
SmallVector<RAIIInt, 2> ints;
|
|
ints.emplace_back(1);
|
|
ints.emplace_back(2);
|
|
ints.emplace_back(3);
|
|
ints.emplace_back(4);
|
|
ints.erase(ints.begin() + 1, ints.end() - 1);
|
|
|
|
SPVC_ASSERT(ints.size() == 2);
|
|
SPVC_ASSERT(ints[0].v == 1);
|
|
SPVC_ASSERT(ints[1].v == 4);
|
|
}
|
|
|
|
static void erase_start()
|
|
{
|
|
SmallVector<RAIIInt, 2> ints;
|
|
ints.emplace_back(1);
|
|
ints.emplace_back(2);
|
|
ints.emplace_back(3);
|
|
ints.emplace_back(4);
|
|
ints.erase(ints.begin(), ints.end() - 2);
|
|
|
|
SPVC_ASSERT(ints.size() == 2);
|
|
SPVC_ASSERT(ints[0].v == 3);
|
|
SPVC_ASSERT(ints[1].v == 4);
|
|
}
|
|
|
|
static void convert_to_std_vector()
|
|
{
|
|
SmallVector<RAIIInt, 4> foo;
|
|
foo.push_back(1);
|
|
foo.push_back(2);
|
|
std::vector<RAIIInt> ints(foo);
|
|
SPVC_ASSERT(ints.size() == 2);
|
|
SPVC_ASSERT(foo.size() == 2);
|
|
SPVC_ASSERT(ints[0].v == 1);
|
|
SPVC_ASSERT(ints[1].v == 2);
|
|
|
|
// This doesn't work on MSVC 2013. Ignore it.
|
|
#if !(defined(_MSC_VER) && _MSC_VER < 1900)
|
|
SmallVector<std::unique_ptr<RAIIInt>> move_only_buffer;
|
|
move_only_buffer.emplace_back(new RAIIInt(40));
|
|
std::vector<std::unique_ptr<RAIIInt>> move_only_vector(std::move(move_only_buffer));
|
|
SPVC_ASSERT(move_only_vector.size() == 1);
|
|
SPVC_ASSERT(move_only_vector[0]->v == 40);
|
|
#endif
|
|
}
|
|
|
|
int main()
|
|
{
|
|
propagate_stack_to_heap();
|
|
insert_end();
|
|
insert_begin_realloc();
|
|
insert_begin_no_realloc();
|
|
insert_middle_realloc();
|
|
insert_middle_no_realloc();
|
|
erase_end();
|
|
erase_middle();
|
|
erase_start();
|
|
|
|
convert_to_std_vector();
|
|
|
|
SPVC_ASSERT(allocations > 0 && deallocations > 0 && deallocations == allocations);
|
|
}
|
|
|