@@ -22,6 +22,10 @@ namespace bson {
22
22
23
23
// / Please refer to https://mongoc.org/libbson/current/api.html
24
24
class Writer {
25
+ struct BSONType {
26
+ bson_t val_;
27
+ };
28
+
25
29
struct IsArray {
26
30
bson_array_builder_t * ptr_;
27
31
};
@@ -43,10 +47,10 @@ class Writer {
43
47
};
44
48
45
49
struct BSONOutputObject {
46
- BSONOutputObject (bson_t _val, ParentType _parent)
50
+ BSONOutputObject (bson_t * _val, ParentType _parent)
47
51
: parent_(_parent), val_(_val) {}
48
52
ParentType parent_;
49
- bson_t val_;
53
+ bson_t * val_;
50
54
};
51
55
52
56
struct BSONOutputVar {};
@@ -65,9 +69,7 @@ class Writer {
65
69
}
66
70
67
71
OutputObjectType object_as_root (const size_t _size) const noexcept {
68
- bson_t val;
69
- bson_init (&val);
70
- return OutputObjectType (val, IsRoot{});
72
+ return OutputObjectType (doc_, IsRoot{});
71
73
}
72
74
73
75
OutputVarType null_as_root () const noexcept {
@@ -93,25 +95,27 @@ class Writer {
93
95
const std::string& _name, const size_t _size,
94
96
OutputObjectType* _parent) const noexcept {
95
97
bson_array_builder_t * val;
96
- bson_append_array_builder_begin (&( _parent->val_ ) , _name.c_str (),
98
+ bson_append_array_builder_begin (_parent->val_ , _name.c_str (),
97
99
static_cast <int >(_name.size ()), &val);
98
- return OutputArrayType (val, IsObject{&( _parent->val_ ) });
100
+ return OutputArrayType (val, IsObject{_parent->val_ });
99
101
}
100
102
101
103
OutputObjectType add_object_to_array (
102
104
const size_t _size, OutputArrayType* _parent) const noexcept {
103
- bson_t val;
104
- bson_array_builder_append_document_begin (_parent->val_ , &val);
105
- return OutputObjectType (val, IsArray{_parent->val_ });
105
+ subdocs_->push_back (BSONType{});
106
+ bson_array_builder_append_document_begin (_parent->val_ ,
107
+ &subdocs_->back ().val_ );
108
+ return OutputObjectType (&subdocs_->back ().val_ , IsArray{_parent->val_ });
106
109
}
107
110
108
111
OutputObjectType add_object_to_object (
109
112
const std::string& _name, const size_t _size,
110
113
OutputObjectType* _parent) const noexcept {
111
- bson_t val;
112
- bson_append_document_begin (&(_parent->val_ ), _name.c_str (),
113
- static_cast <int >(_name.size ()), &val);
114
- return OutputObjectType (val, IsObject{&(_parent->val_ )});
114
+ subdocs_->push_back (BSONType{});
115
+ bson_append_document_begin (_parent->val_ , _name.c_str (),
116
+ static_cast <int >(_name.size ()),
117
+ &subdocs_->back ().val_ );
118
+ return OutputObjectType (&subdocs_->back ().val_ , IsObject{_parent->val_ });
115
119
}
116
120
117
121
template <class T >
@@ -138,18 +142,18 @@ class Writer {
138
142
OutputVarType add_value_to_object (const std::string& _name, const T& _var,
139
143
OutputObjectType* _parent) const noexcept {
140
144
if constexpr (std::is_same<std::remove_cvref_t <T>, std::string>()) {
141
- bson_append_utf8 (&( _parent->val_ ) , _name.c_str (),
145
+ bson_append_utf8 (_parent->val_ , _name.c_str (),
142
146
static_cast <int >(_name.size ()), _var.c_str (),
143
147
static_cast <int >(_var.size ()));
144
148
} else if constexpr (std::is_same<std::remove_cvref_t <T>, bool >()) {
145
- bson_append_bool (&( _parent->val_ ) , _name.c_str (),
149
+ bson_append_bool (_parent->val_ , _name.c_str (),
146
150
static_cast <int >(_name.size ()), _var);
147
151
} else if constexpr (std::is_floating_point<std::remove_cvref_t <T>>()) {
148
- bson_append_double (&( _parent->val_ ) , _name.c_str (),
152
+ bson_append_double (_parent->val_ , _name.c_str (),
149
153
static_cast <int >(_name.size ()),
150
154
static_cast <double >(_var));
151
155
} else if constexpr (std::is_integral<std::remove_cvref_t <T>>()) {
152
- bson_append_int64 (&( _parent->val_ ) , _name.c_str (),
156
+ bson_append_int64 (_parent->val_ , _name.c_str (),
153
157
static_cast <int >(_name.size ()),
154
158
static_cast <std::int32_t >(_var));
155
159
} else {
@@ -165,7 +169,7 @@ class Writer {
165
169
166
170
OutputVarType add_null_to_object (const std::string& _name,
167
171
OutputObjectType* _parent) const noexcept {
168
- bson_append_null (&( _parent->val_ ) , _name.c_str (),
172
+ bson_append_null (_parent->val_ , _name.c_str (),
169
173
static_cast <int >(_name.size ()));
170
174
return OutputVarType{};
171
175
}
@@ -190,11 +194,10 @@ class Writer {
190
194
const auto handle = [&](const auto _parent) {
191
195
using Type = std::remove_cvref_t <decltype (_parent)>;
192
196
if constexpr (std::is_same<Type, IsArray>()) {
193
- bson_array_builder_append_document_end (_parent.ptr_ , &( _obj->val_ ) );
197
+ bson_array_builder_append_document_end (_parent.ptr_ , _obj->val_ );
194
198
} else if constexpr (std::is_same<Type, IsObject>()) {
195
- bson_append_document_end (_parent.ptr_ , &( _obj->val_ ) );
199
+ bson_append_document_end (_parent.ptr_ , _obj->val_ );
196
200
} else if constexpr (std::is_same<Type, IsRoot>()) {
197
- *doc_ = _obj->val_ ;
198
201
} else {
199
202
static_assert (rfl::always_false_v<Type>, " Unsupported type." );
200
203
}
@@ -203,7 +206,12 @@ class Writer {
203
206
}
204
207
205
208
private:
209
+ // / Pointer to the main document. In BSON, documents are what are usually
210
+ // / called objects.
206
211
bson_t * const doc_;
212
+
213
+ // / Contain all of the subdocuments.
214
+ const rfl::Ref<std::vector<BSONType>> subdocs_;
207
215
};
208
216
209
217
} // namespace bson
0 commit comments