Skip to content

Commit f5e1d02

Browse files
Some additional traits: decay_copy and rank<>
1 parent 71f0e61 commit f5e1d02

File tree

2 files changed

+46
-0
lines changed

2 files changed

+46
-0
lines changed

src/bsoncxx/include/bsoncxx/v_noabi/bsoncxx/stdx/type_traits.hpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ DECL_ALIAS(remove_reference);
3434
DECL_ALIAS(remove_const);
3535
DECL_ALIAS(remove_volatile);
3636
DECL_ALIAS(remove_cv);
37+
DECL_ALIAS(add_pointer);
3738
DECL_ALIAS(add_const);
3839
DECL_ALIAS(add_volatile);
3940
DECL_ALIAS(add_lvalue_reference);
@@ -412,6 +413,34 @@ struct is_invocable : is_detected<invoke_result_t, Fun, Args...> {
412413
template <typename T, typename U>
413414
struct is_alike : std::is_same<remove_cvref_t<T>, remove_cvref_t<U>> {};
414415

416+
/**
417+
* @brief Tag type for creating ranked overloads to force disambiguation.
418+
*
419+
* @tparam N The ranking of the overload. A higher value is ranked greater than
420+
* lower values.
421+
*/
422+
template <std::size_t N>
423+
struct rank : rank<N - 1> {};
424+
425+
template <>
426+
struct rank<0> {};
427+
428+
struct _decay_copy_fn {
429+
template <typename T>
430+
constexpr auto operator()(T&& arg) const
431+
noexcept(std::is_nothrow_constructible<decay_t<T>, T&&>{})
432+
-> requires_t<decay_t<T>, std::is_constructible<decay_t<T>, T&&>> {
433+
return static_cast<decay_t<T>>(static_cast<T&&>(arg));
434+
}
435+
};
436+
437+
/**
438+
* @brief Perform a decay-copy on the given value.
439+
*
440+
* Equivalent to the C++23 `auto()` expression.
441+
*/
442+
static constexpr _decay_copy_fn decay_copy;
443+
415444
} // namespace detail
416445

417446
} // namespace v_noabi

src/bsoncxx/test/type_traits.test.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,4 +179,21 @@ static_assert(
179179
value,
180180
"fail");
181181

182+
struct rank_test {
183+
template <typename T>
184+
constexpr int val(T x, bsoncxx::detail::rank<0>) const {
185+
return x.never_instantiated();
186+
}
187+
template <typename T>
188+
constexpr int val(T x, bsoncxx::detail::rank<1>) const {
189+
return x + 30;
190+
}
191+
template <typename T>
192+
constexpr int operator()(T v) const {
193+
return this->val(v, bsoncxx::detail::rank<20>{});
194+
}
195+
};
196+
197+
static_assert(rank_test{}(12) == 42, "fail");
198+
182199
} // namespace

0 commit comments

Comments
 (0)