DYT/Tool/TritonSDK/PublicHeaders/MemAlloc.h

217 lines
5.4 KiB
C
Raw Normal View History

2024-12-25 14:48:51 +00:00
// Copyright (c) 2010-2016 Sundog Software, LLC. All rights reserved worldwide.
/** \file MemAlloc.h
\brief Memory allocation interface for SilverLining.
*/
#ifndef TRITON_MEMALLOC_H
#define TRITON_MEMALLOC_H
#include <cstddef>
#include <string>
#ifdef _WIN32
#define TRITONAPI __cdecl
#else
#define TRITONAPI
#endif
#define TRITON_NEW new
#define TRITON_DELETE delete
#define TRITON_MALLOC Allocator::GetAllocator()->alloc
#define TRITON_FREE Allocator::GetAllocator()->dealloc
namespace Triton
{
/** You may extend the Allocator class to hook your own memory management scheme into Triton.
Instantiate your own implementation of Allocator, and pass it into Allocator::SetAllocator prior to
calling any other Triton methods or instantiating any Triton objects.
Each object in Triton overloads the new and delete operators, and routes memory management through
the Allocator as well.
*/
class Allocator
{
public:
Allocator();
virtual ~Allocator();
/// Allocate a block of memory; defaults to malloc()
virtual void * TRITONAPI alloc(size_t bytes);
/// Free a block of memory; defaults to free()
virtual void TRITONAPI dealloc(void *p);
/// Retrieves the static allocator object
static Allocator * TRITONAPI GetAllocator() {
return sAllocator;
}
/// Sets a new static allocator object. If this is not called, the default
/// implementation using malloc and free is used.
static void TRITONAPI SetAllocator(Allocator *a) {
if( a )
sAllocator = a;
else
sAllocator = &sDefaultAllocator;
}
protected:
static Allocator *sAllocator;
static Allocator sDefaultAllocator;
private:
void *heap;
};
/** This base class for all Triton objects intercepts the new and delete operators,
routing them through Triton::Allocator(). */
class MemObject
{
public:
#if (!(_MSC_VER < 1300))
void *operator new(size_t bytes) {
return TRITON_MALLOC(bytes);
}
void operator delete(void *p) {
TRITON_FREE(p);
}
#endif
};
}
// intercepting STL allocation under VC6 is just hopeless.
#if (_MSC_VER < 1300)
#define TRITON_VECTOR(T) std::vector< T >
#define TRITON_MAP(A, B) std::map< A, B >
#define TRITON_SET(T) std::set< T >
#define TRITON_LIST(T) std::list< T >
#define TRITON_STRING std::string
#define TRITON_STACK(T) std::stack< T >
#else
// Custom STL allocator
#define MAX_ALLOCATOR_SIZE 100E6
template <class T>
class TritonAllocator
{
public:
// type definitions
typedef T value_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
// rebind allocator to type U
template <class U >
struct rebind {
typedef TritonAllocator< U > other;
};
// return address of values
pointer address (reference value) const {
return &value;
}
const_pointer address (const_reference value) const {
return &value;
}
/* constructors and destructor
* - nothing to do because the allocator has no state
*/
TritonAllocator() throw() {
}
TritonAllocator(const TritonAllocator& ) throw() {
}
template <class U >
TritonAllocator (const TritonAllocator< U > &) throw() {
}
~TritonAllocator() throw() {
}
// return maximum number of elements that can be allocated
size_type max_size () const throw() {
return (size_type)(MAX_ALLOCATOR_SIZE / sizeof(T));
}
// allocate but don't initialize num elements of type T
pointer allocate (size_type num, const void* = 0) {
pointer ret = reinterpret_cast<T*>(::Triton::Allocator::GetAllocator()->alloc(num * sizeof(T)));
return ret;
}
// initialize elements of allocated storage p with value value
void construct (pointer p, const T& value) {
// initialize memory with placement new
::new ((void*)p)T(value);
}
// destroy elements of initialized storage p
void destroy (pointer p) {
// destroy objects by calling their destructor
p->~T();
}
// deallocate storage p of deleted elements
void deallocate (pointer p, size_type ) {
::Triton::Allocator::GetAllocator()->dealloc(p);
}
};
// return that all specializations of this allocator are interchangeable
template <class T1, class T2>
bool operator== (const TritonAllocator<T1>&, const TritonAllocator<T2>&) throw()
{
return true;
}
template <class T1, class T2>
bool operator!= (const TritonAllocator<T1>&, const TritonAllocator<T2>&) throw()
{
return false;
}
// Convenience macros for STL object using our allocator
#define TRITON_VECTOR(T) std::vector<T, TritonAllocator< T > >
#define TRITON_MAP(A, B) std::map<A, B, std::less< A >, TritonAllocator< std::pair<A const, B > > >
#define TRITON_SET(T) std::set<T, std::less< T >, TritonAllocator< T > >
#define TRITON_LIST(T) std::list<T, TritonAllocator< T > >
#define TRITON_STRING std::basic_string<char, std::char_traits<char>, TritonAllocator<char> >
#define TRITON_STACK(T) std::stack<T, std::deque< T, TritonAllocator< T > > >
#endif
// "Lazy" wrapper for handling STL objects that were static
template <class T>
class TRITON_LAZY
{
public:
TRITON_LAZY() : obj(0) {}
virtual ~TRITON_LAZY() {
if (obj) TRITON_DELETE obj;
}
T& Get() {
if (!obj) obj = TRITON_NEW T;
return *obj;
}
private:
T* obj;
};
#endif