Merge private branch.

This commit is contained in:
castano
2008-04-17 06:58:18 +00:00
parent d10295fbf6
commit cb91740591
11 changed files with 480 additions and 172 deletions

147
src/nvcore/Algorithms.h Normal file
View File

@ -0,0 +1,147 @@
// This code is in the public domain -- castanyo@yahoo.es
#ifndef NV_CORE_ALGORITHMS_H
#define NV_CORE_ALGORITHMS_H
namespace nv
{
/// Return the maximum of two values.
template <typename T>
inline const T & max(const T & a, const T & b)
{
//return std::max(a, b);
if( a < b ) {
return b;
}
return a;
}
/// Return the minimum of two values.
template <typename T>
inline const T & min(const T & a, const T & b)
{
//return std::min(a, b);
if( b < a ) {
return b;
}
return a;
}
/// Clamp between two values.
template <typename T>
inline const T & clamp(const T & x, const T & a, const T & b)
{
return min(max(x, a), b);
}
/// 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];
}
}
// @@ Swap should be implemented here.
#if 0
// This does not use swap, but copies, in some cases swaps are much faster than copies!
// Container should implement operator[], and size()
template <class Container, class T>
void insertionSort(Container<T> & container)
{
const uint n = container.size();
for (uint i=1; i < n; ++i)
{
T value = container[i];
uint j = i;
while (j > 0 && container[j-1] > value)
{
container[j] = container[j-1];
--j;
}
if (i != j)
{
container[j] = value;
}
}
}
template <class Container, class T>
void quickSort(Container<T> & container)
{
quickSort(container, 0, container.count());
}
{
/* threshhold for transitioning to insertion sort */
while (n > 12) {
int c01,c12,c,m,i,j;
/* compute median of three */
m = n >> 1;
c = p[0] > p[m];
c01 = c;
c = &p[m] > &p[n-1];
c12 = c;
/* if 0 >= mid >= end, or 0 < mid < end, then use mid */
if (c01 != c12) {
/* otherwise, we'll need to swap something else to middle */
int z;
c = p[0] < p[n-1];
/* 0>mid && mid<n: 0>n => n; 0<n => 0 */
/* 0<mid && mid>n: 0>n => 0; 0<n => n */
z = (c == c12) ? 0 : n-1;
swap(p[z], p[m]);
}
/* now p[m] is the median-of-three */
/* swap it to the beginning so it won't move around */
swap(p[0], p[m]);
/* partition loop */
i=1;
j=n-1;
for(;;) {
/* handling of equality is crucial here */
/* for sentinels & efficiency with duplicates */
for (;;++i) {
c = p[i] > p[0];
if (!c) break;
}
a = &p[0];
for (;;--j) {
b=&p[j];
c = p[j] > p[0]
if (!c) break;
}
/* make sure we haven't crossed */
if (i >= j) break;
swap(p[i], p[j]);
++i;
--j;
}
/* recurse on smaller side, iterate on larger */
if (j < (n-i)) {
quickSort(p, j);
p = p+i;
n = n-i;
}
else {
quickSort(p+i, n-i);
n = j;
}
}
insertionSort();
}
#endif // 0
} // nv namespace
#endif // NV_CORE_ALGORITHMS_H

View File

@ -80,13 +80,13 @@ public:
/// Clear all the bits. /// Clear all the bits.
void clearAll() void clearAll()
{ {
memset(m_bitArray.unsecureBuffer(), 0, m_bitArray.size()); memset(m_bitArray.mutableBuffer(), 0, m_bitArray.size());
} }
/// Set all the bits. /// Set all the bits.
void setAll() void setAll()
{ {
memset(m_bitArray.unsecureBuffer(), 0xFF, m_bitArray.size()); memset(m_bitArray.mutableBuffer(), 0xFF, m_bitArray.size());
} }
/// Toggle all the bits. /// Toggle all the bits.

View File

@ -3,7 +3,13 @@ ADD_SUBDIRECTORY(poshlib)
SET(CORE_SRCS SET(CORE_SRCS
nvcore.h nvcore.h
DefsGnucDarwin.h
DefsGnucLinux.h
DefsGnucWin32.h
DefsVcWin32.h
Ptr.h Ptr.h
RefCounted.h
RefCounted.cpp
BitArray.h BitArray.h
Memory.h Memory.h
Memory.cpp Memory.cpp
@ -19,7 +25,10 @@ SET(CORE_SRCS
TextWriter.h TextWriter.h
TextWriter.cpp TextWriter.cpp
Radix.h Radix.h
Radix.cpp) Radix.cpp
CpuInfo.h
CpuInfo.cpp
Algorithms.h)
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}) INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})

View File

@ -19,6 +19,7 @@ Do not use memmove in insert & remove, use copy ctors instead.
#include <nvcore/nvcore.h> #include <nvcore/nvcore.h>
#include <nvcore/Memory.h> #include <nvcore/Memory.h>
#include <nvcore/Debug.h> #include <nvcore/Debug.h>
//#include <nvcore/Stream.h>
#include <string.h> // memmove #include <string.h> // memmove
#include <new> // for placement new #include <new> // for placement new
@ -70,40 +71,10 @@ namespace nv
{ {
// Templates // Templates
/// Return the maximum of two values.
template <typename T>
inline const T & max(const T & a, const T & b)
{
//return std::max(a, b);
if( a < b ) {
return b;
}
return a;
}
/// Return the minimum of two values.
template <typename T>
inline const T & min(const T & a, const T & b)
{
//return std::min(a, b);
if( b < a ) {
return b;
}
return a;
}
/// Clamp between two values.
template <typename T>
inline const T & clamp(const T & x, const T & a, const T & b)
{
return min(max(x, a), b);
}
/// Swap two values. /// Swap two values.
template <typename T> template <typename T>
inline void swap(T & a, T & b) inline void swap(T & a, T & b)
{ {
//return std::swap(a, b);
T temp = a; T temp = a;
a = b; a = b;
b = temp; b = temp;
@ -134,16 +105,6 @@ namespace nv
uint operator()(uint x) const { return x; } uint operator()(uint x) const { return x; }
}; };
/// 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];
}
}
/** Return the next power of two. /** Return the next power of two.
* @see http://graphics.stanford.edu/~seander/bithacks.html * @see http://graphics.stanford.edu/~seander/bithacks.html
@ -154,7 +115,7 @@ namespace nv
inline uint nextPowerOfTwo( uint x ) inline uint nextPowerOfTwo( uint x )
{ {
nvDebugCheck( x != 0 ); nvDebugCheck( x != 0 );
#if 1 // On modern CPUs this is as fast as using the bsr instruction. #if 1 // On modern CPUs this is supposed to be as fast as using the bsr instruction.
x--; x--;
x |= x >> 1; x |= x >> 1;
x |= x >> 2; x |= x >> 2;
@ -177,15 +138,6 @@ namespace nv
return (n & (n-1)) == 0; return (n & (n-1)) == 0;
} }
/// Simple iterator interface.
template <typename T>
struct Iterator
{
virtual void advance();
virtual bool isDone();
virtual T current();
};
/** /**
* Replacement for std::vector that is easier to debug and provides * Replacement for std::vector that is easier to debug and provides
@ -252,7 +204,7 @@ namespace nv
const T * buffer() const { return m_buffer; } const T * buffer() const { return m_buffer; }
/// Get vector pointer. /// Get vector pointer.
T * unsecureBuffer() { return m_buffer; } T * mutableBuffer() { return m_buffer; }
/// Is vector empty. /// Is vector empty.
bool isEmpty() const { return m_size == 0; } bool isEmpty() const { return m_size == 0; }

88
src/nvcore/CpuInfo.cpp Normal file
View File

@ -0,0 +1,88 @@
// This code is in the public domain -- castanyo@yahoo.es
#include <nvcore/CpuInfo.h>
#include <nvcore/Debug.h>
using namespace nv;
#if NV_OS_WIN32
#define _WIN32_WINNT 0x0501
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
static bool isWow64()
{
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process");
BOOL bIsWow64 = FALSE;
if (NULL != fnIsWow64Process)
{
if (!fnIsWow64Process(GetCurrentProcess(), &bIsWow64))
{
return false;
}
}
return bIsWow64 == TRUE;
}
#endif // NV_OS_WIN32
uint CpuInfo::processorCount()
{
#if NV_OS_WIN32
SYSTEM_INFO sysInfo;
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
if (isWow64())
{
GetNativeSystemInfo(&sysInfo);
}
else
{
GetSystemInfo(&sysInfo);
}
uint count = (uint)sysInfo.dwNumberOfProcessors;
nvDebugCheck(count >= 1);
return count;
#else
return 1;
#endif
}
uint CpuInfo::coreCount()
{
return 1;
}
bool CpuInfo::hasMMX()
{
return false;
}
bool CpuInfo::hasSSE()
{
return false;
}
bool CpuInfo::hasSSE2()
{
return false;
}
bool CpuInfo::hasSSE3()
{
return false;
}

88
src/nvcore/CpuInfo.h Normal file
View File

@ -0,0 +1,88 @@
// This code is in the public domain -- castanyo@yahoo.es
#ifndef NV_CORE_CPUINFO_H
#define NV_CORE_CPUINFO_H
#include <nvcore/nvcore.h>
#if NV_CC_MSVC
# include <intrin.h> // __rdtsc
#endif
namespace nv
{
// CPU Information.
class CpuInfo
{
static uint processorCount();
static uint coreCount();
static bool hasMMX();
static bool hasSSE();
static bool hasSSE2();
static bool hasSSE3();
};
#if NV_CC_MSVC
#pragma intrinsic(__rdtsc)
inline uint64 rdtsc()
{
return __rdtsc();
}
#endif
#if NV_CC_GNUC
#if defined(__i386__)
inline /*volatile*/ uint64 rdtsc()
{
uint64 x;
//__asm__ volatile ("rdtsc" : "=A" (x));
__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
return x;
}
#elif defined(__x86_64__)
static __inline__ uint64 rdtsc(void)
{
unsigned int hi, lo;
__asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
}
#elif defined(__powerpc__)
static __inline__ uint64 rdtsc(void)
{
uint64 result=0;
unsigned long int upper, lower, tmp;
__asm__ volatile(
"0: \n"
"\tmftbu %0 \n"
"\tmftb %1 \n"
"\tmftbu %2 \n"
"\tcmpw %2,%0 \n"
"\tbne 0b \n"
: "=r"(upper),"=r"(lower),"=r"(tmp)
);
result = upper;
result = result<<32;
result = result|lower;
return(result);
}
#endif
#endif // NV_CC_GNUC
} // nv namespace
#endif // NV_CORE_CPUINFO_H

View File

@ -70,8 +70,6 @@ typedef uint32 uint;
#pragma warning(disable : 4711) // function selected for automatic inlining #pragma warning(disable : 4711) // function selected for automatic inlining
#pragma warning(disable : 4725) // Pentium fdiv bug #pragma warning(disable : 4725) // Pentium fdiv bug
#pragma warning(disable : 4345) // behavior change: an object of POD type constructed with an initializer of the form () will be default-initialized
#pragma warning(disable : 4786) // Identifier was truncated and cannot be debugged. #pragma warning(disable : 4786) // Identifier was truncated and cannot be debugged.
#pragma warning(disable : 4675) // resolved overload was found by argument-dependent lookup #pragma warning(disable : 4675) // resolved overload was found by argument-dependent lookup

View File

@ -8,6 +8,11 @@
#include <stdio.h> // NULL #include <stdio.h> // NULL
#define NV_DECLARE_PTR(Class) \
typedef SmartPtr<class Class> Class ## Ptr; \
typedef SmartPtr<const class Class> ClassConst ## Ptr
namespace nv namespace nv
{ {
@ -93,125 +98,23 @@ private:
T * m_ptr; T * m_ptr;
}; };
#if 0
/** Reference counted base class to be used with Pointer.
*
* The only requirement of the Pointer class is that the RefCounted class implements the
* addRef and release methods.
*/
class RefCounted
{
NV_FORBID_COPY(RefCounted);
public:
/// Ctor.
RefCounted() : m_count(0), m_weak_proxy(NULL)
{
s_total_obj_count++;
}
/// Virtual dtor.
virtual ~RefCounted()
{
nvCheck( m_count == 0 );
nvCheck( s_total_obj_count > 0 );
s_total_obj_count--;
}
/// Increase reference count.
uint addRef() const
{
s_total_ref_count++;
m_count++;
return m_count;
}
/// Decrease reference count and remove when 0.
uint release() const
{
nvCheck( m_count > 0 );
s_total_ref_count--;
m_count--;
if( m_count == 0 ) {
releaseWeakProxy();
delete this;
return 0;
}
return m_count;
}
/// Get weak proxy.
WeakProxy * getWeakProxy() const
{
if (m_weak_proxy == NULL) {
m_weak_proxy = new WeakProxy;
m_weak_proxy->AddRef();
}
return m_weak_proxy;
}
/// Release the weak proxy.
void releaseWeakProxy() const
{
if (m_weak_proxy != NULL) {
m_weak_proxy->NotifyObjectDied();
m_weak_proxy->Release();
m_weak_proxy = NULL;
}
}
/** @name Debug methods: */
//@{
/// Get reference count.
int refCount() const
{
return m_count;
}
/// Get total number of objects.
static int totalObjectCount()
{
return s_total_obj_count;
}
/// Get total number of references.
static int totalReferenceCount()
{
return s_total_ref_count;
}
//@}
private:
NVCORE_API static int s_total_ref_count;
NVCORE_API static int s_total_obj_count;
mutable int m_count;
mutable WeakProxy * weak_proxy;
};
#endif
/// Smart pointer template class. /// Smart pointer template class.
template <class BaseClass> template <class BaseClass>
class Pointer { class SmartPtr {
public: public:
// BaseClass must implement addRef() and release(). // BaseClass must implement addRef() and release().
typedef Pointer<BaseClass> ThisType; typedef SmartPtr<BaseClass> ThisType;
/// Default ctor. /// Default ctor.
Pointer() : m_ptr(NULL) SmartPtr() : m_ptr(NULL)
{ {
} }
/** Other type assignment. */ /** Other type assignment. */
template <class OtherBase> template <class OtherBase>
Pointer( const Pointer<OtherBase> & tc ) SmartPtr( const SmartPtr<OtherBase> & tc )
{ {
m_ptr = static_cast<BaseClass *>( tc.ptr() ); m_ptr = static_cast<BaseClass *>( tc.ptr() );
if( m_ptr ) { if( m_ptr ) {
@ -220,7 +123,7 @@ public:
} }
/** Copy ctor. */ /** Copy ctor. */
Pointer( const ThisType & bc ) SmartPtr( const ThisType & bc )
{ {
m_ptr = bc.ptr(); m_ptr = bc.ptr();
if( m_ptr ) { if( m_ptr ) {
@ -228,8 +131,8 @@ public:
} }
} }
/** Copy cast ctor. Pointer(NULL) is valid. */ /** Copy cast ctor. SmartPtr(NULL) is valid. */
explicit Pointer( BaseClass * bc ) explicit SmartPtr( BaseClass * bc )
{ {
m_ptr = bc; m_ptr = bc;
if( m_ptr ) { if( m_ptr ) {
@ -238,7 +141,7 @@ public:
} }
/** Dtor. */ /** Dtor. */
~Pointer() ~SmartPtr()
{ {
set(NULL); set(NULL);
} }
@ -249,14 +152,14 @@ public:
/** -> operator. */ /** -> operator. */
BaseClass * operator -> () const BaseClass * operator -> () const
{ {
piCheck( m_ptr != NULL ); nvCheck( m_ptr != NULL );
return m_ptr; return m_ptr;
} }
/** * operator. */ /** * operator. */
BaseClass & operator*() const BaseClass & operator*() const
{ {
piCheck( m_ptr != NULL ); nvCheck( m_ptr != NULL );
return *m_ptr; return *m_ptr;
} }
@ -272,7 +175,7 @@ public:
//@{ //@{
/** Other type assignment. */ /** Other type assignment. */
template <class OtherBase> template <class OtherBase>
void operator = ( const Pointer<OtherBase> & tc ) void operator = ( const SmartPtr<OtherBase> & tc )
{ {
set( static_cast<BaseClass *>(tc.ptr()) ); set( static_cast<BaseClass *>(tc.ptr()) );
} }
@ -295,7 +198,7 @@ public:
//@{ //@{
/** Other type equal comparation. */ /** Other type equal comparation. */
template <class OtherBase> template <class OtherBase>
bool operator == ( const Pointer<OtherBase> & other ) const bool operator == ( const SmartPtr<OtherBase> & other ) const
{ {
return m_ptr == other.ptr(); return m_ptr == other.ptr();
} }
@ -314,7 +217,7 @@ public:
/** Other type not equal comparation. */ /** Other type not equal comparation. */
template <class OtherBase> template <class OtherBase>
bool operator != ( const Pointer<OtherBase> & other ) const bool operator != ( const SmartPtr<OtherBase> & other ) const
{ {
return m_ptr != other.ptr(); return m_ptr != other.ptr();
} }

View File

@ -0,0 +1,9 @@
// This code is in the public domain -- castanyo@yahoo.es
#include "RefCounted.h"
using namespace nv;
int nv::RefCounted::s_total_ref_count = 0;
int nv::RefCounted::s_total_obj_count = 0;

114
src/nvcore/RefCounted.h Normal file
View File

@ -0,0 +1,114 @@
// This code is in the public domain -- castanyo@yahoo.es
#ifndef NV_CORE_REFCOUNTED_H
#define NV_CORE_REFCOUNTED_H
#include <nvcore/nvcore.h>
#include <nvcore/Debug.h>
namespace nv
{
/// Reference counted base class to be used with SmartPtr and WeakPtr.
class RefCounted
{
NV_FORBID_COPY(RefCounted);
public:
/// Ctor.
RefCounted() : m_count(0)/*, m_weak_proxy(NULL)*/
{
s_total_obj_count++;
}
/// Virtual dtor.
virtual ~RefCounted()
{
nvCheck( m_count == 0 );
nvCheck( s_total_obj_count > 0 );
s_total_obj_count--;
}
/// Increase reference count.
uint addRef() const
{
s_total_ref_count++;
m_count++;
return m_count;
}
/// Decrease reference count and remove when 0.
uint release() const
{
nvCheck( m_count > 0 );
s_total_ref_count--;
m_count--;
if( m_count == 0 ) {
// releaseWeakProxy();
delete this;
return 0;
}
return m_count;
}
/*
/// Get weak proxy.
WeakProxy * getWeakProxy() const
{
if (m_weak_proxy == NULL) {
m_weak_proxy = new WeakProxy;
m_weak_proxy->AddRef();
}
return m_weak_proxy;
}
/// Release the weak proxy.
void releaseWeakProxy() const
{
if (m_weak_proxy != NULL) {
m_weak_proxy->NotifyObjectDied();
m_weak_proxy->Release();
m_weak_proxy = NULL;
}
}
*/
/** @name Debug methods: */
//@{
/// Get reference count.
int refCount() const
{
return m_count;
}
/// Get total number of objects.
static int totalObjectCount()
{
return s_total_obj_count;
}
/// Get total number of references.
static int totalReferenceCount()
{
return s_total_ref_count;
}
//@}
private:
NVCORE_API static int s_total_ref_count;
NVCORE_API static int s_total_obj_count;
mutable int m_count;
// mutable WeakProxy * weak_proxy;
};
} // nv namespace
#endif // NV_CORE_REFCOUNTED_H

View File

@ -48,7 +48,7 @@ const char * TextReader::readToEnd()
m_text.reserve(size + 1); m_text.reserve(size + 1);
m_text.resize(size); m_text.resize(size);
m_stream->serialize(m_text.unsecureBuffer(), size); m_stream->serialize(m_text.mutableBuffer(), size);
m_text.pushBack('\0'); m_text.pushBack('\0');
return m_text.buffer(); return m_text.buffer();