[CXX-1294] Add new free functions to assist in efficient subdocument/subarray building with the basic builder Created: 04/Apr/17  Updated: 01/Sep/20  Resolved: 01/Sep/20

Status: Closed
Project: C++ Driver
Component/s: API
Affects Version/s: None
Fix Version/s: None

Type: New Feature Priority: Minor - P4
Reporter: Backlog - CXX Driver Team Assignee: Unassigned
Resolution: Duplicate Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Issue Links:
Duplicate
duplicates CXX-1455 Add JSON-like syntax to construct BSO... Closed
Epic Link: CXX-2082

 Description   

The bsoncxx basic builder provides an extremely flexible API for programmatically building documents with complex structures. However, for use cases of building simple documents of a known schema that contain any nested subdocuments or subarrays, the basic builder API is overly verbose.

To illustrate, see this example of using the basic builder to create the document {a: {b: [1, "x", {c: 1}]}}:

    auto doc1 = make_document(kvp("a", [](sub_document subdoc) {
        subdoc.append(kvp("b", [](sub_array subarr) {
            subarr.append(1, "x", [](sub_document subdoc) { subdoc.append(kvp("c", 1)); });
        }));
    }));

This can be simplified by creating subdocuments and subarrays using bsoncxx::make_document() or bsoncxx::make_array(). However, these helpers create document::value and array::value temporaries, which is inefficient. For example, the following code snippet performs the same function as the above code snippet and is more readable, but it creates two unnecessary document::value temporaries and one unnecessary array::value temporary in the process:

    auto doc2 = make_document(
        kvp("a", make_document(kvp("b", make_array(1, "x", make_document(kvp("c", 1))))))); 

We should provide some solution to users that aims to achieve the best of both worlds: the performance of the lambda approach, but the readability of the make_document() approach. For example, if we had helpers called make_sub_document_func() and make_sub_array_func(), we might be able to use them as follows:

    auto doc3 = make_document(
        kvp("a",
            make_sub_document_func(
                kvp("b", make_sub_array_func(1, "x", make_sub_document_func(kvp("c", 1)))))));



 Comments   
Comment by Clyde Bazile III (Inactive) [ 01/Sep/20 ]

This ticket duplicates CXX-1455, among other similar tickets. The scope WRITING-6412 addresses this, and I'm working on its implementation now.

Comment by J Rassi [ 04/Apr/17 ]

Possible candidate implementation of make_sub_document_func() and make_sub_array_func():

template <typename... Args>
std::function<void(builder::basic::sub_document)> make_sub_document_func(Args&&... args) {
    return [&args...](builder::basic::sub_document subdoc) {
        subdoc.append(std::forward<Args>(args)...);
    };
}
 
template <typename... Args>
std::function<void(builder::basic::sub_array)> make_sub_array_func(Args&&... args) {
    return [&args...](builder::basic::sub_array subarr) {
        subarr.append(std::forward<Args>(args)...);
    };
}

Generated at Wed Feb 07 22:02:05 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.