Skip to content

Commit 71bdb2c

Browse files
committed
[injection] Create an example implementation
1 parent 7311d76 commit 71bdb2c

File tree

5 files changed

+117
-0
lines changed

5 files changed

+117
-0
lines changed

example/inject/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
add_executable(injector injection_impl.cpp)
2+
target_link_libraries(injector PRIVATE rsl-inject)

example/inject/injection_impl.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#include "interface.hpp"
2+
#include <rsl/inject>
3+
4+
5+
namespace foo_impl
6+
{
7+
static constexpr auto target_name = "injected_implementation";
8+
[[=Inject("demo/file.cpp")]]
9+
std::string generateFunction()
10+
{
11+
return " int foo() { return 42;}";
12+
}
13+
} // namespace inject
14+
15+
16+
RSLINJECT_ENABLE_NS(foo_impl)

example/inject/interface.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#pragma once
2+
3+
int foo();

example/inject/main.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include <print>
2+
#include "interface.hpp"
3+
4+
auto main(int argc, char *argv[]) -> int {
5+
std::println("{}", foo());
6+
return 0;
7+
}

include/rsl/inject

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
#include <meta>
2+
#include <string>
3+
#include <fstream>
4+
#include <filesystem>
5+
#include <format>
6+
#include <unordered_map>
7+
#include <set>
8+
9+
#include <rsl/span>
10+
11+
namespace __impl{
12+
13+
struct InjectPath {
14+
char const* msg;
15+
16+
};
17+
} // namespace __impl
18+
19+
20+
static consteval auto Inject(char const* msg) {
21+
return __impl::InjectPath{std::define_static_string(msg)};
22+
};
23+
24+
25+
using injections_type = std::unordered_map<std::filesystem::path, std::string>;
26+
27+
struct injection_info
28+
{
29+
injections_type entries;
30+
std::string target_name;
31+
};
32+
33+
injection_info& injection_info() {
34+
static struct injection_info injected{};
35+
return injected;
36+
}
37+
38+
injections_type& injections(){
39+
return injection_info().entries;
40+
}
41+
42+
std::string generate_cmake() {
43+
std::string out{};
44+
auto& info = injection_info();
45+
// boilerplate
46+
47+
return out;
48+
}
49+
50+
template<std::meta::info func>
51+
void process_injection()
52+
{
53+
constexpr auto vec = rsl::span{std::define_static_array(std::meta::annotations_of(func))};
54+
constexpr std::string_view annotationInfo = std::define_static_string(std::meta::extract<__impl::InjectPath>(vec[0]).msg);
55+
auto const path = std::filesystem::path(annotationInfo);
56+
std::format_to(std::back_inserter(injections()[path]), "{}\n", [:func:]() );
57+
}
58+
59+
void generate_from_injection()
60+
{
61+
for(const auto [path,injection] : injections())
62+
{
63+
if(path.has_parent_path())
64+
std::filesystem::create_directories(path.parent_path());
65+
std::ofstream file{path};
66+
if(file)
67+
file << injection;
68+
}
69+
}
70+
71+
template<std::meta::info source>
72+
constexpr bool gather_injections() {
73+
template for (constexpr auto member : define_static_array(members_of(source, std::meta::access_context::current()))) {
74+
if constexpr(is_function(member))
75+
process_injection<member>();
76+
}
77+
return true;
78+
}
79+
80+
#define RSLINJECT_ENABLE_NS(NS) \
81+
namespace { \
82+
[[maybe_unused]] static bool const _rsl_injection_enabled = \
83+
gather_injections<^^NS>(); \
84+
}
85+
86+
int main()
87+
{
88+
generate_from_injection();
89+
}

0 commit comments

Comments
 (0)