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