mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-07-01 19:03:41 +00:00
Add an internal ASSERT macro
This macro has some advantages over the standard library one: - It prints the place where the macro was triggered - It "references" the condition even in Release to avoid warnings - In release, if possible, it gives compiler hints It is basically is stripped down version of the ASSERT macros I wrote for the Daemon engine in src/common/Assert.h This commit also removes the stray "backend" namespaces for common/ code.
This commit is contained in:
parent
bd0594bab8
commit
fd589f3919
@ -30,6 +30,10 @@ set(NXT_DEFS "")
|
|||||||
set(NXT_INTERNAL_FLAGS "")
|
set(NXT_INTERNAL_FLAGS "")
|
||||||
set(NXT_INTERNAL_DEFS "")
|
set(NXT_INTERNAL_DEFS "")
|
||||||
|
|
||||||
|
if(CMAKE_BUILD_TYPE STREQUAL "Debug" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
|
||||||
|
list(APPEND NXT_DEFS "NXT_ENABLE_ASSERTS")
|
||||||
|
endif()
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
# Define NOMINMAX to prevent conflicts between std::min/max and the min/max macros in WinDef.h
|
# Define NOMINMAX to prevent conflicts between std::min/max and the min/max macros in WinDef.h
|
||||||
list(APPEND NXT_DEFS "NOMINMAX")
|
list(APPEND NXT_DEFS "NOMINMAX")
|
||||||
|
@ -15,6 +15,8 @@
|
|||||||
#include "nxt/nxt.h"
|
#include "nxt/nxt.h"
|
||||||
#include "nxt/nxtcpp.h"
|
#include "nxt/nxtcpp.h"
|
||||||
|
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
#include "backend/{{namespace}}/GeneratedCodeIncludes.h"
|
#include "backend/{{namespace}}/GeneratedCodeIncludes.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
@ -150,7 +152,7 @@ namespace {{namespace}} {
|
|||||||
if (!valid) {
|
if (!valid) {
|
||||||
{{as_backendType(method.return_type)}} fakeResult = nullptr;
|
{{as_backendType(method.return_type)}} fakeResult = nullptr;
|
||||||
bool shouldBeFalse = self->HandleResult(fakeResult);
|
bool shouldBeFalse = self->HandleResult(fakeResult);
|
||||||
assert(shouldBeFalse == false);
|
ASSERT(shouldBeFalse == false);
|
||||||
}
|
}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
@ -15,13 +15,13 @@
|
|||||||
#include "wire/Wire.h"
|
#include "wire/Wire.h"
|
||||||
#include "wire/WireCmd.h"
|
#include "wire/WireCmd.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include "common/Assert.h"
|
||||||
#include <cstring>
|
|
||||||
#include <memory>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace nxt {
|
namespace nxt {
|
||||||
namespace wire {
|
namespace wire {
|
||||||
@ -139,10 +139,10 @@ namespace wire {
|
|||||||
auto object = std::unique_ptr<T>(result);
|
auto object = std::unique_ptr<T>(result);
|
||||||
|
|
||||||
if (id >= objects.size()) {
|
if (id >= objects.size()) {
|
||||||
assert(id == objects.size());
|
ASSERT(id == objects.size());
|
||||||
objects.emplace_back(std::move(object), 0);
|
objects.emplace_back(std::move(object), 0);
|
||||||
} else {
|
} else {
|
||||||
assert(objects[id].object == nullptr);
|
ASSERT(objects[id].object == nullptr);
|
||||||
//* TODO(cwallez@chromium.org): investigate if overflows could cause bad things to happen
|
//* TODO(cwallez@chromium.org): investigate if overflows could cause bad things to happen
|
||||||
objects[id].serial++;
|
objects[id].serial++;
|
||||||
objects[id].object = std::move(object);
|
objects[id].object = std::move(object);
|
||||||
@ -337,7 +337,7 @@ namespace wire {
|
|||||||
|
|
||||||
void ClientBufferMapReadAsync(Buffer* buffer, uint32_t start, uint32_t size, nxtBufferMapReadCallback callback, nxtCallbackUserdata userdata) {
|
void ClientBufferMapReadAsync(Buffer* buffer, uint32_t start, uint32_t size, nxtBufferMapReadCallback callback, nxtCallbackUserdata userdata) {
|
||||||
uint32_t serial = buffer->readRequestSerial++;
|
uint32_t serial = buffer->readRequestSerial++;
|
||||||
assert(buffer->readRequests.find(serial) == buffer->readRequests.end());
|
ASSERT(buffer->readRequests.find(serial) == buffer->readRequests.end());
|
||||||
|
|
||||||
Buffer::MapReadRequestData request;
|
Buffer::MapReadRequestData request;
|
||||||
request.callback = callback;
|
request.callback = callback;
|
||||||
|
@ -15,7 +15,8 @@
|
|||||||
#include "wire/Wire.h"
|
#include "wire/Wire.h"
|
||||||
#include "wire/WireCmd.h"
|
#include "wire/WireCmd.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include "common/Assert.h"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
@ -113,7 +114,7 @@ namespace wire {
|
|||||||
|
|
||||||
//* Marks an ID as deallocated
|
//* Marks an ID as deallocated
|
||||||
void Free(uint32_t id) {
|
void Free(uint32_t id) {
|
||||||
assert(id < known.size());
|
ASSERT(id < known.size());
|
||||||
known[id].allocated = false;
|
known[id].allocated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +168,7 @@ namespace wire {
|
|||||||
if (status != NXT_BUILDER_ERROR_STATUS_UNKNOWN) {
|
if (status != NXT_BUILDER_ERROR_STATUS_UNKNOWN) {
|
||||||
//* Unknown is the only status that can be returned without a call to GetResult
|
//* Unknown is the only status that can be returned without a call to GetResult
|
||||||
//* so we are guaranteed to have created an object.
|
//* so we are guaranteed to have created an object.
|
||||||
assert(builder->builtObjectId != 0);
|
ASSERT(builder->builtObjectId != 0);
|
||||||
|
|
||||||
Return{{Type}}ErrorCallbackCmd cmd;
|
Return{{Type}}ErrorCallbackCmd cmd;
|
||||||
cmd.builtObjectId = builder->builtObjectId;
|
cmd.builtObjectId = builder->builtObjectId;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "backend/Buffer.h"
|
#include "backend/Buffer.h"
|
||||||
#include "backend/Device.h"
|
#include "backend/Device.h"
|
||||||
#include "backend/Texture.h"
|
#include "backend/Texture.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "backend/Buffer.h"
|
#include "backend/Buffer.h"
|
||||||
|
|
||||||
#include "backend/Device.h"
|
#include "backend/Device.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
@ -146,7 +147,7 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void BufferBase::UpdateUsageInternal(nxt::BufferUsageBit usage) {
|
void BufferBase::UpdateUsageInternal(nxt::BufferUsageBit usage) {
|
||||||
assert(IsTransitionPossible(usage));
|
ASSERT(IsTransitionPossible(usage));
|
||||||
currentUsage = usage;
|
currentUsage = usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "backend/Builder.h"
|
#include "backend/Builder.h"
|
||||||
|
|
||||||
#include "backend/Device.h"
|
#include "backend/Device.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
|
@ -14,13 +14,12 @@
|
|||||||
|
|
||||||
#include "backend/CommandAllocator.h"
|
#include "backend/CommandAllocator.h"
|
||||||
|
|
||||||
|
#include "common/Assert.h"
|
||||||
#include "common/Math.h"
|
#include "common/Math.h"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cassert>
|
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#define ASSERT assert
|
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "backend/PipelineLayout.h"
|
#include "backend/PipelineLayout.h"
|
||||||
#include "backend/RenderPass.h"
|
#include "backend/RenderPass.h"
|
||||||
#include "backend/Texture.h"
|
#include "backend/Texture.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
#include "common/BitSetIterator.h"
|
#include "common/BitSetIterator.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
@ -487,7 +488,7 @@ namespace backend {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
assert(false);
|
ASSERT(false);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,11 +15,8 @@
|
|||||||
#ifndef BACKEND_FORWARD_H_
|
#ifndef BACKEND_FORWARD_H_
|
||||||
#define BACKEND_FORWARD_H_
|
#define BACKEND_FORWARD_H_
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
#define ASSERT assert
|
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
class BindGroupBase;
|
class BindGroupBase;
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "backend/Device.h"
|
#include "backend/Device.h"
|
||||||
#include "backend/RenderPass.h"
|
#include "backend/RenderPass.h"
|
||||||
#include "backend/Texture.h"
|
#include "backend/Texture.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "backend/InputState.h"
|
#include "backend/InputState.h"
|
||||||
|
|
||||||
#include "backend/Device.h"
|
#include "backend/Device.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
|
@ -15,14 +15,13 @@
|
|||||||
#ifndef BACKEND_PERSTAGE_H_
|
#ifndef BACKEND_PERSTAGE_H_
|
||||||
#define BACKEND_PERSTAGE_H_
|
#define BACKEND_PERSTAGE_H_
|
||||||
|
|
||||||
|
#include "common/Assert.h"
|
||||||
#include "common/BitSetIterator.h"
|
#include "common/BitSetIterator.h"
|
||||||
#include "common/Constants.h"
|
#include "common/Constants.h"
|
||||||
|
|
||||||
#include "nxt/nxtcpp.h"
|
#include "nxt/nxtcpp.h"
|
||||||
|
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cassert>
|
|
||||||
#define ASSERT assert
|
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
@ -43,22 +42,22 @@ namespace backend {
|
|||||||
class PerStage {
|
class PerStage {
|
||||||
public:
|
public:
|
||||||
T& operator[](nxt::ShaderStage stage) {
|
T& operator[](nxt::ShaderStage stage) {
|
||||||
ASSERT(static_cast<uint32_t>(stage) < kNumStages);
|
NXT_ASSERT(static_cast<uint32_t>(stage) < kNumStages);
|
||||||
return data[static_cast<uint32_t>(stage)];
|
return data[static_cast<uint32_t>(stage)];
|
||||||
}
|
}
|
||||||
const T& operator[](nxt::ShaderStage stage) const {
|
const T& operator[](nxt::ShaderStage stage) const {
|
||||||
ASSERT(static_cast<uint32_t>(stage) < kNumStages);
|
NXT_ASSERT(static_cast<uint32_t>(stage) < kNumStages);
|
||||||
return data[static_cast<uint32_t>(stage)];
|
return data[static_cast<uint32_t>(stage)];
|
||||||
}
|
}
|
||||||
|
|
||||||
T& operator[](nxt::ShaderStageBit stageBit) {
|
T& operator[](nxt::ShaderStageBit stageBit) {
|
||||||
uint32_t bit = static_cast<uint32_t>(stageBit);
|
uint32_t bit = static_cast<uint32_t>(stageBit);
|
||||||
ASSERT(bit != 0 && IsPowerOfTwo(bit) && bit <= (1 << kNumStages));
|
NXT_ASSERT(bit != 0 && IsPowerOfTwo(bit) && bit <= (1 << kNumStages));
|
||||||
return data[Log2(bit)];
|
return data[Log2(bit)];
|
||||||
}
|
}
|
||||||
const T& operator[](nxt::ShaderStageBit stageBit) const {
|
const T& operator[](nxt::ShaderStageBit stageBit) const {
|
||||||
uint32_t bit = static_cast<uint32_t>(stageBit);
|
uint32_t bit = static_cast<uint32_t>(stageBit);
|
||||||
ASSERT(bit != 0 && IsPowerOfTwo(bit) && bit <= (1 << kNumStages));
|
NXT_ASSERT(bit != 0 && IsPowerOfTwo(bit) && bit <= (1 << kNumStages));
|
||||||
return data[Log2(bit)];
|
return data[Log2(bit)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "backend/BindGroupLayout.h"
|
#include "backend/BindGroupLayout.h"
|
||||||
#include "backend/Device.h"
|
#include "backend/Device.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
|
@ -14,8 +14,7 @@
|
|||||||
|
|
||||||
#include "backend/RefCounted.h"
|
#include "backend/RefCounted.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include "common/Assert.h"
|
||||||
#define ASSERT assert
|
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "backend/Buffer.h"
|
#include "backend/Buffer.h"
|
||||||
#include "backend/Device.h"
|
#include "backend/Device.h"
|
||||||
#include "backend/Texture.h"
|
#include "backend/Texture.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "backend/Texture.h"
|
#include "backend/Texture.h"
|
||||||
|
|
||||||
#include "backend/Device.h"
|
#include "backend/Device.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
|
||||||
@ -88,7 +89,7 @@ namespace backend {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TextureBase::UpdateUsageInternal(nxt::TextureUsageBit usage) {
|
void TextureBase::UpdateUsageInternal(nxt::TextureUsageBit usage) {
|
||||||
assert(IsTransitionPossible(usage));
|
ASSERT(IsTransitionPossible(usage));
|
||||||
currentUsage = usage;
|
currentUsage = usage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "backend/d3d12/D3D12Backend.h"
|
#include "backend/d3d12/D3D12Backend.h"
|
||||||
#include "backend/d3d12/ResourceAllocator.h"
|
#include "backend/d3d12/ResourceAllocator.h"
|
||||||
#include "backend/d3d12/ResourceUploader.h"
|
#include "backend/d3d12/ResourceUploader.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
namespace d3d12 {
|
namespace d3d12 {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "backend/d3d12/D3D12Backend.h"
|
#include "backend/d3d12/D3D12Backend.h"
|
||||||
|
|
||||||
|
#include "common/Assert.h"
|
||||||
#include "common/BitSetIterator.h"
|
#include "common/BitSetIterator.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
|
@ -23,10 +23,10 @@
|
|||||||
#include "backend/d3d12/InputStateD3D12.h"
|
#include "backend/d3d12/InputStateD3D12.h"
|
||||||
#include "backend/d3d12/PipelineD3D12.h"
|
#include "backend/d3d12/PipelineD3D12.h"
|
||||||
#include "backend/d3d12/PipelineLayoutD3D12.h"
|
#include "backend/d3d12/PipelineLayoutD3D12.h"
|
||||||
|
#include "backend/d3d12/ResourceAllocator.h"
|
||||||
#include "backend/d3d12/SamplerD3D12.h"
|
#include "backend/d3d12/SamplerD3D12.h"
|
||||||
#include "backend/d3d12/TextureD3D12.h"
|
#include "backend/d3d12/TextureD3D12.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
#include "backend/d3d12/ResourceAllocator.h"
|
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
namespace d3d12 {
|
namespace d3d12 {
|
||||||
|
@ -17,19 +17,19 @@
|
|||||||
#include "backend/d3d12/BindGroupD3D12.h"
|
#include "backend/d3d12/BindGroupD3D12.h"
|
||||||
#include "backend/d3d12/BindGroupLayoutD3D12.h"
|
#include "backend/d3d12/BindGroupLayoutD3D12.h"
|
||||||
#include "backend/d3d12/BufferD3D12.h"
|
#include "backend/d3d12/BufferD3D12.h"
|
||||||
|
#include "backend/d3d12/CommandAllocatorManager.h"
|
||||||
#include "backend/d3d12/CommandBufferD3D12.h"
|
#include "backend/d3d12/CommandBufferD3D12.h"
|
||||||
|
#include "backend/d3d12/DescriptorHeapAllocator.h"
|
||||||
#include "backend/d3d12/InputStateD3D12.h"
|
#include "backend/d3d12/InputStateD3D12.h"
|
||||||
#include "backend/d3d12/PipelineD3D12.h"
|
#include "backend/d3d12/PipelineD3D12.h"
|
||||||
#include "backend/d3d12/PipelineLayoutD3D12.h"
|
#include "backend/d3d12/PipelineLayoutD3D12.h"
|
||||||
#include "backend/d3d12/QueueD3D12.h"
|
#include "backend/d3d12/QueueD3D12.h"
|
||||||
|
#include "backend/d3d12/ResourceAllocator.h"
|
||||||
|
#include "backend/d3d12/ResourceUploader.h"
|
||||||
#include "backend/d3d12/SamplerD3D12.h"
|
#include "backend/d3d12/SamplerD3D12.h"
|
||||||
#include "backend/d3d12/ShaderModuleD3D12.h"
|
#include "backend/d3d12/ShaderModuleD3D12.h"
|
||||||
#include "backend/d3d12/TextureD3D12.h"
|
#include "backend/d3d12/TextureD3D12.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
#include "backend/d3d12/CommandAllocatorManager.h"
|
|
||||||
#include "backend/d3d12/DescriptorHeapAllocator.h"
|
|
||||||
#include "backend/d3d12/ResourceAllocator.h"
|
|
||||||
#include "backend/d3d12/ResourceUploader.h"
|
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
namespace d3d12 {
|
namespace d3d12 {
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include "backend/d3d12/DescriptorHeapAllocator.h"
|
#include "backend/d3d12/DescriptorHeapAllocator.h"
|
||||||
|
|
||||||
#include "backend/d3d12/D3D12Backend.h"
|
#include "backend/d3d12/D3D12Backend.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
namespace d3d12 {
|
namespace d3d12 {
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "backend/d3d12/InputStateD3D12.h"
|
#include "backend/d3d12/InputStateD3D12.h"
|
||||||
#include "backend/d3d12/ShaderModuleD3D12.h"
|
#include "backend/d3d12/ShaderModuleD3D12.h"
|
||||||
#include "backend/d3d12/PipelineLayoutD3D12.h"
|
#include "backend/d3d12/PipelineLayoutD3D12.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
#include <d3dcompiler.h>
|
#include <d3dcompiler.h>
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "backend/d3d12/D3D12Backend.h"
|
#include "backend/d3d12/D3D12Backend.h"
|
||||||
#include "backend/d3d12/BindGroupLayoutD3D12.h"
|
#include "backend/d3d12/BindGroupLayoutD3D12.h"
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
using Microsoft::WRL::ComPtr;
|
using Microsoft::WRL::ComPtr;
|
||||||
|
|
||||||
|
22
src/common/Assert.cpp
Normal file
22
src/common/Assert.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright 2017 The NXT Authors
|
||||||
|
//
|
||||||
|
// 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 "common/Assert.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void HandleAssertionFailure(const char* file, const char* function, int line, const char* condition) {
|
||||||
|
std::cerr << "Assertion failure at " << file << ":" << line << " (" << function << "): " << condition << std::endl;
|
||||||
|
NXT_BREAKPOINT();
|
||||||
|
}
|
74
src/common/Assert.h
Normal file
74
src/common/Assert.h
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// Copyright 2017 The NXT Authors
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#ifndef COMMON_ASSERT_H_
|
||||||
|
#define COMMON_ASSERT_H_
|
||||||
|
|
||||||
|
#include "common/Compiler.h"
|
||||||
|
|
||||||
|
void HandleAssertionFailure(const char* file, const char* function, int line, const char* condition);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* NXT asserts to be used instead of the regular C stdlib assert function (if you don't
|
||||||
|
* use assert yet, you should start now!). In debug ASSERT(condition) will trigger an error,
|
||||||
|
* otherwise in release it does nothing at runtime.
|
||||||
|
*
|
||||||
|
* In case of name clashes (with for example a testing library), you can define the
|
||||||
|
* NXT_SKIP_ASSERT_SHORTHANDS to only define the NXT_ prefixed macros.
|
||||||
|
*
|
||||||
|
* These asserts feature:
|
||||||
|
* - Logging of the error with file, line and function information.
|
||||||
|
* - Breaking in the debugger when an assert is triggered and a debugger is attached.
|
||||||
|
* - Use the assert information to help the compiler optimizer in release builds.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// MSVC triggers a warning in /W4 for do {} while(0). SDL worked around this by using
|
||||||
|
// // (0,0) and points out that it looks like an owl face.
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define NXT_ASSERT_LOOP_CONDITION (0,0)
|
||||||
|
#else
|
||||||
|
#define NXT_ASSERT_LOOP_CONDITION (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// NXT_ASSERT_CALLSITE_HELPER generates the actual assert code. In Debug it does what you would
|
||||||
|
// expect of an assert and in release it tries to give hints to make the compiler generate better code.
|
||||||
|
#if defined(NXT_ENABLE_ASSERTS)
|
||||||
|
#define NXT_ASSERT_CALLSITE_HELPER(file, func, line, condition) \
|
||||||
|
do { \
|
||||||
|
if (!(condition)) { \
|
||||||
|
HandleAssertionFailure(file, func, line, #condition); \
|
||||||
|
} \
|
||||||
|
} while(NXT_ASSERT_LOOP_CONDITION)
|
||||||
|
#else
|
||||||
|
#if defined(_MSC_VER)
|
||||||
|
#define NXT_ASSERT_CALLSITE_HELPER(file, func, line, condition) \
|
||||||
|
__assume(condition)
|
||||||
|
#elif defined(__clang__) && defined(__builtin_assume)
|
||||||
|
#define NXT_ASSERT_CALLSITE_HELPER(file, func, line, condition) \
|
||||||
|
__builtin_assume(condition)
|
||||||
|
#else
|
||||||
|
#define NXT_ASSERT_CALLSITE_HELPER(file, func, line, condition) \
|
||||||
|
do { \
|
||||||
|
(void) sizeof(condition); \
|
||||||
|
} while(NXT_ASSERT_LOOP_CONDITION)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NXT_ASSERT(condition) NXT_ASSERT_CALLSITE_HELPER(__FILE__, __func__, __LINE__, condition)
|
||||||
|
|
||||||
|
#if !defined(NXT_SKIP_ASSERT_SHORTHANDS)
|
||||||
|
#define ASSERT NXT_ASSERT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // COMMON_ASSERT_H_
|
@ -15,123 +15,118 @@
|
|||||||
#ifndef COMMON_BITSETITERATOR_H_
|
#ifndef COMMON_BITSETITERATOR_H_
|
||||||
#define COMMON_BITSETITERATOR_H_
|
#define COMMON_BITSETITERATOR_H_
|
||||||
|
|
||||||
|
#include "common/Assert.h"
|
||||||
#include "common/Math.h"
|
#include "common/Math.h"
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
|
|
||||||
#define ASSERT assert
|
|
||||||
|
|
||||||
// This is ANGLE's BitSetIterator class with a customizable return type
|
// This is ANGLE's BitSetIterator class with a customizable return type
|
||||||
// TODO(cwallez@chromium.org): it could be optimized, in particular when N <= 64
|
// TODO(cwallez@chromium.org): it could be optimized, in particular when N <= 64
|
||||||
|
|
||||||
namespace backend {
|
template <typename T>
|
||||||
|
T roundUp(const T value, const T alignment) {
|
||||||
|
auto temp = value + alignment - static_cast<T>(1);
|
||||||
|
return temp - temp % alignment;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <size_t N, typename T>
|
||||||
T roundUp(const T value, const T alignment) {
|
class BitSetIterator final {
|
||||||
auto temp = value + alignment - static_cast<T>(1);
|
public:
|
||||||
return temp - temp % alignment;
|
BitSetIterator(const std::bitset<N>& bitset);
|
||||||
}
|
BitSetIterator(const BitSetIterator& other);
|
||||||
|
BitSetIterator &operator=(const BitSetIterator& other);
|
||||||
|
|
||||||
template <size_t N, typename T>
|
class Iterator final {
|
||||||
class BitSetIterator final {
|
public:
|
||||||
public:
|
Iterator(const std::bitset<N>& bits);
|
||||||
BitSetIterator(const std::bitset<N>& bitset);
|
Iterator& operator++();
|
||||||
BitSetIterator(const BitSetIterator& other);
|
|
||||||
BitSetIterator &operator=(const BitSetIterator& other);
|
|
||||||
|
|
||||||
class Iterator final {
|
bool operator==(const Iterator& other) const;
|
||||||
public:
|
bool operator!=(const Iterator& other) const;
|
||||||
Iterator(const std::bitset<N>& bits);
|
T operator*() const { return static_cast<T>(mCurrentBit); }
|
||||||
Iterator& operator++();
|
|
||||||
|
|
||||||
bool operator==(const Iterator& other) const;
|
private:
|
||||||
bool operator!=(const Iterator& other) const;
|
unsigned long getNextBit();
|
||||||
T operator*() const { return static_cast<T>(mCurrentBit); }
|
|
||||||
|
|
||||||
private:
|
static const size_t BitsPerWord = sizeof(uint32_t) * 8;
|
||||||
unsigned long getNextBit();
|
std::bitset<N> mBits;
|
||||||
|
unsigned long mCurrentBit;
|
||||||
|
unsigned long mOffset;
|
||||||
|
};
|
||||||
|
|
||||||
static const size_t BitsPerWord = sizeof(uint32_t) * 8;
|
Iterator begin() const { return Iterator(mBits); }
|
||||||
std::bitset<N> mBits;
|
Iterator end() const { return Iterator(std::bitset<N>(0)); }
|
||||||
unsigned long mCurrentBit;
|
|
||||||
unsigned long mOffset;
|
|
||||||
};
|
|
||||||
|
|
||||||
Iterator begin() const { return Iterator(mBits); }
|
private:
|
||||||
Iterator end() const { return Iterator(std::bitset<N>(0)); }
|
const std::bitset<N> mBits;
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
template <size_t N, typename T>
|
||||||
const std::bitset<N> mBits;
|
BitSetIterator<N, T>::BitSetIterator(const std::bitset<N>& bitset)
|
||||||
};
|
: mBits(bitset) {
|
||||||
|
}
|
||||||
|
|
||||||
template <size_t N, typename T>
|
template <size_t N, typename T>
|
||||||
BitSetIterator<N, T>::BitSetIterator(const std::bitset<N>& bitset)
|
BitSetIterator<N, T>::BitSetIterator(const BitSetIterator& other)
|
||||||
: mBits(bitset) {
|
: mBits(other.mBits) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t N, typename T>
|
template <size_t N, typename T>
|
||||||
BitSetIterator<N, T>::BitSetIterator(const BitSetIterator& other)
|
BitSetIterator<N, T>& BitSetIterator<N, T>::operator=(const BitSetIterator& other) {
|
||||||
: mBits(other.mBits) {
|
mBits = other.mBits;
|
||||||
}
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template <size_t N, typename T>
|
template <size_t N, typename T>
|
||||||
BitSetIterator<N, T>& BitSetIterator<N, T>::operator=(const BitSetIterator& other) {
|
BitSetIterator<N, T>::Iterator::Iterator(const std::bitset<N>& bits)
|
||||||
mBits = other.mBits;
|
: mBits(bits), mCurrentBit(0), mOffset(0) {
|
||||||
return *this;
|
if (bits.any()) {
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t N, typename T>
|
|
||||||
BitSetIterator<N, T>::Iterator::Iterator(const std::bitset<N>& bits)
|
|
||||||
: mBits(bits), mCurrentBit(0), mOffset(0) {
|
|
||||||
if (bits.any()) {
|
|
||||||
mCurrentBit = getNextBit();
|
|
||||||
} else {
|
|
||||||
mOffset = static_cast<unsigned long>(roundUp(N, BitsPerWord));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <size_t N, typename T>
|
|
||||||
typename BitSetIterator<N, T>::Iterator& BitSetIterator<N, T>::Iterator::operator++() {
|
|
||||||
ASSERT(mBits.any());
|
|
||||||
mBits.set(mCurrentBit - mOffset, 0);
|
|
||||||
mCurrentBit = getNextBit();
|
mCurrentBit = getNextBit();
|
||||||
return *this;
|
} else {
|
||||||
|
mOffset = static_cast<unsigned long>(roundUp(N, BitsPerWord));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <size_t N, typename T>
|
template <size_t N, typename T>
|
||||||
bool BitSetIterator<N, T>::Iterator::operator==(const Iterator& other) const {
|
typename BitSetIterator<N, T>::Iterator& BitSetIterator<N, T>::Iterator::operator++() {
|
||||||
return mOffset == other.mOffset && mBits == other.mBits;
|
NXT_ASSERT(mBits.any());
|
||||||
}
|
mBits.set(mCurrentBit - mOffset, 0);
|
||||||
|
mCurrentBit = getNextBit();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
template <size_t N, typename T>
|
template <size_t N, typename T>
|
||||||
bool BitSetIterator<N, T>::Iterator::operator!=(const Iterator& other) const {
|
bool BitSetIterator<N, T>::Iterator::operator==(const Iterator& other) const {
|
||||||
return !(*this == other);
|
return mOffset == other.mOffset && mBits == other.mBits;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <size_t N, typename T>
|
template <size_t N, typename T>
|
||||||
unsigned long BitSetIterator<N, T>::Iterator::getNextBit() {
|
bool BitSetIterator<N, T>::Iterator::operator!=(const Iterator& other) const {
|
||||||
static std::bitset<N> wordMask(std::numeric_limits<uint32_t>::max());
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
while (mOffset < N) {
|
template <size_t N, typename T>
|
||||||
uint32_t wordBits = (mBits & wordMask).to_ulong();
|
unsigned long BitSetIterator<N, T>::Iterator::getNextBit() {
|
||||||
if (wordBits != 0ul) {
|
static std::bitset<N> wordMask(std::numeric_limits<uint32_t>::max());
|
||||||
return ScanForward(wordBits) + mOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
mBits >>= BitsPerWord;
|
while (mOffset < N) {
|
||||||
mOffset += BitsPerWord;
|
uint32_t wordBits = (mBits & wordMask).to_ulong();
|
||||||
|
if (wordBits != 0ul) {
|
||||||
|
return ScanForward(wordBits) + mOffset;
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Helper to avoid needing to specify the template parameter size
|
mBits >>= BitsPerWord;
|
||||||
template <size_t N>
|
mOffset += BitsPerWord;
|
||||||
BitSetIterator<N, uint32_t> IterateBitSet(const std::bitset<N>& bitset) {
|
|
||||||
return BitSetIterator<N, uint32_t>(bitset);
|
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to avoid needing to specify the template parameter size
|
||||||
|
template <size_t N>
|
||||||
|
BitSetIterator<N, uint32_t> IterateBitSet(const std::bitset<N>& bitset) {
|
||||||
|
return BitSetIterator<N, uint32_t>(bitset);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // COMMON_BITSETITERATOR_H_
|
#endif // COMMON_BITSETITERATOR_H_
|
||||||
|
@ -15,7 +15,10 @@
|
|||||||
set(COMMON_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
set(COMMON_DIR ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
|
|
||||||
list(APPEND COMMON_SOURCES
|
list(APPEND COMMON_SOURCES
|
||||||
|
${COMMON_DIR}/Assert.cpp
|
||||||
|
${COMMON_DIR}/Assert.h
|
||||||
${COMMON_DIR}/BitSetIterator.h
|
${COMMON_DIR}/BitSetIterator.h
|
||||||
|
${COMMON_DIR}/Compiler.h
|
||||||
${COMMON_DIR}/Math.cpp
|
${COMMON_DIR}/Math.cpp
|
||||||
${COMMON_DIR}/Math.h
|
${COMMON_DIR}/Math.h
|
||||||
${COMMON_DIR}/Serial.h
|
${COMMON_DIR}/Serial.h
|
||||||
|
39
src/common/Compiler.h
Normal file
39
src/common/Compiler.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
// Copyright 2017 The NXT Authors
|
||||||
|
//
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
#ifndef COMMON_COMPILER_H_
|
||||||
|
#define COMMON_COMPILER_H_
|
||||||
|
|
||||||
|
// Defines macros for compiler-specific functionality
|
||||||
|
// - NXT_BREAKPOINT(): Raises an exception and breaks in the debugger
|
||||||
|
|
||||||
|
// Clang and GCC
|
||||||
|
#ifdef __GNUC__
|
||||||
|
|
||||||
|
#if defined(__i386__) || defined(__x86_64__)
|
||||||
|
#define NXT_BREAKPOINT() __asm__ __volatile__("int $3\n\t")
|
||||||
|
#else
|
||||||
|
#error "Implement BREAKPOINT on your platform"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// MSVC
|
||||||
|
#elif defined(_MSC_VER)
|
||||||
|
extern void __cdecl __debugbreak(void);
|
||||||
|
#define NXT_BREAKPOINT() __debugbreak()
|
||||||
|
|
||||||
|
#else
|
||||||
|
#error "Unsupported compiler"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // COMMON_COMPILER_H_
|
@ -14,53 +14,48 @@
|
|||||||
|
|
||||||
#include "common/Math.h"
|
#include "common/Math.h"
|
||||||
|
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <cassert>
|
uint32_t ScanForward(uint32_t bits) {
|
||||||
#define ASSERT assert
|
ASSERT(bits != 0);
|
||||||
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
namespace backend {
|
unsigned long firstBitIndex = 0ul;
|
||||||
|
unsigned char ret = _BitScanForward(&firstBitIndex, bits);
|
||||||
uint32_t ScanForward(uint32_t bits) {
|
ASSERT(ret != 0);
|
||||||
ASSERT(bits != 0);
|
return firstBitIndex;
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#else
|
||||||
unsigned long firstBitIndex = 0ul;
|
return static_cast<unsigned long>(__builtin_ctz(bits));
|
||||||
unsigned char ret = _BitScanForward(&firstBitIndex, bits);
|
#endif
|
||||||
ASSERT(ret != 0);
|
}
|
||||||
return firstBitIndex;
|
|
||||||
#else
|
uint32_t Log2(uint32_t value) {
|
||||||
return static_cast<unsigned long>(__builtin_ctz(bits));
|
ASSERT(value != 0);
|
||||||
#endif
|
#if defined(_WIN32) || defined(_WIN64)
|
||||||
}
|
unsigned long firstBitIndex = 0ul;
|
||||||
|
unsigned char ret = _BitScanReverse(&firstBitIndex, value);
|
||||||
uint32_t Log2(uint32_t value) {
|
ASSERT(ret != 0);
|
||||||
ASSERT(value != 0);
|
return firstBitIndex;
|
||||||
#if defined(_WIN32) || defined(_WIN64)
|
#else
|
||||||
unsigned long firstBitIndex = 0ul;
|
return 31 - __builtin_clz(value);
|
||||||
unsigned char ret = _BitScanReverse(&firstBitIndex, value);
|
#endif
|
||||||
ASSERT(ret != 0);
|
}
|
||||||
return firstBitIndex;
|
|
||||||
#else
|
bool IsPowerOfTwo(size_t n) {
|
||||||
return 31 - __builtin_clz(value);
|
ASSERT(n != 0);
|
||||||
#endif
|
return (n & (n - 1)) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsPowerOfTwo(size_t n) {
|
bool IsAligned(const void* ptr, size_t alignment) {
|
||||||
ASSERT(n != 0);
|
ASSERT(IsPowerOfTwo(alignment));
|
||||||
return (n & (n - 1)) == 0;
|
ASSERT(alignment != 0);
|
||||||
}
|
return (reinterpret_cast<intptr_t>(ptr) & (alignment - 1)) == 0;
|
||||||
|
}
|
||||||
bool IsAligned(const void* ptr, size_t alignment) {
|
|
||||||
ASSERT(IsPowerOfTwo(alignment));
|
void* AlignVoidPtr(void* ptr, size_t alignment) {
|
||||||
ASSERT(alignment != 0);
|
ASSERT(alignment != 0);
|
||||||
return (reinterpret_cast<intptr_t>(ptr) & (alignment - 1)) == 0;
|
return reinterpret_cast<void*>((reinterpret_cast<intptr_t>(ptr) + (alignment - 1)) & ~(alignment - 1));
|
||||||
}
|
|
||||||
|
|
||||||
void* AlignVoidPtr(void* ptr, size_t alignment) {
|
|
||||||
ASSERT(alignment != 0);
|
|
||||||
return reinterpret_cast<void*>((reinterpret_cast<intptr_t>(ptr) + (alignment - 1)) & ~(alignment - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -18,26 +18,22 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace backend {
|
// The following are not valid for 0
|
||||||
|
uint32_t ScanForward(uint32_t bits);
|
||||||
|
uint32_t Log2(uint32_t value);
|
||||||
|
bool IsPowerOfTwo(size_t n);
|
||||||
|
|
||||||
// The following are not valid for 0
|
bool IsAligned(const void* ptr, size_t alignment);
|
||||||
uint32_t ScanForward(uint32_t bits);
|
void* AlignVoidPtr(void* ptr, size_t alignment);
|
||||||
uint32_t Log2(uint32_t value);
|
|
||||||
bool IsPowerOfTwo(size_t n);
|
|
||||||
|
|
||||||
bool IsAligned(const void* ptr, size_t alignment);
|
template<typename T>
|
||||||
void* AlignVoidPtr(void* ptr, size_t alignment);
|
T* Align(T* ptr, size_t alignment) {
|
||||||
|
return reinterpret_cast<T*>(AlignVoidPtr(ptr, alignment));
|
||||||
template<typename T>
|
}
|
||||||
T* Align(T* ptr, size_t alignment) {
|
|
||||||
return reinterpret_cast<T*>(AlignVoidPtr(ptr, alignment));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
const T* Align(const T* ptr, size_t alignment) {
|
|
||||||
return reinterpret_cast<const T*>(AlignVoidPtr(const_cast<T*>(ptr), alignment));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
const T* Align(const T* ptr, size_t alignment) {
|
||||||
|
return reinterpret_cast<const T*>(AlignVoidPtr(const_cast<T*>(ptr), alignment));
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // COMMON_MATH_H_
|
#endif // COMMON_MATH_H_
|
||||||
|
@ -15,322 +15,317 @@
|
|||||||
#ifndef COMMON_SERIALQUEUE_H_
|
#ifndef COMMON_SERIALQUEUE_H_
|
||||||
#define COMMON_SERIALQUEUE_H_
|
#define COMMON_SERIALQUEUE_H_
|
||||||
|
|
||||||
|
#include "common/Assert.h"
|
||||||
#include "common/Serial.h"
|
#include "common/Serial.h"
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#define ASSERT assert
|
template<typename T>
|
||||||
|
class SerialQueue {
|
||||||
|
private:
|
||||||
|
using SerialPair = std::pair<Serial, std::vector<T>>;
|
||||||
|
using Storage = std::vector<SerialPair>;
|
||||||
|
using StorageIterator = typename Storage::iterator;
|
||||||
|
using ConstStorageIterator = typename Storage::const_iterator;
|
||||||
|
|
||||||
namespace backend {
|
public:
|
||||||
|
class Iterator {
|
||||||
|
public:
|
||||||
|
Iterator(StorageIterator start);
|
||||||
|
Iterator& operator++();
|
||||||
|
|
||||||
template<typename T>
|
bool operator==(const Iterator& other) const;
|
||||||
class SerialQueue {
|
bool operator!=(const Iterator& other) const;
|
||||||
private:
|
T& operator*() const;
|
||||||
using SerialPair = std::pair<Serial, std::vector<T>>;
|
|
||||||
using Storage = std::vector<SerialPair>;
|
|
||||||
using StorageIterator = typename Storage::iterator;
|
|
||||||
using ConstStorageIterator = typename Storage::const_iterator;
|
|
||||||
|
|
||||||
public:
|
private:
|
||||||
class Iterator {
|
StorageIterator storageIterator;
|
||||||
public:
|
// Special case the serialIterator when it should be equal to storageIterator.begin()
|
||||||
Iterator(StorageIterator start);
|
// otherwise we could ask storageIterator.begin() when storageIterator is storage.end()
|
||||||
Iterator& operator++();
|
// which is invalid. storageIterator.begin() is tagged with a nullptr.
|
||||||
|
T* serialIterator;
|
||||||
|
};
|
||||||
|
|
||||||
bool operator==(const Iterator& other) const;
|
class ConstIterator {
|
||||||
bool operator!=(const Iterator& other) const;
|
public:
|
||||||
T& operator*() const;
|
ConstIterator(ConstStorageIterator start);
|
||||||
|
ConstIterator& operator++();
|
||||||
|
|
||||||
private:
|
bool operator==(const ConstIterator& other) const;
|
||||||
StorageIterator storageIterator;
|
bool operator!=(const ConstIterator& other) const;
|
||||||
// Special case the serialIterator when it should be equal to storageIterator.begin()
|
const T& operator*() const;
|
||||||
// otherwise we could ask storageIterator.begin() when storageIterator is storage.end()
|
|
||||||
// which is invalid. storageIterator.begin() is tagged with a nullptr.
|
|
||||||
T* serialIterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConstIterator {
|
private:
|
||||||
public:
|
ConstStorageIterator storageIterator;
|
||||||
ConstIterator(ConstStorageIterator start);
|
const T* serialIterator;
|
||||||
ConstIterator& operator++();
|
};
|
||||||
|
|
||||||
bool operator==(const ConstIterator& other) const;
|
class BeginEnd {
|
||||||
bool operator!=(const ConstIterator& other) const;
|
public:
|
||||||
const T& operator*() const;
|
BeginEnd(StorageIterator start, StorageIterator end);
|
||||||
|
|
||||||
private:
|
Iterator begin() const;
|
||||||
ConstStorageIterator storageIterator;
|
Iterator end() const;
|
||||||
const T* serialIterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
class BeginEnd {
|
private:
|
||||||
public:
|
StorageIterator startIt;
|
||||||
BeginEnd(StorageIterator start, StorageIterator end);
|
StorageIterator endIt;
|
||||||
|
};
|
||||||
|
|
||||||
Iterator begin() const;
|
class ConstBeginEnd {
|
||||||
Iterator end() const;
|
public:
|
||||||
|
ConstBeginEnd(ConstStorageIterator start, ConstStorageIterator end);
|
||||||
|
|
||||||
private:
|
ConstIterator begin() const;
|
||||||
StorageIterator startIt;
|
ConstIterator end() const;
|
||||||
StorageIterator endIt;
|
|
||||||
};
|
|
||||||
|
|
||||||
class ConstBeginEnd {
|
private:
|
||||||
public:
|
ConstStorageIterator startIt;
|
||||||
ConstBeginEnd(ConstStorageIterator start, ConstStorageIterator end);
|
ConstStorageIterator endIt;
|
||||||
|
};
|
||||||
|
|
||||||
ConstIterator begin() const;
|
// The serial must be given in (not strictly) increasing order.
|
||||||
ConstIterator end() const;
|
void Enqueue(const T& value, Serial serial);
|
||||||
|
void Enqueue(T&& value, Serial serial);
|
||||||
|
void Enqueue(const std::vector<T>& values, Serial serial);
|
||||||
|
void Enqueue(std::vector<T>&& values, Serial serial);
|
||||||
|
|
||||||
private:
|
bool Empty() const;
|
||||||
ConstStorageIterator startIt;
|
|
||||||
ConstStorageIterator endIt;
|
|
||||||
};
|
|
||||||
|
|
||||||
// The serial must be given in (not strictly) increasing order.
|
// The UpTo variants of Iterate and Clear affect all values associated to a serial
|
||||||
void Enqueue(const T& value, Serial serial);
|
// that is smaller OR EQUAL to the given serial. Iterating is done like so:
|
||||||
void Enqueue(T&& value, Serial serial);
|
// for (const T& value : queue.IterateAll()) { stuff(T); }
|
||||||
void Enqueue(const std::vector<T>& values, Serial serial);
|
ConstBeginEnd IterateAll() const;
|
||||||
void Enqueue(std::vector<T>&& values, Serial serial);
|
ConstBeginEnd IterateUpTo(Serial serial) const;
|
||||||
|
BeginEnd IterateAll();
|
||||||
|
BeginEnd IterateUpTo(Serial serial);
|
||||||
|
|
||||||
bool Empty() const;
|
void Clear();
|
||||||
|
void ClearUpTo(Serial serial);
|
||||||
|
|
||||||
// The UpTo variants of Iterate and Clear affect all values associated to a serial
|
Serial FirstSerial() const;
|
||||||
// that is smaller OR EQUAL to the given serial. Iterating is done like so:
|
|
||||||
// for (const T& value : queue.IterateAll()) { stuff(T); }
|
|
||||||
ConstBeginEnd IterateAll() const;
|
|
||||||
ConstBeginEnd IterateUpTo(Serial serial) const;
|
|
||||||
BeginEnd IterateAll();
|
|
||||||
BeginEnd IterateUpTo(Serial serial);
|
|
||||||
|
|
||||||
void Clear();
|
private:
|
||||||
void ClearUpTo(Serial serial);
|
// Returns the first StorageIterator that a serial bigger than serial.
|
||||||
|
ConstStorageIterator FindUpTo(Serial serial) const;
|
||||||
|
StorageIterator FindUpTo(Serial serial);
|
||||||
|
Storage storage;
|
||||||
|
};
|
||||||
|
|
||||||
Serial FirstSerial() const;
|
// SerialQueue
|
||||||
|
|
||||||
private:
|
template<typename T>
|
||||||
// Returns the first StorageIterator that a serial bigger than serial.
|
void SerialQueue<T>::Enqueue(const T& value, Serial serial) {
|
||||||
ConstStorageIterator FindUpTo(Serial serial) const;
|
NXT_ASSERT(Empty() || storage.back().first <= serial);
|
||||||
StorageIterator FindUpTo(Serial serial);
|
|
||||||
Storage storage;
|
|
||||||
};
|
|
||||||
|
|
||||||
// SerialQueue
|
if (Empty() || storage.back().first < serial) {
|
||||||
|
storage.emplace_back(SerialPair(serial, {}));
|
||||||
|
}
|
||||||
|
storage.back().second.emplace_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void SerialQueue<T>::Enqueue(const T& value, Serial serial) {
|
void SerialQueue<T>::Enqueue(T&& value, Serial serial) {
|
||||||
ASSERT(Empty() || storage.back().first <= serial);
|
NXT_ASSERT(Empty() || storage.back().first <= serial);
|
||||||
|
|
||||||
if (Empty() || storage.back().first < serial) {
|
if (Empty() || storage.back().first < serial) {
|
||||||
storage.emplace_back(SerialPair(serial, {}));
|
storage.emplace_back(SerialPair(serial, {}));
|
||||||
}
|
}
|
||||||
storage.back().second.emplace_back(value);
|
storage.back().second.emplace_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void SerialQueue<T>::Enqueue(const std::vector<T>& values, Serial serial) {
|
||||||
|
NXT_ASSERT(values.size() > 0);
|
||||||
|
NXT_ASSERT(Empty() || storage.back().first <= serial);
|
||||||
|
storage.emplace_back(SerialPair(serial, {values}));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void SerialQueue<T>::Enqueue(std::vector<T>&& values, Serial serial) {
|
||||||
|
NXT_ASSERT(values.size() > 0);
|
||||||
|
NXT_ASSERT(Empty() || storage.back().first <= serial);
|
||||||
|
storage.emplace_back(SerialPair(serial, {values}));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool SerialQueue<T>::Empty() const {
|
||||||
|
return storage.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
typename SerialQueue<T>::ConstBeginEnd SerialQueue<T>::IterateAll() const {
|
||||||
|
return {storage.begin(), storage.end()};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
typename SerialQueue<T>::ConstBeginEnd SerialQueue<T>::IterateUpTo(Serial serial) const {
|
||||||
|
return {storage.begin(), FindUpTo(serial)};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
typename SerialQueue<T>::BeginEnd SerialQueue<T>::IterateAll() {
|
||||||
|
return {storage.begin(), storage.end()};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
typename SerialQueue<T>::BeginEnd SerialQueue<T>::IterateUpTo(Serial serial) {
|
||||||
|
return {storage.begin(), FindUpTo(serial)};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void SerialQueue<T>::Clear() {
|
||||||
|
storage.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void SerialQueue<T>::ClearUpTo(Serial serial) {
|
||||||
|
storage.erase(storage.begin(), FindUpTo(serial));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
Serial SerialQueue<T>::FirstSerial() const {
|
||||||
|
NXT_ASSERT(!Empty());
|
||||||
|
return storage.front().first;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
typename SerialQueue<T>::ConstStorageIterator SerialQueue<T>::FindUpTo(Serial serial) const {
|
||||||
|
auto it = storage.begin();
|
||||||
|
while (it != storage.end() && it->first <= serial) {
|
||||||
|
it ++;
|
||||||
|
}
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
typename SerialQueue<T>::StorageIterator SerialQueue<T>::FindUpTo(Serial serial) {
|
||||||
|
auto it = storage.begin();
|
||||||
|
while (it != storage.end() && it->first <= serial) {
|
||||||
|
it ++;
|
||||||
|
}
|
||||||
|
return it;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerialQueue::BeginEnd
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
SerialQueue<T>::BeginEnd::BeginEnd(typename SerialQueue<T>::StorageIterator start, typename SerialQueue<T>::StorageIterator end)
|
||||||
|
: startIt(start), endIt(end) {
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
typename SerialQueue<T>::Iterator SerialQueue<T>::BeginEnd::begin() const {
|
||||||
|
return {startIt};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
typename SerialQueue<T>::Iterator SerialQueue<T>::BeginEnd::end() const {
|
||||||
|
return {endIt};
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerialQueue::Iterator
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
SerialQueue<T>::Iterator::Iterator(typename SerialQueue<T>::StorageIterator start)
|
||||||
|
: storageIterator(start), serialIterator(nullptr) {
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
typename SerialQueue<T>::Iterator& SerialQueue<T>::Iterator::operator++() {
|
||||||
|
T* vectorData = storageIterator->second.data();
|
||||||
|
|
||||||
|
if (serialIterator == nullptr) {
|
||||||
|
serialIterator = vectorData + 1;
|
||||||
|
} else {
|
||||||
|
serialIterator ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
if (serialIterator >= vectorData + storageIterator->second.size()) {
|
||||||
void SerialQueue<T>::Enqueue(T&& value, Serial serial) {
|
serialIterator = nullptr;
|
||||||
ASSERT(Empty() || storage.back().first <= serial);
|
storageIterator ++;
|
||||||
|
|
||||||
if (Empty() || storage.back().first < serial) {
|
|
||||||
storage.emplace_back(SerialPair(serial, {}));
|
|
||||||
}
|
|
||||||
storage.back().second.emplace_back(value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
return *this;
|
||||||
void SerialQueue<T>::Enqueue(const std::vector<T>& values, Serial serial) {
|
}
|
||||||
ASSERT(values.size() > 0);
|
|
||||||
ASSERT(Empty() || storage.back().first <= serial);
|
template<typename T>
|
||||||
storage.emplace_back(SerialPair(serial, {values}));
|
bool SerialQueue<T>::Iterator::operator==(const typename SerialQueue<T>::Iterator& other) const {
|
||||||
|
return other.storageIterator == storageIterator && other.serialIterator == serialIterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
bool SerialQueue<T>::Iterator::operator!=(const typename SerialQueue<T>::Iterator& other) const {
|
||||||
|
return !(*this == other);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T& SerialQueue<T>::Iterator::operator*() const {
|
||||||
|
if (serialIterator == nullptr) {
|
||||||
|
return *storageIterator->second.begin();
|
||||||
|
}
|
||||||
|
return *serialIterator;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerialQueue::ConstBeginEnd
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
SerialQueue<T>::ConstBeginEnd::ConstBeginEnd(typename SerialQueue<T>::ConstStorageIterator start, typename SerialQueue<T>::ConstStorageIterator end)
|
||||||
|
: startIt(start), endIt(end) {
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
typename SerialQueue<T>::ConstIterator SerialQueue<T>::ConstBeginEnd::begin() const {
|
||||||
|
return {startIt};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
typename SerialQueue<T>::ConstIterator SerialQueue<T>::ConstBeginEnd::end() const {
|
||||||
|
return {endIt};
|
||||||
|
}
|
||||||
|
|
||||||
|
// SerialQueue::ConstIterator
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
SerialQueue<T>::ConstIterator::ConstIterator(typename SerialQueue<T>::ConstStorageIterator start)
|
||||||
|
: storageIterator(start), serialIterator(nullptr) {
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
typename SerialQueue<T>::ConstIterator& SerialQueue<T>::ConstIterator::operator++() {
|
||||||
|
const T* vectorData = storageIterator->second.data();
|
||||||
|
|
||||||
|
if (serialIterator == nullptr) {
|
||||||
|
serialIterator = vectorData + 1;
|
||||||
|
} else {
|
||||||
|
serialIterator ++;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
if (serialIterator >= vectorData + storageIterator->second.size()) {
|
||||||
void SerialQueue<T>::Enqueue(std::vector<T>&& values, Serial serial) {
|
serialIterator = nullptr;
|
||||||
ASSERT(values.size() > 0);
|
storageIterator ++;
|
||||||
ASSERT(Empty() || storage.back().first <= serial);
|
|
||||||
storage.emplace_back(SerialPair(serial, {values}));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
return *this;
|
||||||
bool SerialQueue<T>::Empty() const {
|
}
|
||||||
return storage.empty();
|
|
||||||
}
|
template<typename T>
|
||||||
|
bool SerialQueue<T>::ConstIterator::operator==(const typename SerialQueue<T>::ConstIterator& other) const {
|
||||||
template<typename T>
|
return other.storageIterator == storageIterator && other.serialIterator == serialIterator;
|
||||||
typename SerialQueue<T>::ConstBeginEnd SerialQueue<T>::IterateAll() const {
|
}
|
||||||
return {storage.begin(), storage.end()};
|
|
||||||
}
|
template<typename T>
|
||||||
|
bool SerialQueue<T>::ConstIterator::operator!=(const typename SerialQueue<T>::ConstIterator& other) const {
|
||||||
template<typename T>
|
return !(*this == other);
|
||||||
typename SerialQueue<T>::ConstBeginEnd SerialQueue<T>::IterateUpTo(Serial serial) const {
|
}
|
||||||
return {storage.begin(), FindUpTo(serial)};
|
|
||||||
}
|
template<typename T>
|
||||||
|
const T& SerialQueue<T>::ConstIterator::operator*() const {
|
||||||
template<typename T>
|
if (serialIterator == nullptr) {
|
||||||
typename SerialQueue<T>::BeginEnd SerialQueue<T>::IterateAll() {
|
return *storageIterator->second.begin();
|
||||||
return {storage.begin(), storage.end()};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
typename SerialQueue<T>::BeginEnd SerialQueue<T>::IterateUpTo(Serial serial) {
|
|
||||||
return {storage.begin(), FindUpTo(serial)};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void SerialQueue<T>::Clear() {
|
|
||||||
storage.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
void SerialQueue<T>::ClearUpTo(Serial serial) {
|
|
||||||
storage.erase(storage.begin(), FindUpTo(serial));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
Serial SerialQueue<T>::FirstSerial() const {
|
|
||||||
ASSERT(!Empty());
|
|
||||||
return storage.front().first;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
typename SerialQueue<T>::ConstStorageIterator SerialQueue<T>::FindUpTo(Serial serial) const {
|
|
||||||
auto it = storage.begin();
|
|
||||||
while (it != storage.end() && it->first <= serial) {
|
|
||||||
it ++;
|
|
||||||
}
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
typename SerialQueue<T>::StorageIterator SerialQueue<T>::FindUpTo(Serial serial) {
|
|
||||||
auto it = storage.begin();
|
|
||||||
while (it != storage.end() && it->first <= serial) {
|
|
||||||
it ++;
|
|
||||||
}
|
|
||||||
return it;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SerialQueue::BeginEnd
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
SerialQueue<T>::BeginEnd::BeginEnd(typename SerialQueue<T>::StorageIterator start, typename SerialQueue<T>::StorageIterator end)
|
|
||||||
: startIt(start), endIt(end) {
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
typename SerialQueue<T>::Iterator SerialQueue<T>::BeginEnd::begin() const {
|
|
||||||
return {startIt};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
typename SerialQueue<T>::Iterator SerialQueue<T>::BeginEnd::end() const {
|
|
||||||
return {endIt};
|
|
||||||
}
|
|
||||||
|
|
||||||
// SerialQueue::Iterator
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
SerialQueue<T>::Iterator::Iterator(typename SerialQueue<T>::StorageIterator start)
|
|
||||||
: storageIterator(start), serialIterator(nullptr) {
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
typename SerialQueue<T>::Iterator& SerialQueue<T>::Iterator::operator++() {
|
|
||||||
T* vectorData = storageIterator->second.data();
|
|
||||||
|
|
||||||
if (serialIterator == nullptr) {
|
|
||||||
serialIterator = vectorData + 1;
|
|
||||||
} else {
|
|
||||||
serialIterator ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serialIterator >= vectorData + storageIterator->second.size()) {
|
|
||||||
serialIterator = nullptr;
|
|
||||||
storageIterator ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool SerialQueue<T>::Iterator::operator==(const typename SerialQueue<T>::Iterator& other) const {
|
|
||||||
return other.storageIterator == storageIterator && other.serialIterator == serialIterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool SerialQueue<T>::Iterator::operator!=(const typename SerialQueue<T>::Iterator& other) const {
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
T& SerialQueue<T>::Iterator::operator*() const {
|
|
||||||
if (serialIterator == nullptr) {
|
|
||||||
return *storageIterator->second.begin();
|
|
||||||
}
|
|
||||||
return *serialIterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
// SerialQueue::ConstBeginEnd
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
SerialQueue<T>::ConstBeginEnd::ConstBeginEnd(typename SerialQueue<T>::ConstStorageIterator start, typename SerialQueue<T>::ConstStorageIterator end)
|
|
||||||
: startIt(start), endIt(end) {
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
typename SerialQueue<T>::ConstIterator SerialQueue<T>::ConstBeginEnd::begin() const {
|
|
||||||
return {startIt};
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
typename SerialQueue<T>::ConstIterator SerialQueue<T>::ConstBeginEnd::end() const {
|
|
||||||
return {endIt};
|
|
||||||
}
|
|
||||||
|
|
||||||
// SerialQueue::ConstIterator
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
SerialQueue<T>::ConstIterator::ConstIterator(typename SerialQueue<T>::ConstStorageIterator start)
|
|
||||||
: storageIterator(start), serialIterator(nullptr) {
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
typename SerialQueue<T>::ConstIterator& SerialQueue<T>::ConstIterator::operator++() {
|
|
||||||
const T* vectorData = storageIterator->second.data();
|
|
||||||
|
|
||||||
if (serialIterator == nullptr) {
|
|
||||||
serialIterator = vectorData + 1;
|
|
||||||
} else {
|
|
||||||
serialIterator ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (serialIterator >= vectorData + storageIterator->second.size()) {
|
|
||||||
serialIterator = nullptr;
|
|
||||||
storageIterator ++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool SerialQueue<T>::ConstIterator::operator==(const typename SerialQueue<T>::ConstIterator& other) const {
|
|
||||||
return other.storageIterator == storageIterator && other.serialIterator == serialIterator;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
bool SerialQueue<T>::ConstIterator::operator!=(const typename SerialQueue<T>::ConstIterator& other) const {
|
|
||||||
return !(*this == other);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
const T& SerialQueue<T>::ConstIterator::operator*() const {
|
|
||||||
if (serialIterator == nullptr) {
|
|
||||||
return *storageIterator->second.begin();
|
|
||||||
}
|
|
||||||
return *serialIterator;
|
|
||||||
}
|
}
|
||||||
|
return *serialIterator;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // COMMON_SERIALQUEUE_H_
|
#endif // COMMON_SERIALQUEUE_H_
|
||||||
|
@ -14,13 +14,11 @@
|
|||||||
|
|
||||||
#include "tests/NXTTest.h"
|
#include "tests/NXTTest.h"
|
||||||
|
|
||||||
|
#include "common/Assert.h"
|
||||||
#include "utils/BackendBinding.h"
|
#include "utils/BackendBinding.h"
|
||||||
|
|
||||||
#include "GLFW/glfw3.h"
|
#include "GLFW/glfw3.h"
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#define ASSERT assert
|
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
utils::BackendType ParamToBackendType(BackendType type) {
|
utils::BackendType ParamToBackendType(BackendType type) {
|
||||||
@ -34,7 +32,7 @@ namespace {
|
|||||||
case VulkanBackend:
|
case VulkanBackend:
|
||||||
return utils::BackendType::Vulkan;
|
return utils::BackendType::Vulkan;
|
||||||
default:
|
default:
|
||||||
ASSERT(false);
|
NXT_ASSERT(false);
|
||||||
return utils::BackendType::Null;
|
return utils::BackendType::Null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -50,7 +48,7 @@ namespace {
|
|||||||
case VulkanBackend:
|
case VulkanBackend:
|
||||||
return "Vulkan";
|
return "Vulkan";
|
||||||
default:
|
default:
|
||||||
ASSERT(false);
|
NXT_ASSERT(false);
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -107,10 +105,10 @@ NXTTest::~NXTTest() {
|
|||||||
|
|
||||||
void NXTTest::SetUp() {
|
void NXTTest::SetUp() {
|
||||||
binding = utils::CreateBinding(ParamToBackendType(GetParam()));
|
binding = utils::CreateBinding(ParamToBackendType(GetParam()));
|
||||||
ASSERT(binding != nullptr);
|
NXT_ASSERT(binding != nullptr);
|
||||||
|
|
||||||
GLFWwindow* testWindow = GetWindowForBackend(binding, GetParam());
|
GLFWwindow* testWindow = GetWindowForBackend(binding, GetParam());
|
||||||
ASSERT(testWindow != nullptr);
|
NXT_ASSERT(testWindow != nullptr);
|
||||||
|
|
||||||
binding->SetWindow(testWindow);
|
binding->SetWindow(testWindow);
|
||||||
|
|
||||||
@ -231,7 +229,7 @@ void NXTTest::MapSlotsSynchronously() {
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
void NXTTest::SlotMapReadCallback(nxtBufferMapReadStatus status, const void* data, nxtCallbackUserdata userdata_) {
|
void NXTTest::SlotMapReadCallback(nxtBufferMapReadStatus status, const void* data, nxtCallbackUserdata userdata_) {
|
||||||
ASSERT(status == NXT_BUFFER_MAP_READ_STATUS_SUCCESS);
|
NXT_ASSERT(status == NXT_BUFFER_MAP_READ_STATUS_SUCCESS);
|
||||||
|
|
||||||
auto userdata = reinterpret_cast<MapReadUserdata*>(static_cast<uintptr_t>(userdata_));
|
auto userdata = reinterpret_cast<MapReadUserdata*>(static_cast<uintptr_t>(userdata_));
|
||||||
userdata->test->readbackSlots[userdata->slot].mappedData = data;
|
userdata->test->readbackSlots[userdata->slot].mappedData = data;
|
||||||
@ -242,7 +240,7 @@ void NXTTest::SlotMapReadCallback(nxtBufferMapReadStatus status, const void* dat
|
|||||||
|
|
||||||
void NXTTest::ResolveExpectations() {
|
void NXTTest::ResolveExpectations() {
|
||||||
for(const auto& expectation : deferredExpectations) {
|
for(const auto& expectation : deferredExpectations) {
|
||||||
ASSERT(readbackSlots[expectation.readbackSlot].mappedData != nullptr);
|
NXT_ASSERT(readbackSlots[expectation.readbackSlot].mappedData != nullptr);
|
||||||
|
|
||||||
// Get a pointer to the mapped copy of the data for the expectation.
|
// Get a pointer to the mapped copy of the data for the expectation.
|
||||||
const char* data = reinterpret_cast<const char*>(readbackSlots[expectation.readbackSlot].mappedData);
|
const char* data = reinterpret_cast<const char*>(readbackSlots[expectation.readbackSlot].mappedData);
|
||||||
@ -314,7 +312,7 @@ namespace detail {
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
testing::AssertionResult ExpectEq<T>::Check(const void* data, size_t size) {
|
testing::AssertionResult ExpectEq<T>::Check(const void* data, size_t size) {
|
||||||
ASSERT(size == sizeof(T) * expected.size());
|
NXT_ASSERT(size == sizeof(T) * expected.size());
|
||||||
|
|
||||||
const T* actual = reinterpret_cast<const T*>(data);
|
const T* actual = reinterpret_cast<const T*>(data);
|
||||||
for (size_t i = 0; i < expected.size(); ++i) {
|
for (size_t i = 0; i < expected.size(); ++i) {
|
||||||
|
@ -18,8 +18,6 @@
|
|||||||
|
|
||||||
// This is ANGLE's BitSetIterator_unittests.cpp file.
|
// This is ANGLE's BitSetIterator_unittests.cpp file.
|
||||||
|
|
||||||
using namespace backend;
|
|
||||||
|
|
||||||
class BitSetIteratorTest : public testing::Test {
|
class BitSetIteratorTest : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
std::bitset<40> mStateBits;
|
std::bitset<40> mStateBits;
|
||||||
|
@ -16,8 +16,6 @@
|
|||||||
|
|
||||||
#include "common/Math.h"
|
#include "common/Math.h"
|
||||||
|
|
||||||
using namespace backend;
|
|
||||||
|
|
||||||
// Tests for ScanForward
|
// Tests for ScanForward
|
||||||
TEST(Math, ScanForward) {
|
TEST(Math, ScanForward) {
|
||||||
// Test extrema
|
// Test extrema
|
||||||
|
@ -16,11 +16,11 @@
|
|||||||
|
|
||||||
#include "common/SerialQueue.h"
|
#include "common/SerialQueue.h"
|
||||||
|
|
||||||
using SerialQueue = backend::SerialQueue<int>;
|
using TestSerialQueue = SerialQueue<int>;
|
||||||
|
|
||||||
// A number of basic tests for SerialQueue that are difficult to split from one another
|
// A number of basic tests for SerialQueue that are difficult to split from one another
|
||||||
TEST(SerialQueue, BasicTest) {
|
TEST(SerialQueue, BasicTest) {
|
||||||
SerialQueue queue;
|
TestSerialQueue queue;
|
||||||
|
|
||||||
// Queue starts empty
|
// Queue starts empty
|
||||||
ASSERT_TRUE(queue.Empty());
|
ASSERT_TRUE(queue.Empty());
|
||||||
@ -57,7 +57,7 @@ TEST(SerialQueue, BasicTest) {
|
|||||||
|
|
||||||
// Test enqueuing vectors works
|
// Test enqueuing vectors works
|
||||||
TEST(SerialQueue, EnqueueVectors) {
|
TEST(SerialQueue, EnqueueVectors) {
|
||||||
SerialQueue queue;
|
TestSerialQueue queue;
|
||||||
|
|
||||||
std::vector<int> vector1 = {1, 2, 3, 4};
|
std::vector<int> vector1 = {1, 2, 3, 4};
|
||||||
std::vector<int> vector2 = {5, 6, 7, 8};
|
std::vector<int> vector2 = {5, 6, 7, 8};
|
||||||
@ -78,7 +78,7 @@ TEST(SerialQueue, EnqueueVectors) {
|
|||||||
|
|
||||||
// Test IterateUpTo
|
// Test IterateUpTo
|
||||||
TEST(SerialQueue, IterateUpTo) {
|
TEST(SerialQueue, IterateUpTo) {
|
||||||
SerialQueue queue;
|
TestSerialQueue queue;
|
||||||
|
|
||||||
std::vector<int> vector1 = {1, 2, 3, 4};
|
std::vector<int> vector1 = {1, 2, 3, 4};
|
||||||
std::vector<int> vector2 = {5, 6, 7, 8};
|
std::vector<int> vector2 = {5, 6, 7, 8};
|
||||||
@ -99,7 +99,7 @@ TEST(SerialQueue, IterateUpTo) {
|
|||||||
|
|
||||||
// Test ClearUpTo
|
// Test ClearUpTo
|
||||||
TEST(SerialQueue, ClearUpTo) {
|
TEST(SerialQueue, ClearUpTo) {
|
||||||
SerialQueue queue;
|
TestSerialQueue queue;
|
||||||
|
|
||||||
std::vector<int> vector1 = {1, 2, 3, 4};
|
std::vector<int> vector1 = {1, 2, 3, 4};
|
||||||
std::vector<int> vector2 = {5, 6, 7, 8};
|
std::vector<int> vector2 = {5, 6, 7, 8};
|
||||||
@ -122,7 +122,7 @@ TEST(SerialQueue, ClearUpTo) {
|
|||||||
|
|
||||||
// Test FirstSerial
|
// Test FirstSerial
|
||||||
TEST(SerialQueue, FirstSerial) {
|
TEST(SerialQueue, FirstSerial) {
|
||||||
SerialQueue queue;
|
TestSerialQueue queue;
|
||||||
|
|
||||||
std::vector<int> vector1 = {1, 2, 3, 4};
|
std::vector<int> vector1 = {1, 2, 3, 4};
|
||||||
std::vector<int> vector2 = {5, 6, 7, 8};
|
std::vector<int> vector2 = {5, 6, 7, 8};
|
||||||
|
@ -14,18 +14,17 @@
|
|||||||
|
|
||||||
#include "utils/BackendBinding.h"
|
#include "utils/BackendBinding.h"
|
||||||
|
|
||||||
|
#include "common/Assert.h"
|
||||||
|
|
||||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||||
#include "GLFW/glfw3.h"
|
#include "GLFW/glfw3.h"
|
||||||
#include "GLFW/glfw3native.h"
|
#include "GLFW/glfw3native.h"
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <wrl.h>
|
#include <wrl.h>
|
||||||
#include <d3d12.h>
|
#include <d3d12.h>
|
||||||
#include <dxgi1_4.h>
|
#include <dxgi1_4.h>
|
||||||
|
|
||||||
#define ASSERT assert
|
|
||||||
|
|
||||||
using Microsoft::WRL::ComPtr;
|
using Microsoft::WRL::ComPtr;
|
||||||
|
|
||||||
namespace backend {
|
namespace backend {
|
||||||
@ -229,7 +228,7 @@ namespace utils {
|
|||||||
ComPtr<ID3D12GraphicsCommandList> commandList;
|
ComPtr<ID3D12GraphicsCommandList> commandList;
|
||||||
|
|
||||||
static void ASSERT_SUCCESS(HRESULT hr) {
|
static void ASSERT_SUCCESS(HRESULT hr) {
|
||||||
assert(SUCCEEDED(hr));
|
ASSERT(SUCCEEDED(hr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool GetHardwareAdapter(IDXGIFactory4* factory, IDXGIAdapter1** hardwareAdapter) {
|
static bool GetHardwareAdapter(IDXGIFactory4* factory, IDXGIAdapter1** hardwareAdapter) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user