summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/pool
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/pool')
-rw-r--r--src/boost/libs/pool/CMakeLists.txt24
-rw-r--r--src/boost/libs/pool/Jamfile11
-rw-r--r--src/boost/libs/pool/LICENSE23
-rw-r--r--src/boost/libs/pool/README.md34
-rw-r--r--src/boost/libs/pool/example/Jamfile.v224
-rw-r--r--src/boost/libs/pool/example/sys_allocator.hpp109
-rw-r--r--src/boost/libs/pool/example/time_pool_alloc.cpp558
-rw-r--r--src/boost/libs/pool/index.html13
-rw-r--r--src/boost/libs/pool/meta/libraries.json14
-rw-r--r--src/boost/libs/pool/test/Jamfile.v249
-rw-r--r--src/boost/libs/pool/test/pool_msvc_compiler_bug_test.cpp40
-rw-r--r--src/boost/libs/pool/test/random_shuffle.hpp26
-rw-r--r--src/boost/libs/pool/test/test_bug_1252.cpp66
-rw-r--r--src/boost/libs/pool/test/test_bug_2696.cpp66
-rw-r--r--src/boost/libs/pool/test/test_bug_3349.cpp27
-rw-r--r--src/boost/libs/pool/test/test_bug_4960.cpp45
-rw-r--r--src/boost/libs/pool/test/test_bug_5526.cpp36
-rw-r--r--src/boost/libs/pool/test/test_msvc_mem_leak_detect.cpp50
-rw-r--r--src/boost/libs/pool/test/test_poisoned_macros.cpp50
-rw-r--r--src/boost/libs/pool/test/test_pool_alloc.cpp291
-rw-r--r--src/boost/libs/pool/test/test_simple_seg_storage.cpp304
-rw-r--r--src/boost/libs/pool/test/test_simple_seg_storage.hpp173
-rw-r--r--src/boost/libs/pool/test/test_threading.cpp80
-rw-r--r--src/boost/libs/pool/test/test_valgrind_fail_1.cpp22
-rw-r--r--src/boost/libs/pool/test/test_valgrind_fail_2.cpp20
-rw-r--r--src/boost/libs/pool/test/track_allocator.hpp104
-rw-r--r--src/boost/libs/pool/test/valgrind_config_check.cpp7
27 files changed, 2266 insertions, 0 deletions
diff --git a/src/boost/libs/pool/CMakeLists.txt b/src/boost/libs/pool/CMakeLists.txt
new file mode 100644
index 000000000..02b32b4f9
--- /dev/null
+++ b/src/boost/libs/pool/CMakeLists.txt
@@ -0,0 +1,24 @@
+# Copyright 2018 Mike Dev
+# 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
+#
+# NOTE: CMake support for Boost.Pool is currently experimental at best
+# and the interface is likely to change in the future
+
+cmake_minimum_required(VERSION 3.5)
+project(BoostBind LANGUAGES CXX)
+
+add_library(boost_pool INTERFACE)
+add_library(Boost::pool ALIAS boost_pool)
+
+target_include_directories(boost_pool INTERFACE include)
+
+target_link_libraries(boost_pool
+ INTERFACE
+ Boost::assert
+ Boost::config
+ Boost::integer
+ Boost::throw_exception
+ Boost::type_traits
+ Boost::winapi
+)
diff --git a/src/boost/libs/pool/Jamfile b/src/boost/libs/pool/Jamfile
new file mode 100644
index 000000000..6f4d52865
--- /dev/null
+++ b/src/boost/libs/pool/Jamfile
@@ -0,0 +1,11 @@
+# Boost.Pool Library Jamfile
+#
+# Copyright (c) 2018 James E. King III
+#
+# Use, modification, and distribution are subject to 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)
+
+# please order by name to ease maintenance
+build-project example ;
+build-project test ;
diff --git a/src/boost/libs/pool/LICENSE b/src/boost/libs/pool/LICENSE
new file mode 100644
index 000000000..36b7cd93c
--- /dev/null
+++ b/src/boost/libs/pool/LICENSE
@@ -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.
diff --git a/src/boost/libs/pool/README.md b/src/boost/libs/pool/README.md
new file mode 100644
index 000000000..ca3f82347
--- /dev/null
+++ b/src/boost/libs/pool/README.md
@@ -0,0 +1,34 @@
+Pool, part of collection of the [Boost C++ Libraries](http://github.com/boostorg), provides an efficient way to handle memory suballocation for fixed-size items.
+
+### License
+
+Distributed under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
+
+### Properties
+
+* C++03
+* Header Only
+
+### Build Status
+
+Branch | Travis | Appveyor | Coverity Scan | codecov.io | Deps | Docs | Tests |
+:-------------: | ------ | -------- | ------------- | ---------- | ---- | ---- | ----- |
+[`master`](https://github.com/boostorg/pool/tree/master) | [![Build Status](https://travis-ci.org/boostorg/pool.svg?branch=master)](https://travis-ci.org/boostorg/pool) | [![Build status](https://ci.appveyor.com/api/projects/status/ci0aakleyrgnw7ji/branch/master?svg=true)](https://ci.appveyor.com/project/jeking3/pool-6s5a4/branch/master) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/15800/badge.svg)](https://scan.coverity.com/projects/boostorg-pool) | [![codecov](https://codecov.io/gh/boostorg/pool/branch/master/graph/badge.svg)](https://codecov.io/gh/boostorg/pool/branch/master)| [![Deps](https://img.shields.io/badge/deps-master-brightgreen.svg)](https://pdimov.github.io/boostdep-report/master/pool.html) | [![Documentation](https://img.shields.io/badge/docs-master-brightgreen.svg)](http://www.boost.org/doc/libs/master/doc/html/pool.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-master-brightgreen.svg)](http://www.boost.org/development/tests/master/developer/pool.html)
+[`develop`](https://github.com/boostorg/pool/tree/develop) | [![Build Status](https://travis-ci.org/boostorg/pool.svg?branch=develop)](https://travis-ci.org/boostorg/pool) | [![Build status](https://ci.appveyor.com/api/projects/status/ci0aakleyrgnw7ji/branch/develop?svg=true)](https://ci.appveyor.com/project/jeking3/pool-6s5a4/branch/develop) | [![Coverity Scan Build Status](https://scan.coverity.com/projects/15800/badge.svg)](https://scan.coverity.com/projects/boostorg-pool) | [![codecov](https://codecov.io/gh/boostorg/pool/branch/develop/graph/badge.svg)](https://codecov.io/gh/boostorg/pool/branch/develop) | [![Deps](https://img.shields.io/badge/deps-develop-brightgreen.svg)](https://pdimov.github.io/boostdep-report/develop/pool.html) | [![Documentation](https://img.shields.io/badge/docs-develop-brightgreen.svg)](http://www.boost.org/doc/libs/develop/doc/html/pool.html) | [![Enter the Matrix](https://img.shields.io/badge/matrix-develop-brightgreen.svg)](http://www.boost.org/development/tests/develop/developer/pool.html)
+
+### Directories
+
+| Name | Purpose |
+| ----------- | ------------------------------ |
+| `doc` | documentation |
+| `example` | examples |
+| `include` | headers |
+| `test` | unit tests |
+
+### More information
+
+* [Ask questions](http://stackoverflow.com/questions/ask?tags=c%2B%2B,boost,boost-pool)
+* [Report bugs](https://github.com/boostorg/pool/issues): Be sure to mention Boost version, platform and compiler you're using. A small compilable code sample to reproduce the problem is always good as well.
+* Submit your patches as pull requests against **develop** branch. Note that by submitting patches you agree to license your modifications under the [Boost Software License, Version 1.0](http://www.boost.org/LICENSE_1_0.txt).
+* Discussions about the library are held on the [Boost developers mailing list](http://www.boost.org/community/groups.html#main). Be sure to read the [discussion policy](http://www.boost.org/community/policy.html) before posting and add the `[pool]` tag at the beginning of the subject line.
+
diff --git a/src/boost/libs/pool/example/Jamfile.v2 b/src/boost/libs/pool/example/Jamfile.v2
new file mode 100644
index 000000000..acb8dcb11
--- /dev/null
+++ b/src/boost/libs/pool/example/Jamfile.v2
@@ -0,0 +1,24 @@
+# Boost.Pool Library example Jamfile
+#
+# Copyright (c) 2008 James E. King III
+#
+# 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)
+
+import os ;
+import testing ;
+
+project
+ : requirements
+ <library>/boost/system//boost_system
+ <define>BOOST_ALL_NO_LIB=1
+ <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
+ ;
+
+if ! [ os.environ VALGRIND_OPTS ]
+{
+test-suite "pool-examples"
+ : [ run time_pool_alloc.cpp ]
+ ;
+}
+
diff --git a/src/boost/libs/pool/example/sys_allocator.hpp b/src/boost/libs/pool/example/sys_allocator.hpp
new file mode 100644
index 000000000..50fc052ac
--- /dev/null
+++ b/src/boost/libs/pool/example/sys_allocator.hpp
@@ -0,0 +1,109 @@
+// 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)
+
+#ifndef BOOST_SYS_ALLOCATOR_H
+#define BOOST_SYS_ALLOCATOR_H
+
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable:4100)
+#endif
+
+// Symbols: malloc_allocator, new_delete_allocator
+
+#include <cstddef>
+#include <cstdlib>
+#include <boost/limits.hpp>
+#include <new>
+
+template <typename T>
+struct malloc_allocator
+{
+ typedef T * pointer;
+ typedef const T * const_pointer;
+ typedef T & reference;
+ typedef const T & const_reference;
+ typedef T value_type;
+
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ template <typename U>
+ struct rebind
+ {
+ typedef malloc_allocator<U> other;
+ };
+
+ static pointer address(reference r) { return &r; }
+ static const_pointer address(const_reference r) { return &r; }
+ static pointer allocate(const size_type n, const void* = 0)
+ {
+ const pointer ret = (pointer) std::malloc(n * sizeof(T));
+ if (ret == 0)
+ throw std::bad_alloc();
+ return ret;
+ }
+ static void deallocate(const pointer p, const size_type)
+ { std::free(p); }
+ static size_type max_size() { return (std::numeric_limits<size_type>::max)(); }
+
+ bool operator==(const malloc_allocator &) const { return true; }
+ bool operator!=(const malloc_allocator &) const { return false; }
+
+ malloc_allocator() { }
+ template <typename U>
+ malloc_allocator(const malloc_allocator<U> &) { }
+
+ static void construct(const pointer p, const_reference t)
+ { new ((void *) p) T(t); }
+ static void destroy(const pointer p)
+ { p->~T(); }
+};
+
+template <typename T>
+struct new_delete_allocator
+{
+ typedef T * pointer;
+ typedef const T * const_pointer;
+ typedef T & reference;
+ typedef const T & const_reference;
+ typedef T value_type;
+
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ template <typename U>
+ struct rebind
+ {
+ typedef new_delete_allocator<U> other;
+ };
+
+ static pointer address(reference r) { return &r; }
+ static const_pointer address(const_reference r) { return &r; }
+ static pointer allocate(const size_type n, const void* = 0)
+ { return (pointer) new char[n * sizeof(T)]; }
+ static void deallocate(const pointer p, const size_type)
+ { delete [] (char*)p; }
+ static size_type max_size() { return (std::numeric_limits<size_type>::max)(); }
+
+ bool operator==(const new_delete_allocator &) const { return true; }
+ bool operator!=(const new_delete_allocator &) const { return false; }
+
+ new_delete_allocator() { }
+ template <typename U>
+ new_delete_allocator(const new_delete_allocator<U> &) { }
+
+ static void construct(const pointer p, const_reference t)
+ { new ((void *) p) T(t); }
+ static void destroy(const pointer p)
+ { p->~T(); }
+};
+
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif
+
+#endif
diff --git a/src/boost/libs/pool/example/time_pool_alloc.cpp b/src/boost/libs/pool/example/time_pool_alloc.cpp
new file mode 100644
index 000000000..737c8c265
--- /dev/null
+++ b/src/boost/libs/pool/example/time_pool_alloc.cpp
@@ -0,0 +1,558 @@
+// 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)
+
+#include <boost/pool/pool_alloc.hpp>
+#include <boost/pool/object_pool.hpp>
+
+#include <iostream>
+#include <vector>
+#include <list>
+#include <set>
+
+#include <ctime>
+#include <cerrno>
+
+#include "sys_allocator.hpp"
+
+unsigned long num_ints;
+unsigned long num_loops = 10;
+unsigned l;
+
+template <unsigned N>
+struct larger_structure
+{
+ char data[N];
+};
+
+unsigned test_number;
+
+template <unsigned N>
+static void timing_test_alloc_larger()
+{
+ typedef boost::fast_pool_allocator<larger_structure<N>,
+ boost::default_user_allocator_new_delete,
+ boost::details::pool::null_mutex> alloc;
+ typedef boost::fast_pool_allocator<larger_structure<N> > alloc_sync;
+
+ double end[1][6];
+ std::clock_t start;
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::allocator<larger_structure<N> > a;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ a.deallocate(a.allocate(1), 1);
+ }
+ end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ for (unsigned long i = 0; i < num_ints; ++i)
+ std::free(std::malloc(sizeof(larger_structure<N>)));
+ }
+ end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ for (unsigned long i = 0; i < num_ints; ++i)
+ delete new (std::nothrow) larger_structure<N>;
+ }
+ end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ for (unsigned long i = 0; i < num_ints; ++i)
+ alloc::deallocate(alloc::allocate());
+ }
+ end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ for (unsigned long i = 0; i < num_ints; ++i)
+ alloc_sync::deallocate(alloc_sync::allocate());
+ }
+ end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ boost::pool<> p(sizeof(larger_structure<N>));
+ for (unsigned long i = 0; i < num_ints; ++i)
+ {
+ void * const t = p.malloc();
+ if (t != 0)
+ p.free(t);
+ }
+ }
+ end[0][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ std::cout << "Test " << test_number++ << ": Alloc & Dealloc " << num_ints << " structures of size " << sizeof(larger_structure<N>) << ":" << std::endl;
+ std::cout << " std::allocator: " << end[0][0] << " seconds" << std::endl;
+ std::cout << " malloc/free: " << end[0][1] << " seconds" << std::endl;
+ std::cout << " new/delete: " << end[0][2] << " seconds" << std::endl;
+ std::cout << " Pool Alloc: " << end[0][3] << " seconds" << std::endl;
+ std::cout << " Pool /w Sync: " << end[0][4] << " seconds" << std::endl;
+ std::cout << " Pool: " << end[0][5] << " seconds" << std::endl;
+}
+
+static void timing_test_alloc()
+{
+ typedef boost::fast_pool_allocator<int,
+ boost::default_user_allocator_new_delete,
+ boost::details::pool::null_mutex> alloc;
+ typedef boost::fast_pool_allocator<int> alloc_sync;
+
+ double end[2][6];
+ std::clock_t start;
+
+ int ** p = new int*[num_ints];
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::allocator<int> a;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ a.deallocate(a.allocate(1), 1);
+ }
+ end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ for (unsigned long i = 0; i < num_ints; ++i)
+ std::free(std::malloc(sizeof(int)));
+ }
+ end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ for (unsigned long i = 0; i < num_ints; ++i)
+ delete new (std::nothrow) int;
+ }
+ end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ for (unsigned long i = 0; i < num_ints; ++i)
+ alloc::deallocate(alloc::allocate());
+ }
+ end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ for (unsigned long i = 0; i < num_ints; ++i)
+ alloc_sync::deallocate(alloc_sync::allocate());
+ }
+ end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ boost::pool<> p2(sizeof(int));
+ for (unsigned long i = 0; i < num_ints; ++i)
+ {
+ void * const t = p2.malloc();
+ if (t != 0)
+ p2.free(t);
+ }
+ }
+ end[0][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::allocator<int> a;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ p[i] = a.allocate(1);
+ for (unsigned long i = 0; i < num_ints; ++i)
+ a.deallocate(p[i], 1);
+ }
+ end[1][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ for (unsigned long i = 0; i < num_ints; ++i)
+ p[i] = (int *) std::malloc(sizeof(int));
+ for (unsigned long i = 0; i < num_ints; ++i)
+ std::free(p[i]);
+ }
+ end[1][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ for (unsigned long i = 0; i < num_ints; ++i)
+ p[i] = new (std::nothrow) int;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ delete p[i];
+ }
+ end[1][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ for (unsigned long i = 0; i < num_ints; ++i)
+ p[i] = alloc::allocate();
+ for (unsigned long i = 0; i < num_ints; ++i)
+ alloc::deallocate(p[i]);
+ }
+ end[1][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ for (unsigned long i = 0; i < num_ints; ++i)
+ p[i] = alloc_sync::allocate();
+ for (unsigned long i = 0; i < num_ints; ++i)
+ alloc_sync::deallocate(p[i]);
+ }
+ end[1][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ boost::pool<> pl(sizeof(int));
+ for (unsigned long i = 0; i < num_ints; ++i)
+ p[i] = reinterpret_cast<int *>(pl.malloc());
+ for (unsigned long i = 0; i < num_ints; ++i)
+ if (p[i] != 0)
+ pl.free(p[i]);
+ }
+ end[1][5] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ delete [] p;
+
+ std::cout << "Test 3: Alloc & Dealloc " << num_ints << " ints:" << std::endl;
+ std::cout << " std::allocator: " << end[0][0] << " seconds" << std::endl;
+ std::cout << " malloc/free: " << end[0][1] << " seconds" << std::endl;
+ std::cout << " new/delete: " << end[0][2] << " seconds" << std::endl;
+ std::cout << " Pool Alloc: " << end[0][3] << " seconds" << std::endl;
+ std::cout << " Pool /w Sync: " << end[0][4] << " seconds" << std::endl;
+ std::cout << " Pool: " << end[0][5] << " seconds" << std::endl;
+
+ std::cout << "Test 4: Alloc " << num_ints << " ints & Dealloc " << num_ints << " ints:" << std::endl;
+ std::cout << " std::allocator: " << end[1][0] << " seconds" << std::endl;
+ std::cout << " malloc/free: " << end[1][1] << " seconds" << std::endl;
+ std::cout << " new/delete: " << end[1][2] << " seconds" << std::endl;
+ std::cout << " Pool Alloc: " << end[1][3] << " seconds" << std::endl;
+ std::cout << " Pool /w Sync: " << end[1][4] << " seconds" << std::endl;
+ std::cout << " Pool: " << end[1][5] << " seconds" << std::endl;
+}
+
+static void timing_test_containers()
+{
+ typedef boost::pool_allocator<int,
+ boost::default_user_allocator_new_delete,
+ boost::details::pool::null_mutex> alloc;
+ typedef boost::pool_allocator<int> alloc_sync;
+ typedef boost::fast_pool_allocator<int,
+ boost::default_user_allocator_new_delete,
+ boost::details::pool::null_mutex> fast_alloc;
+ typedef boost::fast_pool_allocator<int> fast_alloc_sync;
+
+ double end[3][5];
+ std::clock_t start;
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::vector<int, std::allocator<int> > x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.push_back(0);
+ }
+ end[0][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::vector<int, malloc_allocator<int> > x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.push_back(0);
+ }
+ end[0][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::vector<int, new_delete_allocator<int> > x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.push_back(0);
+ }
+ end[0][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::vector<int, alloc> x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.push_back(0);
+ }
+ end[0][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::vector<int, alloc_sync> x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.push_back(0);
+ }
+ end[0][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::set<int, std::less<int>, std::allocator<int> > x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.insert(0);
+ }
+ end[1][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::set<int, std::less<int>, malloc_allocator<int> > x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.insert(0);
+ }
+ end[1][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::set<int, std::less<int>, new_delete_allocator<int> > x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.insert(0);
+ }
+ end[1][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::set<int, std::less<int>, fast_alloc> x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.insert(0);
+ }
+ end[1][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::set<int, std::less<int>, fast_alloc_sync> x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.insert(0);
+ }
+ end[1][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::list<int, std::allocator<int> > x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.push_back(0);
+ }
+ end[2][0] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::list<int, malloc_allocator<int> > x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.push_back(0);
+ }
+ end[2][1] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::list<int, new_delete_allocator<int> > x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.push_back(0);
+ }
+ end[2][2] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::list<int, fast_alloc> x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.push_back(0);
+ }
+ end[2][3] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ start = std::clock();
+ for(l = 0; l < num_loops; ++l)
+ {
+ std::list<int, fast_alloc_sync> x;
+ for (unsigned long i = 0; i < num_ints; ++i)
+ x.push_back(0);
+ }
+ end[2][4] = (std::clock() - start) / ((double) CLOCKS_PER_SEC);
+
+ std::cout << "Test 0: Insertion & deletion of " << num_ints << " ints in a vector:" << std::endl;
+ std::cout << " std::allocator: " << end[0][0] << " seconds" << std::endl;
+ std::cout << " malloc/free: " << end[0][1] << " seconds" << std::endl;
+ std::cout << " new/delete: " << end[0][2] << " seconds" << std::endl;
+ std::cout << " Pool Alloc: " << end[0][3] << " seconds" << std::endl;
+ std::cout << " Pool /w Sync: " << end[0][4] << " seconds" << std::endl;
+ std::cout << " Pool: not possible" << std::endl;
+ std::cout << "Test 1: Insertion & deletion of " << num_ints << " ints in a set:" << std::endl;
+ std::cout << " std::allocator: " << end[1][0] << " seconds" << std::endl;
+ std::cout << " malloc/free: " << end[1][1] << " seconds" << std::endl;
+ std::cout << " new/delete: " << end[1][2] << " seconds" << std::endl;
+ std::cout << " Pool Alloc: " << end[1][3] << " seconds" << std::endl;
+ std::cout << " Pool /w Sync: " << end[1][4] << " seconds" << std::endl;
+ std::cout << " Pool: not possible" << std::endl;
+ std::cout << "Test 2: Insertion & deletion of " << num_ints << " ints in a list:" << std::endl;
+ std::cout << " std::allocator: " << end[2][0] << " seconds" << std::endl;
+ std::cout << " malloc/free: " << end[2][1] << " seconds" << std::endl;
+ std::cout << " new/delete: " << end[2][2] << " seconds" << std::endl;
+ std::cout << " Pool Alloc: " << end[2][3] << " seconds" << std::endl;
+ std::cout << " Pool /w Sync: " << end[2][4] << " seconds" << std::endl;
+ std::cout << " Pool: not possible" << std::endl;
+}
+
+int main(int argc, char * argv[])
+{
+ if (argc != 1 && argc != 2)
+ {
+ std::cerr << "Usage: " << argv[0]
+ << " [number_of_ints_to_use_each_try]" << std::endl;
+ return 1;
+ }
+
+ errno = 0;
+
+ if (argc == 2)
+ {
+ num_ints = std::strtoul(argv[1], 0, 10);
+ if (errno != 0)
+ {
+ std::cerr << "Cannot convert number \"" << argv[1] << '"' << std::endl;
+ return 2;
+ }
+ }
+ else
+ num_ints = 700000;
+
+#ifndef _NDEBUG
+ num_ints /= 100;
+#endif
+
+ try
+ {
+ timing_test_containers();
+ timing_test_alloc();
+ test_number = 5;
+ timing_test_alloc_larger<64>();
+ test_number = 6;
+ timing_test_alloc_larger<256>();
+ test_number = 7;
+ timing_test_alloc_larger<4096>();
+ }
+ catch (const std::bad_alloc &)
+ {
+ std::cerr << "Timing tests ran out of memory; try again with a lower value for number of ints"
+ << " (current value is " << num_ints << ")" << std::endl;
+ return 3;
+ }
+ catch (const std::exception & e)
+ {
+ std::cerr << "Error: " << e.what() << std::endl;
+ return 4;
+ }
+ catch (...)
+ {
+ std::cerr << "Unknown error" << std::endl;
+ return 5;
+ }
+
+ return 0;
+}
+
+/*
+
+Output:
+
+MSVC 10.0 using mutli-threaded DLL
+
+ time_pool_alloc.cpp
+ Creating library J:\Cpp\pool\pool\Release\alloc_example.lib and object J:\Cpp\pool\pool\Release\alloc_example.exp
+ Generating code
+ Finished generating code
+ alloc_example.vcxproj -> J:\Cpp\pool\pool\Release\alloc_example.exe
+ Test 0: Insertion & deletion of 700000 ints in a vector:
+ std::allocator: 0.062 seconds
+ malloc/free: 0.078 seconds
+ new/delete: 0.078 seconds
+ Pool Alloc: 0.328 seconds
+ Pool /w Sync: 0.343 seconds
+ Pool: not possible
+ Test 1: Insertion & deletion of 700000 ints in a set:
+ std::allocator: 0.561 seconds
+ malloc/free: 0.546 seconds
+ new/delete: 0.562 seconds
+ Pool Alloc: 0.109 seconds
+ Pool /w Sync: 0.094 seconds
+ Pool: not possible
+ Test 2: Insertion & deletion of 700000 ints in a list:
+ std::allocator: 0.671 seconds
+ malloc/free: 0.67 seconds
+ new/delete: 0.671 seconds
+ Pool Alloc: 0.094 seconds
+ Pool /w Sync: 0.093 seconds
+ Pool: not possible
+ Test 3: Alloc & Dealloc 700000 ints:
+ std::allocator: 0.5 seconds
+ malloc/free: 0.468 seconds
+ new/delete: 0.592 seconds
+ Pool Alloc: 0.032 seconds
+ Pool /w Sync: 0.015 seconds
+ Pool: 0.016 seconds
+ Test 4: Alloc 700000 ints & Dealloc 700000 ints:
+ std::allocator: 0.593 seconds
+ malloc/free: 0.577 seconds
+ new/delete: 0.717 seconds
+ Pool Alloc: 0.032 seconds
+ Pool /w Sync: 0.031 seconds
+ Pool: 0.047 seconds
+ Test 5: Alloc & Dealloc 700000 structures of size 64:
+ std::allocator: 0.499 seconds
+ malloc/free: 0.483 seconds
+ new/delete: 0.624 seconds
+ Pool Alloc: 0.016 seconds
+ Pool /w Sync: 0.031 seconds
+ Pool: 0.016 seconds
+ Test 6: Alloc & Dealloc 700000 structures of size 256:
+ std::allocator: 0.499 seconds
+ malloc/free: 0.484 seconds
+ new/delete: 0.639 seconds
+ Pool Alloc: 0.016 seconds
+ Pool /w Sync: 0.015 seconds
+ Pool: 0.016 seconds
+ Test 7: Alloc & Dealloc 700000 structures of size 4096:
+ std::allocator: 0.515 seconds
+ malloc/free: 0.515 seconds
+ new/delete: 0.639 seconds
+ Pool Alloc: 0.031 seconds
+ Pool /w Sync: 0.016 seconds
+ Pool: 0.016 seconds
+
+*/
+
+
+
diff --git a/src/boost/libs/pool/index.html b/src/boost/libs/pool/index.html
new file mode 100644
index 000000000..2231706a7
--- /dev/null
+++ b/src/boost/libs/pool/index.html
@@ -0,0 +1,13 @@
+<html>
+<head>
+<meta http-equiv="refresh" content="0; URL=doc/html/index.html">
+</head>
+<body>
+Automatic redirection failed, please go to
+<a href="doc/html/index.html">doc/html/index.html</a>.&nbsp;<hr>
+<p>© Copyright Beman Dawes, 2001</p>
+<p>Distributed under the Boost Software License, Version 1.0. (See accompanying
+file <a href="../../LICENSE_1_0.txt">LICENSE_1_0.txt</a> or copy
+at <a href="http://www.boost.org/LICENSE_1_0.txt">www.boost.org/LICENSE_1_0.txt</a>)</p>
+</body>
+</html>
diff --git a/src/boost/libs/pool/meta/libraries.json b/src/boost/libs/pool/meta/libraries.json
new file mode 100644
index 000000000..b03ef3a1f
--- /dev/null
+++ b/src/boost/libs/pool/meta/libraries.json
@@ -0,0 +1,14 @@
+{
+ "key": "pool",
+ "name": "Pool",
+ "authors": [
+ "Steve Cleary"
+ ],
+ "description": "Memory pool management.",
+ "category": [
+ "Memory"
+ ],
+ "maintainers": [
+ "Stephen Cleary <scleary -at- jerviswebb.com>"
+ ]
+}
diff --git a/src/boost/libs/pool/test/Jamfile.v2 b/src/boost/libs/pool/test/Jamfile.v2
new file mode 100644
index 000000000..9e96abcbd
--- /dev/null
+++ b/src/boost/libs/pool/test/Jamfile.v2
@@ -0,0 +1,49 @@
+#~ Copyright Rene Rivera 2008
+#~ Copyright James E. King III 2018
+#~ 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)
+
+
+project
+ : requirements
+ <library>/boost/system//boost_system
+ <define>BOOST_ALL_NO_LIB=1
+ <warnings>all
+ <toolset>clang:<cxxflags>-Wextra
+ <toolset>clang:<cxxflags>-Wno-variadic-macros
+ <toolset>gcc:<cxxflags>-Wextra
+ <toolset>gcc:<cxxflags>-Wshadow
+ <toolset>gcc:<cxxflags>-Wno-variadic-macros
+ <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
+ ;
+
+import common ;
+import os ;
+import testing ;
+
+test-suite pool :
+ [ run test_simple_seg_storage.cpp : : : <toolset>msvc:<cxxflags>-wd4267 ]
+ [ run test_pool_alloc.cpp ]
+ [ run pool_msvc_compiler_bug_test.cpp : : : <toolset>msvc:<cxxflags>-wd4512 ]
+ [ run test_msvc_mem_leak_detect.cpp ]
+ [ run test_bug_3349.cpp ]
+ [ run test_bug_4960.cpp ]
+ [ run test_bug_1252.cpp : : :
+ <toolset>clang:<cxxflags>-Wno-c++11-long-long
+ <toolset>gcc:<cxxflags>-Wno-long-long
+ <toolset>pathscale:<cxxflags>-Wno-long-long ]
+ [ run test_bug_2696.cpp ]
+ [ run test_bug_5526.cpp ]
+ [ run test_threading.cpp : : : <threading>multi <library>/boost/thread//boost_thread ]
+ [ compile test_poisoned_macros.cpp ]
+ ;
+
+if [ os.environ VALGRIND_OPTS ]
+{
+test-suite pool-valgrind :
+ [ run test_pool_alloc.cpp : : : <define>BOOST_POOL_VALGRIND=1 : test_pool_alloc_valgrind ]
+ [ run-fail test_valgrind_fail_1.cpp : : : <define>BOOST_POOL_VALGRIND=1 ]
+ [ run-fail test_valgrind_fail_2.cpp : : : <define>BOOST_POOL_VALGRIND=1 ]
+ ;
+}
+
diff --git a/src/boost/libs/pool/test/pool_msvc_compiler_bug_test.cpp b/src/boost/libs/pool/test/pool_msvc_compiler_bug_test.cpp
new file mode 100644
index 000000000..e188c4701
--- /dev/null
+++ b/src/boost/libs/pool/test/pool_msvc_compiler_bug_test.cpp
@@ -0,0 +1,40 @@
+// Copyright (C) 2008 Jurko Gospodnetic
+//
+// 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)
+
+
+// This tests whether the Boost Pool library managed to get a regression and
+// hit the MSVC 'variables exported to global namespace' bug again. This bug
+// affects at least MSVC 7.1 & 8.0 releases and has been fixed in the MSVC 9.0
+// release.
+//
+// If the bug exists this test should fail to compile, complaining about an
+// ambiguous CRITICAL_SECTION symbol. The bug got fixed by making the boost/
+// /pool/detail/mutex.hpp header reference all Windows API constants using their
+// fully qualified names.
+//
+// To see the bug in action without using any Boost libraries run the
+// following program:
+//
+// namespace One { class Brick; }
+// namespace Two
+// {
+// using namespace One;
+// template <class TinyTemplateParam> class TinyClass {};
+// }
+// class Brick {};
+// Brick brick;
+// int main() {}
+// (17.04.2008.) (Jurko)
+
+
+#include "boost/archive/text_iarchive.hpp"
+#include "boost/pool/detail/mutex.hpp"
+// Including "boost/pool/pool_alloc.hpp" instead of mutex.hpp should work as
+// well.
+
+int main()
+{
+}
diff --git a/src/boost/libs/pool/test/random_shuffle.hpp b/src/boost/libs/pool/test/random_shuffle.hpp
new file mode 100644
index 000000000..1bc545238
--- /dev/null
+++ b/src/boost/libs/pool/test/random_shuffle.hpp
@@ -0,0 +1,26 @@
+/* Copyright (C) 2016 Edward Diener
+*
+* Use, modification and distribution is subject to the
+* Boost Software License, Version 1.0. (See accompanying
+* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_POOL_TEST_RANDOM_SHUFFLE_HPP
+#define BOOST_POOL_TEST_RANDOM_SHUFFLE_HPP
+
+#include <cstdlib>
+#include <iterator>
+#include <algorithm>
+
+template< class RandomIt >
+void pool_test_random_shuffle( RandomIt first, RandomIt last )
+{
+ typename std::iterator_traits<RandomIt>::difference_type i, n;
+ n = last - first;
+ for (i = n-1; i > 0; --i) {
+ using std::swap;
+ swap(first[i], first[std::rand() % (i+1)]);
+ }
+}
+
+#endif // BOOST_POOL_TEST_RANDOM_SHUFFLE_HPP
diff --git a/src/boost/libs/pool/test/test_bug_1252.cpp b/src/boost/libs/pool/test/test_bug_1252.cpp
new file mode 100644
index 000000000..18830571e
--- /dev/null
+++ b/src/boost/libs/pool/test/test_bug_1252.cpp
@@ -0,0 +1,66 @@
+/* Copyright (C) 2011 John Maddock
+*
+* Use, modification and distribution is subject to the
+* Boost Software License, Version 1.0. (See accompanying
+* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+// Test of bug #1252 (https://svn.boost.org/trac/boost/ticket/1252)
+
+#include <boost/pool/pool.hpp>
+#include <boost/detail/lightweight_test.hpp>
+#include <boost/type_traits/alignment_of.hpp>
+#include <cstring>
+
+struct limited_allocator_new_delete
+{
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ static char * malloc BOOST_PREVENT_MACRO_SUBSTITUTION(const size_type bytes)
+ {
+ if(bytes > 1510 * 32)
+ return 0;
+ return new (std::nothrow) char[bytes];
+ }
+ static void free BOOST_PREVENT_MACRO_SUBSTITUTION(char * const block)
+ {
+ delete [] block;
+ }
+};
+
+template <class T>
+void test_alignment(T)
+{
+ unsigned align = boost::alignment_of<T>::value;
+ boost::pool<> p(sizeof(T));
+ unsigned limit = 100000;
+ for(unsigned i = 0; i < limit; ++i)
+ {
+ void* ptr = (p.malloc)();
+ BOOST_TEST(reinterpret_cast<std::size_t>(ptr) % align == 0);
+ // Trample over the memory just to be sure the allocated block is big enough,
+ // if it's not, we'll trample over the next block as well (and our internal housekeeping).
+ std::memset(ptr, 0xff, sizeof(T));
+ }
+}
+
+
+int main()
+{
+ boost::pool<limited_allocator_new_delete> po(1501);
+ void* p = (po.malloc)();
+ BOOST_TEST(p != 0);
+
+ test_alignment(char(0));
+ test_alignment(short(0));
+ test_alignment(int(0));
+ test_alignment(long(0));
+ test_alignment(double(0));
+ test_alignment(float(0));
+ test_alignment((long double)(0));
+#ifndef BOOST_NO_LONG_LONG
+ test_alignment((long long)(0));
+#endif
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/pool/test/test_bug_2696.cpp b/src/boost/libs/pool/test/test_bug_2696.cpp
new file mode 100644
index 000000000..9b72b3d65
--- /dev/null
+++ b/src/boost/libs/pool/test/test_bug_2696.cpp
@@ -0,0 +1,66 @@
+/* Copyright (C) 2011 John Maddock
+*
+* Use, modification and distribution is subject to the
+* Boost Software License, Version 1.0. (See accompanying
+* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+// Test of bug #2696 (https://svn.boost.org/trac/boost/ticket/2696)
+
+#include <boost/pool/pool.hpp>
+#include <boost/detail/lightweight_test.hpp>
+
+struct limited_allocator_new_delete
+{
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ static char * malloc BOOST_PREVENT_MACRO_SUBSTITUTION(const size_type bytes)
+ {
+#ifndef BOOST_POOL_VALGRIND
+ static const unsigned max_size = sizeof(void*) * 40 + boost::integer::static_lcm<sizeof(size_type), sizeof(void *)>::value + sizeof(size_type);
+#else
+ static const unsigned max_size = sizeof(void*) * 40;
+#endif
+ if(bytes > max_size)
+ return 0;
+ return new (std::nothrow) char[bytes];
+ }
+ static void free BOOST_PREVENT_MACRO_SUBSTITUTION(char * const block)
+ {
+ delete [] block;
+ }
+};
+
+int main()
+{
+ static const unsigned alloc_size = sizeof(void*);
+ boost::pool<limited_allocator_new_delete> p1(alloc_size, 10, 40);
+ for(int i = 1; i <= 40; ++i)
+ BOOST_TEST((p1.ordered_malloc)(i));
+ BOOST_TEST(p1.ordered_malloc(42) == 0);
+ //
+ // If the largest block is 40, and we start with 10, we get 10+20+40 elements before
+ // we actually run out of memory:
+ //
+ boost::pool<limited_allocator_new_delete> p2(alloc_size, 10, 40);
+ for(int i = 1; i <= 70; ++i)
+ BOOST_TEST((p2.malloc)());
+ boost::pool<limited_allocator_new_delete> p2b(alloc_size, 10, 40);
+ for(int i = 1; i <= 100; ++i)
+ BOOST_TEST((p2b.ordered_malloc)());
+ //
+ // Try again with no explicit upper limit:
+ //
+ boost::pool<limited_allocator_new_delete> p3(alloc_size);
+ for(int i = 1; i <= 40; ++i)
+ BOOST_TEST((p3.ordered_malloc)(i));
+ BOOST_TEST(p3.ordered_malloc(42) == 0);
+ boost::pool<limited_allocator_new_delete> p4(alloc_size, 10);
+ for(int i = 1; i <= 100; ++i)
+ BOOST_TEST((p4.ordered_malloc)());
+ boost::pool<limited_allocator_new_delete> p5(alloc_size, 10);
+ for(int i = 1; i <= 100; ++i)
+ BOOST_TEST((p5.malloc)());
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/pool/test/test_bug_3349.cpp b/src/boost/libs/pool/test/test_bug_3349.cpp
new file mode 100644
index 000000000..57269d0f8
--- /dev/null
+++ b/src/boost/libs/pool/test/test_bug_3349.cpp
@@ -0,0 +1,27 @@
+/* Copyright (C) 2011 Kwan Ting Chan
+ * Based from bug report submitted by Xiaohan Wang
+ *
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+// Test of bug #3349 (https://svn.boost.org/trac/boost/ticket/3349)
+
+#include <boost/pool/pool.hpp>
+
+#include <boost/core/lightweight_test.hpp>
+
+int main()
+{
+ boost::pool<> p(256, 4);
+
+ void* pBlock1 = p.ordered_malloc( 1 );
+ void* pBlock2 = p.ordered_malloc( 4 );
+ (void)pBlock2; // warning suppression
+
+ p.ordered_free( pBlock1 );
+
+ BOOST_TEST(p.release_memory());
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/pool/test/test_bug_4960.cpp b/src/boost/libs/pool/test/test_bug_4960.cpp
new file mode 100644
index 000000000..e95f714ec
--- /dev/null
+++ b/src/boost/libs/pool/test/test_bug_4960.cpp
@@ -0,0 +1,45 @@
+/* Copyright (C) 2011 Kwan Ting Chan
+ * Based from bug report submitted by Xiaohan Wang
+ *
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+// Test of bug #4960 (https://svn.boost.org/trac/boost/ticket/4960)
+
+#include <boost/pool/pool_alloc.hpp>
+#include <vector>
+#include <iostream>
+
+typedef std::vector<int, boost::pool_allocator<int> > EventVector;
+typedef std::vector<EventVector, boost::pool_allocator<EventVector> > IndexVector;
+
+int main()
+{
+ IndexVector iv;
+ int limit = 100;
+ for (int i = 0; i < limit; ++i)
+ {
+ iv.push_back(EventVector());
+ for(int j = 0; j < limit; ++j)
+ iv.back().push_back(j);
+ }
+
+ boost::pool<boost::default_user_allocator_new_delete> po(4);
+ for(int i = 0; i < limit; ++i)
+ {
+ void* p = po.ordered_malloc(0);
+ po.ordered_free(p, 0);
+ }
+
+ boost::pool_allocator<int> al;
+ for(int i = 0; i < limit; ++i)
+ {
+ int* p = al.allocate(0);
+ al.deallocate(p, 0);
+ }
+
+ std::cout << "it works\n";
+ return 0;
+}
diff --git a/src/boost/libs/pool/test/test_bug_5526.cpp b/src/boost/libs/pool/test/test_bug_5526.cpp
new file mode 100644
index 000000000..a23994a54
--- /dev/null
+++ b/src/boost/libs/pool/test/test_bug_5526.cpp
@@ -0,0 +1,36 @@
+/* Copyright (C) 2011 John Maddock
+*
+* Use, modification and distribution is subject to the
+* Boost Software License, Version 1.0. (See accompanying
+* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+// Test of bug #5526 (https://svn.boost.org/trac/boost/ticket/5526)
+
+#include <boost/smart_ptr/scoped_ptr.hpp>
+#include <boost/pool/pool.hpp>
+#include <boost/pool/singleton_pool.hpp>
+#include <boost/assert.hpp>
+
+struct bad
+{
+ bad()
+ {
+ buf = static_cast<int*>(boost::singleton_pool<int, sizeof(int)>::malloc());
+ *buf = 0x1234;
+ }
+ ~bad()
+ {
+ BOOST_ASSERT(*buf == 0x1234);
+ boost::singleton_pool<int, sizeof(int)>::free(buf);
+ }
+ int* buf;
+};
+
+boost::scoped_ptr<bad> aptr;
+
+int main()
+{
+ aptr.reset(new bad());
+ return 0;
+}
diff --git a/src/boost/libs/pool/test/test_msvc_mem_leak_detect.cpp b/src/boost/libs/pool/test/test_msvc_mem_leak_detect.cpp
new file mode 100644
index 000000000..3a80f168d
--- /dev/null
+++ b/src/boost/libs/pool/test/test_msvc_mem_leak_detect.cpp
@@ -0,0 +1,50 @@
+/* Copyright (C) 2011 Kwan Ting Chan
+ *
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+// Test of bug #4346 (https://svn.boost.org/trac/boost/ticket/4346)
+
+#ifdef _MSC_VER
+#define _CRTDBG_MAP_ALLOC
+#include <stdlib.h>
+#include <crtdbg.h>
+#endif
+
+#include <boost/pool/poolfwd.hpp>
+#include <boost/pool/simple_segregated_storage.hpp>
+#include <boost/pool/pool.hpp>
+#include <boost/pool/pool_alloc.hpp>
+#include <boost/pool/singleton_pool.hpp>
+#include <boost/pool/object_pool.hpp>
+
+#include <vector>
+
+struct Foo {};
+
+int main()
+{
+ {
+ boost::pool<> p(sizeof(int));
+ (p.malloc)();
+ }
+
+ {
+ boost::object_pool<Foo> p;
+ (p.malloc)();
+ }
+
+ {
+ (boost::singleton_pool<Foo, sizeof(int)>::malloc)();
+ }
+ boost::singleton_pool<Foo, sizeof(int)>::purge_memory();
+
+ {
+ std::vector<int, boost::pool_allocator<int> > v;
+ v.push_back(8);
+ }
+ boost::singleton_pool<boost::pool_allocator_tag,
+ sizeof(int)>::release_memory();
+}
diff --git a/src/boost/libs/pool/test/test_poisoned_macros.cpp b/src/boost/libs/pool/test/test_poisoned_macros.cpp
new file mode 100644
index 000000000..072122c2f
--- /dev/null
+++ b/src/boost/libs/pool/test/test_poisoned_macros.cpp
@@ -0,0 +1,50 @@
+/* Copyright (C) 2011 John Maddock
+*
+* Use, modification and distribution is subject to the
+* Boost Software License, Version 1.0. (See accompanying
+* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+//
+// Verify that if malloc/free are macros that everything still works OK:
+//
+
+#include <functional>
+#include <new>
+#include <cstddef>
+#include <cstdlib>
+#include <exception>
+#include <algorithm>
+#include <boost/limits.hpp>
+#include <iostream>
+#include <locale>
+
+namespace std{
+
+ void* undefined_poisoned_symbol1(unsigned x);
+ void undefined_poisoned_symbol2(void* x);
+
+}
+
+#define malloc(x) undefined_poisoned_symbol1(x)
+#define free(x) undefined_poisoned_symbol2(x)
+
+#include <boost/pool/pool.hpp>
+#include <boost/pool/object_pool.hpp>
+#include <boost/pool/pool_alloc.hpp>
+#include <boost/pool/singleton_pool.hpp>
+
+template class boost::object_pool<int, boost::default_user_allocator_new_delete>;
+template class boost::object_pool<int, boost::default_user_allocator_malloc_free>;
+
+template class boost::pool<boost::default_user_allocator_new_delete>;
+template class boost::pool<boost::default_user_allocator_malloc_free>;
+
+template class boost::pool_allocator<int, boost::default_user_allocator_new_delete>;
+template class boost::pool_allocator<int, boost::default_user_allocator_malloc_free>;
+template class boost::fast_pool_allocator<int, boost::default_user_allocator_new_delete>;
+template class boost::fast_pool_allocator<int, boost::default_user_allocator_malloc_free>;
+
+template class boost::simple_segregated_storage<unsigned>;
+
+template class boost::singleton_pool<int, 32>;
diff --git a/src/boost/libs/pool/test/test_pool_alloc.cpp b/src/boost/libs/pool/test/test_pool_alloc.cpp
new file mode 100644
index 000000000..b0b50eabe
--- /dev/null
+++ b/src/boost/libs/pool/test/test_pool_alloc.cpp
@@ -0,0 +1,291 @@
+/* Copyright (C) 2000, 2001 Stephen Cleary
+ * Copyright (C) 2011 Kwan Ting Chan
+ *
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include "random_shuffle.hpp"
+#include <boost/pool/pool_alloc.hpp>
+#include <boost/pool/object_pool.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+#include <algorithm>
+#include <deque>
+#include <list>
+#include <set>
+#include <stdexcept>
+#include <vector>
+
+#include <cstdlib>
+#include <ctime>
+
+// Each "tester" object below checks into and out of the "cdtor_checker",
+// which will check for any problems related to the construction/destruction of
+// "tester" objects.
+class cdtor_checker
+{
+private:
+ // Each constructed object registers its "this" pointer into "objs"
+ std::set<void*> objs;
+
+public:
+ // True iff all objects that have checked in have checked out
+ bool ok() const { return objs.empty(); }
+
+ ~cdtor_checker()
+ {
+ BOOST_TEST(ok());
+ }
+
+ void check_in(void * const This)
+ {
+ BOOST_TEST(objs.find(This) == objs.end());
+ objs.insert(This);
+ }
+
+ void check_out(void * const This)
+ {
+ BOOST_TEST(objs.find(This) != objs.end());
+ objs.erase(This);
+ }
+};
+static cdtor_checker mem;
+
+struct tester
+{
+ tester(bool throw_except = false)
+ {
+ if(throw_except)
+ {
+ throw std::logic_error("Deliberate constructor exception");
+ }
+
+ mem.check_in(this);
+ }
+
+ tester(const tester &)
+ {
+ mem.check_in(this);
+ }
+
+ ~tester()
+ {
+ mem.check_out(this);
+ }
+};
+
+// This is a wrapper around a UserAllocator. It just registers alloc/dealloc
+// to/from the system memory. It's used to make sure pool's are allocating
+// and deallocating system memory properly.
+// Do NOT use this class with static or singleton pools.
+template <typename UserAllocator>
+struct TrackAlloc
+{
+ typedef typename UserAllocator::size_type size_type;
+ typedef typename UserAllocator::difference_type difference_type;
+
+ static std::set<char *> allocated_blocks;
+
+ static char * malloc(const size_type bytes)
+ {
+ char * const ret = UserAllocator::malloc(bytes);
+ allocated_blocks.insert(ret);
+ return ret;
+ }
+
+ static void free(char * const block)
+ {
+ BOOST_TEST(allocated_blocks.find(block) != allocated_blocks.end());
+ allocated_blocks.erase(block);
+ UserAllocator::free(block);
+ }
+
+ static bool ok()
+ {
+ return allocated_blocks.empty();
+ }
+};
+template <typename UserAllocator>
+std::set<char *> TrackAlloc<UserAllocator>::allocated_blocks;
+
+typedef TrackAlloc<boost::default_user_allocator_new_delete> track_alloc;
+
+void test()
+{
+ {
+ // Do nothing pool
+ boost::object_pool<tester> pool;
+ }
+
+ {
+ // Construct several tester objects. Don't delete them (i.e.,
+ // test pool's garbage collection).
+ boost::object_pool<tester> pool;
+ for(int i=0; i < 10; ++i)
+ {
+ pool.construct();
+ }
+ }
+
+ {
+ // Construct several tester objects. Delete some of them.
+ boost::object_pool<tester> pool;
+ std::vector<tester *> v;
+ for(int i=0; i < 10; ++i)
+ {
+ v.push_back(pool.construct());
+ }
+ pool_test_random_shuffle(v.begin(), v.end());
+ for(int j=0; j < 5; ++j)
+ {
+ pool.destroy(v[j]);
+ }
+ }
+
+ {
+ // Test how pool reacts with constructors that throw exceptions.
+ // Shouldn't have any memory leaks.
+ boost::object_pool<tester> pool;
+ for(int i=0; i < 5; ++i)
+ {
+ pool.construct();
+ }
+ for(int j=0; j < 5; ++j)
+ {
+ try
+ {
+ // The following constructions will raise an exception.
+ pool.construct(true);
+ }
+ catch(const std::logic_error &) {}
+ }
+ }
+}
+
+void test_alloc()
+{
+ {
+ // Allocate several tester objects. Delete one.
+ std::vector<tester, boost::pool_allocator<tester> > l;
+ for(int i=0; i < 10; ++i)
+ {
+ l.push_back(tester());
+ }
+ l.pop_back();
+ }
+
+ {
+ // Allocate several tester objects. Delete two.
+ std::deque<tester, boost::pool_allocator<tester> > l;
+ for(int i=0; i < 10; ++i)
+ {
+ l.push_back(tester());
+ }
+ l.pop_back();
+ l.pop_front();
+ }
+
+ {
+ // Allocate several tester objects. Delete two.
+ std::list<tester, boost::fast_pool_allocator<tester> > l;
+ // lists rebind their allocators, so dumping is useless
+ for(int i=0; i < 10; ++i)
+ {
+ l.push_back(tester());
+ }
+ l.pop_back();
+ l.pop_front();
+ }
+
+ tester * tmp;
+ {
+ // Create a memory leak on purpose. (Allocator doesn't have
+ // garbage collection)
+ // (Note: memory leak)
+ boost::pool_allocator<tester> a;
+ tmp = a.allocate(1, 0);
+ new (tmp) tester();
+ }
+ if(mem.ok())
+ {
+ BOOST_ERROR("Pool allocator cleaned up itself");
+ }
+ // Remove memory checker entry (to avoid error later) and
+ // clean up memory leak
+ tmp->~tester();
+ boost::pool_allocator<tester>::deallocate(tmp, 1);
+
+ // test allocating zero elements
+ {
+ boost::pool_allocator<tester> alloc;
+ tester* ip = alloc.allocate(0);
+ alloc.deallocate(ip, 0);
+ }
+}
+
+void test_mem_usage()
+{
+ typedef boost::pool<track_alloc> pool_type;
+
+ {
+ // Constructor should do nothing; no memory allocation
+ pool_type pool(sizeof(int));
+ BOOST_TEST(track_alloc::ok());
+ BOOST_TEST(!pool.release_memory());
+ BOOST_TEST(!pool.purge_memory());
+
+ // Should allocate from system
+ pool.free(pool.malloc());
+ BOOST_TEST(!track_alloc::ok());
+
+ // Ask pool to give up memory it's not using; this should succeed
+ BOOST_TEST(pool.release_memory());
+ BOOST_TEST(track_alloc::ok());
+
+ // Should allocate from system again
+ pool.malloc(); // loses the pointer to the returned chunk (*A*)
+
+ // Ask pool to give up memory it's not using; this should fail
+ BOOST_TEST(!pool.release_memory());
+
+ // Force pool to give up memory it's not using; this should succeed
+ // This will clean up the memory leak from (*A*)
+ BOOST_TEST(pool.purge_memory());
+ BOOST_TEST(track_alloc::ok());
+
+ // Should allocate from system again
+ pool.malloc(); // loses the pointer to the returned chunk (*B*)
+
+ // pool's destructor should purge the memory
+ // This will clean up the memory leak from (*B*)
+ }
+
+ BOOST_TEST(track_alloc::ok());
+}
+
+void test_void()
+{
+ typedef boost::pool_allocator<void> void_allocator;
+ typedef boost::fast_pool_allocator<void> fast_void_allocator;
+
+ typedef void_allocator::rebind<int>::other int_allocator;
+ typedef fast_void_allocator::rebind<int>::other fast_int_allocator;
+
+ std::vector<int, int_allocator> v1;
+ std::vector<int, fast_int_allocator> v2;
+}
+
+int main()
+{
+ std::srand(static_cast<unsigned>(std::time(0)));
+
+ test();
+ test_alloc();
+ test_mem_usage();
+ test_void();
+
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/pool/test/test_simple_seg_storage.cpp b/src/boost/libs/pool/test/test_simple_seg_storage.cpp
new file mode 100644
index 000000000..67a33e002
--- /dev/null
+++ b/src/boost/libs/pool/test/test_simple_seg_storage.cpp
@@ -0,0 +1,304 @@
+/* Copyright (C) 2011 Kwan Ting Chan
+ *
+ * Use, modification and distribution is subject to the
+ * Boost Software License, Version 1.0. (See accompanying
+ * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include "test_simple_seg_storage.hpp"
+#include "track_allocator.hpp"
+#include "random_shuffle.hpp"
+
+#include <boost/pool/simple_segregated_storage.hpp>
+#include <boost/assert.hpp>
+#include <boost/integer/common_factor_ct.hpp>
+#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1600)
+#pragma warning(push)
+#pragma warning(disable: 4244)
+// ..\..\boost/random/uniform_int_distribution.hpp(171) :
+// warning C4127: conditional expression is constant
+#pragma warning(disable: 4127)
+#endif
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int.hpp>
+#include <boost/random/variate_generator.hpp>
+#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1600)
+#pragma warning(pop)
+#endif
+
+#include <boost/core/lightweight_test.hpp>
+
+#include <algorithm>
+#include <functional>
+#include <set>
+#include <vector>
+
+#include <cstddef>
+#include <cstdlib>
+#include <ctime>
+
+#ifdef BOOST_MSVC
+#pragma warning(disable:4267)
+#endif
+
+// "A free list is ordered if repeated calls to malloc() will result in a
+// constantly-increasing sequence of values, as determined by std::less<void*>"
+// Return: true if in constantly-increasing order, false otherwise
+bool check_is_order(const std::vector<void*>& vs)
+{
+ if(vs.size() < 2) { return true; }
+
+ void *lower, *higher;
+ std::vector<void*>::const_iterator ci = vs.begin();
+ lower = *(ci++);
+ while(ci != vs.end())
+ {
+ higher = *(ci++);
+ if(!std::less<void*>()(lower, higher)) { return false; }
+ }
+
+ return true;
+}
+
+// Return: number of chunks malloc'd from store
+std::size_t test_is_order(test_simp_seg_store& store)
+{
+ std::vector<void*> vpv;
+ std::size_t nchunk = 0;
+ // Pre: !empty()
+ while(!store.empty())
+ {
+ void* const first = store.get_first();
+ void* const pv = store.malloc();
+ // "Takes the first available chunk from the free list
+ // and returns it"
+ BOOST_TEST(first == pv);
+
+ vpv.push_back(pv);
+ ++nchunk;
+ }
+ BOOST_TEST(check_is_order(vpv));
+
+ return nchunk;
+}
+
+boost::mt19937 gen;
+
+int main()
+{
+ std::srand(static_cast<unsigned>(std::time(0)));
+ gen.seed(static_cast<boost::uint32_t>(std::time(0)));
+
+ /* Store::segregate(block, sz, partition_sz, end) */
+ std::size_t partition_sz
+ = boost::integer::static_lcm<sizeof(void*), sizeof(int)>::value;
+ boost::uniform_int<> dist(partition_sz, 10000);
+ boost::variate_generator<boost::mt19937&,
+ boost::uniform_int<> > die(gen, dist);
+ std::size_t block_size = die();
+ // Pre: npartition_sz >= sizeof(void*)
+ // npartition_sz = sizeof(void*) * i, for some integer i
+ // nsz >= npartition_sz
+ // block is properly aligned for an array of object of
+ // size npartition_sz and array of void *
+ BOOST_ASSERT(partition_sz >= sizeof(void*));
+ BOOST_ASSERT(partition_sz % sizeof(void*) == 0);
+ BOOST_ASSERT(block_size >= partition_sz);
+ {
+ char* const pc = track_allocator::malloc(block_size);
+ // (Test) Pre: block of memory is valid
+ BOOST_ASSERT(pc);
+ int endadd = 0;
+ void* const pvret = test_simp_seg_store::segregate(pc, block_size,
+ partition_sz, &endadd);
+
+ // The first chunk "is always equal to block"
+ BOOST_TEST(pvret == pc);
+
+ void* cur = test_simp_seg_store::get_nextof(static_cast<int*>(pvret));
+ void* last = pvret;
+ std::size_t nchunk = 1;
+ while(cur != &endadd)
+ {
+ ++nchunk;
+
+ // Memory of each chunk does not overlap
+ // The free list constructed is actually from the given block
+ // The "interleaved free list is ordered"
+ BOOST_TEST(std::less_equal<void*>()(static_cast<char*>(last)
+ + partition_sz, cur));
+ BOOST_TEST(std::less_equal<void*>()(static_cast<char*>(cur)
+ + partition_sz, pc + block_size));
+
+ last = cur;
+ cur = test_simp_seg_store::get_nextof(static_cast<int*>(cur));
+ }
+ // "The last chunk is set to point to end"
+ // "Partitioning into as many partition_sz-sized chunks as possible"
+ BOOST_TEST(nchunk == block_size/partition_sz);
+ }
+
+ /* t.add_block(block, sz, partition_sz), t.malloc() */
+ {
+ // Default constructor of simple_segregated_storage do nothing
+ test_simp_seg_store tstore;
+ // Post: empty()
+ BOOST_TEST(tstore.empty());
+
+ char* const pc = track_allocator::malloc(block_size);
+ tstore.add_block(pc, block_size, partition_sz);
+
+ // The first chunk "is always equal to block"
+ BOOST_TEST(tstore.get_first() == pc);
+
+ // Empty before add_block() => "is ordered after"
+ std::size_t nchunk = test_is_order(tstore);
+ // "Partitioning into as many partition_sz-sized chunks as possible"
+ BOOST_TEST(nchunk == block_size/partition_sz);
+
+ BOOST_ASSERT(partition_sz <= 23);
+ test_simp_seg_store tstore2;
+ char* const pc2 = track_allocator::malloc(88);
+ tstore2.add_block(pc2, 24, partition_sz);
+ tstore2.add_block(pc2 + 64, 24, partition_sz);
+ tstore2.add_block(pc2 + 32, 24, partition_sz);
+ tstore2.add_block(track_allocator::malloc(23), 23, partition_sz);
+ std::size_t nchunk_ref = (3*(24/partition_sz)) + (23/partition_sz);
+ for(nchunk = 0; !tstore2.empty(); tstore2.malloc(), ++nchunk) {}
+ // add_block() merges new free list to existing
+ BOOST_TEST(nchunk == nchunk_ref);
+ }
+
+ /* t.free(chunk) */
+ {
+ test_simp_seg_store tstore;
+ char* const pc = track_allocator::malloc(partition_sz);
+ tstore.add_block(pc, partition_sz, partition_sz);
+ void* pv = tstore.malloc();
+ BOOST_TEST(tstore.empty());
+ tstore.free(pv);
+ }
+
+ /* t.add_ordered_block(block, sz, partition_sz) */
+ {
+ {
+ char* const pc = track_allocator::malloc(6 * partition_sz);
+ std::vector<void*> vpv;
+ vpv.push_back(pc);
+ vpv.push_back(pc + (2 * partition_sz));
+ vpv.push_back(pc + (4 * partition_sz));
+
+ do
+ {
+ test_simp_seg_store tstore;
+ tstore.add_ordered_block(vpv[0], 2*partition_sz, partition_sz);
+ tstore.add_ordered_block(vpv[1], 2*partition_sz, partition_sz);
+ tstore.add_ordered_block(vpv[2], 2*partition_sz, partition_sz);
+ // "Order-preserving"
+ test_is_order(tstore);
+ } while(std::next_permutation(vpv.begin(), vpv.end()));
+ }
+
+ {
+ test_simp_seg_store tstore;
+ char* const pc = track_allocator::malloc(6 * partition_sz);
+ tstore.add_ordered_block(pc, 2 * partition_sz, partition_sz);
+ tstore.add_ordered_block(pc + (4 * partition_sz),
+ (2 * partition_sz), partition_sz);
+ // "Order-preserving"
+ test_is_order(tstore);
+ }
+
+ {
+ test_simp_seg_store tstore;
+ char* const pc = track_allocator::malloc(6 * partition_sz);
+ tstore.add_ordered_block(pc + (4 * partition_sz),
+ (2 * partition_sz), partition_sz);
+ tstore.add_ordered_block(pc, 2 * partition_sz, partition_sz);
+ // "Order-preserving"
+ test_is_order(tstore);
+ }
+ }
+
+ /* t.ordered_free(chunk) */
+ {
+ char* const pc = track_allocator::malloc(6 * partition_sz);
+
+ test_simp_seg_store tstore;
+ tstore.add_block(pc, 6 * partition_sz, partition_sz);
+
+ std::vector<void*> vpv;
+ for(std::size_t i=0; i < 6; ++i) { vpv.push_back(tstore.malloc()); }
+ BOOST_ASSERT(tstore.empty());
+ pool_test_random_shuffle(vpv.begin(), vpv.end());
+
+ for(std::size_t i=0; i < 6; ++i)
+ {
+ tstore.ordered_free(vpv[i]);
+ }
+ // "Order-preserving"
+ test_is_order(tstore);
+ }
+
+ /* t.malloc_n(n, partition_sz) */
+ {
+ {
+ char* const pc = track_allocator::malloc(12 * partition_sz);
+ test_simp_seg_store tstore;
+ tstore.add_ordered_block(pc, 2 * partition_sz, partition_sz);
+ tstore.add_ordered_block(pc + (3 * partition_sz),
+ 3 * partition_sz, partition_sz);
+ tstore.add_ordered_block(pc + (7 * partition_sz),
+ 5 * partition_sz, partition_sz);
+
+ void* pvret = tstore.malloc_n(6, partition_sz);
+ BOOST_TEST(pvret == 0);
+
+ pvret = tstore.malloc_n(0, partition_sz);
+ // There's no prohibition against asking for zero elements
+ BOOST_TEST(pvret == 0);
+
+ pvret = tstore.malloc_n(3, partition_sz);
+ // Implicit assumption that contiguous sequence found is the first
+ // available while traversing from the start of the free list
+ BOOST_TEST(pvret == pc + (3 * partition_sz));
+
+ pvret = tstore.malloc_n(4, partition_sz);
+ BOOST_TEST(pvret == pc + (7 * partition_sz));
+
+ // There should still be two contiguous
+ // and one non-contiguous chunk left
+ std::size_t nchunks = 0;
+ while(!tstore.empty())
+ {
+ tstore.malloc();
+ ++nchunks;
+ }
+ BOOST_TEST(nchunks == 3);
+ }
+
+ {
+ char* const pc = track_allocator::malloc(12 * partition_sz);
+ test_simp_seg_store tstore;
+ tstore.add_ordered_block(pc, 2 * partition_sz, partition_sz);
+ tstore.add_ordered_block(pc + (3 * partition_sz),
+ 3 * partition_sz, partition_sz);
+ tstore.add_ordered_block(pc + (7 * partition_sz),
+ 5 * partition_sz, partition_sz);
+
+ tstore.malloc_n(3, partition_sz);
+ // "Order-preserving"
+ test_is_order(tstore);
+ }
+ }
+
+ for(std::set<char*>::iterator itr
+ = track_allocator::allocated_blocks.begin();
+ itr != track_allocator::allocated_blocks.end();
+ ++itr)
+ {
+ delete [] *itr;
+ }
+ track_allocator::allocated_blocks.clear();
+ return boost::report_errors();
+}
diff --git a/src/boost/libs/pool/test/test_simple_seg_storage.hpp b/src/boost/libs/pool/test/test_simple_seg_storage.hpp
new file mode 100644
index 000000000..548921bb9
--- /dev/null
+++ b/src/boost/libs/pool/test/test_simple_seg_storage.hpp
@@ -0,0 +1,173 @@
+/* Copyright (C) 2000, 2001 Stephen Cleary
+* Copyright (C) 2011 Kwan Ting Chan
+*
+* Use, modification and distribution is subject to the
+* Boost Software License, Version 1.0. (See accompanying
+* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_POOL_TEST_SIMP_SEG_STORE_HPP
+#define BOOST_POOL_TEST_SIMP_SEG_STORE_HPP
+
+#include <boost/pool/simple_segregated_storage.hpp>
+#include <boost/assert.hpp>
+
+#include <boost/detail/lightweight_test.hpp>
+
+#include <functional>
+#include <set>
+#include <utility>
+#include <vector>
+
+#include <cstddef>
+
+class test_simp_seg_store : public boost::simple_segregated_storage<std::size_t>
+{
+private:
+ // ::first is the address of the start of the added block,
+ // ::second is the size in bytes of the added block
+ std::vector<std::pair<void*, std::size_t> > allocated_blocks;
+ size_type np_sz;
+ std::set<void*> allocated_chunks;
+
+ void set_partition_size(const size_type sz)
+ {
+ if(allocated_blocks.empty())
+ {
+ np_sz = sz;
+ }
+ else
+ {
+ BOOST_ASSERT(np_sz == sz);
+ }
+ }
+
+ // Return: true if chunk is from added blocks, false otherwise
+ bool is_inside_allocated_blocks(void* const chunk) const
+ {
+ typedef std::vector<std::pair<void*, std::size_t> >::const_iterator
+ VPIter;
+ for(VPIter iter = allocated_blocks.begin();
+ iter != allocated_blocks.end();
+ ++iter)
+ {
+ if( std::less_equal<void*>()(iter->first, chunk)
+ && std::less_equal<void*>()(static_cast<char*>(chunk) + np_sz,
+ static_cast<char*>(iter->first) + iter->second) )
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ void check_in(void* const chunk)
+ {
+ // Check that the newly allocated chunk has not already previously
+ // been allocated, and that the memory does not overlap with
+ // previously allocated chunks
+ for(std::set<void*>::const_iterator iter = allocated_chunks.begin();
+ iter != allocated_chunks.end();
+ ++iter)
+ {
+ BOOST_TEST( std::less_equal<void*>()(static_cast<char*>(chunk)
+ + np_sz, *iter)
+ || std::less_equal<void*>()(static_cast<char*>(*iter)
+ + np_sz, chunk) );
+ }
+
+ allocated_chunks.insert(chunk);
+ }
+
+ void check_out(void* const chunk)
+ {
+ BOOST_TEST(allocated_chunks.erase(chunk) == 1);
+ }
+
+public:
+ test_simp_seg_store()
+ : np_sz(0) {}
+
+ void* get_first() { return first; }
+ static void*& get_nextof(void* const ptr) { return nextof(ptr); }
+
+ // (Test) Pre: npartition_sz of all added block is the same
+ // different blocks of memory does not overlap
+ void add_block(void* const block,
+ const size_type nsz, const size_type npartition_sz)
+ {
+ set_partition_size(npartition_sz);
+ allocated_blocks.push_back(
+ std::pair<void*, std::size_t>(block, nsz) );
+ boost::simple_segregated_storage<std::size_t>::add_block(
+ block, nsz, npartition_sz );
+ // Post: !empty()
+ BOOST_TEST(!empty());
+ }
+
+ // (Test) Pre: npartition_sz of all added block is the same
+ // different blocks of memory does not overlap
+ void add_ordered_block(void* const block,
+ const size_type nsz, const size_type npartition_sz)
+ {
+ set_partition_size(npartition_sz);
+ allocated_blocks.push_back(
+ std::pair<void*, std::size_t>(block, nsz) );
+ boost::simple_segregated_storage<std::size_t>::add_ordered_block(
+ block, nsz, npartition_sz );
+ // Post: !empty()
+ BOOST_TEST(!empty());
+ }
+
+ void* malloc()
+ {
+ void* const ret
+ = boost::simple_segregated_storage<std::size_t>::malloc();
+ // Chunk returned should actually be from added blocks
+ BOOST_TEST(is_inside_allocated_blocks(ret));
+ check_in(ret);
+ return ret;
+ }
+
+ void free(void* const chunk)
+ {
+ BOOST_ASSERT(chunk);
+ check_out(chunk);
+ boost::simple_segregated_storage<std::size_t>::free(chunk);
+ // Post: !empty()
+ BOOST_TEST(!empty());
+ }
+
+ void ordered_free(void* const chunk)
+ {
+ BOOST_ASSERT(chunk);
+ check_out(chunk);
+ boost::simple_segregated_storage<std::size_t>::ordered_free(chunk);
+ // Post: !empty()
+ BOOST_TEST(!empty());
+ }
+
+ void* malloc_n(size_type n, size_type partition_size)
+ {
+ void* const ret
+ = boost::simple_segregated_storage<std::size_t>::malloc_n(
+ n, partition_size );
+
+ if(ret)
+ {
+ for(std::size_t i=0; i < n; ++i)
+ {
+ void* const chunk = static_cast<char*>(ret)
+ + (i * partition_size);
+ // Memory returned should actually be from added blocks
+ BOOST_TEST(is_inside_allocated_blocks(chunk));
+ check_in(chunk);
+ }
+ }
+
+ return ret;
+ }
+};
+
+#endif // BOOST_POOL_TEST_SIMP_SEG_STORE_HPP
diff --git a/src/boost/libs/pool/test/test_threading.cpp b/src/boost/libs/pool/test/test_threading.cpp
new file mode 100644
index 000000000..f01fea32a
--- /dev/null
+++ b/src/boost/libs/pool/test/test_threading.cpp
@@ -0,0 +1,80 @@
+/* Copyright (C) 2011 John Maddock
+*
+* Use, modification and distribution is subject to the
+* Boost Software License, Version 1.0. (See accompanying
+* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#include <iostream>
+#include <boost/pool/pool_alloc.hpp>
+#include <boost/thread.hpp>
+#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1600)
+#pragma warning(push)
+#pragma warning(disable: 4244)
+// ..\..\boost/random/uniform_int_distribution.hpp(171) :
+// warning C4127: conditional expression is constant
+#pragma warning(disable: 4127)
+// ..\..\boost/random/detail/polynomial.hpp(315) :
+// warning C4267: 'argument' : conversion from 'size_t'
+// to 'int', possible loss of data
+#pragma warning(disable: 4267)
+#endif
+#include <boost/random/mersenne_twister.hpp>
+#include <boost/random/uniform_int_distribution.hpp>
+#if defined(BOOST_MSVC) && (BOOST_MSVC <= 1600)
+#pragma warning(pop)
+#endif
+
+void run_tests()
+{
+ boost::random::mt19937 gen;
+ boost::random::uniform_int_distribution<> dist(-10, 10);
+ std::list<int, boost::fast_pool_allocator<int> > l;
+
+ for(int i = 0; i < 100; ++i)
+ l.push_back(i);
+
+ for(int i = 0; i < 20000; ++i)
+ {
+ int val = dist(gen);
+ if(val < 0)
+ {
+ while(val && l.size())
+ {
+ l.pop_back();
+ ++val;
+ }
+ }
+ else
+ {
+ while(val)
+ {
+ l.push_back(val);
+ --val;
+ }
+ }
+ }
+}
+
+int main()
+{
+ std::list<boost::shared_ptr<boost::thread> > threads;
+ for(int i = 0; i < 10; ++i)
+ {
+ try{
+ threads.push_back(boost::shared_ptr<boost::thread>(new boost::thread(&run_tests)));
+ }
+ catch(const std::exception& e)
+ {
+ std::cerr << "<note>Thread creation failed with message: " << e.what() << "</note>" << std::endl;
+ }
+ }
+ std::list<boost::shared_ptr<boost::thread> >::const_iterator a(threads.begin()), b(threads.end());
+ while(a != b)
+ {
+ (*a)->join();
+ ++a;
+ }
+ return 0;
+}
+
diff --git a/src/boost/libs/pool/test/test_valgrind_fail_1.cpp b/src/boost/libs/pool/test/test_valgrind_fail_1.cpp
new file mode 100644
index 000000000..43e749742
--- /dev/null
+++ b/src/boost/libs/pool/test/test_valgrind_fail_1.cpp
@@ -0,0 +1,22 @@
+/* Copyright (C) 2011 John Maddock
+*
+* Use, modification and distribution is subject to the
+* Boost Software License, Version 1.0. (See accompanying
+* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+// Test of bug #2656 (https://svn.boost.org/trac/boost/ticket/2656)
+
+#include <boost/pool/pool.hpp>
+#include <iostream>
+#include <iomanip>
+
+static const int magic_value = 0x12345678;
+
+int main()
+{
+ boost::pool<> p(sizeof(int));
+ int* ptr = static_cast<int*>((p.malloc)());
+ std::cout << *ptr << std::endl; // uninitialized read
+ return 0;
+}
diff --git a/src/boost/libs/pool/test/test_valgrind_fail_2.cpp b/src/boost/libs/pool/test/test_valgrind_fail_2.cpp
new file mode 100644
index 000000000..84b703b7b
--- /dev/null
+++ b/src/boost/libs/pool/test/test_valgrind_fail_2.cpp
@@ -0,0 +1,20 @@
+/* Copyright (C) 2011 John Maddock
+*
+* Use, modification and distribution is subject to the
+* Boost Software License, Version 1.0. (See accompanying
+* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+// Test of bug #2656 (https://svn.boost.org/trac/boost/ticket/2656)
+
+#include <boost/pool/pool.hpp>
+
+int main()
+{
+ boost::pool<> p(sizeof(int));
+ int* ptr = static_cast<int*>((p.malloc)());
+ *ptr = 0;
+ (p.free)(ptr);
+ *ptr = 2; // write to freed memory
+ return 0;
+}
diff --git a/src/boost/libs/pool/test/track_allocator.hpp b/src/boost/libs/pool/test/track_allocator.hpp
new file mode 100644
index 000000000..ed989f048
--- /dev/null
+++ b/src/boost/libs/pool/test/track_allocator.hpp
@@ -0,0 +1,104 @@
+/* Copyright (C) 2000, 2001 Stephen Cleary
+* Copyright (C) 2011 Kwan Ting Chan
+*
+* Use, modification and distribution is subject to the
+* Boost Software License, Version 1.0. (See accompanying
+* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
+*/
+
+#ifndef BOOST_POOL_TRACK_ALLOCATOR_HPP
+#define BOOST_POOL_TRACK_ALLOCATOR_HPP
+
+#include <boost/detail/lightweight_test.hpp>
+
+#include <new>
+#include <set>
+#include <stdexcept>
+
+#include <cstddef>
+
+// Each "tester" object below checks into and out of the "cdtor_checker",
+// which will check for any problems related to the construction/destruction of
+// "tester" objects.
+class cdtor_checker
+{
+private:
+ // Each constructed object registers its "this" pointer into "objs"
+ std::set<void*> objs;
+
+public:
+ // True iff all objects that have checked in have checked out
+ bool ok() const { return objs.empty(); }
+
+ ~cdtor_checker()
+ {
+ BOOST_TEST(ok());
+ }
+
+ void check_in(void * const This)
+ {
+ BOOST_TEST(objs.find(This) == objs.end());
+ objs.insert(This);
+ }
+
+ void check_out(void * const This)
+ {
+ BOOST_TEST(objs.find(This) != objs.end());
+ objs.erase(This);
+ }
+};
+static cdtor_checker mem;
+
+struct tester
+{
+ tester(bool throw_except = false)
+ {
+ if(throw_except)
+ {
+ throw std::logic_error("Deliberate constructor exception");
+ }
+
+ mem.check_in(this);
+ }
+
+ tester(const tester &)
+ {
+ mem.check_in(this);
+ }
+
+ ~tester()
+ {
+ mem.check_out(this);
+ }
+};
+
+// Allocator that registers alloc/dealloc to/from the system memory
+struct track_allocator
+{
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ static std::set<char*> allocated_blocks;
+
+ static char* malloc(const size_type bytes)
+ {
+ char* const ret = new (std::nothrow) char[bytes];
+ allocated_blocks.insert(ret);
+ return ret;
+ }
+
+ static void free(char* const block)
+ {
+ BOOST_TEST(allocated_blocks.find(block) != allocated_blocks.end());
+ allocated_blocks.erase(block);
+ delete [] block;
+ }
+
+ static bool ok()
+ {
+ return allocated_blocks.empty();
+ }
+};
+std::set<char*> track_allocator::allocated_blocks;
+
+#endif // BOOST_POOL_TRACK_ALLOCATOR_HPP
diff --git a/src/boost/libs/pool/test/valgrind_config_check.cpp b/src/boost/libs/pool/test/valgrind_config_check.cpp
new file mode 100644
index 000000000..35252eefa
--- /dev/null
+++ b/src/boost/libs/pool/test/valgrind_config_check.cpp
@@ -0,0 +1,7 @@
+
+#include <valgrind/valgrind.h>
+
+int main()
+{
+ return 0;
+} \ No newline at end of file