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