Skip to content

CXX-3077 BSON Binary Vector accessor, sub_binary builder #1356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 85 commits into from
Apr 3, 2025
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
826cdd8
Add binary vector subtype
mdbmes Feb 20, 2025
5101593
Add an example that demonstrates most vector view API features
mdbmes Mar 20, 2025
5bddf8c
Bump required libmongoc version to pre-release 2.0.0
mdbmes Mar 20, 2025
fa061e8
Additional binary builder tests, including sub_binary
mdbmes Mar 20, 2025
b2dd2f8
vector API tests
mdbmes Mar 20, 2025
2a478bb
New error codes for use in bsoncxx::vector
mdbmes Mar 20, 2025
8ed6fb9
document the bsoncxx::vector namespaces
mdbmes Mar 20, 2025
b316f50
Add forwarding headers for vector and sub_binary
mdbmes Mar 20, 2025
5360c23
initial implementation for bsoncxx::vector
mdbmes Mar 20, 2025
f573b11
sub_binary builder and integration with core
mdbmes Mar 20, 2025
2b5c35a
remove obsolete workaround for CDRIVER-5732
mdbmes Mar 20, 2025
16b8e1f
avoid int32 overflow prior to bson_append_utf8 invocation
mdbmes Mar 20, 2025
5c6d77e
Temporary MONGOC_VERSION_MINIMUM bump for pre-2.0.0
mdbmes Mar 20, 2025
37fe267
Fixes for conversion warnings
mdbmes Mar 20, 2025
d577c15
Add missing includes
mdbmes Mar 20, 2025
d93b1d7
Fix endian detection for win32
mdbmes Mar 20, 2025
d29c352
fixup! Fix endian detection for win32
mdbmes Mar 20, 2025
5019c3d
Replace problematic operator overloads and tests
mdbmes Mar 20, 2025
8bddeb6
lambda missing capture mode
mdbmes Mar 20, 2025
479a5ac
Add missing include
mdbmes Mar 20, 2025
37ddd51
cstdint consistency fixes
mdbmes Mar 21, 2025
d2b2130
More header and name qualification fixes
mdbmes Mar 21, 2025
983da6b
Revert "avoid int32 overflow prior to bson_append_utf8 invocation"
mdbmes Mar 21, 2025
d1f59dd
Revert "remove obsolete workaround for CDRIVER-5732"
mdbmes Mar 21, 2025
36e3f6c
Merge branch 'master' into CXX-3077
mdbmes Mar 21, 2025
03af662
clang-format
mdbmes Mar 21, 2025
0c26bc8
Update src/bsoncxx/include/bsoncxx/docs/v_noabi.hpp
mdbmes Mar 22, 2025
6bb3376
Revert change to required libbson/libmongoc versions
mdbmes Mar 22, 2025
411a643
Remove ALL_VECTOR_FORMATS
mdbmes Mar 22, 2025
1a3bf3c
Update src/bsoncxx/include/bsoncxx/docs/v_noabi.hpp
mdbmes Mar 24, 2025
d45eca7
Update src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/vector/formats.hpp
mdbmes Mar 24, 2025
9be7d04
Replace most REQUIREs with CHECKs
mdbmes Mar 24, 2025
e184ea5
Replace most REQUIRE with CHECK in bson_builder too
mdbmes Mar 24, 2025
a8c285c
Update src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/builder/basic/sub_…
mdbmes Mar 24, 2025
9d8e4c7
k_vector_out_of_range
mdbmes Mar 24, 2025
973f7b6
doxygen suggestions
mdbmes Mar 24, 2025
7194f60
Rename bsoncxx::v_noabi::vector::impl to detail
mdbmes Mar 25, 2025
d38f8aa
Take the impl out of impl_data
mdbmes Mar 25, 2025
fa51a16
Refactor forward declarations
mdbmes Mar 25, 2025
d69d6e2
Rename vector view to vector accessor
mdbmes Mar 25, 2025
61bfb59
Refactor exported symbols out of 'detail' namespace
mdbmes Mar 26, 2025
c52a7f1
Fix doc comments for vector elements/iterators namespaces
mdbmes Mar 26, 2025
9737bf0
Can't rely on constexpr std::array operator[]
mdbmes Mar 26, 2025
53dc708
Move internal parts of format exports to detail namespace
mdbmes Mar 26, 2025
6b9cd01
Update vector fwd headers
mdbmes Mar 26, 2025
8b61e63
Remove extra includes
mdbmes Mar 26, 2025
799c897
Add core::open_binary for symmetry
mdbmes Mar 26, 2025
a581e0a
Fix duplicate forward declaration
mdbmes Mar 26, 2025
da06589
Add include for completeness
mdbmes Mar 26, 2025
3dfc9f1
Fix typo in test name
mdbmes Mar 26, 2025
9a670cf
Comment about accessor_data constructor assumptions
mdbmes Mar 26, 2025
4ca9431
Document types in vector::accessor
mdbmes Mar 26, 2025
007192b
Add cbegin/cend
mdbmes Mar 26, 2025
352bb73
Requested change to header order
mdbmes Mar 26, 2025
165a5b7
Replace open_binary with suggestion
mdbmes Mar 26, 2025
dccb2fd
Update src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/builder/basic/sub_…
mdbmes Mar 26, 2025
868179a
Update src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/vector/accessor-fw…
mdbmes Mar 26, 2025
b8df720
Update src/bsoncxx/lib/bsoncxx/v_noabi/bsoncxx/vector.cpp
mdbmes Mar 26, 2025
3422b2e
Update src/bsoncxx/test/vector.cpp
mdbmes Mar 26, 2025
2ef0bb2
More header order changes
mdbmes Mar 26, 2025
7ffdb17
Update src/bsoncxx/lib/bsoncxx/v_noabi/bsoncxx/vector.cpp
mdbmes Mar 26, 2025
66b2a02
Update src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/vector/accessor.hpp
mdbmes Mar 26, 2025
e809f9f
Update src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/vector/accessor.hpp
mdbmes Mar 26, 2025
b567118
Revert "Update src/bsoncxx/test/vector.cpp"
mdbmes Mar 26, 2025
d170e9e
Shorten doc comments
mdbmes Mar 26, 2025
9218f97
Disable gcc -Wfloat-equal warnings for comparisons in bsoncxx::vector…
mdbmes Mar 27, 2025
42250ea
Update src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/vector/formats-fwd…
mdbmes Mar 27, 2025
3f61ef4
Hide detail from accessor type declarations
mdbmes Mar 27, 2025
bd78a37
vector example: shorter output, more comments
mdbmes Mar 27, 2025
ebf3ec1
Update src/bsoncxx/test/vector.cpp
mdbmes Mar 27, 2025
c147b88
Prefer CHECK_THROWS_WITH_CODE
mdbmes Mar 27, 2025
5067724
Clarify comment
mdbmes Mar 27, 2025
5b7c991
Unclutter the vector example some more
mdbmes Mar 27, 2025
87849b3
Update src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/types.hpp
mdbmes Mar 27, 2025
bb61396
Update src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/vector/elements.hpp
mdbmes Mar 27, 2025
3747aae
Update src/bsoncxx/lib/bsoncxx/v_noabi/bsoncxx/vector.cpp
mdbmes Mar 27, 2025
107b192
Update src/bsoncxx/lib/bsoncxx/v_noabi/bsoncxx/vector.cpp
mdbmes Mar 27, 2025
f8ad45d
Update src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/vector/detail.hpp
mdbmes Mar 27, 2025
73737dd
Update src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/vector/elements.hpp
mdbmes Mar 27, 2025
14019ab
Add accessor::as_const
mdbmes Mar 27, 2025
cfee0fb
Prefer {} initializers
mdbmes Mar 28, 2025
e66887d
Add test for swap()
mdbmes Apr 1, 2025
9872b74
Portability: replace arithmetic right shift with signed division
mdbmes Apr 1, 2025
4b87eb0
Clarify test name
mdbmes Apr 1, 2025
77205e5
Merge branch 'master' into CXX-3077
mdbmes Apr 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
# Only LIBMONGOC_DOWNLOAD_VERSION needs to be updated when pinning to an unreleased commit.
# If pinning to an unreleased commit, create a "Blocked" JIRA ticket with
# a "depends on" link to the appropriate C Driver version release ticket.
MONGOC_VERSION_MINIMUM = '57bffac11fde38d1ce097bb22fb5322a6114d644' # CXX-3103: bump to 2.0.0 once released.
MONGOC_VERSION_MINIMUM = '0b3bb26c586c8a341710b853183abe5946693931' # CXX-3103: bump to 2.0.0 once released.


class InstallCDriver(Function):
Expand Down
2 changes: 1 addition & 1 deletion .evergreen/generated_configs/functions.yml
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ functions:
type: setup
params:
updates:
- { key: mongoc_version_minimum, value: 57bffac11fde38d1ce097bb22fb5322a6114d644 }
- { key: mongoc_version_minimum, value: 0b3bb26c586c8a341710b853183abe5946693931 }
- command: subprocess.exec
type: setup
params:
Expand Down
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,12 @@ else()
endif()

# Also update etc/purls.txt.
set(LIBBSON_REQUIRED_VERSION 1.30.0)
set(LIBBSON_REQUIRED_VERSION 1.31.0)
set(LIBBSON_REQUIRED_ABI_VERSION 1.0)

# Also update etc/purls.txt.
set(LIBMONGOC_REQUIRED_VERSION 1.30.0)
set(LIBMONGOC_DOWNLOAD_VERSION 57bffac11fde38d1ce097bb22fb5322a6114d644)
set(LIBMONGOC_REQUIRED_VERSION 1.31.0)
set(LIBMONGOC_DOWNLOAD_VERSION 0b3bb26c586c8a341710b853183abe5946693931)
set(LIBMONGOC_REQUIRED_ABI_VERSION 1.0)

set(NEED_DOWNLOAD_C_DRIVER false)
Expand Down
142 changes: 142 additions & 0 deletions examples/bsoncxx/bson_binary_vector.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// Copyright 2009-present MongoDB, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <limits>

#include <bsoncxx/builder/basic/document.hpp>
#include <bsoncxx/builder/basic/kvp.hpp>
#include <bsoncxx/builder/basic/sub_binary.hpp>
#include <bsoncxx/json.hpp>
#include <bsoncxx/types.hpp>
#include <bsoncxx/vector/formats.hpp>
#include <bsoncxx/vector/view.hpp>

#include <examples/macros.hh>

int EXAMPLES_CDECL main() {
using bsoncxx::builder::basic::kvp;
using bsoncxx::builder::basic::make_document;
using bsoncxx::builder::basic::sub_binary;

bsoncxx::document::value doc = make_document(
kvp("binary",
[&](sub_binary sbin) {
uint32_t len = 1000;
uint8_t* vec = sbin.allocate(bsoncxx::binary_sub_type::k_binary, len);
memset(vec, 0x55, len);
}),
kvp("vector_int8",
[&](sub_binary sbin) {
auto view = sbin.allocate(bsoncxx::vector::formats::f_int8{}, 1000);
uint8_t i = 0;
std::generate(view.begin(), view.end(), [&] { return (int8_t)++i; });
}),
kvp("vector_float32",
[&](sub_binary sbin) {
auto view = sbin.allocate(bsoncxx::vector::formats::f_float32{}, 1000);
view[0] = 0.f;
view[1] = 1e-38f;
for (size_t i = 2; i < view.size(); i++) {
view[i] = view[i - 1] + view[i - 2];
}
for (auto i = view.begin(); i != view.end(); i++) {
if (!(*i * 0.f < *i)) {
*i = float(std::sin(double(i - view.begin()) * 1e-3));
}
}
std::fill(view.end() - 10, view.end() - 7, std::numeric_limits<float>::infinity());
view[0] += 1.f;
view[1] *= 1e38f;
view[1] /= 2.f;
view[1] -= 1.f + view[0];
}),
kvp("vector_packed_bit", [&](sub_binary sbin) {
auto view = sbin.allocate(bsoncxx::vector::formats::f_packed_bit{}, 61);
std::fill(view.begin(), view.end(), true);
view[5] = !view[5];
view[6] = view[1];
view[7] = view[5];
view[8] = 0;
view[60] = false;
std::fill(view.end() - 20, view.end() - 4, false);
std::fill(view.end() - 8, view.end() - 5, true);
for (auto i = view.byte_begin(); i != view.byte_end(); i++) {
*i ^= 0xFF;
}
std::copy(view.byte_begin(), view.byte_begin() + 2, view.byte_begin() + 2);
std::copy(view.begin() + 5, view.begin() + 9, view.begin() + 56);
}));

std::cout << bsoncxx::to_json(doc) << std::endl;

{
bsoncxx::vector::view<bsoncxx::vector::formats::f_int8 const> v(doc["vector_int8"].get_binary());
std::cout << "int8: " << v.size() << std::endl;
for (auto i = v.begin(); i != v.end(); i++) {
std::cout << int(*i) << " ";
}
std::cout << std::endl;
}

{
bsoncxx::vector::view<bsoncxx::vector::formats::f_int8 const> v(doc["vector_int8"].get_binary());
std::cout << "int8 bytes: " << v.byte_size() << std::hex << std::endl;
for (auto i = v.byte_begin(); i != v.byte_end(); i++) {
std::cout << int(*i) << " ";
}
std::cout << std::dec << std::endl;
}

{
bsoncxx::vector::view<bsoncxx::vector::formats::f_float32 const> v(doc["vector_float32"].get_binary());
std::cout << "float32: " << v.size() << std::endl;
for (auto i = v.begin(); i != v.end(); i++) {
std::cout << *i << " ";
}
std::cout << std::endl;
}

{
bsoncxx::vector::view<bsoncxx::vector::formats::f_float32 const> v(doc["vector_float32"].get_binary());
std::cout << "float32 bytes: " << v.byte_size() << std::hex << std::endl;
for (auto i = v.byte_begin(); i != v.byte_end(); i++) {
std::cout << int(*i) << " ";
}
std::cout << std::dec << std::endl;
}

{
bsoncxx::vector::view<bsoncxx::vector::formats::f_packed_bit const> v(doc["vector_packed_bit"].get_binary());
std::cout << "packed_bit: " << v.size() << std::endl;
for (auto i = v.begin(); i != v.end(); i++) {
std::cout << *i << " ";
}
std::cout << std::endl;
}

{
bsoncxx::vector::view<bsoncxx::vector::formats::f_packed_bit const> v(doc["vector_packed_bit"].get_binary());
std::cout << "packed_bit bytes: " << v.byte_size() << std::hex << std::endl;
for (auto i = v.byte_begin(); i != v.byte_end(); i++) {
std::cout << int(*i) << " ";
}
std::cout << std::dec << std::endl;
}

return 0;
}
10 changes: 10 additions & 0 deletions src/bsoncxx/include/bsoncxx/docs/top.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,13 @@
/// @namespace bsoncxx::types::bson_value
/// Declares entities representing any BSON value type.
///

///
/// @namespace bsoncxx::vector
/// Declarations related to BSON Binary Vector (@ref bsoncxx::v_noabi::binary_sub_type::k_vector) items.
///

///
/// @namespace bsoncxx::vector::formats
/// Each type here is a supported format for bsoncxx::vector
///
20 changes: 20 additions & 0 deletions src/bsoncxx/include/bsoncxx/docs/v_noabi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,23 @@
/// @namespace bsoncxx::v_noabi::types::bson_value
/// Declares entities representing any BSON value type.
///

///
/// @namespace bsoncxx::v_noabi::vector
/// Declarations related to BSON Binary Vector (@ref bsoncxx::v_noabi::binary_sub_type::k_vector) items.
///

///
/// @namespace bsoncxx::v_noabi::vector::iterators
/// Special-purpose iterator types for bsoncxx::vector
///

///
/// @namespace bsoncxx::v_noabi::vector::elements
/// Special-purpose element reference types for bsoncxx::vector
///

///
/// @namespace bsoncxx::v_noabi::vector::formats
/// Each type here is a supported format for bsoncxx::vector
///
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#pragma once

#include <bsoncxx/builder/basic/sub_array.hpp>
#include <bsoncxx/builder/basic/sub_binary.hpp>
#include <bsoncxx/builder/basic/sub_document.hpp>
#include <bsoncxx/stdx/type_traits.hpp>

Expand All @@ -40,10 +41,19 @@ detail::requires_t<void, detail::is_invocable<T, sub_array>> generic_append(core
core->close_array();
}

template <typename T>
detail::requires_t<void, detail::is_invocable<T, sub_binary>> generic_append(core* core, T&& func) {
detail::invoke(std::forward<T>(func), sub_binary(core));
core->close_binary();
}

template <typename T, typename = void, typename = void>
detail::requires_not_t<void, detail::is_invocable<T, sub_document>, detail::is_invocable<T, sub_array>> generic_append(
core* core,
T&& t) {
detail::requires_not_t<
void,
detail::is_invocable<T, sub_document>,
detail::is_invocable<T, sub_array>,
detail::is_invocable<T, sub_binary>>
generic_append(core* core, T&& t) {
core->append(std::forward<T>(t));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// Copyright 2009-present MongoDB, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

namespace bsoncxx {
namespace v_noabi {
namespace builder {
namespace basic {

class sub_binary;

} // namespace basic
} // namespace builder
} // namespace v_noabi
} // namespace bsoncxx

namespace bsoncxx {
namespace builder {
namespace basic {

using ::bsoncxx::v_noabi::builder::basic::sub_binary;

} // namespace basic
} // namespace builder
} // namespace bsoncxx

///
/// @file
/// Declares @ref bsoncxx::builder::basic::sub_binary, for constructing BSON Binary values in-place.
///
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Copyright 2009-present MongoDB, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#pragma once

#include <cstdint>

#include <bsoncxx/builder/basic/sub_binary-fwd.hpp>

#include <bsoncxx/builder/core.hpp>
#include <bsoncxx/types.hpp>
#include <bsoncxx/vector/formats.hpp>
#include <bsoncxx/vector/impl.hpp>
#include <bsoncxx/vector/view.hpp>

#include <bsoncxx/config/prelude.hpp>

namespace bsoncxx {
namespace v_noabi {
namespace builder {
namespace basic {

///
/// Represents a BSON Binary element being constructed during an append operation.
///
class sub_binary {
public:
///
/// Default constructor
///
sub_binary(core* core) : _core(core) {}

/// @brief Allocate space for an un-initialized BSON Binary element of any subtype.
/// @param sub_type BSON binary subtype code, identifying the format of the data within.
/// @param length Number of bytes to allocate
/// @return Pointer to uninitialized memory within the bson_t, valid only during this sub_binary builder's lifetime.
/// The caller must overwrite every byte if the resulting BSON document is to be used.
/// @throws bsoncxx::v_noabi::exception if this sub_binary has already allocated.
/// bsoncxx::v_noabi::exception if the binary fails to append due to the BSON size limit.
std::uint8_t* allocate(binary_sub_type sub_type, std::uint32_t length) {
return _core->append(sub_type, length);
}

/// @brief Allocate and format space for a BSON Binary Vector with uninitialized elements.
/// @param fmt Instance of a format type from @ref bsoncxx::v_noabi::vector::formats
/// @param element_count Number of elements to allocate space for.
/// @return A vector::view, valid during the lifetime of this sub_binary builder. Every element must be overwritten
/// before that element is read or the resulting document is used.
/// @throws bsoncxx::v_noabi::exception if this sub_binary has already allocated.
/// bsoncxx::v_noabi::exception if the binary fails to append due to the BSON size limit.
/// bsoncxx::v_noabi::exception if a vector of the requested size would be too large to represent.
template <typename Format, typename SFINAE = typename vector::impl::format_traits<Format>::value_type>
vector::view<Format> allocate(Format, std::size_t element_count) {
using format_traits = typename vector::impl::format_traits<Format>;
std::uint32_t binary_data_length = format_traits::length_for_append(element_count);
std::uint8_t* binary_data = allocate(binary_sub_type::k_vector, binary_data_length);
return {
{binary_data,
binary_data_length,
format_traits::write_frame(binary_data, binary_data_length, element_count)}};
}

private:
core* _core;
};

} // namespace basic
} // namespace builder
} // namespace v_noabi
} // namespace bsoncxx

#include <bsoncxx/config/postlude.hpp>

///
/// @file
/// Declares @ref bsoncxx::v_noabi::builder::basic::sub_binary, for constructing BSON Binary values in-place.
///
Loading