15
15
#include < bsoncxx/v1/detail/macros.hpp>
16
16
17
17
#include < cstring>
18
+ #include < memory>
18
19
19
20
#include < bsoncxx/builder/core.hpp>
20
21
#include < bsoncxx/exception/error_code.hpp>
@@ -72,14 +73,33 @@ class managed_bson_t {
72
73
73
74
class core ::impl {
74
75
public:
75
- impl (bool is_array) : _depth(0 ), _root_is_array(is_array), _n(0 ), _has_user_key(false ) {}
76
+ ~impl () {
77
+ _root_ptr->~managed_bson_t ();
78
+ }
79
+
80
+ impl (impl&&) = delete ;
81
+ impl& operator =(impl&&) = delete ;
82
+
83
+ impl (impl const &) = delete ;
84
+ impl& operator =(impl const &) = delete ;
85
+
86
+ impl (bool is_array)
87
+ : _depth(0 ),
88
+ _root_is_array (is_array),
89
+ _n(0 ),
90
+ _root_ptr([this ] {
91
+ void * ptr = _root_storage;
92
+ std::size_t space = sizeof (_root_storage);
93
+ return new (std::align (alignof (managed_bson_t ), sizeof (managed_bson_t ), ptr, space)) managed_bson_t ();
94
+ }()),
95
+ _has_user_key(false ) {}
76
96
77
97
void reinit () {
78
98
while (!_stack.empty ()) {
79
99
_stack.pop_back ();
80
100
}
81
101
82
- bson_reinit (_root. get ());
102
+ bson_reinit (_root_ptr-> get ());
83
103
84
104
_depth = 0 ;
85
105
@@ -95,8 +115,8 @@ class core::impl {
95
115
}
96
116
97
117
uint32_t buf_len;
98
- uint8_t * buf_ptr = bson_destroy_with_steal (_root. get (), true , &buf_len);
99
- bson_init (_root. get ());
118
+ uint8_t * buf_ptr = bson_destroy_with_steal (_root_ptr-> get (), true , &buf_len);
119
+ bson_init (_root_ptr-> get ());
100
120
101
121
return bsoncxx::v_noabi::document::value{buf_ptr, buf_len, bson_free_deleter};
102
122
}
@@ -108,15 +128,15 @@ class core::impl {
108
128
}
109
129
110
130
uint32_t buf_len;
111
- uint8_t * buf_ptr = bson_destroy_with_steal (_root. get (), true , &buf_len);
112
- bson_init (_root. get ());
131
+ uint8_t * buf_ptr = bson_destroy_with_steal (_root_ptr-> get (), true , &buf_len);
132
+ bson_init (_root_ptr-> get ());
113
133
114
134
return bsoncxx::v_noabi::array::value{buf_ptr, buf_len, bson_free_deleter};
115
135
}
116
136
117
137
bson_t * back () {
118
138
if (_stack.empty ()) {
119
- return _root. get ();
139
+ return _root_ptr-> get ();
120
140
} else {
121
141
return &_stack.back ().bson ;
122
142
}
@@ -178,7 +198,7 @@ class core::impl {
178
198
throw bsoncxx::v_noabi::exception {error_code::k_cannot_perform_document_operation_on_array};
179
199
}
180
200
181
- return _root. get ();
201
+ return _root_ptr-> get ();
182
202
}
183
203
184
204
// Throws bsoncxx::v_noabi::exception if the top-level BSON datum is a document.
@@ -187,7 +207,7 @@ class core::impl {
187
207
throw bsoncxx::v_noabi::exception {error_code::k_cannot_perform_array_operation_on_document};
188
208
}
189
209
190
- return _root. get ();
210
+ return _root_ptr-> get ();
191
211
}
192
212
193
213
bool is_array () {
@@ -239,7 +259,9 @@ class core::impl {
239
259
240
260
bool _root_is_array;
241
261
std::size_t _n;
242
- managed_bson_t _root;
262
+
263
+ unsigned char _root_storage[2u * sizeof (managed_bson_t )];
264
+ managed_bson_t * _root_ptr;
243
265
244
266
// The bottom frame of _stack has _root as its parent.
245
267
stack<frame, 4 > _stack;
0 commit comments