GaitGeneration by Graph Search
読み取り中…
検索中…
一致する文字列を見つけられません
toml_serialize_macro.h
[詳解]
1
3
4// Copyright(c) 2023-2025 Design Engineering Laboratory, Saitama University
5// Released under the MIT license
6// https://opensource.org/licenses/mit-license.php
7
8#ifndef DESIGNLAB_TOML_SERIALIZE_MACRO_H_
9#define DESIGNLAB_TOML_SERIALIZE_MACRO_H_
10
11#include <iostream>
12#include <magic_enum.hpp>
13#include <map>
14#include <sstream>
15#include <string>
16#include <vector>
17
19#include "math_euler.h"
20#include "math_quaternion.h"
21#include "math_vector3.h"
22#include "strconv2.h"
23#include "toml11_define.h"
24
34namespace designlab::toml_func {
35
38struct Toml11Description final {
40 static const char kNoTable[];
41
42 Toml11Description(const std::string& t, const std::string& d)
43 : table_name(t), description(d) {}
44
45 std::string table_name;
46 std::string
48};
49
53std::vector<std::string> sjis_to_utf8_vec(
54 const std::vector<std::string>& str_vec);
55
61template <typename T>
62typename std::enable_if<impl::is_toml11_available_type<T>::value>::type
63SetTomlValue(::toml::basic_value<toml::preserve_comments, std::map>* v,
64 const std::string& str, const T& value) {
65 (*v)[str] = value;
66}
67
73template <typename T>
74typename std::enable_if<!impl::is_toml11_available_type<T>::value &&
75 std::is_enum<T>::value>::type
76SetTomlValue(::toml::basic_value<toml::preserve_comments, std::map>* v,
77 const std::string& str, const T& value) {
78 (*v)[str] = static_cast<std::string>(magic_enum::enum_name(value));
79}
80
87template <typename T>
88typename std::enable_if<!impl::is_toml11_available_type<T>::value &&
90SetTomlValue(::toml::basic_value<toml::preserve_comments, std::map>* v,
91 const std::string& str, const T& value) {
92 std::stringstream ss;
93 ss << value;
94 (*v)[str] = ss.str();
95}
96
97template <typename T>
98typename std::enable_if<!impl::is_toml11_available_type<T>::value &&
100SetTomlValue(::toml::basic_value<toml::preserve_comments, std::map>* v,
101 const std::string& str, const T& value) {
102 std::vector<std::string> str_vec(value.size());
103
104 for (int i = 0; i < value.size(); ++i) {
105 std::stringstream ss;
106 ss << value[i];
107 str_vec[i] = ss.str();
108 }
109
110 (*v)[str] = str_vec;
111}
112
114template <typename T, typename Enable = void>
116
122template <typename T>
124 T,
125 typename std::enable_if<impl::is_toml11_available_type<T>::value>::type> {
126 static T Get(::toml::basic_value<toml::preserve_comments, std::map>* v,
127 const std::string& var_str) {
128 return toml::find<T>(*v, var_str);
129 }
130};
131
135template <typename T>
137 T, typename std::enable_if<!impl::is_toml11_available_type<T>::value &&
138 std::is_enum<T>::value>::type> {
144 static T Get(::toml::basic_value<toml::preserve_comments, std::map>* v,
145 const std::string& var_str) {
146 std::string str = toml::find<std::string>(*v, var_str);
147 return magic_enum::enum_cast<T>(str).value();
148 }
149};
150
154template <typename T>
156 T, typename std::enable_if<!impl::is_toml11_available_type<T>::value &&
157 impl::has_input_operator<T>::value>::type> {
163 static T Get(::toml::basic_value<toml::preserve_comments, std::map>* v,
164 const std::string& var_str) {
165 std::string str = toml::find<std::string>(*v, var_str);
166 std::stringstream ss;
167 ss << str;
168 T temp{};
169 ss >> temp;
170 return temp;
171 }
172};
173
174template <typename T>
176 T, typename std::enable_if<
177 !impl::is_toml11_available_type<T>::value &&
178 impl::is_vector_of_has_input_operator<T>::value>::type> {
179 static T Get(::toml::basic_value<toml::preserve_comments, std::map>* v,
180 const std::string& var_str) {
181 std::vector<std::string> str_vec =
182 toml::find<std::vector<std::string>>(*v, var_str);
183
184 T temp{};
185
186 temp.resize(str_vec.size());
187
188 for (int i = 0; i < str_vec.size(); ++i) {
189 std::stringstream ss;
190 ss << str_vec[i];
191 ss >> temp[i];
192 }
193
194 return temp;
195 }
196};
197
205template <typename T>
206T GetTomlValue(::toml::basic_value<toml::preserve_comments, std::map> v,
207 const std::string& var_str) {
208 return GetTomlValueImpl<T>::Get(&v, var_str);
209}
210
211} // namespace designlab::toml_func
212
218#define DESIGNLAB_SUB_MACRO_FIND_MEMBER_VARIABLE_FROM_VALUE(VAR_NAME) \
219 { \
220 const std::string table_str = desc.VAR_NAME.table_name; \
221 \
222 if (table_str == ::designlab::toml_func::Toml11Description::kNoTable) { \
223 obj.VAR_NAME = \
224 ::designlab::toml_func::GetTomlValue<decltype(obj.VAR_NAME)>( \
225 v_, TOML11_STRINGIZE(VAR_NAME)); \
226 } else { \
227 obj.VAR_NAME = \
228 ::designlab::toml_func::GetTomlValue<decltype(obj.VAR_NAME)>( \
229 v_[table_str], TOML11_STRINGIZE(VAR_NAME)); \
230 } \
231 }
232
238#define DESIGNLAB_SUB_MACRO_ASSIGN_MEMBER_VARIABLE_TO_VALUE(VAR) \
239 if (desc.VAR.table_name != \
240 ::designlab::toml_func::Toml11Description::kNoTable) { \
241 if (v.count(desc.VAR.table_name) == 0) { \
242 v[desc.VAR.table_name] = toml::table{}; \
243 } \
244 \
245 ::designlab::toml_func::SetTomlValue(&v[desc.VAR.table_name], \
246 TOML11_STRINGIZE(VAR), obj.VAR); \
247 } else { \
248 ::designlab::toml_func::SetTomlValue(&v, TOML11_STRINGIZE(VAR), obj.VAR); \
249 }
250
257#define DESIGNLAB_SUB_MACRO_ADD_COMMENT(VN) \
258 if (desc.VN.description != "") { \
259 if (desc.VN.table_name != \
260 ::designlab::toml_func::Toml11Description::kNoTable) { \
261 v[desc.VN.table_name][#VN].comments().push_back(desc.VN.description); \
262 } else { \
263 v[#VN].comments().push_back(desc.VN.description); \
264 } \
265 }
266
270#define DESIGNLAB_TOML11_DESCRIPTION_CLASS(CLASS) \
271 struct CLASS##Description final
272
276#define DESIGNLAB_TOML11_FILE_NO_DESCRIPTION() \
277 const ::std::vector<::std::string> file_description_vec{};
278
283#define DESIGNLAB_TOML11_FILE_ADD_DESCRIPTION(DESCRIPTION) \
284 const ::std::vector<::std::string> file_description_vec{ \
285 sjis_to_utf8(DESCRIPTION)};
286
291#define DESIGNLAB_TOML11_FILE_ADD_DESCRIPTION_MULTI_LINE(DESCRIPTION_VEC) \
292 const ::std::vector<::std::string> file_description_vec = \
293 ::designlab::toml_func::sjis_to_utf8_vec(DESCRIPTION_VEC);
294
299#define DESIGNLAB_TOML11_TABLE_ADD_DESCRIPTION(...) \
300 const std::vector<std::string> table_name_description_vec = \
301 ::designlab::toml_func::sjis_to_utf8_vec({__VA_ARGS__});
302
307#define DESIGNLAB_TOML11_TABLE_NO_DESCRIPTION() \
308 const std::vector<std::string> table_name_description_vec = {};
309
315#define DESIGNLAB_TOML11_VARIABLE_ADD_DESCRIPTION(VARIABLE, TABLE, \
316 DESCRIPTION) \
317 const ::designlab::toml_func::Toml11Description VARIABLE { \
318 TABLE, sjis_to_utf8(DESCRIPTION) \
319 }
320
325#define DESIGNLAB_TOML11_VARIABLE_NO_DESCRIPTION(VARIABLE, TABLE) \
326 const ::designlab::toml_func::Toml11Description VARIABLE { TABLE, "" }
327
331#define DESIGNLAB_TOML11_NO_TABLE \
332 ::designlab::toml_func::Toml11Description::kNoTable
333
379#define DESIGNLAB_TOML11_SERIALIZE(NAME, ...) \
380 namespace toml { \
381 template <> \
382 struct from<NAME> { \
383 static_assert(std::is_class<NAME>::value, \
384 "第1引数はクラスか構造体である必要があります."); \
385 static_assert(std::is_default_constructible<NAME>::value, \
386 "第1引数はデフォルトコンストラクタを持つ必要があります."); \
387 \
388 template <typename C, template <typename...> class T, \
389 template <typename...> class A> \
390 static NAME from_toml(basic_value<C, T, A>& v) { \
391 ::toml::basic_value<toml::preserve_comments, std::map> v_ = v; \
392 NAME obj; \
393 NAME##Description desc; \
394 TOML11_FOR_EACH_VA_ARGS( \
395 DESIGNLAB_SUB_MACRO_FIND_MEMBER_VARIABLE_FROM_VALUE, __VA_ARGS__) \
396 return obj; \
397 } \
398 }; \
399 \
400 template <> \
401 struct into<NAME> { \
402 static value into_toml(const NAME& obj) { \
403 ::toml::basic_value<toml::preserve_comments, std::map> v = \
404 ::toml::table{}; \
405 \
406 NAME##Description desc; \
407 \
408 for (const auto i : desc.file_description_vec) { \
409 v.comments().push_back(i); \
410 } \
411 \
412 for (int i = 0; i < desc.table_name_description_vec.size(); ++i) { \
413 v[desc.table_name_description_vec[i]] = ::toml::table{}; \
414 v[desc.table_name_description_vec[i]].comments().push_back( \
415 desc.table_name_description_vec[i + 1]); \
416 ++i; \
417 } \
418 \
419 TOML11_FOR_EACH_VA_ARGS( \
420 DESIGNLAB_SUB_MACRO_ASSIGN_MEMBER_VARIABLE_TO_VALUE, __VA_ARGS__) \
421 TOML11_FOR_EACH_VA_ARGS(DESIGNLAB_SUB_MACRO_ADD_COMMENT, __VA_ARGS__) \
422 return v; \
423 } \
424 }; \
425 \
426 } // namespace toml
427
428#endif // DESIGNLAB_TOML_SERIALIZE_MACRO_H_
tomlファイルのシリアライズ/デシリアライズを行うための関数群.
T GetTomlValue(::toml::basic_value< toml::preserve_comments, std::map > v, const std::string &var_str)
ユーザーが直接呼ぶ関数. GetTomlValueImpl を利用してテンプレートの型を解決し, それに応じたGet関数を呼び出す.
std::vector< std::string > sjis_to_utf8_vec(const std::vector< std::string > &str_vec)
文字列のベクターをShift-jisからUTF-8に変換する.
std::enable_if< impl::is_toml11_available_type< T >::value >::type SetTomlValue(::toml::basic_value< toml::preserve_comments, std::map > *v, const std::string &str, const T &value)
tomlファイルに値を追加するための関数. enum 型と vector3 型と euler_xyz 型以外の型に対応している.
Definition com_type.h:21
出力ストリームが実装されているか判断するメタ関数.
出力ストリームが実装されている vector 型かどうかを判定するメタ関数.
static T Get(::toml::basic_value< toml::preserve_comments, std::map > *v, const std::string &var_str)
tomlファイルから値を取得するための関数.
static T Get(::toml::basic_value< toml::preserve_comments, std::map > *v, const std::string &var_str)
tomlファイルから値を取得するための関数.
static T Get(::toml::basic_value< toml::preserve_comments, std::map > *v, const std::string &var_str)
プライマリ テンプレート.特殊化されない場合はコンパイルエラーになる.
tomlファイルに追加する変数の説明を追加するための構造体.
std::string description
説明,tomlファイルにはコメントとして追加される.
Toml11Description(const std::string &t, const std::string &d)
static const char kNoTable[]
テーブルがない場合に指定する文字列.