Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
29 changes: 14 additions & 15 deletions src/bsoncxx/include/bsoncxx/v1/detail/compare.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,23 +93,22 @@ class strong_ordering {
#pragma pop_macro("DEFOP")

// nonstd: Swap greater/less values
constexpr strong_ordering inverted() const noexcept {
return *this < nullptr ? greater : *this > nullptr ? less : *this;
}
constexpr strong_ordering inverted() const noexcept;
};

#pragma push_macro("INLINE_VAR")
#undef INLINE_VAR
#define INLINE_VAR \
BSONCXX_PRIVATE_IF_GNU_LIKE([[gnu::weak]]) \
BSONCXX_PRIVATE_IF_MSVC(__declspec(selectany))

INLINE_VAR const strong_ordering strong_ordering::less = strong_ordering(strong_ordering::_construct{}, -1);
INLINE_VAR const strong_ordering strong_ordering::greater = strong_ordering(strong_ordering::_construct{}, 1);
INLINE_VAR const strong_ordering strong_ordering::equivalent = strong_ordering(strong_ordering::_construct{}, 0);
INLINE_VAR const strong_ordering strong_ordering::equal = strong_ordering(strong_ordering::_construct{}, 0);

#pragma pop_macro("INLINE_VAR")
BSONCXX_PRIVATE_INLINE_CXX17 strong_ordering const strong_ordering::less =
strong_ordering(strong_ordering::_construct{}, -1);
BSONCXX_PRIVATE_INLINE_CXX17 strong_ordering const strong_ordering::greater =
strong_ordering(strong_ordering::_construct{}, 1);
BSONCXX_PRIVATE_INLINE_CXX17 strong_ordering const strong_ordering::equivalent =
strong_ordering(strong_ordering::_construct{}, 0);
BSONCXX_PRIVATE_INLINE_CXX17 strong_ordering const strong_ordering::equal =
strong_ordering(strong_ordering::_construct{}, 0);

// Define out-of-line to avoid GCC error: ‘bsoncxx::detail::strong_ordering::*’ declared weak after being used
inline constexpr strong_ordering strong_ordering::inverted() const noexcept {
return *this < nullptr ? greater : *this > nullptr ? less : *this;
}

// Implements a three-way comparison between two objects. That is, in
// a single operation, determine whether the left operand is less-than, greater-than,
Expand Down
25 changes: 25 additions & 0 deletions src/bsoncxx/include/bsoncxx/v1/detail/macros.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,31 @@
#endif
// clang-format on

// Use this on variables that can only be inline in C++17 or newer, such as static constexpr data members.
//
// GCC does not allow __inline__ (even with __extension__) given -std=c++11 and -pedantic-errors (unconditional
// compilation error until GCC 12 which added -Wc++17-extensions suppression), but supports [[gnu::weak]] even with
// constant-evaluation and constant-folding on all currently-supported GCC versions (GCC 4.8.x and newer).
//
// Clang: does not allow using [[gnu::weak]] with constexpr, but supports __inline__ as a language extension even with
// -std=c++11 and -pedantic-errors via diagnostic suppression on all currently-supported Clang versions
// (-Wc++1z-extensions suppression since Clang 3.9 and -Wc++17-extensions suppression since Clang 5.0).
//
// MSVC: supports inline variables since 19.12 (with /std:c++latest), but behavior is broken for static data members
// (multiple definitions) until 19.20 even when __cpp_inline_variables is defined.
#if ( \
!defined(_MSC_VER) && \
(__cplusplus >= 201703L || (defined(__cpp_inline_variables) && __cpp_inline_variables >= 201606L))) || \
(defined(_MSC_VER) && _MSC_VER >= 1920 && defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
#define BSONCXX_PRIVATE_INLINE_CXX17 inline
#else
#define BSONCXX_PRIVATE_INLINE_CXX17 \
BSONCXX_PRIVATE_IF_GCC([[gnu::weak]]) \
Copy link
Collaborator

Choose a reason for hiding this comment

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

I expect this needs to be moved below where BSONCXX_PRIVATE_IF_GCC (and others) are defined below.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is not necessary due to BSONCXX_PRIVATE_IF_GCC(...) only being evaluated/substituted when BSONCXX_PRIVATE_INLINE_CXX17 is evaluated/substituted. So long as both macro definitions are visible at the point of substitution, the order does not matter. Nevertheless, moved them below as suggested to better match a typical declaration-dependent order.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Doh right. Thank you for the example.

BSONCXX_PRIVATE_IF_CLANG(_Pragma("clang diagnostic push") _Pragma( \
"clang diagnostic ignored \"-Wc++17-extensions\"") __inline__ _Pragma("clang diagnostic pop")) \
BSONCXX_PRIVATE_IF_MSVC(__declspec(selectany))
#endif

// Disable a warning for a particular compiler.
//
// The argument should be of the form:
Expand Down
1 change: 1 addition & 0 deletions src/bsoncxx/include/bsoncxx/v1/detail/postlude.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
#pragma pop_macro("BSONCXX_PRIVATE_IF_GCC")
#pragma pop_macro("BSONCXX_PRIVATE_IF_GNU_LIKE")
#pragma pop_macro("BSONCXX_PRIVATE_IF_MSVC")
#pragma pop_macro("BSONCXX_PRIVATE_INLINE_CXX17")
#pragma pop_macro("BSONCXX_PRIVATE_PRAGMA_IMPL")
#pragma pop_macro("BSONCXX_PRIVATE_PRAGMA")
#pragma pop_macro("BSONCXX_PRIVATE_RETURNS")
Expand Down
2 changes: 2 additions & 0 deletions src/bsoncxx/include/bsoncxx/v1/detail/prelude.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@
#undef BSONCXX_PRIVATE_IF_GNU_LIKE
#pragma push_macro("BSONCXX_PRIVATE_IF_MSVC")
#undef BSONCXX_PRIVATE_IF_MSVC
#pragma push_macro("BSONCXX_PRIVATE_INLINE_CXX17")
#undef BSONCXX_PRIVATE_INLINE_CXX17
#pragma push_macro("BSONCXX_PRIVATE_PRAGMA")
#undef BSONCXX_PRIVATE_PRAGMA
#pragma push_macro("BSONCXX_PRIVATE_PRAGMA_IMPL")
Expand Down
4 changes: 3 additions & 1 deletion src/bsoncxx/include/bsoncxx/v1/oid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class oid {
///
/// The number of bytes required to represent an ObjectID.
///
static constexpr BSONCXX_ABI_EXPORT std::size_t k_oid_length = 12;
static constexpr std::size_t k_oid_length = 12;

private:
std::array<std::uint8_t, k_oid_length> _bytes;
Expand Down Expand Up @@ -198,6 +198,8 @@ class oid {
/* explicit(false) */ oid(for_overwrite_tag) : _bytes{} {}
};

BSONCXX_PRIVATE_INLINE_CXX17 constexpr std::size_t oid::k_oid_length;

} // namespace v1
} // namespace bsoncxx

Expand Down
48 changes: 27 additions & 21 deletions src/bsoncxx/include/bsoncxx/v1/types/view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ struct b_double {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_double;
static constexpr id type_id = id::k_double;

///
/// The represented value.
Expand Down Expand Up @@ -100,7 +100,7 @@ struct b_string {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_string;
static constexpr id type_id = id::k_string;

///
/// The represented value.
Expand Down Expand Up @@ -148,7 +148,7 @@ struct b_document {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_document;
static constexpr id type_id = id::k_document;

///
/// The represented value.
Expand Down Expand Up @@ -200,7 +200,7 @@ struct b_array {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_array;
static constexpr id type_id = id::k_array;

///
/// The represented value.
Expand Down Expand Up @@ -248,7 +248,7 @@ struct b_binary {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_binary;
static constexpr id type_id = id::k_binary;

///
/// The represented value's binary subtype component.
Expand Down Expand Up @@ -317,7 +317,7 @@ struct b_undefined {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_undefined;
static constexpr id type_id = id::k_undefined;

///
/// Return true.
Expand All @@ -343,7 +343,7 @@ struct b_oid {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_oid;
static constexpr id type_id = id::k_oid;

///
/// The represented value.
Expand Down Expand Up @@ -391,7 +391,7 @@ struct b_bool {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_bool;
static constexpr id type_id = id::k_bool;

///
/// The represented value.
Expand Down Expand Up @@ -439,7 +439,7 @@ struct b_date {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_date;
static constexpr id type_id = id::k_date;

///
/// The represented value (milliseconds relative to the Unix epoch).
Expand Down Expand Up @@ -498,7 +498,7 @@ struct b_null {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_null;
static constexpr id type_id = id::k_null;

///
/// Return true.
Expand All @@ -524,7 +524,7 @@ struct b_regex {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_regex;
static constexpr id type_id = id::k_regex;

///
/// The represented value's "pattern" component.
Expand Down Expand Up @@ -577,7 +577,7 @@ struct b_dbpointer {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_dbpointer;
static constexpr id type_id = id::k_dbpointer;

///
/// The represented value's "$ref" (namespace) component.
Expand Down Expand Up @@ -623,7 +623,7 @@ struct b_code {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_code;
static constexpr id type_id = id::k_code;

///
/// The represented value.
Expand Down Expand Up @@ -673,7 +673,7 @@ struct b_symbol {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_symbol;
static constexpr id type_id = id::k_symbol;

///
/// The represented value.
Expand Down Expand Up @@ -723,7 +723,7 @@ struct b_codewscope {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_codewscope;
static constexpr id type_id = id::k_codewscope;

///
/// The represented value's "$code" component.
Expand Down Expand Up @@ -769,7 +769,7 @@ struct b_int32 {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_int32;
static constexpr id type_id = id::k_int32;

///
/// The represented value.
Expand Down Expand Up @@ -817,7 +817,7 @@ struct b_timestamp {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_timestamp;
static constexpr id type_id = id::k_timestamp;

///
/// The represented value's "i" component.
Expand Down Expand Up @@ -863,7 +863,7 @@ struct b_int64 {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_int64;
static constexpr id type_id = id::k_int64;

///
/// The represented value.
Expand Down Expand Up @@ -911,7 +911,7 @@ struct b_decimal128 {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_decimal128;
static constexpr id type_id = id::k_decimal128;

///
/// The represented value.
Expand Down Expand Up @@ -959,7 +959,7 @@ struct b_maxkey {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_maxkey;
static constexpr id type_id = id::k_maxkey;

///
/// Return true.
Expand All @@ -985,7 +985,7 @@ struct b_minkey {
///
/// The type represented by this BSON type value.
///
static constexpr BSONCXX_ABI_EXPORT id type_id = id::k_minkey;
static constexpr id type_id = id::k_minkey;

///
/// Return true.
Expand All @@ -1004,6 +1004,12 @@ struct b_minkey {

// BSONCXX_V1_TYPES_XMACRO: update above.

#pragma push_macro("X")
#undef X
#define X(_name, _val) BSONCXX_PRIVATE_INLINE_CXX17 constexpr id b_##_name::type_id;
BSONCXX_V1_TYPES_XMACRO(X)
#pragma pop_macro("X")

///
/// A non-owning, read-only union of BSON type values.
///
Expand Down
4 changes: 3 additions & 1 deletion src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/oid.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class oid {
v1::oid _oid;

public:
static constexpr BSONCXX_ABI_EXPORT std::size_t k_oid_length = v1::oid::k_oid_length;
static constexpr std::size_t k_oid_length = v1::oid::k_oid_length;

///
/// Constructs an oid and initializes it to a newly generated ObjectId.
Expand Down Expand Up @@ -165,6 +165,8 @@ class oid {
friend BSONCXX_ABI_EXPORT_CDECL(int) oid_compare(oid const& lhs, oid const& rhs);
};

BSONCXX_PRIVATE_INLINE_CXX17 constexpr std::size_t oid::k_oid_length;

///
/// Convert to the @ref bsoncxx::v_noabi equivalent of `v`.
///
Expand Down
Loading