C++ Essence Library 0.1.0
A Utility Library for Modern C++ Programming
Loading...
Searching...
No Matches
error_extensions.hpp
1/*
2 * Copyright (c) 2024 The RefValue Project
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#pragma once
24
25#include "char8_t_remediation.hpp"
26#include "format_remediation.hpp"
27#include "source_location.hpp"
28
29#include <algorithm>
30#include <array>
31#include <concepts>
32#include <cstddef>
33#include <stdexcept>
34#include <string_view>
35#include <utility>
36
37namespace essence::detail {
38 template <std::size_t N>
39 consteval auto make_format_str() noexcept {
40 constexpr std::string_view part1{U8("[{}] ")};
41 constexpr std::string_view part2{U8("{}")};
42 constexpr std::size_t size = ((part1.size() + part2.size()) * (N / 2) + (N % 2 == 0 ? 0 : part1.size())) + 1;
43
44 std::array<char, size> result{};
45 auto iter = result.begin();
46
47 for (std::size_t i = 0; i < N; i++) {
48 auto part = i % 2 == 0 ? part1 : part2;
49
50 iter = std::ranges::copy(part, iter).out;
51 }
52
53 return result;
54 }
55} // namespace essence::detail
56
57namespace essence {
59 std::string_view str;
60 source_location location;
61
62 template <std::convertible_to<std::string_view> S>
63 constexpr logging_string_view(S&& str, // NOLINT(*-explicit-constructor)
64 const source_location& location = source_location::current()) noexcept
65 : str{std::forward<S>(str)}, location{location} {}
66 };
67
73 struct source_code_aware_runtime_error : std::runtime_error {
74 template <typename... Args>
75 explicit source_code_aware_runtime_error(logging_string_view hint, Args&&... args)
76 : source_code_aware_runtime_error{hint.location, hint.str, std::forward<Args>(args)...} {}
77
78 template <typename... Args>
79 explicit source_code_aware_runtime_error(const source_location& location, Args&&... args)
80 : runtime_error{[&] {
81 static constexpr auto format_array =
82 detail::make_format_str<sizeof...(Args) + 2 + (sizeof...(Args) == 1)>();
83 static constexpr std::string_view format_str{format_array.data()};
84
85 // Explicitly converts to std::string_view if the argument is convertible.
86 static constexpr auto converter = []<typename T>(T&& item) -> decltype(auto) {
87 if constexpr (std::convertible_to<T, std::string_view>) {
88 return std::string_view{std::forward<T>(item)};
89 } else {
90 return std::forward<T>(item);
91 }
92 };
93
94 // Removes the directory part from the file name to provide a simplified output.
95 const std::string_view file_name{location.file_name()};
96 auto file_name_without_directory = file_name.substr(file_name.find_last_of(U8(R"(/\)")) + 1);
97
98 if constexpr (sizeof...(Args) == 1) {
99 return format(format_str, U8("File"), file_name_without_directory, U8("Message"),
100 converter(std::forward<Args>(args))...);
101 } else {
102 return format(
103 format_str, U8("File"), file_name_without_directory, converter(std::forward<Args>(args))...);
104 }
105 }()} {}
106 };
107} // namespace essence
Definition error_extensions.hpp:58
An exception class derived from std::runtime_error that provides source code information of the sourc...
Definition error_extensions.hpp:73
Definition source_location.hpp:39