Skip to content

CXX-2745 add immortal.hh and type_traits.hh #1402

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

eramongodb
Copy link
Collaborator

@eramongodb eramongodb commented May 13, 2025

Related to CXX-2745. Precursor changes to CXX-3232.

Adds two new internal bsoncxx components which are used by upcoming v1 interfaces.


The bsoncxx::immortal<T> class is used to define error category objects in a manner that avoids generating exit-time destructors (hence, "immortal") as can be diagnosed by the -Wexit-time-destructors Clang warning.

The pattern will look as follows:

std::error_category const& example() {
    class type final : public std::error_category { ... };

    // The error category object instance. This is never destroyed!
    static bsoncxx::immortal<type> const instance;

    return instance.value();
}

Several new type traits are introduce to ensure consistency and correctness of v1 interfaces via static assertions. These type traits are derived from patterns observed in v_noabi interfaces and are enforced by v1 interfaces in a more rigorous manner.

The new type traits are:

  • is_semitrivial<T>:
    • T is trivial to copy, move, and destroy ("like an int").
    • Trivial default constructibility is excluded (hence "semi") due to most types requiring non-trivial construction (to enforce class invariants) even when other special member functions are all trivial (invariants are entirely enforced by initialization).
  • is_semiregular<T> and is_regular<T>:
    • T has value semantics ("like an int or std::string") and is (optionally) equality-comparable.
    • is_semitrivial<T> implies is_semiregular<T>.
  • is_nothrow_moveable<T>:
    • T does not throw on destruction, move construction, or move assignment ("like a std::unique_ptr<T>").
    • This is meant to roughly approximate the requirements for is_nothrow_relocatable<T> in C++26 without misleadingly implying actual nothrow relocatability (which is complicated to accurately specify). This type trait is primarily to catch missing noexcept specifiers and highlight immovable types.
    • is_semitrivial<T> implies is_nothrow_moveable<T>.

All class types in bsoncxx and mongocxx are expected to (eventually) satisfy semiregular and nothrow moveable at a minimum to ensure consistent user-friendly behavior (e.g. bsoncxx::document::value is notably not semiregular). Some types may additionally support semitrivialty. Some types may additionally support regularity (equality comparison). If there are any circumstances where nothrow moveability is deliberately violated (potentially-throwing move operations or immovability), we should expect such instances to be highlighted with a negated static assertion ("we do something unusual here!") such as for mongocxx::v_noabi::instance (an immovable class type).

Important

Move constructors and move assignment operators which may allocate memory are still declared noexcept. std::bad_alloc exceptions are NOT accounted for by nothrow moveability, as we do not support recovering from out-of-memory situations in either the C++ or C Driver libraries.

@eramongodb eramongodb requested a review from kevinAlbs May 13, 2025 21:22
@eramongodb eramongodb self-assigned this May 13, 2025
@eramongodb eramongodb requested a review from a team as a code owner May 13, 2025 21:22
@kevinAlbs kevinAlbs requested a review from vector-of-bool May 14, 2025 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant