Merge changes from The Witness.
This commit is contained in:
parent
cb6c18efa4
commit
06c170b41b
@ -9,8 +9,8 @@ This array class requires the elements to be relocable; it uses memmove and real
|
||||
using swap, but I honestly don't care. The only thing that you should be aware of is that internal pointers
|
||||
are not supported.
|
||||
|
||||
The foreach macros that I use are very non-standard and somewhat confusing. It would be nice to have
|
||||
standard foreach as in Qt.
|
||||
Note also that push_back and resize does not support inserting arguments elements that are in the same
|
||||
container. This is forbidden to prevent an extra copy.
|
||||
*/
|
||||
|
||||
|
||||
@ -19,7 +19,7 @@ standard foreach as in Qt.
|
||||
#include "Debug.h"
|
||||
#include "Stream.h"
|
||||
#include "Utils.h" // swap
|
||||
#include "ForEach.h" // swap
|
||||
#include "ForEach.h" // PseudoIndex
|
||||
|
||||
#include <string.h> // memmove
|
||||
#include <new> // for placement new
|
||||
@ -27,69 +27,6 @@ standard foreach as in Qt.
|
||||
|
||||
namespace nv
|
||||
{
|
||||
// @@ Move this to utils?
|
||||
/// Delete all the elements of a container.
|
||||
template <typename T>
|
||||
void deleteAll(T & container)
|
||||
{
|
||||
for (typename T::PseudoIndex i = container.start(); !container.isDone(i); container.advance(i))
|
||||
{
|
||||
delete container[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// @@ Move these templates to Utils.h
|
||||
// @@ Specialize these methods for numeric, pointer, and pod types.
|
||||
|
||||
template <typename T>
|
||||
void construct_range(T * restrict ptr, uint new_size, uint old_size) {
|
||||
for (uint i = old_size; i < new_size; i++) {
|
||||
new(ptr+i) T; // placement new
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void construct_range(T * restrict ptr, uint new_size, uint old_size, const T & elem) {
|
||||
for (uint i = old_size; i < new_size; i++) {
|
||||
new(ptr+i) T(elem); // placement new
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void destroy_range(T * restrict ptr, uint new_size, uint old_size) {
|
||||
for (uint i = new_size; i < old_size; i++) {
|
||||
(ptr+i)->~T(); // Explicit call to the destructor
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void fill(T * restrict dst, uint count, const T & value) {
|
||||
for (uint i = 0; i < count; i++) {
|
||||
dst[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void copy(T * restrict dst, const T * restrict src, uint count) {
|
||||
for (uint i = 0; i < count; i++) {
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool find(const T & element, const T * restrict ptr, uint begin, uint end, uint * index) {
|
||||
for (uint i = begin; i < end; i++) {
|
||||
if (ptr[i] == element) {
|
||||
if (index != NULL) *index = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Replacement for std::vector that is easier to debug and provides
|
||||
* some nice foreach enumerators.
|
||||
@ -107,7 +44,7 @@ namespace nv
|
||||
}
|
||||
|
||||
// Constructor that initializes the vector with the given elements.
|
||||
NV_FORCEINLINE Array(const T * ptr, int num) : m_buffer(NULL), m_capacity(0), m_size(0) {
|
||||
NV_FORCEINLINE Array(const T * ptr, uint num) : m_buffer(NULL), m_capacity(0), m_size(0) {
|
||||
copy(ptr, num);
|
||||
}
|
||||
|
||||
@ -172,8 +109,12 @@ namespace nv
|
||||
#if 1
|
||||
nvDebugCheck(&val < m_buffer || &val > m_buffer+m_size);
|
||||
|
||||
setArraySize(m_size+1);
|
||||
new(m_buffer+m_size-1) T(val);
|
||||
uint old_size = m_size;
|
||||
uint new_size = m_size + 1;
|
||||
|
||||
setArraySize(new_size);
|
||||
|
||||
construct_range(m_buffer, new_size, old_size, val);
|
||||
#else
|
||||
uint new_size = m_size + 1;
|
||||
|
||||
@ -205,7 +146,7 @@ namespace nv
|
||||
}
|
||||
|
||||
/// Qt like push operator.
|
||||
NV_FORCEINLINE Array<T> & operator<< ( const T & t )
|
||||
NV_FORCEINLINE Array<T> & operator<< ( T & t )
|
||||
{
|
||||
push_back(t);
|
||||
return *this;
|
||||
@ -360,6 +301,8 @@ namespace nv
|
||||
/// new ones with the given value.
|
||||
void resize(uint new_size, const T & elem)
|
||||
{
|
||||
nvDebugCheck(&elem < m_buffer || &elem > m_buffer+m_size);
|
||||
|
||||
uint old_size = m_size;
|
||||
|
||||
// Destruct old elements (if we're shrinking).
|
||||
@ -397,10 +340,13 @@ namespace nv
|
||||
}
|
||||
|
||||
/// Copy elements to this array. Resizes it if needed.
|
||||
NV_FORCEINLINE void copy(const T * ptr, uint num)
|
||||
NV_FORCEINLINE void copy(const T * data, uint count)
|
||||
{
|
||||
resize( num ); // @@ call copy operator from 0 to min(num,m_size) and copy constructor from min(num,m_size) to num
|
||||
::nv::copy(m_buffer, ptr, num);
|
||||
destroy_range(m_buffer, count, m_size);
|
||||
|
||||
setArraySize(count);
|
||||
|
||||
::nv::copy(m_buffer, data, count);
|
||||
}
|
||||
|
||||
/// Assignment operator.
|
||||
@ -456,13 +402,14 @@ namespace nv
|
||||
#endif
|
||||
|
||||
// Swap the members of this vector and the given vector.
|
||||
friend void swap(Array & a, Array & b)
|
||||
friend void swapMembers(Array & a, Array & b)
|
||||
{
|
||||
swap(a.m_buffer, b.m_buffer);
|
||||
swap(a.m_capacity, b.m_capacity);
|
||||
swap(a.m_size, b.m_size);
|
||||
nv::swap(a.m_buffer, b.m_buffer);
|
||||
nv::swap(a.m_capacity, b.m_capacity);
|
||||
nv::swap(a.m_size, b.m_size);
|
||||
}
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
// Change array size.
|
||||
@ -510,6 +457,14 @@ protected:
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <typename T>
|
||||
inline void swap(Array<T> & a, Array<T> & b)
|
||||
{
|
||||
swapMembers(a, b);
|
||||
}
|
||||
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_CORE_ARRAY_H
|
||||
|
@ -756,3 +756,50 @@ bool debug::isDebuggerPresent()
|
||||
return getsid(getpid()) != getppid();
|
||||
#endif
|
||||
}
|
||||
|
||||
bool debug::attachToDebugger()
|
||||
{
|
||||
#if NV_OS_WIN32
|
||||
if (isDebuggerPresent() == FALSE) {
|
||||
Path process(1024);
|
||||
process.copy("\"");
|
||||
GetSystemDirectory(process.str() + 1, 1024 - 1);
|
||||
|
||||
process.appendSeparator();
|
||||
|
||||
process.appendFormat("VSJitDebugger.exe\" -p %lu", ::GetCurrentProcessId());
|
||||
|
||||
STARTUPINFO sSi;
|
||||
memset(&sSi, 0, sizeof(sSi));
|
||||
|
||||
PROCESS_INFORMATION sPi;
|
||||
memset(&sPi, 0, sizeof(sPi));
|
||||
|
||||
BOOL b = CreateProcess(NULL, process.str(), NULL, NULL, FALSE, 0, NULL, NULL, &sSi, &sPi);
|
||||
if (b != FALSE) {
|
||||
::WaitForSingleObject(sPi.hProcess, INFINITE);
|
||||
|
||||
DWORD dwExitCode;
|
||||
::GetExitCodeProcess(sPi.hProcess, &dwExitCode);
|
||||
if (dwExitCode != 0) //if exit code is zero, a debugger was selected
|
||||
b = FALSE;
|
||||
}
|
||||
|
||||
if (sPi.hThread != NULL) ::CloseHandle(sPi.hThread);
|
||||
if (sPi.hProcess != NULL) ::CloseHandle(sPi.hProcess);
|
||||
|
||||
if (b == FALSE)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < 5*60; i++) {
|
||||
if (isDebuggerPresent())
|
||||
break;
|
||||
::Sleep(200);
|
||||
}
|
||||
}
|
||||
|
||||
nvDebugBreak();
|
||||
#endif // NV_OS_WIN32
|
||||
|
||||
return true;
|
||||
}
|
@ -18,9 +18,9 @@
|
||||
#define NV_ABORT_EXIT 3
|
||||
|
||||
#define nvNoAssert(exp) \
|
||||
do { \
|
||||
(void)sizeof(exp); \
|
||||
} while(0)
|
||||
NV_MULTI_LINE_MACRO_BEGIN \
|
||||
(void)sizeof(exp); \
|
||||
NV_MULTI_LINE_MACRO_END
|
||||
|
||||
#if NV_NO_ASSERT
|
||||
|
||||
@ -50,42 +50,43 @@
|
||||
# endif
|
||||
|
||||
#define nvDebugBreakOnce() \
|
||||
do { \
|
||||
static bool firstTime = true; \
|
||||
if (firstTime) { firstTime = false; nvDebugBreak(); } \
|
||||
} while(false)
|
||||
NV_MULTI_LINE_MACRO_BEGIN \
|
||||
static bool firstTime = true; \
|
||||
if (firstTime) { firstTime = false; nvDebugBreak(); } \
|
||||
NV_MULTI_LINE_MACRO_END
|
||||
|
||||
# define nvAssertMacro(exp) \
|
||||
do { \
|
||||
if (!(exp)) { \
|
||||
if (nvAbort(#exp, __FILE__, __LINE__, __FUNC__) == NV_ABORT_DEBUG) { \
|
||||
nvDebugBreak(); \
|
||||
} \
|
||||
#define nvAssertMacro(exp) \
|
||||
NV_MULTI_LINE_MACRO_BEGIN \
|
||||
if (!(exp)) { \
|
||||
if (nvAbort(#exp, __FILE__, __LINE__, __FUNC__) == NV_ABORT_DEBUG) { \
|
||||
nvDebugBreak(); \
|
||||
} \
|
||||
} while(false)
|
||||
} \
|
||||
NV_MULTI_LINE_MACRO_END
|
||||
|
||||
# define nvAssertMacroWithIgnoreAll(exp) \
|
||||
do { \
|
||||
#define nvAssertMacroWithIgnoreAll(exp) \
|
||||
NV_MULTI_LINE_MACRO_BEGIN \
|
||||
static bool ignoreAll = false; \
|
||||
if (!ignoreAll && !(exp)) { \
|
||||
if (nvAbort(#exp, __FILE__, __LINE__, __FUNC__) == NV_ABORT_DEBUG) { \
|
||||
int result = nvAbort(#exp, __FILE__, __LINE__, __FUNC__); \
|
||||
if (result == NV_ABORT_DEBUG) { \
|
||||
nvDebugBreak(); \
|
||||
} else { \
|
||||
} else if (result == NV_ABORT_IGNORE) { \
|
||||
ignoreAll = true; \
|
||||
} \
|
||||
} \
|
||||
} while(false)
|
||||
NV_MULTI_LINE_MACRO_END
|
||||
|
||||
# define nvAssert(exp) nvAssertMacro(exp)
|
||||
# define nvCheck(exp) nvAssertMacro(exp)
|
||||
#define nvAssert(exp) nvAssertMacro(exp)
|
||||
#define nvCheck(exp) nvAssertMacro(exp)
|
||||
|
||||
# if defined(_DEBUG)
|
||||
# define nvDebugAssert(exp) nvAssertMacro(exp)
|
||||
# define nvDebugCheck(exp) nvAssertMacro(exp)
|
||||
# else // _DEBUG
|
||||
# define nvDebugAssert(exp) nvNoAssert(exp)
|
||||
# define nvDebugCheck(exp) nvNoAssert(exp)
|
||||
# endif // _DEBUG
|
||||
#if defined(_DEBUG)
|
||||
# define nvDebugAssert(exp) nvAssertMacro(exp)
|
||||
# define nvDebugCheck(exp) nvAssertMacro(exp)
|
||||
#else // _DEBUG
|
||||
# define nvDebugAssert(exp) nvNoAssert(exp)
|
||||
# define nvDebugCheck(exp) nvNoAssert(exp)
|
||||
#endif // _DEBUG
|
||||
|
||||
#endif // NV_NO_ASSERT
|
||||
|
||||
@ -165,6 +166,7 @@ namespace nv
|
||||
NVCORE_API void disableSigHandler();
|
||||
|
||||
NVCORE_API bool isDebuggerPresent();
|
||||
NVCORE_API bool attachToDebugger();
|
||||
}
|
||||
|
||||
} // nv namespace
|
||||
|
@ -5,7 +5,7 @@
|
||||
#define NV_CORE_FOREACH_H
|
||||
|
||||
/*
|
||||
The foreach macros that I use are very non-standard and somewhat confusing, but I like them.
|
||||
These foreach macros are very non-standard and somewhat confusing, but I like them.
|
||||
*/
|
||||
|
||||
|
||||
@ -32,10 +32,10 @@ struct PseudoIndexWrapper {
|
||||
}
|
||||
// PseudoIndex cannot have a dtor!
|
||||
|
||||
template <typename T> typename T::PseudoIndex & operator()(const T * container) {
|
||||
template <typename T> typename T::PseudoIndex & operator()(const T * /*container*/) {
|
||||
return *reinterpret_cast<typename T::PseudoIndex *>(memory);
|
||||
}
|
||||
template <typename T> const typename T::PseudoIndex & operator()(const T * container) const {
|
||||
template <typename T> const typename T::PseudoIndex & operator()(const T * /*container*/) const {
|
||||
return *reinterpret_cast<const typename T::PseudoIndex *>(memory);
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ namespace nv
|
||||
uint pos = (uint)ftell(m_fp);
|
||||
fseek(m_fp, 0, SEEK_END);
|
||||
uint end = (uint)ftell(m_fp);
|
||||
fseek(m_fp, pos, SEEK_SET);
|
||||
fseek(m_fp, pos, SEEK_SET);
|
||||
#endif
|
||||
return end;
|
||||
}
|
||||
@ -326,7 +326,7 @@ namespace nv
|
||||
return len;
|
||||
}
|
||||
|
||||
virtual void seek( uint pos ) { /*Not implemented*/ }
|
||||
virtual void seek( uint /*pos*/ ) { /*Not implemented*/ }
|
||||
virtual uint tell() const { return m_buffer.size(); }
|
||||
virtual uint size() const { return m_buffer.size(); }
|
||||
|
||||
|
@ -483,7 +483,7 @@ const char * Path::extension() const
|
||||
|
||||
|
||||
/// Toggles path separators (ie. \\ into /).
|
||||
void Path::translatePath(char pathSeparator /*= NV_PATH_SEPARATOR*/)
|
||||
void Path::translatePath(char pathSeparator/*=NV_PATH_SEPARATOR*/)
|
||||
{
|
||||
nvCheck( m_str != NULL );
|
||||
|
||||
@ -493,6 +493,18 @@ void Path::translatePath(char pathSeparator /*= NV_PATH_SEPARATOR*/)
|
||||
}
|
||||
}
|
||||
|
||||
void Path::appendSeparator(char pathSeparator/*=NV_PATH_SEPARATOR*/)
|
||||
{
|
||||
nvCheck(!isNull());
|
||||
|
||||
const uint l = length();
|
||||
|
||||
if (m_str[l] != '\\' && m_str[l] != '/') {
|
||||
char separatorString[] = { pathSeparator, '\0' };
|
||||
append(separatorString);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Strip the file name from a path.
|
||||
|
@ -155,6 +155,8 @@ namespace nv
|
||||
|
||||
void translatePath(char pathSeparator = NV_PATH_SEPARATOR);
|
||||
|
||||
void appendSeparator(char pathSeparator = NV_PATH_SEPARATOR);
|
||||
|
||||
void stripFileName();
|
||||
void stripExtension();
|
||||
|
||||
|
@ -73,6 +73,9 @@ namespace nv
|
||||
virtual bool isSaving() const = 0;
|
||||
|
||||
|
||||
void advance(uint offset) { seek(tell() + offset); }
|
||||
|
||||
|
||||
// friends
|
||||
friend Stream & operator<<( Stream & s, bool & c ) {
|
||||
#if NV_OS_DARWIN
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#define NV_INT8_MIN (-128)
|
||||
#define NV_INT8_MAX 127
|
||||
#define NV_UINT8_MAX 255
|
||||
#define NV_INT16_MIN (-32767-1)
|
||||
#define NV_INT16_MAX 32767
|
||||
#define NV_UINT16_MAX 0xffff
|
||||
@ -27,16 +28,6 @@ namespace nv
|
||||
{
|
||||
// Less error prone than casting. From CB:
|
||||
// http://cbloomrants.blogspot.com/2011/06/06-17-11-c-casting-is-devil.html
|
||||
inline int8 asSigned(uint8 x) { return (int8) x; }
|
||||
inline int16 asSigned(uint16 x) { return (int16) x; }
|
||||
inline int32 asSigned(uint32 x) { return (int32) x; }
|
||||
inline int64 asSigned(uint64 x) { return (int64) x; }
|
||||
|
||||
inline uint8 asUnsigned(int8 x) { return (uint8) x; }
|
||||
inline uint16 asUnsigned(int16 x) { return (uint16) x; }
|
||||
inline uint32 asUnsigned(int32 x) { return (uint32) x; }
|
||||
inline uint64 asUnsigned(int64 x) { return (uint64) x; }
|
||||
|
||||
|
||||
// uint32 casts:
|
||||
template <typename T> inline uint32 toU32(T x) { return x; }
|
||||
@ -60,12 +51,55 @@ namespace nv
|
||||
//template <> inline int32 toI32<uint8>(uint8 x) { return x; }
|
||||
//template <> inline int32 toI32<int8>(int8 x) { return x; }
|
||||
|
||||
// uint16 casts:
|
||||
template <typename T> inline uint16 toU16(T x) { return x; }
|
||||
template <> inline uint16 toU16<uint64>(uint64 x) { nvDebugCheck(x <= NV_UINT16_MAX); return (uint16)x; }
|
||||
template <> inline uint16 toU16<int64>(int64 x) { nvDebugCheck(x >= 0 && x <= NV_UINT16_MAX); return (uint16)x; }
|
||||
template <> inline uint16 toU16<uint32>(uint32 x) { nvDebugCheck(x <= NV_UINT16_MAX); return (uint16)x; }
|
||||
template <> inline uint16 toU16<int32>(int32 x) { nvDebugCheck(x >= 0 && x <= NV_UINT16_MAX); return (uint16)x; }
|
||||
//template <> inline uint16 toU16<uint16>(uint16 x) { return x; }
|
||||
template <> inline uint16 toU16<int16>(int16 x) { nvDebugCheck(x >= 0); return (uint16)x; }
|
||||
//template <> inline uint16 toU16<uint8>(uint8 x) { return x; }
|
||||
template <> inline uint16 toU16<int8>(int8 x) { nvDebugCheck(x >= 0); return (uint16)x; }
|
||||
|
||||
// int16 casts:
|
||||
template <typename T> inline int16 toI16(T x) { return x; }
|
||||
template <> inline int16 toI16<uint64>(uint64 x) { nvDebugCheck(x <= NV_INT16_MAX); return (int16)x; }
|
||||
template <> inline int16 toI16<int64>(int64 x) { nvDebugCheck(x >= NV_INT16_MIN && x <= NV_UINT16_MAX); return (int16)x; }
|
||||
template <> inline int16 toI16<uint32>(uint32 x) { nvDebugCheck(x <= NV_INT16_MAX); return (int16)x; }
|
||||
template <> inline int16 toI16<int32>(int32 x) { nvDebugCheck(x >= NV_INT16_MIN && x <= NV_UINT16_MAX); return (int16)x; }
|
||||
template <> inline int16 toI16<uint16>(uint16 x) { nvDebugCheck(x <= NV_INT16_MAX); return (int16)x; }
|
||||
//template <> inline int16 toI16<int16>(int16 x) { return x; }
|
||||
//template <> inline int16 toI16<uint8>(uint8 x) { return x; }
|
||||
//template <> inline int16 toI16<int8>(int8 x) { return x; }
|
||||
|
||||
// uint8 casts:
|
||||
template <typename T> inline uint8 toU8(T x) { return x; }
|
||||
template <> inline uint8 toU8<uint64>(uint64 x) { nvDebugCheck(x <= NV_UINT8_MAX); return (uint8)x; }
|
||||
template <> inline uint8 toU8<int64>(int64 x) { nvDebugCheck(x >= 0 && x <= NV_UINT8_MAX); return (uint8)x; }
|
||||
template <> inline uint8 toU8<uint32>(uint32 x) { nvDebugCheck(x <= NV_UINT8_MAX); return (uint8)x; }
|
||||
template <> inline uint8 toU8<int32>(int32 x) { nvDebugCheck(x >= 0 && x <= NV_UINT8_MAX); return (uint8)x; }
|
||||
template <> inline uint8 toU8<uint16>(uint16 x) { nvDebugCheck(x <= NV_UINT8_MAX); return (uint8)x; }
|
||||
template <> inline uint8 toU8<int16>(int16 x) { nvDebugCheck(x >= 0 && x <= NV_UINT8_MAX); return (uint8)x; }
|
||||
//template <> inline uint8 toU8<uint8>(uint8 x) { return x; }
|
||||
template <> inline uint8 toU8<int8>(int8 x) { nvDebugCheck(x >= 0 && x <= NV_UINT8_MAX); return (uint8)x; }
|
||||
|
||||
// int8 casts:
|
||||
template <typename T> inline int8 toI8(T x) { return x; }
|
||||
template <> inline int8 toI8<uint64>(uint64 x) { nvDebugCheck(x <= NV_INT8_MAX); return (int8)x; }
|
||||
template <> inline int8 toI8<int64>(int64 x) { nvDebugCheck(x >= NV_INT8_MIN && x <= NV_UINT8_MAX); return (int8)x; }
|
||||
template <> inline int8 toI8<uint32>(uint32 x) { nvDebugCheck(x <= NV_INT8_MAX); return (int8)x; }
|
||||
template <> inline int8 toI8<int32>(int32 x) { nvDebugCheck(x >= NV_INT8_MIN && x <= NV_UINT8_MAX); return (int8)x; }
|
||||
template <> inline int8 toI8<uint16>(uint16 x) { nvDebugCheck(x <= NV_INT8_MAX); return (int8)x; }
|
||||
template <> inline int8 toI8<int16>(int16 x) { nvDebugCheck(x >= NV_INT8_MIN && x <= NV_UINT8_MAX); return (int8)x; }
|
||||
template <> inline int8 toI8<uint8>(uint8 x) { nvDebugCheck(x <= NV_INT8_MAX); return (int8)x; }
|
||||
//template <> inline int8 toI8<int8>(int8 x) { return x; }
|
||||
|
||||
/// Swap two values.
|
||||
template <typename T>
|
||||
inline void swap(T & a, T & b)
|
||||
{
|
||||
T temp = a;
|
||||
T temp(a);
|
||||
a = b;
|
||||
b = temp;
|
||||
}
|
||||
@ -191,6 +225,67 @@ namespace nv
|
||||
};
|
||||
|
||||
|
||||
// @@ Move this to utils?
|
||||
/// Delete all the elements of a container.
|
||||
template <typename T>
|
||||
void deleteAll(T & container)
|
||||
{
|
||||
for (typename T::PseudoIndex i = container.start(); !container.isDone(i); container.advance(i))
|
||||
{
|
||||
delete container[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// @@ Specialize these methods for numeric, pointer, and pod types.
|
||||
|
||||
template <typename T>
|
||||
void construct_range(T * restrict ptr, uint new_size, uint old_size) {
|
||||
for (uint i = old_size; i < new_size; i++) {
|
||||
new(ptr+i) T; // placement new
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void construct_range(T * restrict ptr, uint new_size, uint old_size, const T & elem) {
|
||||
for (uint i = old_size; i < new_size; i++) {
|
||||
new(ptr+i) T(elem); // placement new
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void destroy_range(T * restrict ptr, uint new_size, uint old_size) {
|
||||
for (uint i = new_size; i < old_size; i++) {
|
||||
(ptr+i)->~T(); // Explicit call to the destructor
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void fill(T * restrict dst, uint count, const T & value) {
|
||||
for (uint i = 0; i < count; i++) {
|
||||
dst[i] = value;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void copy(T * restrict dst, const T * restrict src, uint count) {
|
||||
for (uint i = 0; i < count; i++) {
|
||||
dst[i] = src[i];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
bool find(const T & element, const T * restrict ptr, uint begin, uint end, uint * index) {
|
||||
for (uint i = begin; i < end; i++) {
|
||||
if (ptr[i] == element) {
|
||||
if (index != NULL) *index = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // nv namespace
|
||||
|
||||
#endif // NV_CORE_UTILS_H
|
||||
|
@ -90,7 +90,7 @@
|
||||
|
||||
#if defined POSH_COMPILER_CLANG
|
||||
# define NV_CC_CLANG 1
|
||||
# define NV_CC_GCC 1 // Clang is compatible with GCC.
|
||||
# define NV_CC_GNUC 1 // Clang is compatible with GCC.
|
||||
# define NV_CC_STRING "clang"
|
||||
#elif defined POSH_COMPILER_GCC
|
||||
# define NV_CC_GNUC 1
|
||||
@ -168,6 +168,17 @@ typedef uint32 uint;
|
||||
#define NV_STRING2(x) #x
|
||||
#define NV_STRING(x) NV_STRING2(x)
|
||||
|
||||
#if NV_CC_MSVC
|
||||
#define NV_MULTI_LINE_MACRO_BEGIN do {
|
||||
#define NV_MULTI_LINE_MACRO_END \
|
||||
__pragma(warning(push)) \
|
||||
__pragma(warning(disable:4127)) \
|
||||
} while(false) \
|
||||
__pragma(warning(pop))
|
||||
#else
|
||||
#define NV_MULTI_LINE_MACRO_BEGIN do {
|
||||
#define NV_MULTI_LINE_MACRO_END } while(false)
|
||||
#endif
|
||||
|
||||
#if __cplusplus > 199711L
|
||||
#define nvStaticCheck(x) static_assert(x)
|
||||
|
Loading…
Reference in New Issue
Block a user