Skip to content

Commit b68fad3

Browse files
authored
CXX-2745 add immortal.hh and type_traits.hh (#1402)
1 parent efb7da5 commit b68fad3

File tree

3 files changed

+142
-0
lines changed

3 files changed

+142
-0
lines changed

src/bsoncxx/lib/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,13 @@ set_dist_list(src_bsoncxx_lib_DIST
104104
bsoncxx/private/convert.hh
105105
bsoncxx/private/export.hh
106106
bsoncxx/private/helpers.hh
107+
bsoncxx/private/immortal.hh
107108
bsoncxx/private/itoa.hh
108109
bsoncxx/private/bson.hh
109110
bsoncxx/private/make_unique.hh
110111
bsoncxx/private/stack.hh
111112
bsoncxx/private/suppress_deprecation_warnings.hh
113+
bsoncxx/private/type_traits.hh
112114
bsoncxx/private/version.hh
113115
bsoncxx/v_noabi/bsoncxx/types/bson_value/value.hh
114116
bsoncxx/v1/config/config.hpp.in
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// Copyright 2009-present MongoDB, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#pragma once
16+
17+
#include <bsoncxx/v1/detail/macros.hpp>
18+
19+
#include <new>
20+
21+
namespace bsoncxx {
22+
23+
//
24+
// Used to construct an object whose destructor is never invoked (hence, "immortal").
25+
//
26+
// This is primarily to avoid generating exit-time destructors for error category objects:
27+
//
28+
// ```cpp
29+
// std::error_category const& name() noexcept {
30+
// class type final : public std::error_category { ... };
31+
// static bsoncxx::immortal<type> const instance;
32+
// return instance.value();
33+
// }
34+
// ```
35+
//
36+
template <typename T>
37+
class immortal {
38+
private:
39+
alignas(T) unsigned char _storage[sizeof(T)];
40+
41+
public:
42+
~immortal() = default;
43+
immortal(immortal&&) = delete;
44+
immortal& operator=(immortal&&) = delete;
45+
immortal(immortal const&) = delete;
46+
immortal& operator=(immortal const&) = delete;
47+
48+
template <typename... Args>
49+
explicit immortal(Args&&... args) {
50+
new (_storage) T(BSONCXX_PRIVATE_FWD(args)...);
51+
}
52+
53+
T const& value() const {
54+
return *reinterpret_cast<T const*>(_storage);
55+
}
56+
57+
T& value() {
58+
return *reinterpret_cast<T*>(_storage);
59+
}
60+
};
61+
62+
} // namespace bsoncxx
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
// Copyright 2009-present MongoDB, Inc.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#pragma once
16+
17+
#include <bsoncxx/v1/detail/type_traits.hpp>
18+
19+
namespace bsoncxx {
20+
21+
template <typename LHS, typename RHS>
22+
using is_assignable_from_expr = decltype(std::declval<LHS>() = std::declval<RHS>());
23+
24+
// Approximates the `assignable_from` concept in C++20.
25+
template <typename LHS, typename RHS>
26+
struct is_assignable_from : detail::conjunction<
27+
std::is_lvalue_reference<LHS>,
28+
std::is_same<detail::detected_t<is_assignable_from_expr, LHS, RHS>, LHS>> {};
29+
30+
// Equivalent to `is_assignable_from` but also requires noexceptness.
31+
template <typename LHS, typename RHS>
32+
struct is_nothrow_assignable_from
33+
: detail::bool_constant<
34+
is_assignable_from<LHS, RHS>::value && noexcept(std::declval<LHS>() = std::declval<RHS>())> {};
35+
36+
// Approximates the `movable` concept in C++20.
37+
template <typename T>
38+
struct is_movable : detail::conjunction<
39+
std::is_object<T>,
40+
std::is_move_constructible<T>,
41+
is_assignable_from<T&, T>,
42+
detail::is_swappable<T>> {};
43+
44+
// Equivalent to `is_moveable` but additionally requires noexceptness.
45+
template <typename T>
46+
struct is_nothrow_moveable : detail::conjunction<
47+
std::is_object<T>,
48+
std::is_nothrow_move_constructible<T>,
49+
is_nothrow_assignable_from<T&, T>,
50+
detail::is_nothrow_swappable<T>> {};
51+
52+
// Approximates the `copyable` concept in C++20.
53+
template <typename T>
54+
struct is_copyable : detail::conjunction<
55+
std::is_copy_constructible<T>,
56+
is_movable<T>,
57+
is_assignable_from<T&, T&>,
58+
is_assignable_from<T&, T const&>,
59+
is_assignable_from<T&, T const>> {};
60+
61+
// Approximates the `semiregular` concept in C++20.
62+
template <typename T>
63+
struct is_semiregular : detail::conjunction<is_copyable<T>, std::is_default_constructible<T>> {};
64+
65+
// Approximates the `regular` concept in C++20.
66+
template <typename T>
67+
struct is_regular : detail::conjunction<is_semiregular<T>, detail::is_equality_comparable<T>> {};
68+
69+
// Equivalent to `is_trivial` without requiring trivial default constructibility.
70+
template <typename T>
71+
struct is_semitrivial : detail::conjunction<
72+
std::is_trivially_destructible<T>,
73+
std::is_trivially_move_constructible<T>,
74+
std::is_trivially_move_assignable<T>,
75+
std::is_trivially_copy_constructible<T>,
76+
std::is_trivially_copy_assignable<T>> {};
77+
78+
} // namespace bsoncxx

0 commit comments

Comments
 (0)