C++ Essence Library 0.1.0
A Utility Library for Modern C++ Programming
Loading...
Searching...
No Matches
struct.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 "../common_types.hpp"
26#include "../detail/data_member_binding.hpp"
27#include "../naming_convention.hpp"
28#include "../struct.hpp"
29
30#include <cstddef>
31#include <string>
32#include <tuple>
33#include <type_traits>
34#include <utility>
35#include <vector>
36
37namespace essence::meta::runtime {
42 template <typename T>
43 requires std::is_class_v<T>
48 using enclosing_type = T;
49
53 inline static const std::string enclosing_type_name{get_literal_string_t<T>()};
54
55
59 std::string raw_name;
60
64 std::string name;
65 };
66
67 template <typename T>
68 requires std::is_class_v<T>
69 std::span<const std::string> get_data_member_names() {
70 static const auto cache = [] {
71 std::vector<std::string> result;
72
73 for (auto&& item : meta::probe_data_member_names<T>()) {
74 result.emplace_back(std::string{item});
75 }
76
77 return result;
78 }();
79
80 return cache;
81 }
82
89 template <naming_convention Convention, typename T>
90 requires std::is_class_v<T>
91 std::span<const data_member_info<T>> get_data_member_info() {
92 static const auto cache = [] {
93 std::vector<data_member_info<T>> result;
94
95 for (auto&& item : get_data_member_names<T>()) {
96 result.emplace_back(item, convert_naming_convention(item, Convention));
97 }
98
99 return result;
100 }();
101
102 return cache;
103 }
104
113 template <naming_convention Convention = naming_convention::none, typename T, typename Callable>
114 requires std::is_class_v<std::decay_t<T>>
115 void enumerate_data_members(T&& obj, Callable&& handler) {
116 using decayed_type = std::decay_t<T>;
117
118 static const auto cache = get_data_member_info<Convention, decayed_type>();
119 static constexpr auto make_ref_info = []<typename U>(const data_member_info<decayed_type>& item, U& reference) {
120 struct ref_info {
121 using enclosing_type = decayed_type;
122
123 const std::string& enclosing_type_name;
124 const std::string& raw_name;
125 const std::string& name;
126 U& reference;
127 };
128
129 return ref_info{
130 .enclosing_type_name = item.enclosing_type_name,
131 .raw_name = item.raw_name,
132 .name = item.name,
133 .reference = reference,
134 };
135 };
136
137 auto pointers = detail::make_data_member_pointers(std::forward<T>(obj));
138 auto tuple = std::forward_as_tuple(std::forward<Callable>(handler));
139
140 [&]<std::size_t... Is>(std::index_sequence<Is...>) {
141 std::apply(
142 [&pointers]<typename InnerCallable>(InnerCallable&& handler) {
143 std::forward<InnerCallable>(handler)(make_ref_info(cache[Is], *std::get<Is>(pointers))...);
144 },
145 std::move(tuple));
146 }(std::make_index_sequence<std::tuple_size_v<decltype(pointers)>>{});
147 }
148} // namespace essence::meta::runtime
Information of a direct data member of a class.
Definition struct.hpp:44
T enclosing_type
The type of the enclosing class.
Definition struct.hpp:48
static const std::string enclosing_type_name
The name of the type of the enclosing class.
Definition struct.hpp:53
std::string name
The name of the data member.
Definition struct.hpp:64
std::string raw_name
The original name of the data member without a conversion of the naming convention.
Definition struct.hpp:59