mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-12-16 00:17:03 +00:00
Format: src/{common, utils, wire}
This commit is contained in:
committed by
Corentin Wallez
parent
a351ce9618
commit
9d01c6c26d
@@ -16,7 +16,11 @@
|
||||
|
||||
#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;
|
||||
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();
|
||||
}
|
||||
|
||||
@@ -17,63 +17,64 @@
|
||||
|
||||
#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.
|
||||
|
||||
/*
|
||||
* 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.
|
||||
// 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(NXT_COMPILER_MSVC)
|
||||
#define NXT_ASSERT_LOOP_CONDITION (0,0)
|
||||
# define NXT_ASSERT_LOOP_CONDITION (0, 0)
|
||||
#else
|
||||
#define NXT_ASSERT_LOOP_CONDITION (0)
|
||||
# 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.
|
||||
// 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)) { \
|
||||
# define NXT_ASSERT_CALLSITE_HELPER(file, func, line, condition) \
|
||||
do { \
|
||||
if (!(condition)) { \
|
||||
HandleAssertionFailure(file, func, line, #condition); \
|
||||
} \
|
||||
} while(NXT_ASSERT_LOOP_CONDITION)
|
||||
} \
|
||||
} while (NXT_ASSERT_LOOP_CONDITION)
|
||||
#else
|
||||
#if defined(NXT_COMPILER_MSVC)
|
||||
#define NXT_ASSERT_CALLSITE_HELPER(file, func, line, condition) \
|
||||
__assume(condition)
|
||||
#elif defined(NXT_COMPILER_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
|
||||
# if defined(NXT_COMPILER_MSVC)
|
||||
# define NXT_ASSERT_CALLSITE_HELPER(file, func, line, condition) __assume(condition)
|
||||
# elif defined(NXT_COMPILER_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)
|
||||
#define NXT_UNREACHABLE() \
|
||||
do { \
|
||||
NXT_ASSERT(NXT_ASSERT_LOOP_CONDITION && "Unreachable code hit"); NXT_BUILTIN_UNREACHABLE(); \
|
||||
} while(NXT_ASSERT_LOOP_CONDITION)
|
||||
#define NXT_UNREACHABLE() \
|
||||
do { \
|
||||
NXT_ASSERT(NXT_ASSERT_LOOP_CONDITION && "Unreachable code hit"); \
|
||||
NXT_BUILTIN_UNREACHABLE(); \
|
||||
} while (NXT_ASSERT_LOOP_CONDITION)
|
||||
|
||||
#if !defined(NXT_SKIP_ASSERT_SHORTHANDS)
|
||||
#define ASSERT NXT_ASSERT
|
||||
#define UNREACHABLE NXT_UNREACHABLE
|
||||
# define ASSERT NXT_ASSERT
|
||||
# define UNREACHABLE NXT_UNREACHABLE
|
||||
#endif
|
||||
|
||||
#endif // COMMON_ASSERT_H_
|
||||
void HandleAssertionFailure(const char* file,
|
||||
const char* function,
|
||||
int line,
|
||||
const char* condition);
|
||||
|
||||
#endif // COMMON_ASSERT_H_
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <bitset>
|
||||
#include <limits>
|
||||
|
||||
|
||||
// This is ANGLE's BitSetIterator class with a customizable return type
|
||||
// TODO(cwallez@chromium.org): it could be optimized, in particular when N <= 64
|
||||
|
||||
@@ -33,44 +32,48 @@ T roundUp(const T value, const T alignment) {
|
||||
|
||||
template <size_t N, typename T>
|
||||
class BitSetIterator final {
|
||||
public:
|
||||
BitSetIterator(const std::bitset<N>& bitset);
|
||||
BitSetIterator(const BitSetIterator& other);
|
||||
BitSetIterator &operator=(const BitSetIterator& other);
|
||||
public:
|
||||
BitSetIterator(const std::bitset<N>& bitset);
|
||||
BitSetIterator(const BitSetIterator& other);
|
||||
BitSetIterator& operator=(const BitSetIterator& other);
|
||||
|
||||
class Iterator final {
|
||||
public:
|
||||
Iterator(const std::bitset<N>& bits);
|
||||
Iterator& operator++();
|
||||
class Iterator final {
|
||||
public:
|
||||
Iterator(const std::bitset<N>& bits);
|
||||
Iterator& operator++();
|
||||
|
||||
bool operator==(const Iterator& other) const;
|
||||
bool operator!=(const Iterator& other) const;
|
||||
T operator*() const { return static_cast<T>(mCurrentBit); }
|
||||
bool operator==(const Iterator& other) const;
|
||||
bool operator!=(const Iterator& other) const;
|
||||
T operator*() const {
|
||||
return static_cast<T>(mCurrentBit);
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned long getNextBit();
|
||||
private:
|
||||
unsigned long getNextBit();
|
||||
|
||||
static const size_t BitsPerWord = sizeof(uint32_t) * 8;
|
||||
std::bitset<N> mBits;
|
||||
unsigned long mCurrentBit;
|
||||
unsigned long mOffset;
|
||||
};
|
||||
static const size_t BitsPerWord = sizeof(uint32_t) * 8;
|
||||
std::bitset<N> mBits;
|
||||
unsigned long mCurrentBit;
|
||||
unsigned long mOffset;
|
||||
};
|
||||
|
||||
Iterator begin() const { return Iterator(mBits); }
|
||||
Iterator end() const { return Iterator(std::bitset<N>(0)); }
|
||||
Iterator begin() const {
|
||||
return Iterator(mBits);
|
||||
}
|
||||
Iterator end() const {
|
||||
return Iterator(std::bitset<N>(0));
|
||||
}
|
||||
|
||||
private:
|
||||
const std::bitset<N> mBits;
|
||||
private:
|
||||
const std::bitset<N> mBits;
|
||||
};
|
||||
|
||||
template <size_t N, typename T>
|
||||
BitSetIterator<N, T>::BitSetIterator(const std::bitset<N>& bitset)
|
||||
: mBits(bitset) {
|
||||
BitSetIterator<N, T>::BitSetIterator(const std::bitset<N>& bitset) : mBits(bitset) {
|
||||
}
|
||||
|
||||
template <size_t N, typename T>
|
||||
BitSetIterator<N, T>::BitSetIterator(const BitSetIterator& other)
|
||||
: mBits(other.mBits) {
|
||||
BitSetIterator<N, T>::BitSetIterator(const BitSetIterator& other) : mBits(other.mBits) {
|
||||
}
|
||||
|
||||
template <size_t N, typename T>
|
||||
|
||||
@@ -21,32 +21,32 @@
|
||||
// - NXT_BUILTIN_UNREACHABLE(): Hints the compiler that a code path is unreachable
|
||||
|
||||
// Clang and GCC
|
||||
#ifdef __GNUC__
|
||||
#if defined(__clang__)
|
||||
#define NXT_COMPILER_CLANG
|
||||
#else
|
||||
#define NXT_COMPILER_GCC
|
||||
#endif
|
||||
#if defined(__GNUC__)
|
||||
# if defined(__clang__)
|
||||
# define NXT_COMPILER_CLANG
|
||||
# else
|
||||
# define NXT_COMPILER_GCC
|
||||
# endif
|
||||
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#define NXT_BREAKPOINT() __asm__ __volatile__("int $3\n\t")
|
||||
#else
|
||||
#error "Implement BREAKPOINT on your platform"
|
||||
#endif
|
||||
# if defined(__i386__) || defined(__x86_64__)
|
||||
# define NXT_BREAKPOINT() __asm__ __volatile__("int $3\n\t")
|
||||
# else
|
||||
# error "Implement BREAKPOINT on your platform"
|
||||
# endif
|
||||
|
||||
#define NXT_BUILTIN_UNREACHABLE() __builtin_unreachable()
|
||||
# define NXT_BUILTIN_UNREACHABLE() __builtin_unreachable()
|
||||
|
||||
// MSVC
|
||||
#elif defined(_MSC_VER)
|
||||
#define NXT_COMPILER_MSVC
|
||||
# define NXT_COMPILER_MSVC
|
||||
|
||||
extern void __cdecl __debugbreak(void);
|
||||
#define NXT_BREAKPOINT() __debugbreak()
|
||||
extern void __cdecl __debugbreak(void);
|
||||
# define NXT_BREAKPOINT() __debugbreak()
|
||||
|
||||
#define NXT_BUILTIN_UNREACHABLE() __assume(false)
|
||||
# define NXT_BUILTIN_UNREACHABLE() __assume(false)
|
||||
|
||||
#else
|
||||
#error "Unsupported compiler"
|
||||
# error "Unsupported compiler"
|
||||
#endif
|
||||
|
||||
#endif // COMMON_COMPILER_H_
|
||||
#endif // COMMON_COMPILER_H_
|
||||
|
||||
@@ -19,11 +19,12 @@
|
||||
|
||||
static constexpr uint32_t kMaxPushConstants = 32u;
|
||||
static constexpr uint32_t kMaxBindGroups = 4u;
|
||||
static constexpr uint32_t kMaxBindingsPerGroup = 16u; // TODO(cwallez@chromium.org): investigate bindgroup limits
|
||||
// TODO(cwallez@chromium.org): investigate bindgroup limits
|
||||
static constexpr uint32_t kMaxBindingsPerGroup = 16u;
|
||||
static constexpr uint32_t kMaxVertexAttributes = 16u;
|
||||
static constexpr uint32_t kMaxVertexInputs = 16u;
|
||||
static constexpr uint32_t kNumStages = 3;
|
||||
static constexpr uint32_t kMaxColorAttachments = 4u;
|
||||
static constexpr uint32_t kTextureRowPitchAlignment = 256u;
|
||||
|
||||
#endif // COMMON_CONSTANTS_H_
|
||||
#endif // COMMON_CONSTANTS_H_
|
||||
|
||||
@@ -17,11 +17,11 @@
|
||||
#include "common/Platform.h"
|
||||
|
||||
#if NXT_PLATFORM_WINDOWS
|
||||
#include <windows.h>
|
||||
# include <windows.h>
|
||||
#elif NXT_PLATFORM_POSIX
|
||||
#include <dlfcn.h>
|
||||
# include <dlfcn.h>
|
||||
#else
|
||||
#error "Unsupported platform for DynamicLib"
|
||||
# error "Unsupported platform for DynamicLib"
|
||||
#endif
|
||||
|
||||
DynamicLib::~DynamicLib() {
|
||||
@@ -42,21 +42,21 @@ bool DynamicLib::Valid() const {
|
||||
}
|
||||
|
||||
bool DynamicLib::Open(const std::string& filename, std::string* error) {
|
||||
#if NXT_PLATFORM_WINDOWS
|
||||
mHandle = LoadLibraryA(filename.c_str());
|
||||
#if NXT_PLATFORM_WINDOWS
|
||||
mHandle = LoadLibraryA(filename.c_str());
|
||||
|
||||
if (mHandle == nullptr && error != nullptr) {
|
||||
*error = "Windows Error: " + std::to_string(GetLastError());
|
||||
}
|
||||
#elif NXT_PLATFORM_POSIX
|
||||
mHandle = dlopen(filename.c_str(), RTLD_NOW);
|
||||
if (mHandle == nullptr && error != nullptr) {
|
||||
*error = "Windows Error: " + std::to_string(GetLastError());
|
||||
}
|
||||
#elif NXT_PLATFORM_POSIX
|
||||
mHandle = dlopen(filename.c_str(), RTLD_NOW);
|
||||
|
||||
if (mHandle == nullptr && error != nullptr) {
|
||||
*error = dlerror();
|
||||
}
|
||||
#else
|
||||
#error "Unsupported platform for DynamicLib"
|
||||
#endif
|
||||
if (mHandle == nullptr && error != nullptr) {
|
||||
*error = dlerror();
|
||||
}
|
||||
#else
|
||||
# error "Unsupported platform for DynamicLib"
|
||||
#endif
|
||||
|
||||
return mHandle != nullptr;
|
||||
}
|
||||
@@ -66,13 +66,13 @@ void DynamicLib::Close() {
|
||||
return;
|
||||
}
|
||||
|
||||
#if NXT_PLATFORM_WINDOWS
|
||||
FreeLibrary(static_cast<HMODULE>(mHandle));
|
||||
#elif NXT_PLATFORM_POSIX
|
||||
dlclose(mHandle);
|
||||
#else
|
||||
#error "Unsupported platform for DynamicLib"
|
||||
#endif
|
||||
#if NXT_PLATFORM_WINDOWS
|
||||
FreeLibrary(static_cast<HMODULE>(mHandle));
|
||||
#elif NXT_PLATFORM_POSIX
|
||||
dlclose(mHandle);
|
||||
#else
|
||||
# error "Unsupported platform for DynamicLib"
|
||||
#endif
|
||||
|
||||
mHandle = nullptr;
|
||||
}
|
||||
@@ -80,21 +80,21 @@ void DynamicLib::Close() {
|
||||
void* DynamicLib::GetProc(const std::string& procName, std::string* error) const {
|
||||
void* proc = nullptr;
|
||||
|
||||
#if NXT_PLATFORM_WINDOWS
|
||||
proc = reinterpret_cast<void*>(GetProcAddress(static_cast<HMODULE>(mHandle), procName.c_str()));
|
||||
#if NXT_PLATFORM_WINDOWS
|
||||
proc = reinterpret_cast<void*>(GetProcAddress(static_cast<HMODULE>(mHandle), procName.c_str()));
|
||||
|
||||
if (proc == nullptr && error != nullptr) {
|
||||
*error = "Windows Error: " + std::to_string(GetLastError());
|
||||
}
|
||||
#elif NXT_PLATFORM_POSIX
|
||||
proc = reinterpret_cast<void*>(dlsym(mHandle, procName.c_str()));
|
||||
if (proc == nullptr && error != nullptr) {
|
||||
*error = "Windows Error: " + std::to_string(GetLastError());
|
||||
}
|
||||
#elif NXT_PLATFORM_POSIX
|
||||
proc = reinterpret_cast<void*>(dlsym(mHandle, procName.c_str()));
|
||||
|
||||
if (proc == nullptr && error != nullptr) {
|
||||
*error = dlerror();
|
||||
}
|
||||
#else
|
||||
#error "Unsupported platform for DynamicLib"
|
||||
#endif
|
||||
if (proc == nullptr && error != nullptr) {
|
||||
*error = dlerror();
|
||||
}
|
||||
#else
|
||||
# error "Unsupported platform for DynamicLib"
|
||||
#endif
|
||||
|
||||
return proc;
|
||||
}
|
||||
|
||||
@@ -21,34 +21,34 @@
|
||||
#include <type_traits>
|
||||
|
||||
class DynamicLib {
|
||||
public:
|
||||
DynamicLib() = default;
|
||||
~DynamicLib();
|
||||
public:
|
||||
DynamicLib() = default;
|
||||
~DynamicLib();
|
||||
|
||||
DynamicLib(const DynamicLib&) = delete;
|
||||
DynamicLib& operator=(const DynamicLib&) = delete;
|
||||
DynamicLib(const DynamicLib&) = delete;
|
||||
DynamicLib& operator=(const DynamicLib&) = delete;
|
||||
|
||||
DynamicLib(DynamicLib&& other);
|
||||
DynamicLib& operator=(DynamicLib&& other);
|
||||
DynamicLib(DynamicLib&& other);
|
||||
DynamicLib& operator=(DynamicLib&& other);
|
||||
|
||||
bool Valid() const;
|
||||
bool Valid() const;
|
||||
|
||||
bool Open(const std::string& filename, std::string* error = nullptr);
|
||||
void Close();
|
||||
bool Open(const std::string& filename, std::string* error = nullptr);
|
||||
void Close();
|
||||
|
||||
void* GetProc(const std::string& procName, std::string* error = nullptr) const;
|
||||
void* GetProc(const std::string& procName, std::string* error = nullptr) const;
|
||||
|
||||
template<typename T>
|
||||
bool GetProc(T** proc, const std::string& procName, std::string* error = nullptr) const {
|
||||
ASSERT(proc != nullptr);
|
||||
static_assert(std::is_function<T>::value, "");
|
||||
template <typename T>
|
||||
bool GetProc(T** proc, const std::string& procName, std::string* error = nullptr) const {
|
||||
ASSERT(proc != nullptr);
|
||||
static_assert(std::is_function<T>::value, "");
|
||||
|
||||
*proc = reinterpret_cast<T*>(GetProc(procName, error));
|
||||
return *proc != nullptr;
|
||||
}
|
||||
*proc = reinterpret_cast<T*>(GetProc(procName, error));
|
||||
return *proc != nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
void* mHandle = nullptr;
|
||||
private:
|
||||
void* mHandle = nullptr;
|
||||
};
|
||||
|
||||
#endif // COMMON_DYNAMICLIB_H_
|
||||
#endif // COMMON_DYNAMICLIB_H_
|
||||
|
||||
@@ -17,31 +17,31 @@
|
||||
#include "common/Assert.h"
|
||||
|
||||
#if defined(NXT_COMPILER_MSVC)
|
||||
#include <intrin.h>
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
uint32_t ScanForward(uint32_t bits) {
|
||||
ASSERT(bits != 0);
|
||||
#if defined(NXT_COMPILER_MSVC)
|
||||
unsigned long firstBitIndex = 0ul;
|
||||
unsigned char ret = _BitScanForward(&firstBitIndex, bits);
|
||||
ASSERT(ret != 0);
|
||||
return firstBitIndex;
|
||||
#else
|
||||
return static_cast<uint32_t>(__builtin_ctz(bits));
|
||||
#endif
|
||||
#if defined(NXT_COMPILER_MSVC)
|
||||
unsigned long firstBitIndex = 0ul;
|
||||
unsigned char ret = _BitScanForward(&firstBitIndex, bits);
|
||||
ASSERT(ret != 0);
|
||||
return firstBitIndex;
|
||||
#else
|
||||
return static_cast<uint32_t>(__builtin_ctz(bits));
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t Log2(uint32_t value) {
|
||||
ASSERT(value != 0);
|
||||
#if defined(NXT_COMPILER_MSVC)
|
||||
unsigned long firstBitIndex = 0ul;
|
||||
unsigned char ret = _BitScanReverse(&firstBitIndex, value);
|
||||
ASSERT(ret != 0);
|
||||
return firstBitIndex;
|
||||
#else
|
||||
return 31 - static_cast<uint32_t>(__builtin_clz(value));
|
||||
#endif
|
||||
#if defined(NXT_COMPILER_MSVC)
|
||||
unsigned long firstBitIndex = 0ul;
|
||||
unsigned char ret = _BitScanReverse(&firstBitIndex, value);
|
||||
ASSERT(ret != 0);
|
||||
return firstBitIndex;
|
||||
#else
|
||||
return 31 - static_cast<uint32_t>(__builtin_clz(value));
|
||||
#endif
|
||||
}
|
||||
|
||||
bool IsPowerOfTwo(size_t n) {
|
||||
@@ -58,7 +58,8 @@ bool IsPtrAligned(const void* ptr, size_t alignment) {
|
||||
void* AlignVoidPtr(void* ptr, size_t alignment) {
|
||||
ASSERT(IsPowerOfTwo(alignment));
|
||||
ASSERT(alignment != 0);
|
||||
return reinterpret_cast<void*>((reinterpret_cast<size_t>(ptr) + (alignment - 1)) & ~(alignment - 1));
|
||||
return reinterpret_cast<void*>((reinterpret_cast<size_t>(ptr) + (alignment - 1)) &
|
||||
~(alignment - 1));
|
||||
}
|
||||
|
||||
bool IsAligned(uint32_t value, size_t alignment) {
|
||||
|
||||
@@ -28,14 +28,14 @@ void* AlignVoidPtr(void* ptr, size_t alignment);
|
||||
bool IsAligned(uint32_t value, size_t alignment);
|
||||
uint32_t Align(uint32_t value, size_t alignment);
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
T* AlignPtr(T* ptr, size_t alignment) {
|
||||
return reinterpret_cast<T*>(AlignVoidPtr(ptr, alignment));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
const T* AlignPtr(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_
|
||||
|
||||
@@ -16,15 +16,15 @@
|
||||
#define COMMON_PLATFORM_H_
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#define NXT_PLATFORM_WINDOWS 1
|
||||
# define NXT_PLATFORM_WINDOWS 1
|
||||
#elif defined(__linux__)
|
||||
#define NXT_PLATFORM_LINUX 1
|
||||
#define NXT_PLATFORM_POSIX 1
|
||||
# define NXT_PLATFORM_LINUX 1
|
||||
# define NXT_PLATFORM_POSIX 1
|
||||
#elif defined(__APPLE__)
|
||||
#define NXT_PLATFORM_APPLE 1
|
||||
#define NXT_PLATFORM_POSIX 1
|
||||
# define NXT_PLATFORM_APPLE 1
|
||||
# define NXT_PLATFORM_POSIX 1
|
||||
#else
|
||||
#error "Unsupported platform."
|
||||
# error "Unsupported platform."
|
||||
#endif
|
||||
|
||||
#endif // COMMON_PLATFORM_H_
|
||||
#endif // COMMON_PLATFORM_H_
|
||||
|
||||
@@ -19,4 +19,4 @@
|
||||
|
||||
using Serial = uint64_t;
|
||||
|
||||
#endif // COMMON_SERIAL_H_
|
||||
#endif // COMMON_SERIAL_H_
|
||||
|
||||
@@ -21,101 +21,101 @@
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
template<typename T>
|
||||
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;
|
||||
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;
|
||||
|
||||
public:
|
||||
class Iterator {
|
||||
public:
|
||||
Iterator(StorageIterator start);
|
||||
Iterator& operator++();
|
||||
public:
|
||||
class Iterator {
|
||||
public:
|
||||
Iterator(StorageIterator start);
|
||||
Iterator& operator++();
|
||||
|
||||
bool operator==(const Iterator& other) const;
|
||||
bool operator!=(const Iterator& other) const;
|
||||
T& operator*() const;
|
||||
bool operator==(const Iterator& other) const;
|
||||
bool operator!=(const Iterator& other) const;
|
||||
T& operator*() const;
|
||||
|
||||
private:
|
||||
StorageIterator mStorageIterator;
|
||||
// Special case the mSerialIterator when it should be equal to mStorageIterator.begin()
|
||||
// otherwise we could ask mStorageIterator.begin() when mStorageIterator is mStorage.end()
|
||||
// which is invalid. mStorageIterator.begin() is tagged with a nullptr.
|
||||
T* mSerialIterator;
|
||||
};
|
||||
private:
|
||||
StorageIterator mStorageIterator;
|
||||
// Special case the mSerialIterator when it should be equal to mStorageIterator.begin()
|
||||
// otherwise we could ask mStorageIterator.begin() when mStorageIterator is mStorage.end()
|
||||
// which is invalid. mStorageIterator.begin() is tagged with a nullptr.
|
||||
T* mSerialIterator;
|
||||
};
|
||||
|
||||
class ConstIterator {
|
||||
public:
|
||||
ConstIterator(ConstStorageIterator start);
|
||||
ConstIterator& operator++();
|
||||
class ConstIterator {
|
||||
public:
|
||||
ConstIterator(ConstStorageIterator start);
|
||||
ConstIterator& operator++();
|
||||
|
||||
bool operator==(const ConstIterator& other) const;
|
||||
bool operator!=(const ConstIterator& other) const;
|
||||
const T& operator*() const;
|
||||
bool operator==(const ConstIterator& other) const;
|
||||
bool operator!=(const ConstIterator& other) const;
|
||||
const T& operator*() const;
|
||||
|
||||
private:
|
||||
ConstStorageIterator mStorageIterator;
|
||||
const T* mSerialIterator;
|
||||
};
|
||||
private:
|
||||
ConstStorageIterator mStorageIterator;
|
||||
const T* mSerialIterator;
|
||||
};
|
||||
|
||||
class BeginEnd {
|
||||
public:
|
||||
BeginEnd(StorageIterator start, StorageIterator end);
|
||||
class BeginEnd {
|
||||
public:
|
||||
BeginEnd(StorageIterator start, StorageIterator end);
|
||||
|
||||
Iterator begin() const;
|
||||
Iterator end() const;
|
||||
Iterator begin() const;
|
||||
Iterator end() const;
|
||||
|
||||
private:
|
||||
StorageIterator mStartIt;
|
||||
StorageIterator mEndIt;
|
||||
};
|
||||
private:
|
||||
StorageIterator mStartIt;
|
||||
StorageIterator mEndIt;
|
||||
};
|
||||
|
||||
class ConstBeginEnd {
|
||||
public:
|
||||
ConstBeginEnd(ConstStorageIterator start, ConstStorageIterator end);
|
||||
class ConstBeginEnd {
|
||||
public:
|
||||
ConstBeginEnd(ConstStorageIterator start, ConstStorageIterator end);
|
||||
|
||||
ConstIterator begin() const;
|
||||
ConstIterator end() const;
|
||||
ConstIterator begin() const;
|
||||
ConstIterator end() const;
|
||||
|
||||
private:
|
||||
ConstStorageIterator mStartIt;
|
||||
ConstStorageIterator mEndIt;
|
||||
};
|
||||
private:
|
||||
ConstStorageIterator mStartIt;
|
||||
ConstStorageIterator mEndIt;
|
||||
};
|
||||
|
||||
// The serial must be given in (not strictly) increasing order.
|
||||
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);
|
||||
// The serial must be given in (not strictly) increasing order.
|
||||
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);
|
||||
|
||||
bool Empty() const;
|
||||
bool Empty() const;
|
||||
|
||||
// The UpTo variants of Iterate and Clear affect all values associated to a serial
|
||||
// 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);
|
||||
// The UpTo variants of Iterate and Clear affect all values associated to a serial
|
||||
// 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();
|
||||
void ClearUpTo(Serial serial);
|
||||
void Clear();
|
||||
void ClearUpTo(Serial serial);
|
||||
|
||||
Serial FirstSerial() const;
|
||||
Serial FirstSerial() const;
|
||||
|
||||
private:
|
||||
// Returns the first StorageIterator that a serial bigger than serial.
|
||||
ConstStorageIterator FindUpTo(Serial serial) const;
|
||||
StorageIterator FindUpTo(Serial serial);
|
||||
Storage mStorage;
|
||||
private:
|
||||
// Returns the first StorageIterator that a serial bigger than serial.
|
||||
ConstStorageIterator FindUpTo(Serial serial) const;
|
||||
StorageIterator FindUpTo(Serial serial);
|
||||
Storage mStorage;
|
||||
};
|
||||
|
||||
// SerialQueue
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void SerialQueue<T>::Enqueue(const T& value, Serial serial) {
|
||||
NXT_ASSERT(Empty() || mStorage.back().first <= serial);
|
||||
|
||||
@@ -125,7 +125,7 @@ void SerialQueue<T>::Enqueue(const T& value, Serial serial) {
|
||||
mStorage.back().second.emplace_back(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void SerialQueue<T>::Enqueue(T&& value, Serial serial) {
|
||||
NXT_ASSERT(Empty() || mStorage.back().first <= serial);
|
||||
|
||||
@@ -135,132 +135,133 @@ void SerialQueue<T>::Enqueue(T&& value, Serial serial) {
|
||||
mStorage.back().second.emplace_back(value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void SerialQueue<T>::Enqueue(const std::vector<T>& values, Serial serial) {
|
||||
NXT_ASSERT(values.size() > 0);
|
||||
NXT_ASSERT(Empty() || mStorage.back().first <= serial);
|
||||
mStorage.emplace_back(SerialPair(serial, {values}));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void SerialQueue<T>::Enqueue(std::vector<T>&& values, Serial serial) {
|
||||
NXT_ASSERT(values.size() > 0);
|
||||
NXT_ASSERT(Empty() || mStorage.back().first <= serial);
|
||||
mStorage.emplace_back(SerialPair(serial, {values}));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
bool SerialQueue<T>::Empty() const {
|
||||
return mStorage.empty();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
typename SerialQueue<T>::ConstBeginEnd SerialQueue<T>::IterateAll() const {
|
||||
return {mStorage.begin(), mStorage.end()};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
typename SerialQueue<T>::ConstBeginEnd SerialQueue<T>::IterateUpTo(Serial serial) const {
|
||||
return {mStorage.begin(), FindUpTo(serial)};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
typename SerialQueue<T>::BeginEnd SerialQueue<T>::IterateAll() {
|
||||
return {mStorage.begin(), mStorage.end()};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
typename SerialQueue<T>::BeginEnd SerialQueue<T>::IterateUpTo(Serial serial) {
|
||||
return {mStorage.begin(), FindUpTo(serial)};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void SerialQueue<T>::Clear() {
|
||||
mStorage.clear();
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
void SerialQueue<T>::ClearUpTo(Serial serial) {
|
||||
mStorage.erase(mStorage.begin(), FindUpTo(serial));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
Serial SerialQueue<T>::FirstSerial() const {
|
||||
NXT_ASSERT(!Empty());
|
||||
return mStorage.front().first;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
typename SerialQueue<T>::ConstStorageIterator SerialQueue<T>::FindUpTo(Serial serial) const {
|
||||
auto it = mStorage.begin();
|
||||
while (it != mStorage.end() && it->first <= serial) {
|
||||
it ++;
|
||||
it++;
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
typename SerialQueue<T>::StorageIterator SerialQueue<T>::FindUpTo(Serial serial) {
|
||||
auto it = mStorage.begin();
|
||||
while (it != mStorage.end() && it->first <= serial) {
|
||||
it ++;
|
||||
it++;
|
||||
}
|
||||
return it;
|
||||
}
|
||||
|
||||
// SerialQueue::BeginEnd
|
||||
|
||||
template<typename T>
|
||||
SerialQueue<T>::BeginEnd::BeginEnd(typename SerialQueue<T>::StorageIterator start, typename SerialQueue<T>::StorageIterator end)
|
||||
template <typename T>
|
||||
SerialQueue<T>::BeginEnd::BeginEnd(typename SerialQueue<T>::StorageIterator start,
|
||||
typename SerialQueue<T>::StorageIterator end)
|
||||
: mStartIt(start), mEndIt(end) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
typename SerialQueue<T>::Iterator SerialQueue<T>::BeginEnd::begin() const {
|
||||
return {mStartIt};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
typename SerialQueue<T>::Iterator SerialQueue<T>::BeginEnd::end() const {
|
||||
return {mEndIt};
|
||||
}
|
||||
|
||||
// SerialQueue::Iterator
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
SerialQueue<T>::Iterator::Iterator(typename SerialQueue<T>::StorageIterator start)
|
||||
: mStorageIterator(start), mSerialIterator(nullptr) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
typename SerialQueue<T>::Iterator& SerialQueue<T>::Iterator::operator++() {
|
||||
T* vectorData = mStorageIterator->second.data();
|
||||
|
||||
if (mSerialIterator == nullptr) {
|
||||
mSerialIterator = vectorData + 1;
|
||||
} else {
|
||||
mSerialIterator ++;
|
||||
mSerialIterator++;
|
||||
}
|
||||
|
||||
if (mSerialIterator >= vectorData + mStorageIterator->second.size()) {
|
||||
mSerialIterator = nullptr;
|
||||
mStorageIterator ++;
|
||||
mStorageIterator++;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
bool SerialQueue<T>::Iterator::operator==(const typename SerialQueue<T>::Iterator& other) const {
|
||||
return other.mStorageIterator == mStorageIterator && other.mSerialIterator == mSerialIterator;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
bool SerialQueue<T>::Iterator::operator!=(const typename SerialQueue<T>::Iterator& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
T& SerialQueue<T>::Iterator::operator*() const {
|
||||
if (mSerialIterator == nullptr) {
|
||||
return *mStorageIterator->second.begin();
|
||||
@@ -270,57 +271,60 @@ T& SerialQueue<T>::Iterator::operator*() const {
|
||||
|
||||
// SerialQueue::ConstBeginEnd
|
||||
|
||||
template<typename T>
|
||||
SerialQueue<T>::ConstBeginEnd::ConstBeginEnd(typename SerialQueue<T>::ConstStorageIterator start, typename SerialQueue<T>::ConstStorageIterator end)
|
||||
template <typename T>
|
||||
SerialQueue<T>::ConstBeginEnd::ConstBeginEnd(typename SerialQueue<T>::ConstStorageIterator start,
|
||||
typename SerialQueue<T>::ConstStorageIterator end)
|
||||
: mStartIt(start), mEndIt(end) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
typename SerialQueue<T>::ConstIterator SerialQueue<T>::ConstBeginEnd::begin() const {
|
||||
return {mStartIt};
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
typename SerialQueue<T>::ConstIterator SerialQueue<T>::ConstBeginEnd::end() const {
|
||||
return {mEndIt};
|
||||
}
|
||||
|
||||
// SerialQueue::ConstIterator
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
SerialQueue<T>::ConstIterator::ConstIterator(typename SerialQueue<T>::ConstStorageIterator start)
|
||||
: mStorageIterator(start), mSerialIterator(nullptr) {
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
typename SerialQueue<T>::ConstIterator& SerialQueue<T>::ConstIterator::operator++() {
|
||||
const T* vectorData = mStorageIterator->second.data();
|
||||
|
||||
if (mSerialIterator == nullptr) {
|
||||
mSerialIterator = vectorData + 1;
|
||||
} else {
|
||||
mSerialIterator ++;
|
||||
mSerialIterator++;
|
||||
}
|
||||
|
||||
if (mSerialIterator >= vectorData + mStorageIterator->second.size()) {
|
||||
mSerialIterator = nullptr;
|
||||
mStorageIterator ++;
|
||||
mStorageIterator++;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SerialQueue<T>::ConstIterator::operator==(const typename SerialQueue<T>::ConstIterator& other) const {
|
||||
template <typename T>
|
||||
bool SerialQueue<T>::ConstIterator::operator==(
|
||||
const typename SerialQueue<T>::ConstIterator& other) const {
|
||||
return other.mStorageIterator == mStorageIterator && other.mSerialIterator == mSerialIterator;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool SerialQueue<T>::ConstIterator::operator!=(const typename SerialQueue<T>::ConstIterator& other) const {
|
||||
template <typename T>
|
||||
bool SerialQueue<T>::ConstIterator::operator!=(
|
||||
const typename SerialQueue<T>::ConstIterator& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
const T& SerialQueue<T>::ConstIterator::operator*() const {
|
||||
if (mSerialIterator == nullptr) {
|
||||
return *mStorageIterator->second.begin();
|
||||
@@ -328,4 +332,4 @@ const T& SerialQueue<T>::ConstIterator::operator*() const {
|
||||
return *mSerialIterator;
|
||||
}
|
||||
|
||||
#endif // COMMON_SERIALQUEUE_H_
|
||||
#endif // COMMON_SERIALQUEUE_H_
|
||||
|
||||
Reference in New Issue
Block a user