1
0
mirror of https://git.suyu.dev/suyu/suyu synced 2025-09-10 16:26:32 -05:00

Initial commit

This commit is contained in:
Crimson-Hawk
2024-03-05 16:42:40 +08:00
commit f1e4595ebf
39576 changed files with 7006612 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
CRTLinkage: dynamic
LibraryLinkage: dynamic

View File

@@ -0,0 +1,8 @@
Package: boost-pool
Version: 1.79.0
Depends: boost-assert, boost-config, boost-integer, boost-throw-exception, boost-type-traits, boost-vcpkg-helpers, boost-winapi
Architecture: x64-windows
Multi-Arch: same
Abi: f53abd1be62e7e71cadf9ce7d38ccf5edc7b8505d9970a8c74849587e388bfd4
Description: Boost pool module
Type: Port

View File

@@ -0,0 +1,107 @@
m4_dnl
m4_dnl Copyright (C) 2000 Stephen Cleary
m4_dnl
m4_dnl Distributed under the Boost Software License, Version 1.0. (See accompany-
m4_dnl ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
m4_dnl
m4_dnl See http://www.boost.org for updates, documentation, and revision history.
m4_dnl
m4_dnl
m4_dnl
m4_dnl BOOST_M4_FOR: repeat a given text for a range of values
m4_dnl $1 - variable to hold the current value.
m4_dnl $2 - the starting value.
m4_dnl $3 - the ending value (text is _not_ repeated for this value).
m4_dnl $4 - the text to repeat.
m4_dnl $5 - the delimeter text (optional).
m4_dnl
m4_dnl If the starting value is < ending value:
m4_dnl Will repeat $4, binding $1 to the values in the range [$2, $3).
m4_dnl Else (that is, starting value >= ending value):
m4_dnl Will do nothing
m4_dnl Repeats $5 in-between each occurrence of $4
m4_dnl
m4_dnl Logic:
m4_dnl Set $1 to $2 and call BOOST_M4_FOR_LIST_HELPER:
m4_dnl If $1 >= $3, do nothing
m4_dnl Else
m4_dnl output $4,
m4_dnl set $1 to itself incremented,
m4_dnl If $1 != $3, output $5,
m4_dnl and use recursion
m4_dnl
m4_define(`BOOST_M4_FOR',
`m4_ifelse(m4_eval($# < 4 || $# > 5), 1,
`m4_errprint(m4___file__:m4___line__: `Boost m4 script: BOOST_M4_FOR: Wrong number of arguments ($#)')',
`m4_pushdef(`$1', `$2')BOOST_M4_FOR_HELPER($@)m4_popdef(`$1')')')m4_dnl
m4_define(`BOOST_M4_FOR_HELPER',
`m4_ifelse(m4_eval($1 >= $3), 1, ,
`$4`'m4_define(`$1', m4_incr($1))m4_ifelse(m4_eval($1 != $3), 1, `$5')`'BOOST_M4_FOR_HELPER($@)')')m4_dnl
m4_dnl
m4_dnl Testing/Examples:
m4_dnl
m4_dnl The following line will output:
m4_dnl "repeat.m4:42: Boost m4 script: BOOST_M4_FOR: Wrong number of arguments (3)"
m4_dnl BOOST_M4_FOR(i, 1, 3)
m4_dnl
m4_dnl The following line will output:
m4_dnl "repeat.m4:46: Boost m4 script: BOOST_M4_FOR: Wrong number of arguments (6)"
m4_dnl BOOST_M4_FOR(i, 1, 3, i, ` ', 13)
m4_dnl
m4_dnl The following line will output (nothing):
m4_dnl ""
m4_dnl BOOST_M4_FOR(i, 7, 0, i )
m4_dnl
m4_dnl The following line will output (nothing):
m4_dnl ""
m4_dnl BOOST_M4_FOR(i, 0, 0, i )
m4_dnl
m4_dnl The following line will output:
m4_dnl "0 1 2 3 4 5 6 "
m4_dnl BOOST_M4_FOR(i, 0, 7, i )
m4_dnl
m4_dnl The following line will output:
m4_dnl "-13 -12 -11 "
m4_dnl BOOST_M4_FOR(i, -13, -10, i )
m4_dnl
m4_dnl The following two lines will output:
m4_dnl "(0, 0) (0, 1) (0, 2) (0, 3) "
m4_dnl "(1, 0) (1, 1) (1, 2) (1, 3) "
m4_dnl "(2, 0) (2, 1) (2, 2) (2, 3) "
m4_dnl "(3, 0) (3, 1) (3, 2) (3, 3) "
m4_dnl "(4, 0) (4, 1) (4, 2) (4, 3) "
m4_dnl "(5, 0) (5, 1) (5, 2) (5, 3) "
m4_dnl "(6, 0) (6, 1) (6, 2) (6, 3) "
m4_dnl "(7, 0) (7, 1) (7, 2) (7, 3) "
m4_dnl ""
m4_dnl BOOST_M4_FOR(i, 0, 8, BOOST_M4_FOR(j, 0, 4, (i, j) )
m4_dnl )
m4_dnl
m4_dnl The following line will output (nothing):
m4_dnl ""
m4_dnl BOOST_M4_FOR(i, 7, 0, i, |)
m4_dnl
m4_dnl The following line will output (nothing):
m4_dnl ""
m4_dnl BOOST_M4_FOR(i, 0, 0, i, |)
m4_dnl
m4_dnl The following line will output:
m4_dnl "0|1|2|3|4|5|6"
m4_dnl BOOST_M4_FOR(i, 0, 7, i, |)
m4_dnl
m4_dnl The following line will output:
m4_dnl "-13, -12, -11"
m4_dnl BOOST_M4_FOR(i, -13, -10, i, `, ')
m4_dnl
m4_dnl The following two lines will output:
m4_dnl "[(0, 0), (0, 1), (0, 2), (0, 3)],"
m4_dnl "[(1, 0), (1, 1), (1, 2), (1, 3)],"
m4_dnl "[(2, 0), (2, 1), (2, 2), (2, 3)],"
m4_dnl "[(3, 0), (3, 1), (3, 2), (3, 3)],"
m4_dnl "[(4, 0), (4, 1), (4, 2), (4, 3)],"
m4_dnl "[(5, 0), (5, 1), (5, 2), (5, 3)],"
m4_dnl "[(6, 0), (6, 1), (6, 2), (6, 3)],"
m4_dnl "[(7, 0), (7, 1), (7, 2), (7, 3)]"
m4_dnl BOOST_M4_FOR(i, 0, 8, `[BOOST_M4_FOR(j, 0, 4, (i, j), `, ')]', `,
m4_dnl ')
m4_dnl

View File

@@ -0,0 +1,69 @@
// Copyright (C) 2000 Stephen Cleary
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef BOOST_POOL_GUARD_HPP
#define BOOST_POOL_GUARD_HPP
/*!
\file
\brief Extremely Light-Weight guard class.
\details Auto-lock/unlock-er
detail/guard.hpp provides a type guard<Mutex>
that allows scoped access to the Mutex's locking and unlocking operations.
It is used to ensure that a Mutex is unlocked, even if an exception is thrown.
*/
namespace boost {
namespace details {
namespace pool {
template <typename Mutex> //!< \tparam Mutex (platform-specific) mutex class.
class guard
{ //! Locks the mutex, binding guard<Mutex> to Mutex.
/*! Example:
Given a (platform-specific) mutex class, we can wrap code as follows:
extern mutex global_lock;
static void f()
{
boost::details::pool::guard<mutex> g(global_lock);
// g's constructor locks "global_lock"
... // do anything:
// throw exceptions
// return
// or just fall through
} // g's destructor unlocks "global_lock"
*/
private:
Mutex & mtx;
guard(const guard &); //!< Guards the mutex, ensuring unlocked on destruction, even if exception is thrown.
void operator=(const guard &);
public:
explicit guard(Mutex & nmtx)
:mtx(nmtx)
{ //! Locks the mutex of the guard class.
mtx.lock();
}
~guard()
{ //! destructor unlocks the mutex of the guard class.
mtx.unlock();
}
}; // class guard
} // namespace pool
} // namespace details
} // namespace boost
#endif

View File

@@ -0,0 +1,144 @@
// Copyright (C) 2000 Stephen Cleary
// Copyright (C) 2018 Peter Dimov
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef BOOST_POOL_MUTEX_HPP
#define BOOST_POOL_MUTEX_HPP
#include <boost/config.hpp>
namespace boost{ namespace details{ namespace pool{
class null_mutex
{
private:
null_mutex(const null_mutex &);
void operator=(const null_mutex &);
public:
null_mutex() {}
static void lock() {}
static void unlock() {}
};
}}} // namespace boost::details::pool
#if !defined(BOOST_HAS_THREADS) || defined(BOOST_NO_MT) || defined(BOOST_POOL_NO_MT)
namespace boost{ namespace details{ namespace pool{
typedef null_mutex default_mutex;
}}} // namespace boost::details::pool
#elif !defined(BOOST_NO_CXX11_HDR_MUTEX)
#include <mutex>
namespace boost{ namespace details{ namespace pool{
typedef std::mutex default_mutex;
}}} // namespace boost::details::pool
#elif defined(BOOST_HAS_PTHREADS)
#include <boost/assert.hpp>
#include <pthread.h>
namespace boost{ namespace details{ namespace pool{
class pt_mutex
{
private:
pthread_mutex_t m_;
pt_mutex(pt_mutex const &);
pt_mutex & operator=(pt_mutex const &);
public:
pt_mutex()
{
BOOST_VERIFY( pthread_mutex_init( &m_, 0 ) == 0 );
}
~pt_mutex()
{
BOOST_VERIFY( pthread_mutex_destroy( &m_ ) == 0 );
}
void lock()
{
BOOST_VERIFY( pthread_mutex_lock( &m_ ) == 0 );
}
void unlock()
{
BOOST_VERIFY( pthread_mutex_unlock( &m_ ) == 0 );
}
};
typedef pt_mutex default_mutex;
}}} // namespace boost::details::pool
#elif defined(BOOST_HAS_WINTHREADS) || defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__)
#include <boost/winapi/critical_section.hpp>
namespace boost{ namespace details{ namespace pool{
class cs_mutex
{
private:
boost::winapi::CRITICAL_SECTION_ cs_;
cs_mutex(cs_mutex const &);
cs_mutex & operator=(cs_mutex const &);
public:
cs_mutex()
{
boost::winapi::InitializeCriticalSection( &cs_ );
}
~cs_mutex()
{
boost::winapi::DeleteCriticalSection( &cs_ );
}
void lock()
{
boost::winapi::EnterCriticalSection( &cs_ );
}
void unlock()
{
boost::winapi::LeaveCriticalSection( &cs_ );
}
};
typedef cs_mutex default_mutex;
}}} // namespace boost::details::pool
#else
// Use #define BOOST_DISABLE_THREADS to avoid this error
# error Unrecognized threading platform
#endif
#endif // #ifndef BOOST_POOL_MUTEX_HPP

View File

@@ -0,0 +1,24 @@
@echo off
rem
rem Copyright (C) 2000, 2001 Stephen Cleary
rem
rem Distributed under the Boost Software License, Version 1.0. (See accompany-
rem ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
rem Check for Windows NT
if %OS%==Windows_NT goto NT
rem Not NT - run m4 as normal, then exit
m4 -P -E -DNumberOfArguments=%1 pool_construct.m4 > pool_construct.ipp
goto end
rem DJGPP programs (including m4) running on Windows/NT do NOT support long
rem file names (see the DJGPP v2 FAQ, question 8.1)
rem Note that the output doesn't have to be a short name because it's an
rem argument to the command shell, not m4.
:NT
m4 -P -E -DNumberOfArguments=%1 < pool_construct.m4 > pool_construct.ipp
:end

View File

@@ -0,0 +1,852 @@
// Copyright (C) 2000 Stephen Cleary
//
// Distributed under the Boost Software License, Version 1.0. (See accompany-
// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// 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(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;
}

View File

@@ -0,0 +1,84 @@
m4_dnl
m4_dnl Copyright (C) 2000 Stephen Cleary
m4_dnl
m4_dnl Distributed under the Boost Software License, Version 1.0. (See accompany-
m4_dnl ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
m4_dnl
m4_dnl See http://www.boost.org for updates, documentation, and revision history.
m4_dnl
m4_dnl
m4_dnl
m4_dnl Avoid the use of any m4_* identifiers in this header file,
m4_dnl as that may cause incompatibility problems with future
m4_dnl versions of m4.
m4_dnl
m4_dnl This is a normal header file, except that lines starting
m4_dnl with `m4_dnl' will be stripped, TBA_FOR
m4_dnl macros will be replaced with repeated text, and text in
m4_dnl single quotes (`...') will have their single quotes
m4_dnl stripped.
m4_dnl
m4_dnl
m4_dnl Check to make sure NumberOfArguments was defined. If it's not defined,
m4_dnl default to 3
m4_dnl
m4_ifdef(`NumberOfArguments', , `m4_errprint(m4___file__:m4___line__`: NumberOfArguments is not defined; defaulting to 3
')m4_define(`NumberOfArguments', 3)')m4_dnl
m4_ifelse(NumberOfArguments, , `m4_errprint(m4___file__:m4___line__`: NumberOfArguments is defined to be empty; defaulting to 3
')m4_define(`NumberOfArguments', 3)')m4_dnl
m4_dnl
m4_dnl Check to make sure NumberOfArguments >= 1. If it's not, then fatal error.
m4_dnl
m4_ifelse(m4_eval(NumberOfArguments < 1), 1, `m4_errprint(m4___file__:m4___line__`: NumberOfArguments ('NumberOfArguments`) is less than 1
')m4_m4exit(1)')m4_dnl
m4_dnl
m4_dnl Include the BOOST_M4_FOR macro definition
m4_dnl
m4_include(`for.m4')`'m4_dnl
m4_dnl
m4_dnl Begin the generated file.
m4_dnl
// Copyright (C) 2000 Stephen Cleary
//
// Distributed under the Boost Software License, Version 1.0. (See accompany-
// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for updates, documentation, and revision history.
m4_dnl These warnings apply to the file generated from this file.
m4_dnl Of course, you may freely edit this file.
// This file was AUTOMATICALLY GENERATED from "m4___file__"
// Do NOT include directly!
// Do NOT edit!
m4_dnl
m4_dnl First we define a simple 'cv_qual' macro which takes a number, either
m4_dnl 0, 1, 2, or 3, and determines cv-qualification.
m4_dnl
m4_define(`cv_qual',
`m4_ifelse($1, 0, `',
`m4_ifelse($1, 1, `const ',
`m4_ifelse($1, 2, `volatile ',
`m4_ifelse($1, 3, `const volatile ',
`m4_errprint(m4___file__:m4___line__: `Boost m4 script: cv-determiner: Not 0, 1, 2, or 3 (was '$1`)')'
)')')')')m4_dnl
m4_dnl
m4_dnl Next we go through the actual loop. For each number of arguments from
m4_dnl 1 to NumberOfArguments, we create a template function that takes that
m4_dnl many template arguments, and also generate all cv-qualified permutations
m4_dnl of that function.
m4_dnl
BOOST_M4_FOR(N, 1, NumberOfArguments + 1,
`BOOST_M4_FOR(cv, 0, m4_eval(4 ** N),
`template <BOOST_M4_FOR(i, 0, N, `typename T`'i', `, ')>
element_type * construct(BOOST_M4_FOR(i, 0, N,
`cv_qual(m4_eval((cv >> (i * 2)) % 4))T`'i & a`'i', `, '))
{
element_type * const ret = (malloc)();
if (ret == 0)
return ret;
try { new (ret) element_type(BOOST_M4_FOR(i, 0, N, `a`'i', `, ')); }
catch (...) { (free)(ret); throw; }
return ret;
}
')')

View File

@@ -0,0 +1,12 @@
#!/bin/sh
#
# Copyright (C) 2000 Stephen Cleary
#
# Distributed under the Boost Software License, Version 1.0. (See accompany-
# ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# See http://www.boost.org for updates, documentation, and revision history.
#
m4 -P -E -DNumberOfArguments=$1 pool_construct.m4 > pool_construct.ipp

View File

@@ -0,0 +1,25 @@
@echo off
rem
rem Copyright (C) 2001 Stephen Cleary
rem
rem Distributed under the Boost Software License, Version 1.0. (See accompany-
rem ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
rem
rem See http://www.boost.org for updates, documentation, and revision history.
rem
rem Check for Windows NT
if %OS%==Windows_NT goto NT
rem Not NT - run m4 as normal, then exit
m4 -P -E -DNumberOfArguments=%1 pool_construct_simple.m4 > pool_construct_simple.ipp
goto end
rem DJGPP programs (including m4) running on Windows/NT do NOT support long
rem file names (see the DJGPP v2 FAQ, question 8.1)
rem Note that the output doesn't have to be a short name because it's an
rem argument to the command shell, not m4.
:NT
m4 -P -E -DNumberOfArguments=%1 < pool_construct_simple.m4 > pool_construct_simple.ipp
:end

View File

@@ -0,0 +1,43 @@
// Copyright (C) 2000 Stephen Cleary
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// 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;
}

View File

@@ -0,0 +1,72 @@
m4_dnl
m4_dnl Copyright (C) 2001 Stephen Cleary
m4_dnl
m4_dnl Distributed under the Boost Software License, Version 1.0. (See accompany-
m4_dnl ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
m4_dnl
m4_dnl See http://www.boost.org for updates, documentation, and revision history.
m4_dnl
m4_dnl
m4_dnl
m4_dnl Avoid the use of any m4_* identifiers in this header file,
m4_dnl as that may cause incompatibility problems with future
m4_dnl versions of m4.
m4_dnl
m4_dnl This is a normal header file, except that lines starting
m4_dnl with `m4_dnl' will be stripped, TBA_FOR
m4_dnl macros will be replaced with repeated text, and text in
m4_dnl single quotes (`...') will have their single quotes
m4_dnl stripped.
m4_dnl
m4_dnl
m4_dnl Check to make sure NumberOfArguments was defined. If it's not defined,
m4_dnl default to 3
m4_dnl
m4_ifdef(`NumberOfArguments', , `m4_errprint(m4___file__:m4___line__`: NumberOfArguments is not defined; defaulting to 3
')m4_define(`NumberOfArguments', 3)')m4_dnl
m4_ifelse(NumberOfArguments, , `m4_errprint(m4___file__:m4___line__`: NumberOfArguments is defined to be empty; defaulting to 3
')m4_define(`NumberOfArguments', 3)')m4_dnl
m4_dnl
m4_dnl Check to make sure NumberOfArguments >= 1. If it's not, then fatal error.
m4_dnl
m4_ifelse(m4_eval(NumberOfArguments < 1), 1, `m4_errprint(m4___file__:m4___line__`: NumberOfArguments ('NumberOfArguments`) is less than 1
')m4_m4exit(1)')m4_dnl
m4_dnl
m4_dnl Include the BOOST_M4_FOR macro definition
m4_dnl
m4_include(`for.m4')`'m4_dnl
m4_dnl
m4_dnl Begin the generated file.
m4_dnl
// Copyright (C) 2000 Stephen Cleary
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for updates, documentation, and revision history.
m4_dnl These warnings apply to the file generated from this file.
m4_dnl Of course, you may freely edit this file.
// This file was AUTOMATICALLY GENERATED from "m4___file__"
// Do NOT include directly!
// Do NOT edit!
m4_dnl
m4_dnl Here we go through the actual loop. For each number of arguments from
m4_dnl 1 to NumberOfArguments, we create a template function that takes that
m4_dnl many template arguments.
m4_dnl
BOOST_M4_FOR(N, 1, NumberOfArguments + 1,
`template <BOOST_M4_FOR(i, 0, N, `typename T`'i', `, ')>
element_type * construct(BOOST_M4_FOR(i, 0, N,
`const T`'i & a`'i', `, '))
{
element_type * const ret = (malloc)();
if (ret == 0)
return ret;
try { new (ret) element_type(BOOST_M4_FOR(i, 0, N, `a`'i', `, ')); }
catch (...) { (free)(ret); throw; }
return ret;
}
')

View File

@@ -0,0 +1,12 @@
#!/bin/sh
#
# Copyright (C) 2001 Stephen Cleary
#
# Distributed under the Boost Software License, Version 1.0. (See accompany-
# ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#
# See http://www.boost.org for updates, documentation, and revision history.
#
m4 -P -E -DNumberOfArguments=$1 pool_construct_simple.m4 > pool_construct_simple.ipp

View File

@@ -0,0 +1,287 @@
// Copyright (C) 2000, 2001 Stephen Cleary
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef BOOST_OBJECT_POOL_HPP
#define BOOST_OBJECT_POOL_HPP
/*!
\file
\brief Provides a template type boost::object_pool<T, UserAllocator>
that can be used for fast and efficient memory allocation of objects of type T.
It also provides automatic destruction of non-deallocated objects.
*/
#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 BOOST_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 {
/*! \brief A template class
that can be used for fast and efficient memory allocation of objects.
It also provides automatic destruction of non-deallocated objects.
\details
<b>T</b> The type of object to allocate/deallocate.
T must have a non-throwing destructor.
<b>UserAllocator</b>
Defines the allocator that the underlying Pool will use to allocate memory from the system.
See <a href="boost_pool/pool/pooling.html#boost_pool.pool.pooling.user_allocator">User Allocators</a> for details.
Class object_pool is a template class
that can be used for fast and efficient memory allocation of objects.
It also provides automatic destruction of non-deallocated objects.
When the object pool is destroyed, then the destructor for type T
is called for each allocated T that has not yet been deallocated. O(N).
Whenever an object of type ObjectPool needs memory from the system,
it will request it from its UserAllocator template parameter.
The amount requested is determined using a doubling algorithm;
that is, each time more system memory is allocated,
the amount of system memory requested is doubled.
Users may control the doubling algorithm by the parameters passed
to the object_pool's constructor.
*/
template <typename T, typename UserAllocator>
class object_pool: protected pool<UserAllocator>
{ //!
public:
typedef T element_type; //!< ElementType
typedef UserAllocator user_allocator; //!<
typedef typename pool<UserAllocator>::size_type size_type; //!< pool<UserAllocator>::size_type
typedef typename pool<UserAllocator>::difference_type difference_type; //!< pool<UserAllocator>::difference_type
protected:
//! \return The underlying boost:: \ref pool storage used by *this.
pool<UserAllocator> & store()
{
return *this;
}
//! \return The underlying boost:: \ref pool storage used by *this.
const pool<UserAllocator> & store() const
{
return *this;
}
// for the sake of code readability :)
static void * & nextof(void * const ptr)
{ //! \returns The next memory block after ptr (for the sake of code readability :)
return *(static_cast<void **>(ptr));
}
public:
explicit object_pool(const size_type arg_next_size = 32, const size_type arg_max_size = 0)
:
pool<UserAllocator>(sizeof(T), arg_next_size, arg_max_size)
{ //! Constructs a new (empty by default) ObjectPool.
//! \param next_size Number of chunks to request from the system the next time that object needs to allocate system memory (default 32).
//! \pre next_size != 0.
//! \param max_size Maximum number of chunks to ever request from the system - this puts a cap on the doubling algorithm
//! used by the underlying pool.
}
~object_pool();
// Returns 0 if out-of-memory.
element_type * malloc BOOST_PREVENT_MACRO_SUBSTITUTION()
{ //! Allocates memory that can hold one object of type ElementType.
//!
//! If out of memory, returns 0.
//!
//! Amortized O(1).
return static_cast<element_type *>(store().ordered_malloc());
}
void free BOOST_PREVENT_MACRO_SUBSTITUTION(element_type * const chunk)
{ //! De-Allocates memory that holds a chunk of type ElementType.
//!
//! Note that p may not be 0.\n
//!
//! Note that the destructor for p is not called. O(N).
store().ordered_free(chunk);
}
bool is_from(element_type * const chunk) const
{ /*! \returns true if chunk was allocated from *this or
may be returned as the result of a future allocation from *this.
Returns false if chunk was allocated from some other pool or
may be returned as the result of a future allocation from some other pool.
Otherwise, the return value is meaningless.
\note This function may NOT be used to reliably test random pointer values!
*/
return store().is_from(chunk);
}
element_type * construct()
{ //! \returns A pointer to an object of type T, allocated in memory from the underlying pool
//! and default constructed. The returned objected can be freed by a call to \ref destroy.
//! Otherwise the returned object will be automatically destroyed when *this is destroyed.
element_type * const ret = (malloc)();
if (ret == 0)
return ret;
try { new (ret) element_type(); }
catch (...) { (free)(ret); throw; }
return ret;
}
#if defined(BOOST_DOXYGEN)
template <class Arg1, ... class ArgN>
element_type * construct(Arg1&, ... ArgN&)
{
//! \returns A pointer to an object of type T, allocated in memory from the underlying pool
//! and constructed from arguments Arg1 to ArgN. The returned objected can be freed by a call to \ref destroy.
//! Otherwise the returned object will be automatically destroyed when *this is destroyed.
//!
//! \note Since the number and type of arguments to this function is totally arbitrary, a simple system has been
//! set up to automatically generate template construct functions. This system is based on the macro preprocessor
//! m4, which is standard on UNIX systems and also available for Win32 systems.\n\n
//! detail/pool_construct.m4, when run with m4, will create the file detail/pool_construct.ipp, which only defines
//! the construct functions for the proper number of arguments. The number of arguments may be passed into the
//! file as an m4 macro, NumberOfArguments; if not provided, it will default to 3.\n\n
//! For each different number of arguments (1 to NumberOfArguments), a template function is generated. There
//! are the same number of template parameters as there are arguments, and each argument's type is a reference
//! to that (possibly cv-qualified) template argument. Each possible permutation of the cv-qualifications is also generated.\n\n
//! Because each permutation is generated for each possible number of arguments, the included file size grows
//! exponentially in terms of the number of constructor arguments, not linearly. For the sake of rational
//! compile times, only use as many arguments as you need.\n\n
//! detail/pool_construct.bat and detail/pool_construct.sh are also provided to call m4, defining NumberOfArguments
//! to be their command-line parameter. See these files for more details.
}
#else
// Include automatically-generated file for family of template construct() functions.
// Copy .inc renamed .ipp to conform to Doxygen include filename expectations, PAB 12 Jan 11.
// But still get Doxygen warning:
// I:/boost-sandbox/guild/pool/boost/pool/object_pool.hpp:82:
// Warning: include file boost/pool/detail/pool_construct.ipp
// not found, perhaps you forgot to add its directory to INCLUDE_PATH?
// But the file IS found and referenced OK, but cannot view code.
// This seems because not at the head of the file
// But if moved this up, Doxygen is happy, but of course it won't compile,
// because the many constructors *must* go here.
#ifndef BOOST_NO_TEMPLATE_CV_REF_OVERLOADS
# include <boost/pool/detail/pool_construct.ipp>
#else
# include <boost/pool/detail/pool_construct_simple.ipp>
#endif
#endif
void destroy(element_type * const chunk)
{ //! Destroys an object allocated with \ref construct.
//!
//! Equivalent to:
//!
//! p->~ElementType(); this->free(p);
//!
//! \pre p must have been previously allocated from *this via a call to \ref construct.
chunk->~T();
(free)(chunk);
}
size_type get_next_size() const
{ //! \returns The number of chunks that will be allocated next time we run out of memory.
return store().get_next_size();
}
void set_next_size(const size_type x)
{ //! Set a new number of chunks to allocate the next time we run out of memory.
//! \param x wanted next_size (must not be zero).
store().set_next_size(x);
}
};
template <typename T, typename UserAllocator>
object_pool<T, UserAllocator>::~object_pool()
{
#ifndef BOOST_POOL_VALGRIND
// handle trivial case of invalid list.
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();
#else
// destruct all used elements:
for(std::set<void*>::iterator pos = this->used_list.begin(); pos != this->used_list.end(); ++pos)
{
static_cast<T*>(*pos)->~T();
}
// base class will actually free the memory...
#endif
}
} // namespace boost
// The following code might be put into some Boost.Config header in a later revision
#ifdef BOOST_BORLANDC
# pragma option pop
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,512 @@
// Copyright (C) 2000, 2001 Stephen Cleary
// Copyright (C) 2010 Paul A. Bristow added Doxygen comments.
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef BOOST_POOL_ALLOC_HPP
#define BOOST_POOL_ALLOC_HPP
/*!
\file
\brief C++ Standard Library compatible pool-based allocators.
\details This header provides two template types -
\ref pool_allocator and \ref fast_pool_allocator -
that can be used for fast and efficient memory allocation
in conjunction with the C++ Standard Library containers.
These types both satisfy the Standard Allocator requirements [20.1.5]
and the additional requirements in [20.1.5/4],
so they can be used with either Standard or user-supplied containers.
In addition, the fast_pool_allocator also provides an additional allocation
and an additional deallocation function:
<table>
<tr><th>Expression</th><th>Return Type</th><th>Semantic Equivalence<th></tr>
<tr><td><tt>PoolAlloc::allocate()</tt></td><td><tt>T *</tt></td><td><tt>PoolAlloc::allocate(1)</tt></tr>
<tr><td><tt>PoolAlloc::deallocate(p)</tt></td><td>void</tt></td><td><tt>PoolAlloc::deallocate(p, 1)</tt></tr>
</table>
The typedef user_allocator publishes the value of the UserAllocator template parameter.
<b>Notes</b>
If the allocation functions run out of memory, they will throw <tt>std::bad_alloc</tt>.
The underlying Pool type used by the allocators is accessible through the Singleton Pool Interface.
The identifying tag used for pool_allocator is pool_allocator_tag,
and the tag used for fast_pool_allocator is fast_pool_allocator_tag.
All template parameters of the allocators (including implementation-specific ones)
determine the type of the underlying Pool,
with the exception of the first parameter T, whose size is used instead.
Since the size of T is used to determine the type of the underlying Pool,
each allocator for different types of the same size will share the same underlying pool.
The tag class prevents pools from being shared between pool_allocator and fast_pool_allocator.
For example, on a system where
<tt>sizeof(int) == sizeof(void *)</tt>, <tt>pool_allocator<int></tt> and <tt>pool_allocator<void *></tt>
will both allocate/deallocate from/to the same pool.
If there is only one thread running before main() starts and after main() ends,
then both allocators are completely thread-safe.
<b>Compiler and STL Notes</b>
A number of common STL libraries contain bugs in their using of allocators.
Specifically, they pass null pointers to the deallocate function,
which is explicitly forbidden by the Standard [20.1.5 Table 32].
PoolAlloc will work around these libraries if it detects them;
currently, workarounds are in place for:
Borland C++ (Builder and command-line compiler)
with default (RogueWave) library, ver. 5 and earlier,
STLport (with any compiler), ver. 4.0 and earlier.
*/
// std::numeric_limits
#include <boost/limits.hpp>
// new, std::bad_alloc
#include <new>
#include <boost/throw_exception.hpp>
#include <boost/pool/poolfwd.hpp>
// boost::singleton_pool
#include <boost/pool/singleton_pool.hpp>
#include <boost/detail/workaround.hpp>
// C++11 features detection
#include <boost/config.hpp>
// std::forward
#ifdef BOOST_HAS_VARIADIC_TMPL
#include <utility>
#endif
#ifdef BOOST_POOL_INSTRUMENT
#include <iostream>
#include <iomanip>
#endif
// The following code will be put into Boost.Config in a later revision
#if defined(_RWSTD_VER) || defined(__SGI_STL_PORT) || \
BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x582))
#define BOOST_NO_PROPER_STL_DEALLOCATE
#endif
namespace boost {
#ifdef BOOST_POOL_INSTRUMENT
template <bool b>
struct debug_info
{
static unsigned allocated;
};
template <bool b>
unsigned debug_info<b>::allocated = 0;
#endif
//! Simple tag type used by pool_allocator as an argument to the
//! underlying singleton_pool.
struct pool_allocator_tag
{
};
/*! \brief A C++ Standard Library conforming allocator, based on an underlying pool.
Template parameters for pool_allocator are defined as follows:
<b>T</b> Type of object to allocate/deallocate.
<b>UserAllocator</B>. Defines the method that the underlying Pool will use to allocate memory from the system. See
<a href="boost_pool/pool/pooling.html#boost_pool.pool.pooling.user_allocator">User Allocators</a> for details.
<b>Mutex</b> Allows the user to determine the type of synchronization to be used on the underlying singleton_pool.
<b>NextSize</b> The value of this parameter is passed to the underlying singleton_pool when it is created.
<b>MaxSize</b> Limit on the maximum size used.
\attention
The underlying singleton_pool used by the this allocator
constructs a pool instance that
<b>is never freed</b>. This means that memory allocated
by the allocator can be still used after main() has
completed, but may mean that some memory checking programs
will complain about leaks.
*/
template <typename T,
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize >
class pool_allocator
{
public:
typedef T value_type; //!< value_type of template parameter T.
typedef UserAllocator user_allocator; //!< allocator that defines the method that the underlying Pool will use to allocate memory from the system.
typedef Mutex mutex; //!< typedef mutex publishes the value of the template parameter Mutex.
BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize); //!< next_size publishes the values of the template parameter 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;
//! \brief Nested class rebind allows for transformation from
//! pool_allocator<T> to pool_allocator<U>.
//!
//! Nested class rebind allows for transformation from
//! pool_allocator<T> to pool_allocator<U> via the member
//! typedef other.
template <typename U>
struct rebind
{ //
typedef pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
};
public:
pool_allocator()
{ /*! Results in default construction of the underlying singleton_pool IFF an
instance of this allocator is constructed during global initialization (
required to ensure construction of singleton_pool IFF an
instance of this allocator is constructed during global
initialization. See ticket #2359 for a complete explanation at
http://svn.boost.org/trac/boost/ticket/2359) .
*/
singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
NextSize, MaxSize>::is_from(0);
}
// 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, MaxSize> &)
{ /*! Results in the default construction of the underlying singleton_pool, this
is required to ensure construction of singleton_pool IFF an
instance of this allocator is constructed during global
initialization. See ticket #2359 for a complete explanation
at http://svn.boost.org/trac/boost/ticket/2359 .
*/
singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
NextSize, MaxSize>::is_from(0);
}
// 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)(); }
#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
template <typename U, typename... Args>
static void construct(U* ptr, Args&&... args)
{ new (ptr) U(std::forward<Args>(args)...); }
#else
static void construct(const pointer ptr, const value_type & t)
{ new (ptr) T(t); }
#endif
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)
{
#ifdef BOOST_POOL_INSTRUMENT
debug_info<true>::allocated += n * sizeof(T);
std::cout << "Allocating " << n << " * " << sizeof(T) << " bytes...\n"
"Total allocated is now " << debug_info<true>::allocated << std::endl;
#endif
const pointer ret = static_cast<pointer>(
singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
NextSize, MaxSize>::ordered_malloc(n) );
if ((ret == 0) && n)
boost::throw_exception(std::bad_alloc());
return ret;
}
static pointer allocate(const size_type n, const void * const)
{ //! allocate n bytes
//! \param n bytes to allocate.
//! \param unused.
return allocate(n);
}
static void deallocate(const pointer ptr, const size_type n)
{ //! Deallocate n bytes from ptr
//! \param ptr location to deallocate from.
//! \param n number of bytes to deallocate.
#ifdef BOOST_POOL_INSTRUMENT
debug_info<true>::allocated -= n * sizeof(T);
std::cout << "Deallocating " << n << " * " << sizeof(T) << " bytes...\n"
"Total allocated is now " << debug_info<true>::allocated << std::endl;
#endif
#ifdef BOOST_NO_PROPER_STL_DEALLOCATE
if (ptr == 0 || n == 0)
return;
#endif
singleton_pool<pool_allocator_tag, sizeof(T), UserAllocator, Mutex,
NextSize, MaxSize>::ordered_free(ptr, n);
}
};
/*! \brief Specialization of pool_allocator<void>.
Specialization of pool_allocator for type void: required by the standard to make this a conforming allocator type.
*/
template<
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize>
class pool_allocator<void, UserAllocator, Mutex, NextSize, MaxSize>
{
public:
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;
//! \brief Nested class rebind allows for transformation from
//! pool_allocator<T> to pool_allocator<U>.
//!
//! Nested class rebind allows for transformation from
//! pool_allocator<T> to pool_allocator<U> via the member
//! typedef other.
template <class U>
struct rebind
{
typedef pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
};
};
//! Simple tag type used by fast_pool_allocator as a template parameter to the underlying singleton_pool.
struct fast_pool_allocator_tag
{
};
/*! \brief A C++ Standard Library conforming allocator geared towards allocating single chunks.
While class template <tt>pool_allocator</tt> is a more general-purpose solution geared towards
efficiently servicing requests for any number of contiguous chunks,
<tt>fast_pool_allocator</tt> is also a general-purpose solution,
but is geared towards efficiently servicing requests for one chunk at a time;
it will work for contiguous chunks, but not as well as <tt>pool_allocator</tt>.
If you are seriously concerned about performance,
use <tt>fast_pool_allocator</tt> when dealing with containers such as <tt>std::list</tt>,
and use <tt>pool_allocator</tt> when dealing with containers such as <tt>std::vector</tt>.
The template parameters are defined as follows:
<b>T</b> Type of object to allocate/deallocate.
<b>UserAllocator</b>. Defines the method that the underlying Pool will use to allocate memory from the system.
See <a href="boost_pool/pool/pooling.html#boost_pool.pool.pooling.user_allocator">User Allocators</a> for details.
<b>Mutex</b> Allows the user to determine the type of synchronization to be used on the underlying <tt>singleton_pool</tt>.
<b>NextSize</b> The value of this parameter is passed to the underlying Pool when it is created.
<b>MaxSize</b> Limit on the maximum size used.
\attention
The underlying singleton_pool used by the this allocator
constructs a pool instance that
<b>is never freed</b>. This means that memory allocated
by the allocator can be still used after main() has
completed, but may mean that some memory checking programs
will complain about leaks.
*/
template <typename T,
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize >
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;
//! \brief Nested class rebind allows for transformation from
//! fast_pool_allocator<T> to fast_pool_allocator<U>.
//!
//! Nested class rebind allows for transformation from
//! fast_pool_allocator<T> to fast_pool_allocator<U> via the member
//! typedef other.
template <typename U>
struct rebind
{
typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
};
public:
fast_pool_allocator()
{
//! Ensures construction of the underlying singleton_pool IFF an
//! instance of this allocator is constructed during global
//! initialization. See ticket #2359 for a complete explanation
//! at http://svn.boost.org/trac/boost/ticket/2359 .
singleton_pool<fast_pool_allocator_tag, sizeof(T),
UserAllocator, Mutex, NextSize, MaxSize>::is_from(0);
}
// Default copy constructor used.
// Default assignment operator used.
// Not explicit, mimicking std::allocator [20.4.1]
template <typename U>
fast_pool_allocator(
const fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> &)
{
//! Ensures construction of the underlying singleton_pool IFF an
//! instance of this allocator is constructed during global
//! initialization. See ticket #2359 for a complete explanation
//! at http://svn.boost.org/trac/boost/ticket/2359 .
singleton_pool<fast_pool_allocator_tag, sizeof(T),
UserAllocator, Mutex, NextSize, MaxSize>::is_from(0);
}
// Default destructor used.
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)(); }
#if defined(BOOST_HAS_VARIADIC_TMPL) && defined(BOOST_HAS_RVALUE_REFS)
template <typename U, typename... Args>
void construct(U* ptr, Args&&... args)
{ new (ptr) U(std::forward<Args>(args)...); }
#else
void construct(const pointer ptr, const value_type & t)
{ new (ptr) T(t); }
#endif
void destroy(const pointer ptr)
{ //! Destroy ptr using destructor.
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, MaxSize>::malloc)() ) :
static_cast<pointer>(
singleton_pool<fast_pool_allocator_tag, sizeof(T),
UserAllocator, Mutex, NextSize, MaxSize>::ordered_malloc(n) );
if (ret == 0)
boost::throw_exception(std::bad_alloc());
return ret;
}
static pointer allocate(const size_type n, const void * const)
{ //! Allocate memory .
return allocate(n);
}
static pointer allocate()
{ //! Allocate memory.
const pointer ret = static_cast<pointer>(
(singleton_pool<fast_pool_allocator_tag, sizeof(T),
UserAllocator, Mutex, NextSize, MaxSize>::malloc)() );
if (ret == 0)
boost::throw_exception(std::bad_alloc());
return ret;
}
static void deallocate(const pointer ptr, const size_type n)
{ //! Deallocate memory.
#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, MaxSize>::free)(ptr);
else
(singleton_pool<fast_pool_allocator_tag, sizeof(T),
UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr, n);
}
static void deallocate(const pointer ptr)
{ //! deallocate/free
(singleton_pool<fast_pool_allocator_tag, sizeof(T),
UserAllocator, Mutex, NextSize, MaxSize>::free)(ptr);
}
};
/*! \brief Specialization of fast_pool_allocator<void>.
Specialization of fast_pool_allocator<void> required to make the allocator standard-conforming.
*/
template<
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize >
class fast_pool_allocator<void, UserAllocator, Mutex, NextSize, MaxSize>
{
public:
typedef void* pointer;
typedef const void* const_pointer;
typedef void value_type;
//! \brief Nested class rebind allows for transformation from
//! fast_pool_allocator<T> to fast_pool_allocator<U>.
//!
//! Nested class rebind allows for transformation from
//! fast_pool_allocator<T> to fast_pool_allocator<U> via the member
//! typedef other.
template <class U> struct rebind
{
typedef fast_pool_allocator<U, UserAllocator, Mutex, NextSize, MaxSize> other;
};
};
} // namespace boost
#endif

View File

@@ -0,0 +1,82 @@
// Copyright (C) 2000, 2001 Stephen Cleary
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef BOOST_POOLFWD_HPP
#define BOOST_POOLFWD_HPP
/*!
\file
\brief Forward declarations of all public (non-implemention) classes.
*/
#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,
unsigned MaxSize = 0>
class 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,
unsigned MaxSize = 0>
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,
unsigned MaxSize = 0>
class fast_pool_allocator;
} // namespace boost
#endif

View File

@@ -0,0 +1,377 @@
// Copyright (C) 2000, 2001 Stephen Cleary
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef BOOST_SIMPLE_SEGREGATED_STORAGE_HPP
#define BOOST_SIMPLE_SEGREGATED_STORAGE_HPP
/*!
\file
\brief Simple Segregated Storage.
\details A simple segregated storage implementation:
simple segregated storage is the basic idea behind the Boost Pool library.
Simple segregated storage is the simplest, and probably the fastest,
memory allocation/deallocation algorithm.
It begins by partitioning a memory block into fixed-size chunks.
Where the block comes from is not important until implementation time.
A Pool is some object that uses Simple Segregated Storage in this fashion.
*/
// std::greater
#include <functional>
#include <boost/pool/poolfwd.hpp>
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127) // Conditional expression is constant
#endif
#ifdef BOOST_POOL_VALIDATE
# define BOOST_POOL_VALIDATE_INTERNALS validate();
#else
# define BOOST_POOL_VALIDATE_INTERNALS
#endif
namespace boost {
/*!
\brief Simple Segregated Storage is the simplest, and probably the fastest,
memory allocation/deallocation algorithm. It is responsible for
partitioning a memory block into fixed-size chunks: where the block comes from
is determined by the client of the class.
\details Template class simple_segregated_storage controls access to a free list of memory chunks.
Please note that this is a very simple class, with preconditions on almost all its functions. It is intended to
be the fastest and smallest possible quick memory allocator - e.g., something to use in embedded systems.
This class delegates many difficult preconditions to the user (i.e., alignment issues).
An object of type simple_segregated_storage<SizeType> is empty if its free list is empty.
If it is not empty, then it is ordered if its free list is ordered. A free list is ordered if repeated calls
to <tt>malloc()</tt> will result in a constantly-increasing sequence of values, as determined by <tt>std::less<void *></tt>.
A member function is <i>order-preserving</i> if the free list maintains its order orientation (that is, an
ordered free list is still ordered after the member function call).
*/
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 &);
static void * try_malloc_n(void * & start, size_type n,
size_type partition_size);
protected:
void * first; /*!< This data member is the free list.
It points to the first chunk in the free list,
or is equal to 0 if the free list is empty.
*/
void * find_prev(void * ptr);
// for the sake of code readability :)
static void * & nextof(void * const ptr)
{ //! The return value is just *ptr cast to the appropriate type. ptr must not be 0. (For the sake of code readability :)
//! As an example, let us assume that we want to truncate the free list after the first chunk.
//! That is, we want to set *first to 0; this will result in a free list with only one entry.
//! The normal way to do this is to first cast first to a pointer to a pointer to void,
//! and then dereference and assign (*static_cast<void **>(first) = 0;).
//! This can be done more easily through the use of this convenience function (nextof(first) = 0;).
//! \returns dereferenced pointer.
return *(static_cast<void **>(ptr));
}
public:
// Post: empty()
simple_segregated_storage()
:first(0)
{ //! Construct empty storage area.
//! \post empty()
}
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)
{ //! Add block
//! Segregate this block and merge its free list into the
//! free list referred to by "first".
//! \pre Same as segregate.
//! \post !empty()
BOOST_POOL_VALIDATE_INTERNALS
first = segregate(block, nsz, npartition_sz, first);
BOOST_POOL_VALIDATE_INTERNALS
}
// Same preconditions as 'segregate'
// Post: !empty()
void add_ordered_block(void * const block,
const size_type nsz, const size_type npartition_sz)
{ //! add block (ordered into list)
//! This (slower) version of add_block segregates the
//! block and merges its free list into our free list
//! in the proper order.
BOOST_POOL_VALIDATE_INTERNALS
// 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));
BOOST_POOL_VALIDATE_INTERNALS
}
// default destructor.
bool empty() const
{ //! \returns true only if simple_segregated_storage is empty.
return (first == 0);
}
void * malloc BOOST_PREVENT_MACRO_SUBSTITUTION()
{ //! Create a chunk.
//! \pre !empty()
//! Increment the "first" pointer to point to the next chunk.
BOOST_POOL_VALIDATE_INTERNALS
void * const ret = first;
// Increment the "first" pointer to point to the next chunk.
first = nextof(first);
BOOST_POOL_VALIDATE_INTERNALS
return ret;
}
void free BOOST_PREVENT_MACRO_SUBSTITUTION(void * const chunk)
{ //! Free a chunk.
//! \pre chunk was previously returned from a malloc() referring to the same free list.
//! \post !empty()
BOOST_POOL_VALIDATE_INTERNALS
nextof(chunk) = first;
first = chunk;
BOOST_POOL_VALIDATE_INTERNALS
}
void ordered_free(void * const chunk)
{ //! This (slower) implementation of 'free' places the memory
//! back in the list in its proper order.
//! \pre chunk was previously returned from a malloc() referring to the same free list
//! \post !empty().
// Find where "chunk" goes in the free list
BOOST_POOL_VALIDATE_INTERNALS
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;
}
BOOST_POOL_VALIDATE_INTERNALS
}
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)
{
BOOST_POOL_VALIDATE_INTERNALS
if(n != 0)
add_block(chunks, n * partition_size, partition_size);
BOOST_POOL_VALIDATE_INTERNALS
}
// 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)
{ //! Free n chunks from order list.
//! \pre chunks was previously allocated from *this with the same
//! values for n and partition_size.
//! \pre n should not be zero (n == 0 has no effect).
BOOST_POOL_VALIDATE_INTERNALS
if(n != 0)
add_ordered_block(chunks, n * partition_size, partition_size);
BOOST_POOL_VALIDATE_INTERNALS
}
#ifdef BOOST_POOL_VALIDATE
void validate()
{
int index = 0;
void* old = 0;
void* ptr = first;
while(ptr)
{
void* pt = nextof(ptr); // trigger possible segfault *before* we update variables
++index;
old = ptr;
ptr = nextof(ptr);
}
}
#endif
};
//! 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").
//! \note Note that this function finds the location previous to where ptr would go
//! if it was in the free list.
//! It does not find the entry in the free list before ptr
//! (unless ptr is already in the free list).
//! Specifically, find_prev(0) will return 0,
//! not the last entry in the free list.
//! \returns location previous to where ptr would go if it was in the free list.
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);
}
}
//! Segregate block into chunks.
//! \pre npartition_sz >= sizeof(void *)
//! \pre npartition_sz = sizeof(void *) * i, for some integer i
//! \pre nsz >= npartition_sz
//! \pre 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 **.
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;
}
//! \pre (n > 0), (start != 0), (nextof(start) != 0)
//! \post (start != 0)
//! The 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;
}
//! Attempts to find a contiguous sequence of n partition_sz-sized chunks. If found, removes them
//! all from the free list and returns a pointer to the first. If not found, returns 0. It is strongly
//! recommended (but not required) that the free list be ordered, as this algorithm will fail to find
//! a contiguous sequence unless it is contiguous in the free list as well. Order-preserving.
//! O(N) with respect to the size of the free list.
template <typename SizeType>
void * simple_segregated_storage<SizeType>::malloc_n(const size_type n,
const size_type partition_size)
{
BOOST_POOL_VALIDATE_INTERNALS
if(n == 0)
return 0;
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);
BOOST_POOL_VALIDATE_INTERNALS
return ret;
}
} // namespace boost
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#endif

View File

@@ -0,0 +1,251 @@
// Copyright (C) 2000, 2001 Stephen Cleary
//
// Distributed under the Boost Software License, Version 1.0. (See
// accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
//
// See http://www.boost.org for updates, documentation, and revision history.
#ifndef BOOST_SINGLETON_POOL_HPP
#define BOOST_SINGLETON_POOL_HPP
/*!
\file
\brief The <tt>singleton_pool</tt> class allows other pool interfaces
for types of the same size to share the same underlying pool.
\details Header singleton_pool.hpp provides a template class <tt>singleton_pool</tt>,
which provides access to a pool as a singleton object.
*/
#include <boost/pool/poolfwd.hpp>
// boost::pool
#include <boost/pool/pool.hpp>
// boost::details::pool::guard
#include <boost/pool/detail/guard.hpp>
#include <boost/type_traits/aligned_storage.hpp>
namespace boost {
/*!
The singleton_pool class allows other pool interfaces
for types of the same size to share the same pool. Template
parameters are as follows:
<b>Tag</b> User-specified type to uniquely identify this pool: allows different unbounded sets of singleton pools to exist.
<b>RequestedSize</b> The size of each chunk returned by member function <tt>malloc()</tt>.
<B>UserAllocator</b> User allocator, default = default_user_allocator_new_delete.
<b>Mutex</B> This class is the type of mutex to use to protect simultaneous access to the underlying Pool.
Can be any Boost.Thread Mutex type or <tt>boost::details::pool::null_mutex</tt>.
It is exposed so that users may declare some singleton pools normally (i.e., with synchronization), but
some singleton pools without synchronization (by specifying <tt>boost::details::pool::null_mutex</tt>) for efficiency reasons.
The member typedef <tt>mutex</tt> exposes the value of this template parameter. The default for this
parameter is boost::details::pool::default_mutex which is a synonym for either <tt>boost::details::pool::null_mutex</tt>
(when threading support is turned off in the compiler (so BOOST_HAS_THREADS is not set), or threading support
has ben explicitly disabled with BOOST_DISABLE_THREADS (Boost-wide disabling of threads) or BOOST_POOL_NO_MT (this library only))
or for <tt>boost::mutex</tt> (when threading support is enabled in the compiler).
<B>NextSize</b> The value of this parameter is passed to the underlying Pool when it is created and
specifies the number of chunks to allocate in the first allocation request (defaults to 32).
The member typedef <tt>static const value next_size</tt> exposes the value of this template parameter.
<b>MaxSize</B>The value of this parameter is passed to the underlying Pool when it is created and
specifies the maximum number of chunks to allocate in any single allocation request (defaults to 0).
<b>Notes:</b>
The underlying pool <i>p</i> referenced by the static functions
in singleton_pool is actually declared in a way that is:
1 Thread-safe if there is only one thread running before main() begins and after main() ends
-- all of the static functions of singleton_pool synchronize their access to p.
2 Guaranteed to be constructed before it is used --
thus, the simple static object in the synopsis above would actually be an incorrect implementation.
The actual implementation to guarantee this is considerably more complicated.
3 Note too that a different underlying pool p exists
for each different set of template parameters,
including implementation-specific ones.
4 The underlying pool is constructed "as if" by:
pool<UserAllocator> p(RequestedSize, NextSize, MaxSize);
\attention
The underlying pool constructed by the singleton
<b>is never freed</b>. This means that memory allocated
by a singleton_pool can be still used after main() has
completed, but may mean that some memory checking programs
will complain about leaks from singleton_pool.
*/
template <typename Tag,
unsigned RequestedSize,
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize >
class singleton_pool
{
public:
typedef Tag tag; /*!< The Tag template parameter uniquely
identifies this pool and allows
different unbounded sets of singleton pools to exist.
For example, the pool allocators use two tag classes to ensure that the
two different allocator types never share the same underlying singleton pool.
Tag is never actually used by singleton_pool.
*/
typedef Mutex mutex; //!< The type of mutex used to synchonise access to this pool (default <tt>details::pool::default_mutex</tt>).
typedef UserAllocator user_allocator; //!< The user-allocator used by this pool, default = <tt>default_user_allocator_new_delete</tt>.
typedef typename pool<UserAllocator>::size_type size_type; //!< size_type of user allocator.
typedef typename pool<UserAllocator>::difference_type difference_type; //!< difference_type of user allocator.
BOOST_STATIC_CONSTANT(unsigned, requested_size = RequestedSize); //!< The size of each chunk allocated by this pool.
BOOST_STATIC_CONSTANT(unsigned, next_size = NextSize); //!< The number of chunks to allocate on the first allocation.
private:
singleton_pool();
#ifndef BOOST_DOXYGEN
struct pool_type: public Mutex, public pool<UserAllocator>
{
pool_type() : pool<UserAllocator>(RequestedSize, NextSize, MaxSize) {}
}; // struct pool_type: Mutex
#else
//
// This is invoked when we build with Doxygen only:
//
public:
static pool<UserAllocator> p; //!< For exposition only!
#endif
public:
static void * malloc BOOST_PREVENT_MACRO_SUBSTITUTION()
{ //! Equivalent to SingletonPool::p.malloc(); synchronized.
pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
return (p.malloc)();
}
static void * ordered_malloc()
{ //! Equivalent to SingletonPool::p.ordered_malloc(); synchronized.
pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
return p.ordered_malloc();
}
static void * ordered_malloc(const size_type n)
{ //! Equivalent to SingletonPool::p.ordered_malloc(n); synchronized.
pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
return p.ordered_malloc(n);
}
static bool is_from(void * const ptr)
{ //! Equivalent to SingletonPool::p.is_from(chunk); synchronized.
//! \returns true if chunk is from SingletonPool::is_from(chunk)
pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
return p.is_from(ptr);
}
static void free BOOST_PREVENT_MACRO_SUBSTITUTION(void * const ptr)
{ //! Equivalent to SingletonPool::p.free(chunk); synchronized.
pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
(p.free)(ptr);
}
static void ordered_free(void * const ptr)
{ //! Equivalent to SingletonPool::p.ordered_free(chunk); synchronized.
pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
p.ordered_free(ptr);
}
static void free BOOST_PREVENT_MACRO_SUBSTITUTION(void * const ptr, const size_type n)
{ //! Equivalent to SingletonPool::p.free(chunk, n); synchronized.
pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
(p.free)(ptr, n);
}
static void ordered_free(void * const ptr, const size_type n)
{ //! Equivalent to SingletonPool::p.ordered_free(chunk, n); synchronized.
pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
p.ordered_free(ptr, n);
}
static bool release_memory()
{ //! Equivalent to SingletonPool::p.release_memory(); synchronized.
pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
return p.release_memory();
}
static bool purge_memory()
{ //! Equivalent to SingletonPool::p.purge_memory(); synchronized.
pool_type & p = get_pool();
details::pool::guard<Mutex> g(p);
return p.purge_memory();
}
private:
typedef boost::aligned_storage<sizeof(pool_type), boost::alignment_of<pool_type>::value> storage_type;
static storage_type storage;
static pool_type& get_pool()
{
static bool f = false;
if(!f)
{
// This code *must* be called before main() starts,
// and when only one thread is executing.
f = true;
new (&storage) pool_type;
}
// The following line does nothing else than force the instantiation
// of singleton<T>::create_object, whose constructor is
// called before main() begins.
create_object.do_nothing();
return *static_cast<pool_type*>(static_cast<void*>(&storage));
}
struct object_creator
{
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.
singleton_pool<Tag, RequestedSize, UserAllocator, Mutex, NextSize, MaxSize>::get_pool();
}
inline void do_nothing() const
{
}
};
static object_creator create_object;
}; // struct singleton_pool
template <typename Tag,
unsigned RequestedSize,
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize >
typename singleton_pool<Tag, RequestedSize, UserAllocator, Mutex, NextSize, MaxSize>::storage_type singleton_pool<Tag, RequestedSize, UserAllocator, Mutex, NextSize, MaxSize>::storage;
template <typename Tag,
unsigned RequestedSize,
typename UserAllocator,
typename Mutex,
unsigned NextSize,
unsigned MaxSize >
typename singleton_pool<Tag, RequestedSize, UserAllocator, Mutex, NextSize, MaxSize>::object_creator singleton_pool<Tag, RequestedSize, UserAllocator, Mutex, NextSize, MaxSize>::create_object;
} // namespace boost
#endif

View File

@@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

View File

@@ -0,0 +1,4 @@
The package boost is compatible with built-in CMake targets:
find_package(Boost REQUIRED [COMPONENTS <libs>...])
target_link_libraries(main PRIVATE Boost::boost Boost::<lib1> Boost::<lib2> ...)

View File

@@ -0,0 +1,115 @@
{
"$schema": "https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.1/schemas/spdx-schema.json",
"spdxVersion": "SPDX-2.2",
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"documentNamespace": "https://spdx.org/spdxdocs/boost-pool-x64-windows-1.79.0-ac46e850-d1ed-4224-a257-55d07d989413",
"name": "boost-pool:x64-windows@1.79.0 f53abd1be62e7e71cadf9ce7d38ccf5edc7b8505d9970a8c74849587e388bfd4",
"creationInfo": {
"creators": [
"Tool: vcpkg-9268e366206712e38102b28dbd1617697a99ff2e"
],
"created": "2022-07-23T08:23:32Z"
},
"relationships": [
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "GENERATES",
"relatedSpdxElement": "SPDXRef-binary"
},
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "CONTAINS",
"relatedSpdxElement": "SPDXRef-file-0"
},
{
"spdxElementId": "SPDXRef-port",
"relationshipType": "CONTAINS",
"relatedSpdxElement": "SPDXRef-file-1"
},
{
"spdxElementId": "SPDXRef-binary",
"relationshipType": "GENERATED_FROM",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-0",
"relationshipType": "CONTAINED_BY",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-1",
"relationshipType": "CONTAINED_BY",
"relatedSpdxElement": "SPDXRef-port"
},
{
"spdxElementId": "SPDXRef-file-1",
"relationshipType": "DEPENDENCY_MANIFEST_OF",
"relatedSpdxElement": "SPDXRef-port"
}
],
"packages": [
{
"name": "boost-pool",
"SPDXID": "SPDXRef-port",
"versionInfo": "1.79.0",
"downloadLocation": "NOASSERTION",
"homepage": "https://github.com/boostorg/pool",
"licenseConcluded": "BSL-1.0",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"description": "Boost pool module",
"comment": "This is the port (recipe) consumed by vcpkg."
},
{
"name": "boost-pool:x64-windows",
"SPDXID": "SPDXRef-binary",
"versionInfo": "f53abd1be62e7e71cadf9ce7d38ccf5edc7b8505d9970a8c74849587e388bfd4",
"downloadLocation": "NONE",
"licenseConcluded": "BSL-1.0",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"comment": "This is a binary package built by vcpkg."
},
{
"SPDXID": "SPDXRef-resource-1",
"name": "boostorg/pool",
"downloadLocation": "git+https://github.com/boostorg/pool@boost-1.79.0",
"licenseConcluded": "NOASSERTION",
"licenseDeclared": "NOASSERTION",
"copyrightText": "NOASSERTION",
"checksums": [
{
"algorithm": "SHA512",
"checksumValue": "ea62735a0f53bf0f94fd994055dc422007557f4a42c35d9b76259fa23e01f7ed637334342e3127d725a187610fff9a76bba044837bfc545bac21594ea8d58500"
}
]
}
],
"files": [
{
"fileName": "./portfile.cmake",
"SPDXID": "SPDXRef-file-0",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "f4a674cb21db7657ffa0c92ba0c612542599948e4cd6b6ccbe3211a52ba87f1c"
}
],
"licenseConcluded": "NOASSERTION",
"copyrightText": "NOASSERTION"
},
{
"fileName": "./vcpkg.json",
"SPDXID": "SPDXRef-file-1",
"checksums": [
{
"algorithm": "SHA256",
"checksumValue": "7f47863240140f9f29b2719fff0233ca3999359e79668ed6f0ca3d87778e46ab"
}
],
"licenseConcluded": "NOASSERTION",
"copyrightText": "NOASSERTION"
}
]
}

View File

@@ -0,0 +1,18 @@
boost-assert a50eed453b8be6c8932fb3d5f8feaf194a2ebeaed7982db4e36e3ba17f3ec107
boost-config 797535e8975ed7cf5bbe11d9f7fe26caa5da8fe819888564758d82a21109fade
boost-integer 7a387f2417014a6cf56a8a8cd689c8153efaaf93ea6beba8f390f5b9577da9cb
boost-throw-exception 4bb4a0182f0f071c3c1ffd9cbd82fbc3bc7db4a35346f930bbe504e7e3a94e0a
boost-type-traits 74f62124585467fbb6c4fa16015164d11e1a079d6bdb70ec1c3fe7cf65b9a594
boost-vcpkg-helpers c81c7b003df356a1a120a7c0c2f5a2ac95f3c33b006a2a5b4c02dcf0c9f3deaa
boost-winapi e3a25230fe97591ec7dbff1bfe0e2db388523e993305526811adef219f215c5a
cmake 3.23.2
features core
portfile.cmake f4a674cb21db7657ffa0c92ba0c612542599948e4cd6b6ccbe3211a52ba87f1c
ports.cmake 366c60b768113102408b32ac1d7c7b48ef7d30a477af2a220ecc222d9ffa3166
post_build_checks 2
powershell 7.2.5
triplet x64-windows
triplet_abi 4556164a2cd3dd6f4742101eabb46def7e71b6e5856faa88e5d005aac12a803c-c0600b35e024ce0485ed253ef5419f3686f7257cfb58cb6a24febcb600fc4b4c-27ebd443f77a6c449168adfa6ce8def60cf46e88
vcpkg.json 7f47863240140f9f29b2719fff0233ca3999359e79668ed6f0ca3d87778e46ab
vcpkg_from_git 0aab20e34e84d52ba4763f009e539bfa8f418c41c918c8cf700156f1a8551a10
vcpkg_from_github b743742296a114ea1b18ae99672e02f142c4eb2bef7f57d36c038bedbfb0502f