Restructure repository to include all source folders
Move git root from Client/ to src/ to track all source code: - Client: Game client source (moved to Client/Client/) - Server: Game server source - GameTools: Development tools - CryptoSource: Encryption utilities - database: Database scripts - Script: Game scripts - rylCoder_16.02.2008_src: Legacy coder tools - GMFont, Game: Additional resources 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
// Copyright (C) 2000 Stephen Cleary (shammah@voyager.net)
|
||||
//
|
||||
// This file can be redistributed and/or modified under the terms found
|
||||
// in "copyright.html"
|
||||
// This software and its documentation is provided "as is" without express or
|
||||
// implied warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_POOL_CT_GCD_LCM_HPP
|
||||
#define BOOST_POOL_CT_GCD_LCM_HPP
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/ice.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace details {
|
||||
namespace pool {
|
||||
|
||||
// Compile-time calculation of greatest common divisor and least common multiple
|
||||
|
||||
//
|
||||
// ct_gcd is a compile-time algorithm that calculates the greatest common
|
||||
// divisor of two unsigned integers, using Euclid's algorithm.
|
||||
//
|
||||
// assumes: A != 0 && B != 0
|
||||
//
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
namespace details {
|
||||
template <unsigned A, unsigned B, bool Bis0>
|
||||
struct ct_gcd_helper;
|
||||
template <unsigned A, unsigned B>
|
||||
struct ct_gcd_helper<A, B, false>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(unsigned, A_mod_B_ = A % B);
|
||||
BOOST_STATIC_CONSTANT(unsigned, value =
|
||||
(::boost::details::pool::details::ct_gcd_helper<
|
||||
B, static_cast<unsigned>(A_mod_B_),
|
||||
::boost::type_traits::ice_eq<A_mod_B_, 0>::value
|
||||
>::value) );
|
||||
};
|
||||
template <unsigned A, unsigned B>
|
||||
struct ct_gcd_helper<A, B, true>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(unsigned, value = A);
|
||||
};
|
||||
} // namespace details
|
||||
|
||||
template <unsigned A, unsigned B>
|
||||
struct ct_gcd
|
||||
{
|
||||
BOOST_STATIC_ASSERT(A != 0 && B != 0);
|
||||
BOOST_STATIC_CONSTANT(unsigned, value =
|
||||
(::boost::details::pool::details::ct_gcd_helper<A, B, false>::value) );
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
// Thanks to Peter Dimov for providing this workaround!
|
||||
namespace details {
|
||||
template<unsigned A> struct ct_gcd2
|
||||
{
|
||||
template<unsigned B>
|
||||
struct helper
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(unsigned, value = ct_gcd2<B>::helper<A % B>::value);
|
||||
};
|
||||
template<>
|
||||
struct helper<0>
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(unsigned, value = A);
|
||||
};
|
||||
};
|
||||
} // namespace details
|
||||
|
||||
template<unsigned A, unsigned B> struct ct_gcd
|
||||
{
|
||||
BOOST_STATIC_ASSERT(A != 0 && B != 0);
|
||||
enum { value = details::ct_gcd2<A>::helper<B>::value };
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
//
|
||||
// ct_lcm is a compile-time algorithm that calculates the least common
|
||||
// multiple of two unsigned integers.
|
||||
//
|
||||
// assumes: A != 0 && B != 0
|
||||
//
|
||||
template <unsigned A, unsigned B>
|
||||
struct ct_lcm
|
||||
{
|
||||
BOOST_STATIC_CONSTANT(unsigned, value =
|
||||
(A / ::boost::details::pool::ct_gcd<A, B>::value * B) );
|
||||
};
|
||||
|
||||
} // namespace pool
|
||||
} // namespace details
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,59 @@
|
||||
// Copyright (C) 2000 Stephen Cleary (shammah@voyager.net)
|
||||
//
|
||||
// This file can be redistributed and/or modified under the terms found
|
||||
// in "copyright.html"
|
||||
// This software and its documentation is provided "as is" without express or
|
||||
// implied warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_POOL_GCD_LCM_HPP
|
||||
#define BOOST_POOL_GCD_LCM_HPP
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace details {
|
||||
namespace pool {
|
||||
|
||||
// Greatest common divisor and least common multiple
|
||||
|
||||
//
|
||||
// gcd is an algorithm that calculates the greatest common divisor of two
|
||||
// integers, using Euclid's algorithm.
|
||||
//
|
||||
// Pre: A > 0 && B > 0
|
||||
// Recommended: A > B
|
||||
template <typename Integer>
|
||||
Integer gcd(Integer A, Integer B)
|
||||
{
|
||||
do
|
||||
{
|
||||
const Integer tmp(B);
|
||||
B = A % B;
|
||||
A = tmp;
|
||||
} while (B != 0);
|
||||
|
||||
return A;
|
||||
}
|
||||
|
||||
//
|
||||
// lcm is an algorithm that calculates the least common multiple of two
|
||||
// integers.
|
||||
//
|
||||
// Pre: A > 0 && B > 0
|
||||
// Recommended: A > B
|
||||
template <typename Integer>
|
||||
Integer lcm(const Integer & A, const Integer & B)
|
||||
{
|
||||
Integer ret = A;
|
||||
ret /= gcd(A, B);
|
||||
ret *= B;
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace pool
|
||||
} // namespace details
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2000 Stephen Cleary (shammah@voyager.net)
|
||||
//
|
||||
// This file can be redistributed and/or modified under the terms found
|
||||
// in "copyright.html"
|
||||
// This software and its documentation is provided "as is" without express or
|
||||
// implied warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_POOL_GUARD_HPP
|
||||
#define BOOST_POOL_GUARD_HPP
|
||||
|
||||
// Extremely Light-Weight guard glass
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace details {
|
||||
namespace pool {
|
||||
|
||||
template <typename Mutex>
|
||||
class guard
|
||||
{
|
||||
private:
|
||||
Mutex & mtx;
|
||||
|
||||
guard(const guard &);
|
||||
void operator=(const guard &);
|
||||
|
||||
public:
|
||||
explicit guard(Mutex & nmtx)
|
||||
:mtx(nmtx) { mtx.lock(); }
|
||||
|
||||
~guard() { mtx.unlock(); }
|
||||
};
|
||||
|
||||
} // namespace pool
|
||||
} // namespace details
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
141
Server/RylServerProject/BaseLibrary/boost/pool/detail/mutex.hpp
Normal file
141
Server/RylServerProject/BaseLibrary/boost/pool/detail/mutex.hpp
Normal file
@@ -0,0 +1,141 @@
|
||||
// Copyright (C) 2000 Stephen Cleary (shammah@voyager.net)
|
||||
//
|
||||
// This file can be redistributed and/or modified under the terms found
|
||||
// in "copyright.html"
|
||||
// This software and its documentation is provided "as is" without express or
|
||||
// implied warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_POOL_MUTEX_HPP
|
||||
#define BOOST_POOL_MUTEX_HPP
|
||||
|
||||
// Extremely Light-Weight wrapper classes for OS thread synchronization
|
||||
|
||||
// Configuration: for now, we just choose between pthread or Win32 mutexes or none
|
||||
|
||||
#define BOOST_MUTEX_HELPER_NONE 0
|
||||
#define BOOST_MUTEX_HELPER_WIN32 1
|
||||
#define BOOST_MUTEX_HELPER_PTHREAD 2
|
||||
|
||||
#ifdef WIN32
|
||||
#ifndef __WIN32__
|
||||
#define __WIN32__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_NO_MT
|
||||
// No multithreading -> make locks into no-ops
|
||||
#define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_NONE
|
||||
#else
|
||||
#ifdef __WIN32__
|
||||
#define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_WIN32
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#ifdef _POSIX_THREADS
|
||||
#define BOOST_MUTEX_HELPER BOOST_MUTEX_HELPER_PTHREAD
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_MUTEX_HELPER
|
||||
#error Unable to determine platform mutex type; define BOOST_NO_MT to assume single-threaded
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef __WIN32__
|
||||
#include <windows.h>
|
||||
#endif
|
||||
#ifdef _POSIX_THREADS
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace details {
|
||||
namespace pool {
|
||||
|
||||
#ifdef __WIN32__
|
||||
|
||||
class win32_mutex
|
||||
{
|
||||
private:
|
||||
CRITICAL_SECTION mtx;
|
||||
|
||||
win32_mutex(const win32_mutex &);
|
||||
void operator=(const win32_mutex &);
|
||||
|
||||
public:
|
||||
win32_mutex()
|
||||
{ InitializeCriticalSection(&mtx); }
|
||||
|
||||
~win32_mutex()
|
||||
{ DeleteCriticalSection(&mtx); }
|
||||
|
||||
void lock()
|
||||
{ EnterCriticalSection(&mtx); }
|
||||
|
||||
void unlock()
|
||||
{ LeaveCriticalSection(&mtx); }
|
||||
};
|
||||
|
||||
#endif // defined(__WIN32__)
|
||||
|
||||
#ifdef _POSIX_THREADS
|
||||
|
||||
class pthread_mutex
|
||||
{
|
||||
private:
|
||||
pthread_mutex_t mtx;
|
||||
|
||||
pthread_mutex(const pthread_mutex &);
|
||||
void operator=(const pthread_mutex &);
|
||||
|
||||
public:
|
||||
pthread_mutex()
|
||||
{ pthread_mutex_init(&mtx, 0); }
|
||||
|
||||
~pthread_mutex()
|
||||
{ pthread_mutex_destroy(&mtx); }
|
||||
|
||||
void lock()
|
||||
{ pthread_mutex_lock(&mtx); }
|
||||
|
||||
void unlock()
|
||||
{ pthread_mutex_unlock(&mtx); }
|
||||
};
|
||||
|
||||
#endif // defined(_POSIX_THREADS)
|
||||
|
||||
class null_mutex
|
||||
{
|
||||
private:
|
||||
null_mutex(const null_mutex &);
|
||||
void operator=(const null_mutex &);
|
||||
|
||||
public:
|
||||
null_mutex() { }
|
||||
|
||||
static void lock() { }
|
||||
static void unlock() { }
|
||||
};
|
||||
|
||||
#if BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_NONE
|
||||
typedef null_mutex default_mutex;
|
||||
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_WIN32
|
||||
typedef win32_mutex default_mutex;
|
||||
#elif BOOST_MUTEX_HELPER == BOOST_MUTEX_HELPER_PTHREAD
|
||||
typedef pthread_mutex default_mutex;
|
||||
#endif
|
||||
|
||||
} // namespace pool
|
||||
} // namespace details
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#undef BOOST_MUTEX_HELPER_WIN32
|
||||
#undef BOOST_MUTEX_HELPER_PTHREAD
|
||||
#undef BOOST_MUTEX_HELPER_NONE
|
||||
#undef BOOST_MUTEX_HELPER
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,858 @@
|
||||
// Copyright (C) 2000 Stephen Cleary (shammah@voyager.net)
|
||||
//
|
||||
// Permission to copy, use, and distribute this software is granted, provided
|
||||
// that this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted,
|
||||
// provided that this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty, and
|
||||
// with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// This file was AUTOMATICALLY GENERATED from "pool_c~1.m4"
|
||||
// Do NOT include directly!
|
||||
// Do NOT edit!
|
||||
|
||||
template <typename T0>
|
||||
element_type * construct(T0 & a0)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0>
|
||||
element_type * construct(const T0 & a0)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0>
|
||||
element_type * construct(volatile T0 & a0)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0>
|
||||
element_type * construct(const volatile T0 & a0)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(T0 & a0, T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(const T0 & a0, T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(volatile T0 & a0, T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(const volatile T0 & a0, T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(T0 & a0, const T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(const T0 & a0, const T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(volatile T0 & a0, const T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(const volatile T0 & a0, const T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(T0 & a0, volatile T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(const T0 & a0, volatile T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(volatile T0 & a0, volatile T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(const volatile T0 & a0, volatile T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(T0 & a0, const volatile T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(const T0 & a0, const volatile T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(volatile T0 & a0, const volatile T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(const volatile T0 & a0, const volatile T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, const T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, const T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, const T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, const T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, volatile T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, volatile T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, volatile T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, volatile T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, const volatile T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, const volatile T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, const volatile T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, const volatile T1 & a1, T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, const T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, const T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, const T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, const T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, volatile T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, volatile T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, volatile T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, volatile T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, const volatile T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, const volatile T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, const volatile T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, const volatile T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, const T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, const T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, const T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, const T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, volatile T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, volatile T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, volatile T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, volatile T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, const volatile T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, const volatile T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, const volatile T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, const volatile T1 & a1, volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, const T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, const T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, const T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, const T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, volatile T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, volatile T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, volatile T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, volatile T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(T0 & a0, const volatile T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, const volatile T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(volatile T0 & a0, const volatile T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const volatile T0 & a0, const volatile T1 & a1, const volatile T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
// Copyright (C) 2000 Stephen Cleary (shammah@voyager.net)
|
||||
//
|
||||
// This file can be redistributed and/or modified under the terms found
|
||||
// in "copyright.html"
|
||||
// This software and its documentation is provided "as is" without express or
|
||||
// implied warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
// This file was AUTOMATICALLY GENERATED from "stdin"
|
||||
// Do NOT include directly!
|
||||
// Do NOT edit!
|
||||
|
||||
template <typename T0>
|
||||
element_type * construct(const T0 & a0)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1>
|
||||
element_type * construct(const T0 & a0, const T1 & a1)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
template <typename T0, typename T1, typename T2>
|
||||
element_type * construct(const T0 & a0, const T1 & a1, const T2 & a2)
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(a0, a1, a2); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
// Copyright (C) 2000 Stephen Cleary (shammah@voyager.net)
|
||||
//
|
||||
// This file can be redistributed and/or modified under the terms found
|
||||
// in "copyright.html"
|
||||
// This software and its documentation is provided "as is" without express or
|
||||
// implied warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_POOL_SINGLETON_HPP
|
||||
#define BOOST_POOL_SINGLETON_HPP
|
||||
|
||||
// The following code might be put into some Boost.Config header in a later revision
|
||||
#ifdef __BORLANDC__
|
||||
# pragma option push -w-inl
|
||||
#endif
|
||||
|
||||
//
|
||||
// The following helper classes are placeholders for a generic "singleton"
|
||||
// class. The classes below support usage of singletons, including use in
|
||||
// program startup/shutdown code, AS LONG AS there is only one thread
|
||||
// running before main() begins, and only one thread running after main()
|
||||
// exits.
|
||||
//
|
||||
// This class is also limited in that it can only provide singleton usage for
|
||||
// classes with default constructors.
|
||||
//
|
||||
|
||||
// The design of this class is somewhat twisted, but can be followed by the
|
||||
// calling inheritance. Let us assume that there is some user code that
|
||||
// calls "singleton_default<T>::instance()". The following (convoluted)
|
||||
// sequence ensures that the same function will be called before main():
|
||||
// instance() contains a call to create_object.do_nothing()
|
||||
// Thus, object_creator is implicitly instantiated, and create_object
|
||||
// must exist.
|
||||
// Since create_object is a static member, its constructor must be
|
||||
// called before main().
|
||||
// The constructor contains a call to instance(), thus ensuring that
|
||||
// instance() will be called before main().
|
||||
// The first time instance() is called (i.e., before main()) is the
|
||||
// latest point in program execution where the object of type T
|
||||
// can be created.
|
||||
// Thus, any call to instance() will auto-magically result in a call to
|
||||
// instance() before main(), unless already present.
|
||||
// Furthermore, since the instance() function contains the object, instead
|
||||
// of the singleton_default class containing a static instance of the
|
||||
// object, that object is guaranteed to be constructed (at the latest) in
|
||||
// the first call to instance(). This permits calls to instance() from
|
||||
// static code, even if that code is called before the file-scope objects
|
||||
// in this file have been initialized.
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace details {
|
||||
namespace pool {
|
||||
|
||||
// T must be: no-throw default constructible and no-throw destructible
|
||||
template <typename T>
|
||||
struct singleton_default
|
||||
{
|
||||
private:
|
||||
struct object_creator
|
||||
{
|
||||
// This constructor does nothing more than ensure that instance()
|
||||
// is called before main() begins, thus creating the static
|
||||
// T object before multithreading race issues can come up.
|
||||
object_creator() { singleton_default<T>::instance(); }
|
||||
inline void do_nothing() const { }
|
||||
};
|
||||
static object_creator create_object;
|
||||
|
||||
singleton_default();
|
||||
|
||||
public:
|
||||
typedef T object_type;
|
||||
|
||||
// If, at any point (in user code), singleton_default<T>::instance()
|
||||
// is called, then the following function is instantiated.
|
||||
static object_type & instance()
|
||||
{
|
||||
// This is the object that we return a reference to.
|
||||
// It is guaranteed to be created before main() begins because of
|
||||
// the next line.
|
||||
static object_type obj;
|
||||
|
||||
// The following line does nothing else than force the instantiation
|
||||
// of singleton_default<T>::create_object, whose constructor is
|
||||
// called before main() begins.
|
||||
create_object.do_nothing();
|
||||
|
||||
return obj;
|
||||
}
|
||||
};
|
||||
template <typename T>
|
||||
typename singleton_default<T>::object_creator
|
||||
singleton_default<T>::create_object;
|
||||
|
||||
} // namespace pool
|
||||
} // namespace details
|
||||
|
||||
} // namespace boost
|
||||
|
||||
// The following code might be put into some Boost.Config header in a later revision
|
||||
#ifdef __BORLANDC__
|
||||
# pragma option pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
158
Server/RylServerProject/BaseLibrary/boost/pool/object_pool.hpp
Normal file
158
Server/RylServerProject/BaseLibrary/boost/pool/object_pool.hpp
Normal file
@@ -0,0 +1,158 @@
|
||||
// Copyright (C) 2000, 2001 Stephen Cleary (shammah@voyager.net)
|
||||
//
|
||||
// This file can be redistributed and/or modified under the terms found
|
||||
// in "copyright.html"
|
||||
// This software and its documentation is provided "as is" without express or
|
||||
// implied warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_OBJECT_POOL_HPP
|
||||
#define BOOST_OBJECT_POOL_HPP
|
||||
|
||||
#include <boost/pool/poolfwd.hpp>
|
||||
|
||||
// boost::pool
|
||||
#include <boost/pool/pool.hpp>
|
||||
|
||||
// The following code will be put into Boost.Config in a later revision
|
||||
#if defined(BOOST_MSVC) || defined(__KCC)
|
||||
# define BOOST_NO_TEMPLATE_CV_REF_OVERLOADS
|
||||
#endif
|
||||
|
||||
// The following code might be put into some Boost.Config header in a later revision
|
||||
#ifdef __BORLANDC__
|
||||
# pragma option push -w-inl
|
||||
#endif
|
||||
|
||||
// There are a few places in this file where the expression "this->m" is used.
|
||||
// This expression is used to force instantiation-time name lookup, which I am
|
||||
// informed is required for strict Standard compliance. It's only necessary
|
||||
// if "m" is a member of a base class that is dependent on a template
|
||||
// parameter.
|
||||
// Thanks to Jens Maurer for pointing this out!
|
||||
|
||||
namespace boost {
|
||||
|
||||
// T must have a non-throwing destructor
|
||||
template <typename T, typename UserAllocator>
|
||||
class object_pool: protected pool<UserAllocator>
|
||||
{
|
||||
public:
|
||||
typedef T element_type;
|
||||
typedef UserAllocator user_allocator;
|
||||
typedef typename pool<UserAllocator>::size_type size_type;
|
||||
typedef typename pool<UserAllocator>::difference_type difference_type;
|
||||
|
||||
protected:
|
||||
pool<UserAllocator> & store() { return *this; }
|
||||
const pool<UserAllocator> & store() const { return *this; }
|
||||
|
||||
// for the sake of code readability :)
|
||||
static void * & nextof(void * const ptr)
|
||||
{ return *(static_cast<void **>(ptr)); }
|
||||
|
||||
public:
|
||||
// This constructor parameter is an extension!
|
||||
explicit object_pool(const size_type next_size = 32)
|
||||
:pool<UserAllocator>(sizeof(T), next_size) { }
|
||||
|
||||
~object_pool();
|
||||
|
||||
// Returns 0 if out-of-memory
|
||||
element_type * malloc()
|
||||
{ return static_cast<element_type *>(store().ordered_malloc()); }
|
||||
void free(element_type * const chunk)
|
||||
{ store().ordered_free(chunk); }
|
||||
bool is_from(element_type * const chunk) const
|
||||
{ return store().is_from(chunk); }
|
||||
|
||||
element_type * construct()
|
||||
{
|
||||
element_type * const ret = malloc();
|
||||
if (ret == 0)
|
||||
return ret;
|
||||
try { new (ret) element_type(); }
|
||||
catch (...) { free(ret); throw; }
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Include automatically-generated file for family of template construct()
|
||||
// functions
|
||||
#ifndef BOOST_NO_TEMPLATE_CV_REF_OVERLOADS
|
||||
# include <boost/pool/detail/pool_construct.inc>
|
||||
#else
|
||||
# include <boost/pool/detail/pool_construct_simple.inc>
|
||||
#endif
|
||||
|
||||
void destroy(element_type * const chunk)
|
||||
{
|
||||
chunk->~T();
|
||||
free(chunk);
|
||||
}
|
||||
|
||||
// These functions are extensions!
|
||||
size_type get_next_size() const { return store().get_next_size(); }
|
||||
void set_next_size(const size_type x) { store().set_next_size(x); }
|
||||
};
|
||||
|
||||
template <typename T, typename UserAllocator>
|
||||
object_pool<T, UserAllocator>::~object_pool()
|
||||
{
|
||||
// handle trivial case
|
||||
if (!this->list.valid())
|
||||
return;
|
||||
|
||||
details::PODptr<size_type> iter = this->list;
|
||||
details::PODptr<size_type> next = iter;
|
||||
|
||||
// Start 'freed_iter' at beginning of free list
|
||||
void * freed_iter = this->first;
|
||||
|
||||
const size_type partition_size = this->alloc_size();
|
||||
|
||||
do
|
||||
{
|
||||
// increment next
|
||||
next = next.next();
|
||||
|
||||
// delete all contained objects that aren't freed
|
||||
|
||||
// Iterate 'i' through all chunks in the memory block
|
||||
for (char * i = iter.begin(); i != iter.end(); i += partition_size)
|
||||
{
|
||||
// If this chunk is free
|
||||
if (i == freed_iter)
|
||||
{
|
||||
// Increment freed_iter to point to next in free list
|
||||
freed_iter = nextof(freed_iter);
|
||||
|
||||
// Continue searching chunks in the memory block
|
||||
continue;
|
||||
}
|
||||
|
||||
// This chunk is not free (allocated), so call its destructor
|
||||
static_cast<T *>(static_cast<void *>(i))->~T();
|
||||
// and continue searching chunks in the memory block
|
||||
}
|
||||
|
||||
// free storage
|
||||
UserAllocator::free(iter.begin());
|
||||
|
||||
// increment iter
|
||||
iter = next;
|
||||
} while (iter.valid());
|
||||
|
||||
// Make the block list empty so that the inherited destructor doesn't try to
|
||||
// free it again.
|
||||
this->list.invalidate();
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
// The following code might be put into some Boost.Config header in a later revision
|
||||
#ifdef __BORLANDC__
|
||||
# pragma option pop
|
||||
#endif
|
||||
|
||||
#endif
|
||||
568
Server/RylServerProject/BaseLibrary/boost/pool/pool.hpp
Normal file
568
Server/RylServerProject/BaseLibrary/boost/pool/pool.hpp
Normal file
@@ -0,0 +1,568 @@
|
||||
// Copyright (C) 2000, 2001 Stephen Cleary (shammah@voyager.net)
|
||||
//
|
||||
// This file can be redistributed and/or modified under the terms found
|
||||
// in "copyright.html"
|
||||
// This software and its documentation is provided "as is" without express or
|
||||
// implied warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_POOL_HPP
|
||||
#define BOOST_POOL_HPP
|
||||
|
||||
#include <boost/config.hpp> // for workarounds
|
||||
|
||||
// std::less, std::less_equal, std::greater
|
||||
#include <functional>
|
||||
// new[], delete[], std::nothrow
|
||||
#include <new>
|
||||
// std::size_t, std::ptrdiff_t
|
||||
#include <cstddef>
|
||||
// std::malloc, std::free
|
||||
#include <cstdlib>
|
||||
// std::invalid_argument
|
||||
#include <exception>
|
||||
// std::max
|
||||
#include <algorithm>
|
||||
|
||||
#include <boost/pool/poolfwd.hpp>
|
||||
|
||||
// boost::details::pool::ct_lcm
|
||||
#include <boost/pool/detail/ct_gcd_lcm.hpp>
|
||||
// boost::details::pool::lcm
|
||||
#include <boost/pool/detail/gcd_lcm.hpp>
|
||||
// boost::simple_segregated_storage
|
||||
#include <boost/pool/simple_segregated_storage.hpp>
|
||||
|
||||
#ifdef BOOST_NO_STDC_NAMESPACE
|
||||
namespace std { using ::malloc; using ::free; }
|
||||
#endif
|
||||
|
||||
// There are a few places in this file where the expression "this->m" is used.
|
||||
// This expression is used to force instantiation-time name lookup, which I am
|
||||
// informed is required for strict Standard compliance. It's only necessary
|
||||
// if "m" is a member of a base class that is dependent on a template
|
||||
// parameter.
|
||||
// Thanks to Jens Maurer for pointing this out!
|
||||
|
||||
namespace boost {
|
||||
|
||||
struct default_user_allocator_new_delete
|
||||
{
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
static char * malloc(const size_type bytes)
|
||||
{ return new (std::nothrow) char[bytes]; }
|
||||
static void free(char * const block)
|
||||
{ delete [] block; }
|
||||
};
|
||||
|
||||
struct default_user_allocator_malloc_free
|
||||
{
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
static char * malloc(const size_type bytes)
|
||||
{ return reinterpret_cast<char *>(std::malloc(bytes)); }
|
||||
static void free(char * const block)
|
||||
{ std::free(block); }
|
||||
};
|
||||
|
||||
namespace details {
|
||||
|
||||
// PODptr is a class that pretends to be a "pointer" to different class types
|
||||
// that don't really exist. It provides member functions to access the "data"
|
||||
// of the "object" it points to. Since these "class" types are of variable
|
||||
// size, and contains some information at the *end* of its memory (for
|
||||
// alignment reasons), PODptr must contain the size of this "class" as well as
|
||||
// the pointer to this "object".
|
||||
template <typename SizeType>
|
||||
class PODptr
|
||||
{
|
||||
public:
|
||||
typedef SizeType size_type;
|
||||
|
||||
private:
|
||||
char * ptr;
|
||||
size_type sz;
|
||||
|
||||
char * ptr_next_size() const
|
||||
{ return (ptr + sz - sizeof(size_type)); }
|
||||
char * ptr_next_ptr() const
|
||||
{
|
||||
return (ptr_next_size() -
|
||||
pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value);
|
||||
}
|
||||
|
||||
public:
|
||||
PODptr(char * const nptr, const size_type nsize)
|
||||
:ptr(nptr), sz(nsize) { }
|
||||
PODptr()
|
||||
:ptr(0), sz(0) { }
|
||||
|
||||
bool valid() const { return (begin() != 0); }
|
||||
void invalidate() { begin() = 0; }
|
||||
char * & begin() { return ptr; }
|
||||
char * begin() const { return ptr; }
|
||||
char * end() const { return ptr_next_ptr(); }
|
||||
size_type total_size() const { return sz; }
|
||||
size_type element_size() const
|
||||
{
|
||||
return (sz - sizeof(size_type) -
|
||||
pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value);
|
||||
}
|
||||
|
||||
size_type & next_size() const
|
||||
{ return *(reinterpret_cast<size_type *>(ptr_next_size())); }
|
||||
char * & next_ptr() const
|
||||
{ return *(reinterpret_cast<char **>(ptr_next_ptr())); }
|
||||
|
||||
PODptr next() const
|
||||
{ return PODptr<size_type>(next_ptr(), next_size()); }
|
||||
void next(const PODptr & arg) const
|
||||
{
|
||||
next_ptr() = arg.begin();
|
||||
next_size() = arg.total_size();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace details
|
||||
|
||||
template <typename UserAllocator>
|
||||
class pool: protected simple_segregated_storage<
|
||||
typename UserAllocator::size_type>
|
||||
{
|
||||
public:
|
||||
typedef UserAllocator user_allocator;
|
||||
typedef typename UserAllocator::size_type size_type;
|
||||
typedef typename UserAllocator::difference_type difference_type;
|
||||
|
||||
private:
|
||||
BOOST_STATIC_CONSTANT(unsigned, min_alloc_size =
|
||||
(::boost::details::pool::ct_lcm<sizeof(void *), sizeof(size_type)>::value) );
|
||||
|
||||
// Returns 0 if out-of-memory
|
||||
// Called if malloc/ordered_malloc needs to resize the free list
|
||||
void * malloc_need_resize();
|
||||
void * ordered_malloc_need_resize();
|
||||
|
||||
protected:
|
||||
details::PODptr<size_type> list;
|
||||
|
||||
simple_segregated_storage<size_type> & store() { return *this; }
|
||||
const simple_segregated_storage<size_type> & store() const { return *this; }
|
||||
const size_type requested_size;
|
||||
size_type next_size;
|
||||
|
||||
// finds which POD in the list 'chunk' was allocated from
|
||||
details::PODptr<size_type> find_POD(void * const chunk) const;
|
||||
|
||||
// is_from() tests a chunk to determine if it belongs in a block
|
||||
static bool is_from(void * const chunk, char * const i,
|
||||
const size_type sizeof_i)
|
||||
{
|
||||
// We use std::less_equal and std::less to test 'chunk'
|
||||
// against the array bounds because standard operators
|
||||
// may return unspecified results.
|
||||
// This is to ensure portability. The operators < <= > >= are only
|
||||
// defined for pointers to objects that are 1) in the same array, or
|
||||
// 2) subobjects of the same object [5.9/2].
|
||||
// The functor objects guarantee a total order for any pointer [20.3.3/8]
|
||||
//WAS:
|
||||
// return (std::less_equal<void *>()(static_cast<void *>(i), chunk)
|
||||
// && std::less<void *>()(chunk,
|
||||
// static_cast<void *>(i + sizeof_i)));
|
||||
std::less_equal<void *> lt_eq;
|
||||
std::less<void *> lt;
|
||||
return (lt_eq(i, chunk) && lt(chunk, i + sizeof_i));
|
||||
}
|
||||
|
||||
size_type alloc_size() const
|
||||
{
|
||||
const unsigned min_size = min_alloc_size;
|
||||
return details::pool::lcm<size_type>(requested_size, min_size);
|
||||
}
|
||||
|
||||
// for the sake of code readability :)
|
||||
static void * & nextof(void * const ptr)
|
||||
{ return *(static_cast<void **>(ptr)); }
|
||||
|
||||
public:
|
||||
// The second parameter here is an extension!
|
||||
// pre: npartition_size != 0 && nnext_size != 0
|
||||
explicit pool(const size_type nrequested_size,
|
||||
const size_type nnext_size = 32)
|
||||
:list(0, 0), requested_size(nrequested_size), next_size(nnext_size)
|
||||
{ }
|
||||
|
||||
~pool() { purge_memory(); }
|
||||
|
||||
size_type get_requested_size() const { return requested_size; }
|
||||
|
||||
// Releases memory blocks that don't have chunks allocated
|
||||
// pre: lists are ordered
|
||||
// Returns true if memory was actually deallocated
|
||||
bool release_memory();
|
||||
|
||||
// Releases *all* memory blocks, even if chunks are still allocated
|
||||
// Returns true if memory was actually deallocated
|
||||
bool purge_memory();
|
||||
|
||||
// These functions are extensions!
|
||||
size_type get_next_size() const { return next_size; }
|
||||
void set_next_size(const size_type nnext_size) { next_size = nnext_size; }
|
||||
|
||||
// Both malloc and ordered_malloc do a quick inlined check first for any
|
||||
// free chunks. Only if we need to get another memory block do we call
|
||||
// the non-inlined *_need_resize() functions.
|
||||
// Returns 0 if out-of-memory
|
||||
void * malloc()
|
||||
{
|
||||
// Look for a non-empty storage
|
||||
if (!store().empty())
|
||||
return store().malloc();
|
||||
return malloc_need_resize();
|
||||
}
|
||||
|
||||
void * ordered_malloc()
|
||||
{
|
||||
// Look for a non-empty storage
|
||||
if (!store().empty())
|
||||
return store().malloc();
|
||||
return ordered_malloc_need_resize();
|
||||
}
|
||||
|
||||
// Returns 0 if out-of-memory
|
||||
// Allocate a contiguous section of n chunks
|
||||
void * ordered_malloc(size_type n);
|
||||
|
||||
// pre: 'chunk' must have been previously
|
||||
// returned by *this.malloc().
|
||||
void free(void * const chunk)
|
||||
{ store().free(chunk); }
|
||||
|
||||
// pre: 'chunk' must have been previously
|
||||
// returned by *this.malloc().
|
||||
void ordered_free(void * const chunk)
|
||||
{ store().ordered_free(chunk); }
|
||||
|
||||
// pre: 'chunk' must have been previously
|
||||
// returned by *this.malloc(n).
|
||||
void free(void * const chunks, const size_type n)
|
||||
{
|
||||
const size_type partition_size = alloc_size();
|
||||
const size_type total_req_size = n * requested_size;
|
||||
const size_type num_chunks = total_req_size / partition_size +
|
||||
static_cast<bool>(total_req_size % partition_size);
|
||||
|
||||
store().free_n(chunks, num_chunks, partition_size);
|
||||
}
|
||||
|
||||
// pre: 'chunk' must have been previously
|
||||
// returned by *this.malloc(n).
|
||||
void ordered_free(void * const chunks, const size_type n)
|
||||
{
|
||||
const size_type partition_size = alloc_size();
|
||||
const size_type total_req_size = n * requested_size;
|
||||
const size_type num_chunks = total_req_size / partition_size +
|
||||
static_cast<bool>(total_req_size % partition_size);
|
||||
|
||||
store().ordered_free_n(chunks, num_chunks, partition_size);
|
||||
}
|
||||
|
||||
// is_from() tests a chunk to determine if it was allocated from *this
|
||||
bool is_from(void * const chunk) const
|
||||
{
|
||||
return (find_POD(chunk).valid());
|
||||
}
|
||||
};
|
||||
|
||||
template <typename UserAllocator>
|
||||
bool pool<UserAllocator>::release_memory()
|
||||
{
|
||||
// This is the return value: it will be set to true when we actually call
|
||||
// UserAllocator::free(..)
|
||||
bool ret = false;
|
||||
|
||||
// This is a current & previous iterator pair over the memory block list
|
||||
details::PODptr<size_type> ptr = list;
|
||||
details::PODptr<size_type> prev;
|
||||
|
||||
// This is a current & previous iterator pair over the free memory chunk list
|
||||
// Note that "prev_free" in this case does NOT point to the previous memory
|
||||
// chunk in the free list, but rather the last free memory chunk before the
|
||||
// current block.
|
||||
void * free = this->first;
|
||||
void * prev_free = 0;
|
||||
|
||||
const size_type partition_size = alloc_size();
|
||||
|
||||
// Search through all the all the allocated memory blocks
|
||||
while (ptr.valid())
|
||||
{
|
||||
// At this point:
|
||||
// ptr points to a valid memory block
|
||||
// free points to either:
|
||||
// 0 if there are no more free chunks
|
||||
// the first free chunk in this or some next memory block
|
||||
// prev_free points to either:
|
||||
// the last free chunk in some previous memory block
|
||||
// 0 if there is no such free chunk
|
||||
|
||||
// If there are no more free memory chunks, then every remaining
|
||||
// block is allocated out to its fullest capacity, and we can't
|
||||
// release any more memory
|
||||
if (free == 0)
|
||||
return ret;
|
||||
|
||||
// We have to check all the chunks. If they are *all* free (i.e., present
|
||||
// in the free list), then we can free the block.
|
||||
bool all_chunks_free = true;
|
||||
|
||||
// Iterate 'i' through all chunks in the memory block
|
||||
for (char * i = ptr.begin(); i != ptr.end(); i += partition_size)
|
||||
{
|
||||
// If this chunk is not free
|
||||
if (i != free)
|
||||
{
|
||||
// We won't be able to free this block
|
||||
all_chunks_free = false;
|
||||
|
||||
// Abort searching the chunks; we won't be able to free this
|
||||
// block because a chunk is not free.
|
||||
break;
|
||||
}
|
||||
|
||||
// We do not increment prev_free because we are in the same block
|
||||
free = nextof(free);
|
||||
}
|
||||
|
||||
const details::PODptr<size_type> next = ptr.next();
|
||||
|
||||
if (!all_chunks_free)
|
||||
{
|
||||
// Rush through all free chunks from this block
|
||||
std::less<void *> lt;
|
||||
void * const last = ptr.end() - partition_size;
|
||||
do
|
||||
{
|
||||
free = nextof(free);
|
||||
} while (lt(free, last));
|
||||
|
||||
// Increment free one more time and set prev_free to maintain the
|
||||
// invariants:
|
||||
// free points to the first free chunk in some next memory block, or
|
||||
// 0 if there is no such chunk.
|
||||
// prev_free points to the last free chunk in this memory block.
|
||||
prev_free = free;
|
||||
free = nextof(free);
|
||||
}
|
||||
else
|
||||
{
|
||||
// All chunks from this block are free
|
||||
|
||||
// Remove block from list
|
||||
if (prev.valid())
|
||||
prev.next(next);
|
||||
else
|
||||
list = next;
|
||||
|
||||
// Remove all entries in the free list from this block
|
||||
if (prev_free != 0)
|
||||
nextof(prev_free) = free;
|
||||
else
|
||||
this->first = free;
|
||||
|
||||
// And release memory
|
||||
UserAllocator::free(ptr.begin());
|
||||
ret = true;
|
||||
}
|
||||
|
||||
// Increment ptr
|
||||
ptr = next;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename UserAllocator>
|
||||
bool pool<UserAllocator>::purge_memory()
|
||||
{
|
||||
details::PODptr<size_type> iter = list;
|
||||
|
||||
if (!iter.valid())
|
||||
return false;
|
||||
|
||||
do
|
||||
{
|
||||
// hold "next" pointer
|
||||
const details::PODptr<size_type> next = iter.next();
|
||||
|
||||
// delete the storage
|
||||
UserAllocator::free(iter.begin());
|
||||
|
||||
// increment iter
|
||||
iter = next;
|
||||
} while (iter.valid());
|
||||
|
||||
list.invalidate();
|
||||
this->first = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename UserAllocator>
|
||||
void * pool<UserAllocator>::malloc_need_resize()
|
||||
{
|
||||
// No memory in any of our storages; make a new storage,
|
||||
const size_type partition_size = alloc_size();
|
||||
const size_type POD_size = next_size * partition_size +
|
||||
details::pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value + sizeof(size_type);
|
||||
char * const ptr = UserAllocator::malloc(POD_size);
|
||||
if (ptr == 0)
|
||||
return 0;
|
||||
const details::PODptr<size_type> node(ptr, POD_size);
|
||||
next_size <<= 1;
|
||||
|
||||
// initialize it,
|
||||
store().add_block(node.begin(), node.element_size(), partition_size);
|
||||
|
||||
// insert it into the list,
|
||||
node.next(list);
|
||||
list = node;
|
||||
|
||||
// and return a chunk from it.
|
||||
return store().malloc();
|
||||
}
|
||||
|
||||
template <typename UserAllocator>
|
||||
void * pool<UserAllocator>::ordered_malloc_need_resize()
|
||||
{
|
||||
// No memory in any of our storages; make a new storage,
|
||||
const size_type partition_size = alloc_size();
|
||||
const size_type POD_size = next_size * partition_size +
|
||||
details::pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value + sizeof(size_type);
|
||||
char * const ptr = UserAllocator::malloc(POD_size);
|
||||
if (ptr == 0)
|
||||
return 0;
|
||||
const details::PODptr<size_type> node(ptr, POD_size);
|
||||
next_size <<= 1;
|
||||
|
||||
// initialize it,
|
||||
// (we can use "add_block" here because we know that
|
||||
// the free list is empty, so we don't have to use
|
||||
// the slower ordered version)
|
||||
store().add_block(node.begin(), node.element_size(), partition_size);
|
||||
|
||||
// insert it into the list,
|
||||
// handle border case
|
||||
if (!list.valid() || std::greater<void *>()(list.begin(), node.begin()))
|
||||
{
|
||||
node.next(list);
|
||||
list = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
details::PODptr<size_type> prev = list;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// if we're about to hit the end or
|
||||
// if we've found where "node" goes
|
||||
if (prev.next_ptr() == 0
|
||||
|| std::greater<void *>()(prev.next_ptr(), node.begin()))
|
||||
break;
|
||||
|
||||
prev = prev.next();
|
||||
}
|
||||
|
||||
node.next(prev.next());
|
||||
prev.next(node);
|
||||
}
|
||||
|
||||
// and return a chunk from it.
|
||||
return store().malloc();
|
||||
}
|
||||
|
||||
template <typename UserAllocator>
|
||||
void * pool<UserAllocator>::ordered_malloc(const size_type n)
|
||||
{
|
||||
const size_type partition_size = alloc_size();
|
||||
const size_type total_req_size = n * requested_size;
|
||||
const size_type num_chunks = total_req_size / partition_size +
|
||||
static_cast<bool>(total_req_size % partition_size);
|
||||
|
||||
void * ret = store().malloc_n(num_chunks, partition_size);
|
||||
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
// Not enougn memory in our storages; make a new storage,
|
||||
next_size = std::max(next_size, num_chunks);
|
||||
const size_type POD_size = next_size * partition_size +
|
||||
details::pool::ct_lcm<sizeof(size_type), sizeof(void *)>::value + sizeof(size_type);
|
||||
char * const ptr = UserAllocator::malloc(POD_size);
|
||||
if (ptr == 0)
|
||||
return 0;
|
||||
const details::PODptr<size_type> node(ptr, POD_size);
|
||||
|
||||
// Split up block so we can use what wasn't requested
|
||||
// (we can use "add_block" here because we know that
|
||||
// the free list is empty, so we don't have to use
|
||||
// the slower ordered version)
|
||||
if (next_size > num_chunks)
|
||||
store().add_block(node.begin() + num_chunks * partition_size,
|
||||
node.element_size() - num_chunks * partition_size, partition_size);
|
||||
|
||||
next_size <<= 1;
|
||||
|
||||
// insert it into the list,
|
||||
// handle border case
|
||||
if (!list.valid() || std::greater<void *>()(list.begin(), node.begin()))
|
||||
{
|
||||
node.next(list);
|
||||
list = node;
|
||||
}
|
||||
else
|
||||
{
|
||||
details::PODptr<size_type> prev = list;
|
||||
|
||||
while (true)
|
||||
{
|
||||
// if we're about to hit the end or
|
||||
// if we've found where "node" goes
|
||||
if (prev.next_ptr() == 0
|
||||
|| std::greater<void *>()(prev.next_ptr(), node.begin()))
|
||||
break;
|
||||
|
||||
prev = prev.next();
|
||||
}
|
||||
|
||||
node.next(prev.next());
|
||||
prev.next(node);
|
||||
}
|
||||
|
||||
// and return it.
|
||||
return node.begin();
|
||||
}
|
||||
|
||||
template <typename UserAllocator>
|
||||
details::PODptr<typename pool<UserAllocator>::size_type>
|
||||
pool<UserAllocator>::find_POD(void * const chunk) const
|
||||
{
|
||||
// We have to find which storage this chunk is from.
|
||||
details::PODptr<size_type> iter = list;
|
||||
while (iter.valid())
|
||||
{
|
||||
if (is_from(chunk, iter.begin(), iter.element_size()))
|
||||
return iter;
|
||||
iter = iter.next();
|
||||
}
|
||||
|
||||
return iter;
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
220
Server/RylServerProject/BaseLibrary/boost/pool/pool_alloc.hpp
Normal file
220
Server/RylServerProject/BaseLibrary/boost/pool/pool_alloc.hpp
Normal file
@@ -0,0 +1,220 @@
|
||||
// Copyright (C) 2000, 2001 Stephen Cleary (shammah@voyager.net)
|
||||
//
|
||||
// This file can be redistributed and/or modified under the terms found
|
||||
// in "copyright.html"
|
||||
// This software and its documentation is provided "as is" without express or
|
||||
// implied warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_POOL_ALLOC_HPP
|
||||
#define BOOST_POOL_ALLOC_HPP
|
||||
|
||||
// std::numeric_limits
|
||||
#include <boost/limits.hpp>
|
||||
// new, std::bad_alloc
|
||||
#include <new>
|
||||
|
||||
#include <boost/pool/poolfwd.hpp>
|
||||
|
||||
// boost::singleton_pool
|
||||
#include <boost/pool/singleton_pool.hpp>
|
||||
|
||||
// The following code will be put into Boost.Config in a later revision
|
||||
#if defined(_RWSTD_VER) || defined(__SGI_STL_PORT)
|
||||
// Needed, as of bcc 5.5 and STLPort 4.5b8
|
||||
#define BOOST_NO_PROPER_STL_DEALLOCATE
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
struct pool_allocator_tag { };
|
||||
|
||||
template <typename T,
|
||||
typename UserAllocator,
|
||||
typename Mutex,
|
||||
unsigned NextSize>
|
||||
class pool_allocator
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef UserAllocator user_allocator;
|
||||
typedef Mutex mutex;
|
||||
BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize);
|
||||
|
||||
typedef value_type * pointer;
|
||||
typedef const value_type * const_pointer;
|
||||
typedef value_type & reference;
|
||||
typedef const value_type & const_reference;
|
||||
typedef typename pool<UserAllocator>::size_type size_type;
|
||||
typedef typename pool<UserAllocator>::difference_type difference_type;
|
||||
|
||||
template <typename U>
|
||||
struct rebind
|
||||
{
|
||||
typedef pool_allocator<U, UserAllocator, Mutex, NextSize> other;
|
||||
};
|
||||
|
||||
public:
|
||||
pool_allocator() { }
|
||||
|
||||
// default copy constructor
|
||||
|
||||
// default assignment operator
|
||||
|
||||
// not explicit, mimicking std::allocator [20.4.1]
|
||||
template <typename U>
|
||||
pool_allocator(const pool_allocator<U, UserAllocator, Mutex, NextSize> &)
|
||||
{ }
|
||||
|
||||
// default destructor
|
||||
|
||||
static pointer address(reference r)
|
||||
{ return &r; }
|
||||
static const_pointer address(const_reference s)
|
||||
{ return &s; }
|
||||
static size_type max_size()
|
||||
{ return std::numeric_limits<size_type>::max(); }
|
||||
static void construct(const pointer ptr, const value_type & t)
|
||||
{ new (ptr) T(t); }
|
||||
static void destroy(const pointer ptr)
|
||||
{
|
||||
ptr->~T();
|
||||
(void) ptr; // avoid unused variable warning
|
||||
}
|
||||
|
||||
bool operator==(const pool_allocator &) const
|
||||
{ return true; }
|
||||
bool operator!=(const pool_allocator &) const
|
||||
{ return false; }
|
||||
|
||||
static pointer allocate(const size_type n)
|
||||
{
|
||||
const pointer ret = static_cast<pointer>(
|
||||
singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
|
||||
NextSize>::ordered_malloc(n) );
|
||||
if (ret == 0)
|
||||
throw std::bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
static pointer allocate(const size_type n, const void * const)
|
||||
{ return allocate(n); }
|
||||
static void deallocate(const pointer ptr, const size_type n)
|
||||
{
|
||||
#ifdef BOOST_NO_PROPER_STL_DEALLOCATE
|
||||
if (ptr == 0 || n == 0)
|
||||
return;
|
||||
#endif
|
||||
singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
|
||||
NextSize>::ordered_free(ptr, n);
|
||||
}
|
||||
};
|
||||
|
||||
struct fast_pool_allocator_tag { };
|
||||
|
||||
template <typename T,
|
||||
typename UserAllocator,
|
||||
typename Mutex,
|
||||
unsigned NextSize>
|
||||
class fast_pool_allocator
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
typedef UserAllocator user_allocator;
|
||||
typedef Mutex mutex;
|
||||
BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize);
|
||||
|
||||
typedef value_type * pointer;
|
||||
typedef const value_type * const_pointer;
|
||||
typedef value_type & reference;
|
||||
typedef const value_type & const_reference;
|
||||
typedef typename pool<UserAllocator>::size_type size_type;
|
||||
typedef typename pool<UserAllocator>::difference_type difference_type;
|
||||
|
||||
template <typename U>
|
||||
struct rebind
|
||||
{
|
||||
typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize> other;
|
||||
};
|
||||
|
||||
public:
|
||||
fast_pool_allocator() { }
|
||||
|
||||
// default copy constructor
|
||||
|
||||
// default assignment operator
|
||||
|
||||
// not explicit, mimicking std::allocator [20.4.1]
|
||||
template <typename U>
|
||||
fast_pool_allocator(
|
||||
const fast_pool_allocator<U, UserAllocator, Mutex, NextSize> &)
|
||||
{ }
|
||||
|
||||
// default destructor
|
||||
|
||||
static pointer address(reference r)
|
||||
{ return &r; }
|
||||
static const_pointer address(const_reference s)
|
||||
{ return &s; }
|
||||
static size_type max_size()
|
||||
{ return std::numeric_limits<size_type>::max(); }
|
||||
void construct(const pointer ptr, const value_type & t)
|
||||
{ new (ptr) T(t); }
|
||||
void destroy(const pointer ptr)
|
||||
{
|
||||
ptr->~T();
|
||||
(void) ptr; // avoid unused variable warning
|
||||
}
|
||||
|
||||
bool operator==(const fast_pool_allocator &) const
|
||||
{ return true; }
|
||||
bool operator!=(const fast_pool_allocator &) const
|
||||
{ return false; }
|
||||
|
||||
static pointer allocate(const size_type n)
|
||||
{
|
||||
const pointer ret = (n == 1) ?
|
||||
static_cast<pointer>(
|
||||
singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
||||
UserAllocator, Mutex, NextSize>::malloc() ) :
|
||||
static_cast<pointer>(
|
||||
singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
||||
UserAllocator, Mutex, NextSize>::ordered_malloc(n) );
|
||||
if (ret == 0)
|
||||
throw std::bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
static pointer allocate(const size_type n, const void * const)
|
||||
{ return allocate(n); }
|
||||
static pointer allocate()
|
||||
{
|
||||
const pointer ret = static_cast<pointer>(
|
||||
singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
||||
UserAllocator, Mutex, NextSize>::malloc() );
|
||||
if (ret == 0)
|
||||
throw std::bad_alloc();
|
||||
return ret;
|
||||
}
|
||||
static void deallocate(const pointer ptr, const size_type n)
|
||||
{
|
||||
#ifdef BOOST_NO_PROPER_STL_DEALLOCATE
|
||||
if (ptr == 0 || n == 0)
|
||||
return;
|
||||
#endif
|
||||
if (n == 1)
|
||||
singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
||||
UserAllocator, Mutex, NextSize>::free(ptr);
|
||||
else
|
||||
singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
||||
UserAllocator, Mutex, NextSize>::free(ptr, n);
|
||||
}
|
||||
static void deallocate(const pointer ptr)
|
||||
{
|
||||
singleton_pool<fast_pool_allocator_tag, sizeof(T),
|
||||
UserAllocator, Mutex, NextSize>::free(ptr);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
74
Server/RylServerProject/BaseLibrary/boost/pool/poolfwd.hpp
Normal file
74
Server/RylServerProject/BaseLibrary/boost/pool/poolfwd.hpp
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright (C) 2000, 2001 Stephen Cleary (shammah@voyager.net)
|
||||
//
|
||||
// This file can be redistributed and/or modified under the terms found
|
||||
// in "copyright.html"
|
||||
// This software and its documentation is provided "as is" without express or
|
||||
// implied warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_POOLFWD_HPP
|
||||
#define BOOST_POOLFWD_HPP
|
||||
|
||||
#include <boost/config.hpp> // for workarounds
|
||||
|
||||
// std::size_t
|
||||
#include <cstddef>
|
||||
|
||||
// boost::details::pool::default_mutex
|
||||
#include <boost/pool/detail/mutex.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
//
|
||||
// Location: <boost/pool/simple_segregated_storage.hpp>
|
||||
//
|
||||
template <typename SizeType = std::size_t>
|
||||
class simple_segregated_storage;
|
||||
|
||||
//
|
||||
// Location: <boost/pool/pool.hpp>
|
||||
//
|
||||
struct default_user_allocator_new_delete;
|
||||
struct default_user_allocator_malloc_free;
|
||||
|
||||
template <typename UserAllocator = default_user_allocator_new_delete>
|
||||
class pool;
|
||||
|
||||
//
|
||||
// Location: <boost/pool/object_pool.hpp>
|
||||
//
|
||||
template <typename T, typename UserAllocator = default_user_allocator_new_delete>
|
||||
class object_pool;
|
||||
|
||||
//
|
||||
// Location: <boost/pool/singleton_pool.hpp>
|
||||
//
|
||||
template <typename Tag, unsigned RequestedSize,
|
||||
typename UserAllocator = default_user_allocator_new_delete,
|
||||
typename Mutex = details::pool::default_mutex,
|
||||
unsigned NextSize = 32>
|
||||
struct singleton_pool;
|
||||
|
||||
//
|
||||
// Location: <boost/pool/pool_alloc.hpp>
|
||||
//
|
||||
struct pool_allocator_tag;
|
||||
|
||||
template <typename T,
|
||||
typename UserAllocator = default_user_allocator_new_delete,
|
||||
typename Mutex = details::pool::default_mutex,
|
||||
unsigned NextSize = 32>
|
||||
class pool_allocator;
|
||||
|
||||
struct fast_pool_allocator_tag;
|
||||
|
||||
template <typename T,
|
||||
typename UserAllocator = default_user_allocator_new_delete,
|
||||
typename Mutex = details::pool::default_mutex,
|
||||
unsigned NextSize = 32>
|
||||
class fast_pool_allocator;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,266 @@
|
||||
// Copyright (C) 2000, 2001 Stephen Cleary (shammah@voyager.net)
|
||||
//
|
||||
// This file can be redistributed and/or modified under the terms found
|
||||
// in "copyright.html"
|
||||
// This software and its documentation is provided "as is" without express or
|
||||
// implied warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_SIMPLE_SEGREGATED_STORAGE_HPP
|
||||
#define BOOST_SIMPLE_SEGREGATED_STORAGE_HPP
|
||||
|
||||
// std::greater
|
||||
#include <functional>
|
||||
|
||||
#include <boost/pool/poolfwd.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
template <typename SizeType>
|
||||
class simple_segregated_storage
|
||||
{
|
||||
public:
|
||||
typedef SizeType size_type;
|
||||
|
||||
private:
|
||||
simple_segregated_storage(const simple_segregated_storage &);
|
||||
void operator=(const simple_segregated_storage &);
|
||||
|
||||
// pre: (n > 0), (start != 0), (nextof(start) != 0)
|
||||
// post: (start != 0)
|
||||
static void * try_malloc_n(void * & start, size_type n,
|
||||
size_type partition_size);
|
||||
|
||||
protected:
|
||||
void * first;
|
||||
|
||||
// Traverses the free list referred to by "first",
|
||||
// and returns the iterator previous to where
|
||||
// "ptr" would go if it was in the free list.
|
||||
// Returns 0 if "ptr" would go at the beginning
|
||||
// of the free list (i.e., before "first")
|
||||
void * find_prev(void * ptr);
|
||||
|
||||
// for the sake of code readability :)
|
||||
static void * & nextof(void * const ptr)
|
||||
{ return *(static_cast<void **>(ptr)); }
|
||||
|
||||
public:
|
||||
// Post: empty()
|
||||
simple_segregated_storage()
|
||||
:first(0) { }
|
||||
|
||||
// pre: npartition_sz >= sizeof(void *)
|
||||
// npartition_sz = sizeof(void *) * i, for some integer i
|
||||
// nsz >= npartition_sz
|
||||
// block is properly aligned for an array of object of
|
||||
// size npartition_sz and array of void *
|
||||
// The requirements above guarantee that any pointer to a chunk
|
||||
// (which is a pointer to an element in an array of npartition_sz)
|
||||
// may be cast to void **.
|
||||
static void * segregate(void * block,
|
||||
size_type nsz, size_type npartition_sz,
|
||||
void * end = 0);
|
||||
|
||||
// Same preconditions as 'segregate'
|
||||
// Post: !empty()
|
||||
void add_block(void * const block,
|
||||
const size_type nsz, const size_type npartition_sz)
|
||||
{
|
||||
// Segregate this block and merge its free list into the
|
||||
// free list referred to by "first"
|
||||
first = segregate(block, nsz, npartition_sz, first);
|
||||
}
|
||||
|
||||
// Same preconditions as 'segregate'
|
||||
// Post: !empty()
|
||||
void add_ordered_block(void * const block,
|
||||
const size_type nsz, const size_type npartition_sz)
|
||||
{
|
||||
// This (slower) version of add_block segregates the
|
||||
// block and merges its free list into our free list
|
||||
// in the proper order
|
||||
|
||||
// Find where "block" would go in the free list
|
||||
void * const loc = find_prev(block);
|
||||
|
||||
// Place either at beginning or in middle/end
|
||||
if (loc == 0)
|
||||
add_block(block, nsz, npartition_sz);
|
||||
else
|
||||
nextof(loc) = segregate(block, nsz, npartition_sz, nextof(loc));
|
||||
}
|
||||
|
||||
// default destructor
|
||||
|
||||
bool empty() const { return (first == 0); }
|
||||
|
||||
// pre: !empty()
|
||||
void * malloc()
|
||||
{
|
||||
void * const ret = first;
|
||||
|
||||
// Increment the "first" pointer to point to the next chunk
|
||||
first = nextof(first);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// pre: chunk was previously returned from a malloc() referring to the
|
||||
// same free list
|
||||
// post: !empty()
|
||||
void free(void * const chunk)
|
||||
{
|
||||
nextof(chunk) = first;
|
||||
first = chunk;
|
||||
}
|
||||
|
||||
// pre: chunk was previously returned from a malloc() referring to the
|
||||
// same free list
|
||||
// post: !empty()
|
||||
void ordered_free(void * const chunk)
|
||||
{
|
||||
// This (slower) implementation of 'free' places the memory
|
||||
// back in the list in its proper order.
|
||||
|
||||
// Find where "chunk" goes in the free list
|
||||
void * const loc = find_prev(chunk);
|
||||
|
||||
// Place either at beginning or in middle/end
|
||||
if (loc == 0)
|
||||
free(chunk);
|
||||
else
|
||||
{
|
||||
nextof(chunk) = nextof(loc);
|
||||
nextof(loc) = chunk;
|
||||
}
|
||||
}
|
||||
|
||||
// Note: if you're allocating/deallocating n a lot, you should
|
||||
// be using an ordered pool.
|
||||
void * malloc_n(size_type n, size_type partition_size);
|
||||
|
||||
// pre: chunks was previously allocated from *this with the same
|
||||
// values for n and partition_size
|
||||
// post: !empty()
|
||||
// Note: if you're allocating/deallocating n a lot, you should
|
||||
// be using an ordered pool.
|
||||
void free_n(void * const chunks, const size_type n,
|
||||
const size_type partition_size)
|
||||
{
|
||||
add_block(chunks, n * partition_size, partition_size);
|
||||
}
|
||||
|
||||
// pre: chunks was previously allocated from *this with the same
|
||||
// values for n and partition_size
|
||||
// post: !empty()
|
||||
void ordered_free_n(void * const chunks, const size_type n,
|
||||
const size_type partition_size)
|
||||
{
|
||||
add_ordered_block(chunks, n * partition_size, partition_size);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename SizeType>
|
||||
void * simple_segregated_storage<SizeType>::find_prev(void * const ptr)
|
||||
{
|
||||
// Handle border case
|
||||
if (first == 0 || std::greater<void *>()(first, ptr))
|
||||
return 0;
|
||||
|
||||
void * iter = first;
|
||||
while (true)
|
||||
{
|
||||
// if we're about to hit the end or
|
||||
// if we've found where "ptr" goes
|
||||
if (nextof(iter) == 0 || std::greater<void *>()(nextof(iter), ptr))
|
||||
return iter;
|
||||
|
||||
iter = nextof(iter);
|
||||
}
|
||||
}
|
||||
|
||||
template <typename SizeType>
|
||||
void * simple_segregated_storage<SizeType>::segregate(
|
||||
void * const block,
|
||||
const size_type sz,
|
||||
const size_type partition_sz,
|
||||
void * const end)
|
||||
{
|
||||
// Get pointer to last valid chunk, preventing overflow on size calculations
|
||||
// The division followed by the multiplication just makes sure that
|
||||
// old == block + partition_sz * i, for some integer i, even if the
|
||||
// block size (sz) is not a multiple of the partition size.
|
||||
char * old = static_cast<char *>(block)
|
||||
+ ((sz - partition_sz) / partition_sz) * partition_sz;
|
||||
|
||||
// Set it to point to the end
|
||||
nextof(old) = end;
|
||||
|
||||
// Handle border case where sz == partition_sz (i.e., we're handling an array
|
||||
// of 1 element)
|
||||
if (old == block)
|
||||
return block;
|
||||
|
||||
// Iterate backwards, building a singly-linked list of pointers
|
||||
for (char * iter = old - partition_sz; iter != block;
|
||||
old = iter, iter -= partition_sz)
|
||||
nextof(iter) = old;
|
||||
|
||||
// Point the first pointer, too
|
||||
nextof(block) = old;
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
// The following function attempts to find n contiguous chunks
|
||||
// of size partition_size in the free list, starting at start.
|
||||
// If it succeds, it returns the last chunk in that contiguous
|
||||
// sequence, so that the sequence is known by [start, {retval}]
|
||||
// If it fails, it does do either because it's at the end of the
|
||||
// free list or hits a non-contiguous chunk. In either case,
|
||||
// it will return 0, and set start to the last considered
|
||||
// chunk. You are at the end of the free list if
|
||||
// nextof(start) == 0. Otherwise, start points to the last
|
||||
// chunk in the contiguous sequence, and nextof(start) points
|
||||
// to the first chunk in the next contiguous sequence (assuming
|
||||
// an ordered free list)
|
||||
template <typename SizeType>
|
||||
void * simple_segregated_storage<SizeType>::try_malloc_n(
|
||||
void * & start, size_type n, const size_type partition_size)
|
||||
{
|
||||
void * iter = nextof(start);
|
||||
while (--n != 0)
|
||||
{
|
||||
void * next = nextof(iter);
|
||||
if (next != static_cast<char *>(iter) + partition_size)
|
||||
{
|
||||
// next == 0 (end-of-list) or non-contiguous chunk found
|
||||
start = iter;
|
||||
return 0;
|
||||
}
|
||||
iter = next;
|
||||
}
|
||||
return iter;
|
||||
}
|
||||
|
||||
template <typename SizeType>
|
||||
void * simple_segregated_storage<SizeType>::malloc_n(const size_type n,
|
||||
const size_type partition_size)
|
||||
{
|
||||
void * start = &first;
|
||||
void * iter;
|
||||
do
|
||||
{
|
||||
if (nextof(start) == 0)
|
||||
return 0;
|
||||
iter = try_malloc_n(start, n, partition_size);
|
||||
} while (iter == 0);
|
||||
void * const ret = nextof(start);
|
||||
nextof(start) = nextof(iter);
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,120 @@
|
||||
// Copyright (C) 2000, 2001 Stephen Cleary (shammah@voyager.net)
|
||||
//
|
||||
// This file can be redistributed and/or modified under the terms found
|
||||
// in "copyright.html"
|
||||
// This software and its documentation is provided "as is" without express or
|
||||
// implied warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// See http://www.boost.org for updates, documentation, and revision history.
|
||||
|
||||
#ifndef BOOST_SINGLETON_POOL_HPP
|
||||
#define BOOST_SINGLETON_POOL_HPP
|
||||
|
||||
#include <boost/pool/poolfwd.hpp>
|
||||
|
||||
// boost::pool
|
||||
#include <boost/pool/pool.hpp>
|
||||
// boost::details::pool::singleton_default
|
||||
#include <boost/pool/detail/singleton.hpp>
|
||||
// boost::details::pool::guard
|
||||
#include <boost/pool/detail/guard.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
//
|
||||
// The singleton_pool class allows other pool interfaces for types of the same
|
||||
// size to share the same pool
|
||||
//
|
||||
template <typename Tag, unsigned RequestedSize,
|
||||
typename UserAllocator,
|
||||
typename Mutex,
|
||||
unsigned NextSize>
|
||||
struct singleton_pool
|
||||
{
|
||||
public:
|
||||
typedef Tag tag;
|
||||
typedef Mutex mutex;
|
||||
typedef UserAllocator user_allocator;
|
||||
typedef typename pool<UserAllocator>::size_type size_type;
|
||||
typedef typename pool<UserAllocator>::difference_type difference_type;
|
||||
|
||||
BOOST_STATIC_CONSTANT(unsigned, requested_size = RequestedSize);
|
||||
BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize);
|
||||
|
||||
private:
|
||||
struct pool_type: Mutex
|
||||
{
|
||||
pool<UserAllocator> p;
|
||||
pool_type():p(RequestedSize, NextSize) { }
|
||||
};
|
||||
|
||||
typedef details::pool::singleton_default<pool_type> singleton;
|
||||
|
||||
singleton_pool();
|
||||
|
||||
public:
|
||||
static void * malloc()
|
||||
{
|
||||
pool_type & p = singleton::instance();
|
||||
details::pool::guard<Mutex> g(p);
|
||||
return p.p.malloc();
|
||||
}
|
||||
static void * ordered_malloc()
|
||||
{
|
||||
pool_type & p = singleton::instance();
|
||||
details::pool::guard<Mutex> g(p);
|
||||
return p.p.ordered_malloc();
|
||||
}
|
||||
static void * ordered_malloc(const size_type n)
|
||||
{
|
||||
pool_type & p = singleton::instance();
|
||||
details::pool::guard<Mutex> g(p);
|
||||
return p.p.ordered_malloc(n);
|
||||
}
|
||||
static bool is_from(void * const ptr)
|
||||
{
|
||||
pool_type & p = singleton::instance();
|
||||
details::pool::guard<Mutex> g(p);
|
||||
return p.p.is_from(ptr);
|
||||
}
|
||||
static void free(void * const ptr)
|
||||
{
|
||||
pool_type & p = singleton::instance();
|
||||
details::pool::guard<Mutex> g(p);
|
||||
p.p.free(ptr);
|
||||
}
|
||||
static void ordered_free(void * const ptr)
|
||||
{
|
||||
pool_type & p = singleton::instance();
|
||||
details::pool::guard<Mutex> g(p);
|
||||
p.p.ordered_free(ptr);
|
||||
}
|
||||
static void free(void * const ptr, const size_type n)
|
||||
{
|
||||
pool_type & p = singleton::instance();
|
||||
details::pool::guard<Mutex> g(p);
|
||||
p.p.free(ptr, n);
|
||||
}
|
||||
static void ordered_free(void * const ptr, const size_type n)
|
||||
{
|
||||
pool_type & p = singleton::instance();
|
||||
details::pool::guard<Mutex> g(p);
|
||||
p.p.ordered_free(ptr, n);
|
||||
}
|
||||
static bool release_memory()
|
||||
{
|
||||
pool_type & p = singleton::instance();
|
||||
details::pool::guard<Mutex> g(p);
|
||||
return p.p.release_memory();
|
||||
}
|
||||
static bool purge_memory()
|
||||
{
|
||||
pool_type & p = singleton::instance();
|
||||
details::pool::guard<Mutex> g(p);
|
||||
return p.p.purge_memory();
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user