Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
7 changes: 7 additions & 0 deletions src/bsoncxx/include/bsoncxx/v1/oid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,13 @@ class oid {
friend std::error_code make_error_code(errc v) {
return {static_cast<int>(v), error_category()};
}

class internal;

private:
struct uninit_type {};

oid(uninit_type) : _bytes{} {} // Required by bsoncxx::v_noabi::oid::oid().
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: rename to zeroinit_type? This value-initiailizes the _bytes to all zeroes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The zero-initialization is meant to be an implementation detail that avoids language-level undefined behavior (in the spirit of -ftrivial-auto-var-init=zero and to avoid triggering static analysis warnings for uninitialized data members), but it's still meant to be library-level undefined behavior to access _bytes after initializing with uninit_type, since the elements are expected to be unconditionally overwritten by v_noabi::oid::oid() anyways. I expect/hope the compiler should be able to see this unconditional write-without-read and optimize accordingly (ignoring exception paths):

v_noabi::oid::oid()
  // Zeroed bytes are never read after this initialization.
  : _oid{v1::oid::internal::make_oid_without_init()}
{
  // Unconditionally overwritten.
  _oid = v1::oid{};
}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On second thought, to avoid the "uninit" confusion, adopted the *_for_overwrite suffix from std::make_unique_for_overwrite, which hopefully makes the intention much clearer.

};

} // namespace v1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#pragma once

#include <bsoncxx/v1/element/view-fwd.hpp>

#include <bsoncxx/config/prelude.hpp>

namespace bsoncxx {
Expand All @@ -29,7 +31,7 @@ class element;
namespace bsoncxx {
namespace array {

using ::bsoncxx::v_noabi::array::element;
using v_noabi::array::element;

} // namespace array
} // namespace bsoncxx
Expand All @@ -40,3 +42,6 @@ using ::bsoncxx::v_noabi::array::element;
/// @file
/// Declares @ref bsoncxx::v_noabi::array::element.
///
/// @par Includes
/// - @ref bsoncxx/v1/element/view-fwd.hpp
///
124 changes: 74 additions & 50 deletions src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/array/element.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@

#pragma once

#include <bsoncxx/array/element-fwd.hpp>

//

#include <bsoncxx/v1/element/view.hpp>

#include <cstddef>
#include <cstdint>

#include <bsoncxx/array/element-fwd.hpp>
#include <bsoncxx/array/view-fwd.hpp>
#include <bsoncxx/types/bson_value/view-fwd.hpp>

Expand All @@ -36,50 +41,41 @@ namespace array {
/// interrogated by calling type() and a specific value can be extracted through
/// get_X() accessors.
///
class element : private document::element {
class element : private v_noabi::document::element {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For backward compatibility, the existing structure where "v_noabi::array::* is defined in terms of v_noabi::document::*" is preserved as-is.

As far as I can tell, CXX-1830 can be resolved per its current description: there is no difference between the API for v_noabi::array::element and v_noabi::document::element (all public member functions are using-declared) and v1 removes the distinction completely with v1::element::view. Instead, CXX-1830 is repurposed to also track v_noabi::array::* API consistency as a whole with v_noabi::document::*.

public:
BSONCXX_ABI_EXPORT_CDECL() element();

using document::element::operator bool;

using document::element::type;

using document::element::get_array;
using document::element::get_binary;
using document::element::get_bool;
using document::element::get_code;
using document::element::get_codewscope;
using document::element::get_date;
using document::element::get_dbpointer;
using document::element::get_decimal128;
using document::element::get_document;
using document::element::get_double;
using document::element::get_int32;
using document::element::get_int64;
using document::element::get_maxkey;
using document::element::get_minkey;
using document::element::get_null;
using document::element::get_oid;
using document::element::get_regex;
using document::element::get_string;
using document::element::get_symbol;
using document::element::get_timestamp;
using document::element::get_undefined;

using document::element::get_value;

using document::element::operator[];

using document::element::key;
using document::element::keylen;
using document::element::length;
using document::element::offset;
using document::element::raw;

private:
friend ::bsoncxx::v_noabi::array::view;

explicit element(std::uint8_t const* raw, std::uint32_t length, std::uint32_t offset, std::uint32_t keylen);
element() : v_noabi::document::element() {}

/* explicit(false) */ element(v1::element::view const& v) : v_noabi::document::element{v} {}

using v_noabi::document::element::operator v1::element::view;

using v_noabi::document::element::operator bool;

using v_noabi::document::element::raw;

using v_noabi::document::element::length;

using v_noabi::document::element::offset;

using v_noabi::document::element::keylen;

using v_noabi::document::element::type;

using v_noabi::document::element::key;

#pragma push_macro("X")
#undef X
#define X(_name, _value) using v_noabi::document::element::get_##_name;
BSONCXX_V1_TYPES_XMACRO(X)
#pragma pop_macro("X")

using v_noabi::document::element::get_value;

using v_noabi::document::element::get_owning_value;

using v_noabi::document::element::operator[];

friend bool operator==(element const& lhs, v_noabi::types::bson_value::view const& rhs);
};

///
Expand All @@ -90,16 +86,24 @@ class element : private document::element {
/// @{

/// @relatesalso bsoncxx::v_noabi::array::element
BSONCXX_ABI_EXPORT_CDECL(bool) operator==(element const& elem, types::bson_value::view const& v);
inline bool operator==(element const& lhs, v_noabi::types::bson_value::view const& rhs) {
return static_cast<v_noabi::document::element const&>(lhs) == rhs;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Take advantage of (private) inheritance to defer implementation to v_noabi::document::element.

}

/// @relatesalso bsoncxx::v_noabi::array::element
BSONCXX_ABI_EXPORT_CDECL(bool) operator==(types::bson_value::view const& v, element const& elem);
inline bool operator==(v_noabi::types::bson_value::view const& lhs, element const& rhs) {
return rhs == lhs;
}

/// @relatesalso bsoncxx::v_noabi::array::element
BSONCXX_ABI_EXPORT_CDECL(bool) operator!=(element const& elem, types::bson_value::view const& v);
inline bool operator!=(element const& lhs, v_noabi::types::bson_value::view const& rhs) {
return !(lhs == rhs);
}

/// @relatesalso bsoncxx::v_noabi::array::element
BSONCXX_ABI_EXPORT_CDECL(bool) operator!=(types::bson_value::view const& v, element const& elem);
inline bool operator!=(v_noabi::types::bson_value::view const& lhs, element const& rhs) {
return !(lhs == rhs);
}

/// @}
///
Expand All @@ -108,11 +112,27 @@ BSONCXX_ABI_EXPORT_CDECL(bool) operator!=(types::bson_value::view const& v, elem
} // namespace v_noabi
} // namespace bsoncxx

namespace bsoncxx {
namespace v_noabi {

// Ambiguous whether `v1::element::view` should be converted to `v1::array::element` or `v1::document::element.`
// v_noabi::array::element from_v1(v1::element::view const& v);

///
/// Convert to the @ref bsoncxx::v1 equivalent of `v`.
///
inline v1::element::view to_v1(v_noabi::array::element const& v) {
return v1::element::view{v};
}

} // namespace v_noabi
} // namespace bsoncxx

namespace bsoncxx {
namespace array {

using ::bsoncxx::v_noabi::array::operator==;
using ::bsoncxx::v_noabi::array::operator!=;
using v_noabi::array::operator==;
using v_noabi::array::operator!=;

} // namespace array
} // namespace bsoncxx
Expand All @@ -123,3 +143,7 @@ using ::bsoncxx::v_noabi::array::operator!=;
/// @file
/// Provides @ref bsoncxx::v_noabi::array::element.
///
/// @par Includes
/// - @ref bsoncxx/document/element.hpp
/// - @ref bsoncxx/v1/element/view.hpp
///
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#pragma once

#include <bsoncxx/v1/array/value-fwd.hpp>

#include <bsoncxx/config/prelude.hpp>

namespace bsoncxx {
Expand All @@ -29,7 +31,7 @@ class value;
namespace bsoncxx {
namespace array {

using ::bsoncxx::v_noabi::array::value;
using v_noabi::array::value;

} // namespace array
} // namespace bsoncxx
Expand All @@ -40,3 +42,6 @@ using ::bsoncxx::v_noabi::array::value;
/// @file
/// Declares @ref bsoncxx::v_noabi::array::value.
///
/// @par Includes
/// - @ref bsoncxx/v1/array/value-fwd.hpp
///
Loading