kaycxx-assert
C++ assertion library
Loading...
Searching...
No Matches
assert_throw.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2026 Klaus Reimer <k@ailis.de>
2// SPDX-License-Identifier: MIT
3
4#pragma once
5
11#include <concepts>
12#include <exception>
13#include <format>
14#include <functional>
15#include <regex>
16#include <string_view>
17#include <utility>
18
20#include <kaycxx/assert/detail/source_location.hpp>
21#include <kaycxx/assert/detail/exception_type.hpp>
22#include <kaycxx/assert/detail/exception_type_name.hpp>
23#include <kaycxx/assert/detail/to_string.hpp>
24
25namespace kaycxx::assert {
26
43template <detail::exception_type Exception, std::invocable Function>
45 Function&& function,
46 std::string_view expected_message,
47 std::string_view reason = {},
48 std::optional<std::source_location> location = KAYCXX_ASSERT_DEFAULT_SOURCE
49) {
50 auto expected_type = detail::exception_type_name<Exception>();
51
52 try {
53 std::invoke(std::forward<Function>(function));
54 } catch (Exception const& exception) {
55 auto actual_message = std::string_view(exception.what());
56 if (actual_message == expected_message) {
57 return;
58 }
59
60 auto actual_string = detail::to_string(actual_message);
61 auto expected_string = detail::to_string(expected_message);
62 auto message = std::format(
63 "Expected exception message <{}> but caught <{}>",
64 expected_string,
65 actual_string
66 );
67 throw assertion_error(message, reason, std::move(actual_string), std::move(expected_string), location);
68 } catch (std::exception const& exception) {
69 auto actual_string = detail::exception_type_name(exception);
70 auto message = std::format(
71 "Expected function to throw exception of type <{}> but caught <{}>",
72 expected_type,
73 actual_string
74 );
75 throw assertion_error(message, reason, std::move(actual_string), std::move(expected_type), location);
76 } catch (...) {
77 auto message = std::format(
78 "Expected function to throw exception of type <{}> but caught <unknown exception>",
79 expected_type
80 );
81 throw assertion_error(message, reason, "unknown exception", std::move(expected_type), location);
82 }
83
84 auto expected_string = detail::to_string(expected_message);
85 auto message = std::format(
86 "Expected function to throw exception of type <{}> with message <{}>",
87 expected_type,
88 expected_string
89 );
90 throw assertion_error(message, reason, "no exception", std::move(expected_string), location);
91}
92
109template <detail::exception_type Exception, std::invocable Function>
111 Function&& function,
112 std::regex const& expected_message,
113 std::string_view reason = {},
114 std::optional<std::source_location> location = KAYCXX_ASSERT_DEFAULT_SOURCE
115) {
116 auto expected_type = detail::exception_type_name<Exception>();
117
118 try {
119 std::invoke(std::forward<Function>(function));
120 } catch (Exception const& exception) {
121 auto actual_message = std::string_view(exception.what());
122 if (std::regex_match(actual_message.begin(), actual_message.end(), expected_message)) {
123 return;
124 }
125
126 auto actual_string = detail::to_string(actual_message);
127 auto message = std::format("Expected exception message to match regex but caught <{}>", actual_string);
128 throw assertion_error(message, reason, std::move(actual_string), "regex", location);
129 } catch (std::exception const& exception) {
130 auto actual_string = detail::exception_type_name(exception);
131 auto message = std::format(
132 "Expected function to throw exception of type <{}> but caught <{}>",
133 expected_type,
134 actual_string
135 );
136 throw assertion_error(message, reason, std::move(actual_string), std::move(expected_type), location);
137 } catch (...) {
138 auto message = std::format(
139 "Expected function to throw exception of type <{}> but caught <unknown exception>",
140 expected_type
141 );
142 throw assertion_error(message, reason, "unknown exception", std::move(expected_type), location);
143 }
144
145 auto message = std::format(
146 "Expected function to throw exception of type <{}> with message matching regex",
147 expected_type
148 );
149 throw assertion_error(message, reason, "no exception", "regex", location);
150}
151
152} // namespace kaycxx::assert
Defines the assertion_error type.
Assertion functions and related types.
Definition assert.hpp:15
void assert_throw(Function &&function, std::string_view expected_message, std::string_view reason={}, std::optional< std::source_location > location=KAYCXX_ASSERT_DEFAULT_SOURCE)
Asserts that the function throws an exception of the expected type with the exact expected message.
Definition assert_throw.hpp:44