diff --git a/src/bsoncxx/lib/CMakeLists.txt b/src/bsoncxx/lib/CMakeLists.txt index dada934282..6d228cdbda 100644 --- a/src/bsoncxx/lib/CMakeLists.txt +++ b/src/bsoncxx/lib/CMakeLists.txt @@ -104,11 +104,13 @@ set_dist_list(src_bsoncxx_lib_DIST bsoncxx/private/convert.hh bsoncxx/private/export.hh bsoncxx/private/helpers.hh + bsoncxx/private/immortal.hh bsoncxx/private/itoa.hh bsoncxx/private/bson.hh bsoncxx/private/make_unique.hh bsoncxx/private/stack.hh bsoncxx/private/suppress_deprecation_warnings.hh + bsoncxx/private/type_traits.hh bsoncxx/private/version.hh bsoncxx/v_noabi/bsoncxx/types/bson_value/value.hh bsoncxx/v1/config/config.hpp.in diff --git a/src/bsoncxx/lib/bsoncxx/private/immortal.hh b/src/bsoncxx/lib/bsoncxx/private/immortal.hh new file mode 100644 index 0000000000..661e09c466 --- /dev/null +++ b/src/bsoncxx/lib/bsoncxx/private/immortal.hh @@ -0,0 +1,62 @@ +// 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 + +#include + +namespace bsoncxx { + +// +// Used to construct an object whose destructor is never invoked (hence, "immortal"). +// +// This is primarily to avoid generating exit-time destructors for error category objects: +// +// ```cpp +// std::error_category const& name() noexcept { +// class type final : public std::error_category { ... }; +// static bsoncxx::immortal const instance; +// return instance.value(); +// } +// ``` +// +template +class immortal { + private: + alignas(T) unsigned char _storage[sizeof(T)]; + + public: + ~immortal() = default; + immortal(immortal&&) = delete; + immortal& operator=(immortal&&) = delete; + immortal(immortal const&) = delete; + immortal& operator=(immortal const&) = delete; + + template + explicit immortal(Args&&... args) { + new (_storage) T(BSONCXX_PRIVATE_FWD(args)...); + } + + T const& value() const { + return *reinterpret_cast(_storage); + } + + T& value() { + return *reinterpret_cast(_storage); + } +}; + +} // namespace bsoncxx diff --git a/src/bsoncxx/lib/bsoncxx/private/type_traits.hh b/src/bsoncxx/lib/bsoncxx/private/type_traits.hh new file mode 100644 index 0000000000..4d993ccd21 --- /dev/null +++ b/src/bsoncxx/lib/bsoncxx/private/type_traits.hh @@ -0,0 +1,78 @@ +// 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 + +namespace bsoncxx { + +template +using is_assignable_from_expr = decltype(std::declval() = std::declval()); + +// Approximates the `assignable_from` concept in C++20. +template +struct is_assignable_from : detail::conjunction< + std::is_lvalue_reference, + std::is_same, LHS>> {}; + +// Equivalent to `is_assignable_from` but also requires noexceptness. +template +struct is_nothrow_assignable_from + : detail::bool_constant< + is_assignable_from::value && noexcept(std::declval() = std::declval())> {}; + +// Approximates the `movable` concept in C++20. +template +struct is_movable : detail::conjunction< + std::is_object, + std::is_move_constructible, + is_assignable_from, + detail::is_swappable> {}; + +// Equivalent to `is_moveable` but additionally requires noexceptness. +template +struct is_nothrow_moveable : detail::conjunction< + std::is_object, + std::is_nothrow_move_constructible, + is_nothrow_assignable_from, + detail::is_nothrow_swappable> {}; + +// Approximates the `copyable` concept in C++20. +template +struct is_copyable : detail::conjunction< + std::is_copy_constructible, + is_movable, + is_assignable_from, + is_assignable_from, + is_assignable_from> {}; + +// Approximates the `semiregular` concept in C++20. +template +struct is_semiregular : detail::conjunction, std::is_default_constructible> {}; + +// Approximates the `regular` concept in C++20. +template +struct is_regular : detail::conjunction, detail::is_equality_comparable> {}; + +// Equivalent to `is_trivial` without requiring trivial default constructibility. +template +struct is_semitrivial : detail::conjunction< + std::is_trivially_destructible, + std::is_trivially_move_constructible, + std::is_trivially_move_assignable, + std::is_trivially_copy_constructible, + std::is_trivially_copy_assignable> {}; + +} // namespace bsoncxx