mimic++ v5
Loading...
Searching...
No Matches
Utility.hpp
Go to the documentation of this file.
1// // Copyright Dominic (DNKpp) Koepke 2024 - 2024.
2// // Distributed under the Boost Software License, Version 1.0.
3// // (See accompanying file LICENSE_1_0.txt or copy at
4// // https://www.boost.org/LICENSE_1_0.txt)
5
6#ifndef MIMICPP_UTILITY_HPP
7#define MIMICPP_UTILITY_HPP
8
9#pragma once
10
11#include "mimic++/Fwd.hpp"
12
13#include <cassert>
14#include <source_location>
15#include <string_view>
16#include <utility>
17
18namespace mimicpp
19{
20 template <typename...>
22 : public std::bool_constant<false>
23 {
24 };
25
26 template <std::size_t priority>
29 : public priority_tag<priority - 1>
31 {
32 };
33
34 template <>
35 struct priority_tag<0>
36 {
37 };
38
39 [[nodiscard]]
41 const std::source_location& lhs,
42 const std::source_location& rhs) noexcept
43 {
44 return std::string_view{lhs.file_name()} == std::string_view{rhs.file_name()}
45 && std::string_view{lhs.function_name()} == std::string_view{rhs.function_name()}
46 && lhs.line() == rhs.line()
47 && lhs.column() == rhs.column();
48 }
49
50 template <typename From, typename To>
52 requires {
53 static_cast<To>(std::declval<From>());
54 };
55
56 template <typename From, typename To>
59 && requires {
60 { static_cast<To>(std::declval<From>()) } noexcept;
61 };
62
63 template <typename T, typename... Others>
64 concept same_as_any = (... || std::same_as<T, Others>);
65
66 template <typename T>
67 requires std::is_enum_v<T>
68 [[nodiscard]]
69 constexpr std::underlying_type_t<T> to_underlying(const T value) noexcept
70 {
71 return static_cast<std::underlying_type_t<T>>(value);
72 }
73
74 template <typename T, template <typename> typename Trait>
75 concept satisfies = Trait<T>::value;
76
77 // GCOVR_EXCL_START
78
79#ifdef __cpp_lib_unreachable
80 using std::unreachable;
81#else
82
88 [[noreturn]]
89 inline void unreachable()
90 {
91 assert(false);
92
93 // Uses compiler specific extensions if possible.
94 // Even if no extension is used, undefined behavior is still raised by
95 // an empty function body and the noreturn attribute.
96 #if defined(_MSC_VER) && !defined(__clang__) // MSVC
97 __assume(false);
98 #else // GCC, Clang
99 __builtin_unreachable();
100 #endif
101 }
102#endif
103
104 // GCOVR_EXCL_STOP
105
106 [[nodiscard]]
107 constexpr bool is_matching(const Constness lhs, const Constness rhs) noexcept
108 {
109 return std::cmp_not_equal(0, to_underlying(lhs) & to_underlying(rhs));
110 }
111
112 [[nodiscard]]
113 constexpr bool is_matching(const ValueCategory lhs, const ValueCategory rhs) noexcept
114 {
115 return std::cmp_not_equal(0, to_underlying(lhs) & to_underlying(rhs));
116 }
117}
118
119namespace mimicpp::detail
120{
121 template <typename Parsed, typename... Rest>
122 struct unique;
123
124 template <typename... Uniques, typename First, typename... Others>
125 struct unique<
126 type_list<Uniques...>,
127 First,
128 Others...>
129 {
130 using current_t = std::conditional_t<
131 same_as_any<First, Uniques...>,
132 type_list<Uniques...>,
133 type_list<Uniques..., First>>;
134
135 using type_t = typename unique<
136 current_t,
137 Others...>::type_t;
138 };
139
140 template <typename... Uniques>
141 struct unique<type_list<Uniques...>>
142 {
143 using type_t = type_list<Uniques...>;
144 };
145
146 template <typename... Types>
147 using unique_list_t = typename unique<type_list<>, Types...>::type_t;
148}
149
150#endif
Definition Utility.hpp:51
Definition Utility.hpp:64
Definition Utility.hpp:75
Definition BoostTest.hpp:20
void unreachable()
Invokes undefined behavior.
Definition Utility.hpp:89
constexpr bool is_same_source_location(const std::source_location &lhs, const std::source_location &rhs) noexcept
Definition Utility.hpp:40
ValueCategory
Definition Fwd.hpp:30
constexpr bool is_matching(const Constness lhs, const Constness rhs) noexcept
Definition Utility.hpp:107
Constness
Definition Fwd.hpp:23
constexpr std::underlying_type_t< T > to_underlying(const T value) noexcept
Definition Utility.hpp:69
Definition Utility.hpp:23
Definition Utility.hpp:31