1212
1313#include < jsoncons/config/compiler_support.hpp>
1414#include < jsoncons/config/jsoncons_config.hpp>
15+ #include < jsoncons/json_array.hpp>
16+ #include < jsoncons/json_object.hpp>
17+ #include < jsoncons/json_type.hpp>
1518
1619namespace jsoncons {
1720
21+ struct json_ref_object_t
22+ {
23+ explicit json_ref_object_t () = default;
24+ };
25+
26+ JSONCONS_INLINE_CONSTEXPR json_ref_object_t json_ref_object{};
27+
28+ struct json_ref_array_t
29+ {
30+ explicit json_ref_array_t () = default;
31+ };
32+
33+ JSONCONS_INLINE_CONSTEXPR json_ref_array_t json_ref_array{};
34+
1835enum class json_ref_storage_kind : uint8_t {json_ref,array,object};
1936
2037template <typename Json,typename Allocator=std::allocator<char >>
2138class json_ref
2239{
40+ public:
2341 using allocator_type = Allocator;
2442 using json_type = typename std::remove_const<Json>::type;
2543 using key_type = typename json_type::key_type;
2644 using policy_type = typename json_type::policy_type;
2745 using array = typename policy_type::template array<json_ref>;
2846 using object = typename policy_type::template object<key_type,json_ref>;
29-
47+ using char_type = typename Json::char_type;
48+ using string_view_type = typename Json::string_view_type;
49+ private:
3050 struct common_storage
3151 {
3252 json_ref_storage_kind storage_kind_;
@@ -118,6 +138,30 @@ class json_ref
118138 }
119139 }
120140
141+ explicit json_ref (json_ref_object_t )
142+ {
143+ auto ptr = create_object (Allocator{});
144+ construct<object_storage>(ptr);
145+ }
146+
147+ json_ref (json_ref_object_t , const Allocator& alloc)
148+ {
149+ auto ptr = create_object (alloc);
150+ construct<object_storage>(ptr);
151+ }
152+
153+ explicit json_ref (json_ref_array_t )
154+ {
155+ auto ptr = create_array (Allocator{});
156+ construct<array_storage>(ptr);
157+ }
158+
159+ json_ref (json_ref_array_t , const Allocator& alloc)
160+ {
161+ auto ptr = create_array (alloc);
162+ construct<array_storage>(ptr);
163+ }
164+
121165 template <typename T,typename ... Args>
122166 bool is (Args&&... args) const noexcept
123167 {
@@ -131,6 +175,12 @@ class json_ref
131175 }
132176private:
133177
178+ template <typename StorageType,typename ... Args>
179+ void construct (Args&&... args)
180+ {
181+ ::new (&cast<StorageType>()) StorageType (std::forward<Args>(args)...);
182+ }
183+
134184 void destroy ()
135185 {
136186 switch (common_.storage_kind_ )
@@ -206,6 +256,44 @@ class json_ref
206256 {
207257 return ref_;
208258 }
259+
260+ template <typename ... Args>
261+ typename array_storage::pointer create_array (const allocator_type& alloc, Args&& ... args)
262+ {
263+ using stor_allocator_type = typename array_storage::allocator_type;
264+ stor_allocator_type stor_alloc (alloc);
265+ auto ptr = std::allocator_traits<stor_allocator_type>::allocate (stor_alloc, 1 );
266+ JSONCONS_TRY
267+ {
268+ std::allocator_traits<stor_allocator_type>::construct (stor_alloc, ext_traits::to_plain_pointer (ptr),
269+ std::forward<Args>(args)...);
270+ }
271+ JSONCONS_CATCH (...)
272+ {
273+ std::allocator_traits<stor_allocator_type>::deallocate (stor_alloc, ptr,1 );
274+ JSONCONS_RETHROW;
275+ }
276+ return ptr;
277+ }
278+
279+ template <typename ... Args>
280+ typename object_storage::pointer create_object (const allocator_type& alloc, Args&& ... args)
281+ {
282+ using stor_allocator_type = typename object_storage::allocator_type;
283+ stor_allocator_type stor_alloc (alloc);
284+ auto ptr = std::allocator_traits<stor_allocator_type>::allocate (stor_alloc, 1 );
285+ JSONCONS_TRY
286+ {
287+ std::allocator_traits<stor_allocator_type>::construct (stor_alloc, ext_traits::to_plain_pointer (ptr),
288+ std::forward<Args>(args)...);
289+ }
290+ JSONCONS_CATCH (...)
291+ {
292+ std::allocator_traits<stor_allocator_type>::deallocate (stor_alloc, ptr,1 );
293+ JSONCONS_RETHROW;
294+ }
295+ return ptr;
296+ }
209297};
210298
211299} // namespace jsoncons
0 commit comments