1- #pragma once
1+ #include <cstddef>
2+ #include <meta>
23#include <source_location>
34#include <string_view>
4- #include <meta>
5- #include <cstddef>
6-
7- #include <rsl/string_view>
85
96namespace rsl {
10- struct source_location {
11- rsl::string_view file;
12- rsl::string_view function;
13- std::size_t line;
14- std::size_t column;
15-
16- consteval source_location(std::source_location sloc = std::source_location::current())
17- : file(std::define_static_string(sloc.file_name()))
18- , function(std::define_static_string(sloc.function_name()))
19- , line(sloc.line())
20- , column(sloc.column()) {}
21-
22- explicit source_location(rsl::string_view file,
23- rsl::string_view function,
24- std::size_t line,
25- std::size_t column = 0)
26- : file(file)
27- , function(function)
28- , line(line)
29- , column(column) {}
7+
8+ class source_location {
9+ struct RawSloc {
10+ const char* file_name = std::define_static_string("");
11+ const char* function_name = std::define_static_string("");
12+ unsigned line = 0;
13+ unsigned column = 0;
14+ };
15+
16+ struct SourceContext : RawSloc {
17+ consteval SourceContext(RawSloc raw) : RawSloc(raw) {}
18+
19+ constexpr virtual ~SourceContext() = default;
20+ consteval virtual std::meta::info scope() const = 0;
21+ consteval virtual std::meta::access_context access_context() const = 0;
22+ };
23+
24+ template <std::meta::access_context R, RawSloc Data>
25+ consteval static SourceContext const* make_context() {
26+ struct SourceContextImpl : SourceContext {
27+ using SourceContext::SourceContext;
28+ consteval virtual std::meta::info scope() const { return R.scope(); }
29+ consteval virtual std::meta::access_context access_context() const { return R; }
30+ };
31+ constexpr static SourceContextImpl obj{Data};
32+ return &obj;
33+ };
34+
35+ // TODO: remove
36+ //? this is a workaround for clang-p2996:
37+ //? static member functions aren't extracted as free functions
38+ template <std::meta::access_context R, RawSloc Data>
39+ constexpr static SourceContext const* _impl_context = make_context<R, Data>();
40+
41+ explicit consteval source_location(SourceContext const* data) : _impl_sloc(data) {}
42+
43+ public:
44+ SourceContext const* _impl_sloc = nullptr;
45+ consteval source_location()
46+ : _impl_sloc(make_context<std::meta::access_context::unchecked(), {}>()) {}
47+
48+ consteval static source_location current(
49+ std::source_location sloc = std::source_location::current(),
50+ std::meta::access_context ctx = std::meta::access_context::current()) {
51+ auto base = RawSloc{define_static_string(std::string_view(sloc.file_name())),
52+ define_static_string(std::string_view(sloc.function_name())),
53+ sloc.line(),
54+ sloc.column()};
55+
56+ // TODO: with gcc we can use make_context directly - _impl_context is a workaround for clang
57+ return source_location{extract<SourceContext const*>(
58+ substitute(^^_impl_context, {reflect_constant(ctx), std::meta::reflect_constant(base)}))};
59+ }
60+
61+ // TODO wrap file_name and function_name in rsl::cstring_view as soon as implemented
62+ constexpr char const* file_name() const noexcept { return _impl_sloc->file_name; }
63+ constexpr char const* function_name() const noexcept { return _impl_sloc->function_name; }
64+ constexpr unsigned line() const noexcept { return _impl_sloc->line; }
65+ constexpr unsigned column() const noexcept { return _impl_sloc->column; }
66+
67+ // consteval-only extensions
68+ consteval std::meta::info scope() const noexcept { return _impl_sloc->scope(); }
69+ consteval std::meta::access_context access_context() const noexcept {
70+ return _impl_sloc->access_context();
71+ }
3072};
73+
3174} // namespace rsl
0 commit comments