1//////////////////////////////////////////////////////////////////////////////
2//
3// (C) Copyright Ion Gaztanaga 2015-2015. Distributed under the Boost
4// Software License, Version 1.0. (See accompanying file
5// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7// See http://www.boost.org/libs/container for documentation.
8//
9//////////////////////////////////////////////////////////////////////////////
10#include <boost/container/pmr/global_resource.hpp>
11#include <boost/container/pmr/memory_resource.hpp>
12#include <boost/core/lightweight_test.hpp>
13
14#include "derived_from_memory_resource.hpp"
15
16#include <cstdlib>
17#include <new>
18
19using namespace boost::container;
20using namespace boost::container::pmr;
21
22#ifdef BOOST_MSVC
23#pragma warning (push)
24#pragma warning (disable : 4290)
25#endif
26
27#if __cplusplus >= 201103L
28#define BOOST_CONTAINER_NEW_EXCEPTION_SPECIFIER
29#define BOOST_CONTAINER_DELETE_EXCEPTION_SPECIFIER noexcept
30#else
31#define BOOST_CONTAINER_NEW_EXCEPTION_SPECIFIER throw(std::bad_alloc)
32#define BOOST_CONTAINER_DELETE_EXCEPTION_SPECIFIER throw()
33#endif
34
35#if defined(BOOST_GCC) && (BOOST_GCC >= 50000)
36#pragma GCC diagnostic ignored "-Wsized-deallocation"
37#endif
38
39//ASAN does not support operator new overloading
40#ifndef BOOST_CONTAINER_ASAN
41
42std::size_t allocation_count = 0;
43
44void* operator new[](std::size_t count) BOOST_CONTAINER_NEW_EXCEPTION_SPECIFIER
45{
46 ++allocation_count;
47 return std::malloc(size: count);
48}
49
50void operator delete[](void *p) BOOST_CONTAINER_DELETE_EXCEPTION_SPECIFIER
51{
52 --allocation_count;
53 return std::free(ptr: p);
54}
55
56#endif //BOOST_CONTAINER_ASAN
57
58#ifdef BOOST_MSVC
59#pragma warning (pop)
60#endif
61
62#ifndef BOOST_CONTAINER_ASAN
63
64void test_new_delete_resource()
65{
66 //Make sure new_delete_resource calls new[]/delete[]
67 std::size_t memcount = allocation_count;
68 memory_resource *mr = new_delete_resource();
69 //each time should return the same pointer
70 BOOST_TEST(mr == new_delete_resource());
71 #if !defined(BOOST_CONTAINER_DYNAMIC_LINKING) //No new delete replacement possible new_delete is a DLL
72 BOOST_TEST(memcount == allocation_count);
73 #endif
74 void *addr = mr->allocate(bytes: 16, alignment: 1);
75 #if !defined(BOOST_CONTAINER_DYNAMIC_LINKING) //No new delete replacement possible new_delete is a DLL
76 BOOST_TEST((allocation_count - memcount) == 1);
77 #endif
78 mr->deallocate(p: addr, bytes: 16, alignment: 1);
79 BOOST_TEST(memcount == allocation_count);
80}
81
82#endif //BOOST_CONTAINER_ASAN
83
84void test_null_memory_resource()
85{
86 //Make sure it throw or returns null
87 memory_resource *mr = null_memory_resource();
88 BOOST_TEST(mr != 0);
89
90 #if !defined(BOOST_NO_EXCEPTIONS)
91 bool bad_allocexception_thrown = false;
92
93 BOOST_CONTAINER_TRY{
94 mr->allocate(bytes: 1, alignment: 1);
95 }
96 BOOST_CONTAINER_CATCH(std::bad_alloc&) {
97 bad_allocexception_thrown = true;
98 }
99 BOOST_CONTAINER_CATCH(...) {
100 }
101 BOOST_CONTAINER_CATCH_END
102
103 BOOST_TEST(bad_allocexception_thrown == true);
104 #endif //BOOST_NO_EXCEPTIONS
105}
106
107void test_default_resource()
108{
109 //Default resource must be new/delete before set_default_resource
110 BOOST_TEST(get_default_resource() == new_delete_resource());
111 //Set default resource and obtain previous
112 derived_from_memory_resource d;
113 memory_resource *prev_default = set_default_resource(&d);
114 BOOST_TEST(get_default_resource() == &d);
115 //Set default resource with null, which should be new/delete
116 prev_default = set_default_resource(0);
117 BOOST_TEST(prev_default == &d);
118 BOOST_TEST(get_default_resource() == new_delete_resource());
119}
120
121int main()
122{
123 #ifndef BOOST_CONTAINER_ASAN
124 test_new_delete_resource();
125 #endif
126 test_null_memory_resource();
127 test_default_resource();
128 return ::boost::report_errors();
129}
130

source code of boost/libs/container/test/global_resource_test.cpp