1 //
2 // Copyright (c) 2019 Vinnie Falco (vinnie.falco@gmail.com)
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/boostorg/json
8 //
9
10 #include <boost/json/monotonic_resource.hpp>
11 #include <boost/json/static_resource.hpp>
12 #include <boost/json/value.hpp>
13
14 #ifndef BOOST_JSON_STANDALONE
15 #include <boost/container/pmr/vector.hpp>
16 #endif
17 #include <vector>
18
19 #include "test_suite.hpp"
20
21 #ifdef assert
22 #undef assert
23 #endif
24 #define assert BOOST_TEST
25
26 BOOST_JSON_NS_BEGIN
27
28 namespace doc_background {
29
30 namespace background {
31 #ifdef BOOST_JSON_STANDALONE
32 template<class T>
33 using vector = std::pmr::vector<T>;
34 #else
35 template<class T>
36 using vector = boost::container::pmr::vector<T>;
37 #endif
38 } // background
39
40 //----------------------------------------------------------
41
42 namespace std {
43 template<class T>
44 using allocator = ::std::allocator<T>;
45 } // std
46
47 //[doc_background_1
48 namespace std {
49
50 template< class T, class Allocator = std::allocator< T > >
51 class vector;
52
53 } // namespace std
54 //]
55
56 //----------------------------------------------------------
57
58 //[doc_background_2
59 namespace std {
60
61 template< class T, class Allocator >
62 class vector
63 {
64 public:
65 explicit vector( Allocator const& alloc );
66
67 //...
68 //]
69 };
70
71 template<class T, class A>
vector(A const &)72 vector<T,A>::vector(A const&){}
73 }
74
75 //----------------------------------------------------------
76
77 //[doc_background_3
78 namespace std {
79 namespace pmr {
80
81 class memory_resource
82 {
83 public:
84 virtual ~memory_resource();
85
86 void* allocate ( size_t bytes, size_t alignment );
87 void deallocate( void* p, size_t bytes, size_t alignment );
88 bool is_equal ( const memory_resource& other ) const;
89
90 protected:
91 virtual void* do_allocate ( size_t bytes, size_t alignment ) = 0;
92 virtual void do_deallocate( void* p, size_t bytes, size_t alignment ) = 0;
93 virtual bool do_is_equal ( memory_resource const& other ) const noexcept = 0;
94 };
95
96 } // namespace pmr
97 } // namespace std
98 //]
99
100 //----------------------------------------------------------
101
102 //[doc_background_4
103
104 namespace std {
105 namespace pmr {
106
107 template< class T >
108 using vector = std::vector< T, polymorphic_allocator< T > >;
109
110 } // namespace pmr
111 } // namespace std
112
113 //]
114
115 //----------------------------------------------------------
116
set1()117 static void set1() {
118 using namespace background;
119
120 //----------------------------------------------------------
121 {
122 struct T {};
123 //[doc_background_5
124 // A type of memory resource
125 monotonic_resource mr;
126
127 // Construct a vector using the monotonic buffer resource
128 vector< T > v1(( polymorphic_allocator< T >(&mr) ));
129
130 // Or this way, since construction from memory_resource* is implicit:
131 vector< T > v2( &mr );
132 //]
133 }
134 //----------------------------------------------------------
135 {
136 //[doc_background_6
137 {
138 // A type of memory resource which uses a stack buffer
139 unsigned char temp[4096];
140 static_resource mr( temp, sizeof(temp) );
141
142 // Construct a vector using the static buffer resource
143 vector< value > v( &mr );
144
145 // The vector will allocate from `temp` first, and then the heap.
146 }
147 //]
148 }
149 //----------------------------------------------------------
150
151 } // set1
152
153 //----------------------------------------------------------
154
155 struct my_resource : memory_resource
156 {
do_allocatedoc_background::my_resource157 void* do_allocate ( size_t, size_t ) override { return 0; }
do_deallocatedoc_background::my_resource158 void do_deallocate( void*, size_t, size_t ) override {}
do_is_equaldoc_background::my_resource159 bool do_is_equal ( memory_resource const& ) const noexcept override { return true; }
160 };
161 //[doc_background_7
162 namespace my_library {
163
get_chars1()164 std::pmr::vector<char> get_chars1()
165 {
166 // This leaks memory because `v` does not own the memory resource
167 std::pmr::vector<char> v( new my_resource );
168
169 return v;
170 }
171
172 } // my_library
173 //]
174
175 //----------------------------------------------------------
176
177 //[doc_background_8
178 namespace my_library {
179
get_chars2()180 std::pmr::vector<char> get_chars2()
181 {
182 // Declare a local memory resource
183 my_resource mr;
184
185 // Construct a vector that uses our resource
186 std::pmr::vector<char> v( &mr );
187
188 // Undefined behavior, `mr` goes out of scope!
189 return v;
190 }
191
192 } // my_library
193 //]
194
195 //----------------------------------------------------------
196
197 } // doc_background
198
199 class doc_background_test
200 {
201 public:
202 void
run()203 run()
204 {
205 using namespace doc_background;
206 (void)&set1;
207 BOOST_TEST_PASS();
208 }
209 };
210
211 TEST_SUITE(doc_background_test, "boost.json.doc_background");
212
213 BOOST_JSON_NS_END
214