-
Notifications
You must be signed in to change notification settings - Fork 8
/
metadata_example.cpp
106 lines (88 loc) · 3.39 KB
/
metadata_example.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*******************************************************************************
* This file is part of the "https://github.com/blackmatov/meta.hpp"
* For conditions of distribution and use, see copyright notice in LICENSE.md
* Copyright (C) 2021-2024, by Matvey Cherevko ([email protected])
******************************************************************************/
#include <meta.hpp/meta_all.hpp>
#include <doctest/doctest.h>
#include <fmt/core.h>
namespace
{
struct ivec3 {
int x{};
int y{};
int z{};
};
ivec3 cross(const ivec3& a, const ivec3& b) {
return {
a.y * b.z - a.z * b.y,
a.z * b.x - a.x * b.z,
a.x * b.y - a.y * b.x, };
}
}
TEST_CASE("meta/meta_examples/metadata") {
namespace meta = meta_hpp;
using namespace std::literals;
// you can add additional key-value metadata to any types and their properties:
// key: std::string
// value: meta::uvalue
meta::class_<ivec3>(meta::metadata_() // for class type
("tooltip", "3D Vector"s)
)
.member_("x", &ivec3::x, meta::metadata_() // for class members
("tooltip", "X-Coordinate"s)
)
.member_("y", &ivec3::y, meta::metadata_()
("tooltip", "Y-Coordinate"s)
)
.member_("z", &ivec3::z, meta::metadata_()
("tooltip", "Z-Coordinate"s)
);
const meta::scope math_scope = meta::local_scope_("math")
.typedef_<ivec3>("ivec3")
.function_("cross", &cross,
meta::arguments_()
("first vector")
("second vector", meta::metadata_() // even function arguments can have metadata
("tooltip", "The second cross product argument"s)),
meta::metadata_() // for functions in a scope
("tooltip", "Cross product of vectors"s));
// after binding, you can use it as you wish
// in this example, I'm just going to print all of them to stdout
for ( const auto& [type_name, type] : math_scope.get_typedefs() ) {
if ( !type.is_class() ) {
continue;
}
const meta::class_type& class_type = type.as_class();
const meta::metadata_map& class_metadata = class_type.get_metadata();
fmt::print("{} ({})\n",
type_name,
class_metadata.at("tooltip").as<std::string>());
for ( const meta::member& member : class_type.get_members() ) {
const meta::metadata_map& member_metadata = member.get_metadata();
fmt::print(" - {} ({})\n",
member.get_name(),
member_metadata.at("tooltip").as<std::string>());
}
}
for ( const meta::function& function : math_scope.get_functions() ) {
const meta::metadata_map& function_metadata = function.get_metadata();
fmt::print(" + {}/{} ({})\n",
function.get_name(),
function.get_type().get_arity(),
function_metadata.at("tooltip").as<std::string>());
for ( const meta::argument& argument : function.get_arguments() ) {
fmt::print(" ({}) : {}\n",
argument.get_position(),
argument.get_name());
}
}
// Output:
// ivec3 (3D Vector)
// - x (X-Coordinate)
// - y (Y-Coordinate)
// - z (Z-Coordinate)
// + cross/2 (Cross product of vectors)
// (0) : first vector
// (1) : second vector
}