userver: userver/utils/impl/source_location.hpp Source File
⚠️ This is the documentation for an old userver version. Click here to switch to the latest version.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages Concepts
source_location.hpp
1#pragma once
2
3#include <cstdint>
4#include <string_view>
5#include <type_traits>
6
7#include <userver/logging/log_filepath.hpp>
8
9USERVER_NAMESPACE_BEGIN
10
11namespace utils::impl {
12
13class SourceLocation final {
14 struct EmplaceEnabler final {
15 constexpr explicit EmplaceEnabler() noexcept = default;
16 };
17
18 public:
19 static constexpr SourceLocation Current(
20 EmplaceEnabler /*unused*/ = EmplaceEnabler{},
21 std::string_view file_name = USERVER_FILEPATH,
22 std::string_view function_name = __builtin_FUNCTION(),
23 std::uint_least32_t line = __builtin_LINE()) noexcept {
24 return SourceLocation{line, file_name, function_name};
25 }
26
27 // Mainly intended for interfacing with external libraries.
28 static constexpr SourceLocation Custom(
29 std::uint_least32_t line, std::string_view file_name,
30 std::string_view function_name) noexcept {
31 return SourceLocation{line, file_name, function_name};
32 }
33
34 constexpr std::uint_least32_t GetLine() const noexcept { return line_; }
35
36 constexpr std::string_view GetLineString() const noexcept {
37 return std::string_view(&line_string_[kMaxLineDigits - line_digits_],
38 line_digits_);
39 }
40
41 constexpr std::string_view GetFileName() const noexcept { return file_name_; }
42
43 constexpr std::string_view GetFunctionName() const noexcept {
44 return function_name_;
45 }
46
47 private:
48 static_assert(sizeof(std::uint_least32_t) == sizeof(std::uint32_t));
49
50 static constexpr std::size_t kMaxLineDigits = 8;
51
52 constexpr SourceLocation(std::uint_least32_t line, std::string_view file_name,
53 std::string_view function_name) noexcept
54 : line_(line),
55 line_digits_(DigitsBase10(line)),
56 file_name_(file_name),
57 function_name_(function_name) {
58 FillLineString();
59 }
60
61 static constexpr std::size_t DigitsBase10(std::uint32_t line) noexcept {
62 static_assert(sizeof(line) == 4);
63 return 1 //
64 + (line >= 10) //
65 + (line >= 100) //
66 + (line >= 1000) //
67 + (line >= 10000) //
68 + (line >= 100000) //
69 + (line >= 1000000) //
70 + (line >= 10000000) //
71 + (line >= 100000000) //
72 + (line >= 1000000000); //
73 }
74
75 constexpr void FillLineString() noexcept {
76 constexpr std::size_t kMaxSupportedLine = 99999999;
77 if (line_ > kMaxSupportedLine) {
78 // Line string greater than 8 digits won't fit. Use fake line numbers
79 // for 100M+ lines source files.
80 line_ = kMaxSupportedLine;
81 line_digits_ = kMaxLineDigits;
82 }
83 auto line = line_;
84 line_string_[kMaxLineDigits - 1] = '0';
85 for (std::size_t index = kMaxLineDigits - 1; line > 0;
86 line /= 10, --index) {
87 line_string_[index] = '0' + (line % 10);
88 }
89 }
90
91 std::uint32_t line_;
92 std::uint32_t line_digits_;
93 char line_string_[kMaxLineDigits]{};
94 std::string_view file_name_;
95 std::string_view function_name_;
96};
97
98} // namespace utils::impl
99
100USERVER_NAMESPACE_END