tetl 0.1.0
Embedded Template Library
Loading...
Searching...
No Matches
common_reference.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: BSL-1.0
2// SPDX-FileCopyrightText: Copyright (C) 2021 Tobias Hienzsch
3
4#ifndef TETL_TYPE_TRAITS_COMMON_REFERENCE_HPP
5#define TETL_TYPE_TRAITS_COMMON_REFERENCE_HPP
6
7#include <etl/_type_traits/add_pointer.hpp>
8#include <etl/_type_traits/basic_common_reference.hpp>
9#include <etl/_type_traits/copy_cv.hpp>
10#include <etl/_type_traits/declval.hpp>
11#include <etl/_type_traits/integral_constant.hpp>
12#include <etl/_type_traits/is_convertible.hpp>
13#include <etl/_type_traits/is_lvalue_reference.hpp>
14#include <etl/_type_traits/is_reference.hpp>
15#include <etl/_type_traits/is_same.hpp>
16#include <etl/_type_traits/remove_reference.hpp>
17
18namespace etl {
19
20namespace detail {
21
22template <typename X, typename Y>
23using cond_res = decltype(false ? etl::declval<X (&)()>()() : etl::declval<Y (&)()>()());
24
25template <typename A, typename B, typename X = remove_reference_t<A>, typename Y = remove_reference_t<B>>
26struct common_ref;
27
28template <typename A, typename B>
29using common_ref_t = typename common_ref<A, B>::type;
30
31template <typename A, typename B, typename X, typename Y>
32 requires requires { typename cond_res<copy_cv_t<X, Y>&, copy_cv_t<Y, X>&>; }
33 and is_reference_v<cond_res<copy_cv_t<X, Y>&, copy_cv_t<Y, X>&>>
34struct common_ref<A&, B&, X, Y> {
35 using type = cond_res<copy_cv_t<X, Y>&, copy_cv_t<Y, X>&>;
36};
37
38} // namespace detail
39
40/// \brief Determines the common reference type of the types T..., that is, the type to which all the
41/// types in T... can be converted or bound. If such a type exists (as determined according to the
42/// rules below), the member type names that type. Otherwise, there is no member type. The behavior is
43/// undefined if any of the types in T... is an incomplete type other than (possibly cv-qualified)
44/// void.
45template <typename... T>
46struct common_reference;
47
48template <typename... T>
49using common_reference_t = typename common_reference<T...>::type;
50
51// if sizeof...(T) is zero
52template <>
53struct common_reference<> { };
54
55// if sizeof...(T) is one
56template <typename T0>
57struct common_reference<T0> {
58 using type = T0;
59};
60
61template <typename T1, typename T2>
62 requires requires { typename etl::detail::common_ref_t<T1, T2>; }
63 and is_reference_v<T1>
64 and is_reference_v<T2>
65 and is_convertible_v<add_pointer_t<T1>, add_pointer_t<etl::detail::common_ref_t<T1, T2>>>
66 and is_convertible_v<add_pointer_t<T2>, add_pointer_t<etl::detail::common_ref_t<T1, T2>>>
67struct common_reference<T1, T2> {
68 using type = etl::detail::common_ref_t<T1, T2>;
69};
70
71} // namespace etl
72
73#endif // TETL_TYPE_TRAITS_COMMON_REFERENCE_HPP
Definition adjacent_find.hpp:9