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
12#include <iostream>
13#include <map>
14#include <sstream>
15#include <string>
16#include <vector>
17
18#include <magic_enum.hpp>
19
20#include "strconv2.h"
21
23#include "math_euler.h"
24#include "math_quaternion.h"
25#include "math_vector3.h"
26#include "toml11_define.h"
27
28
39{
40
44{
46 static const char kNoTable[];
47
48 Toml11Description(const std::string& t, const std::string& d) :
49 table_name(t),
51 {
52 }
53
54 std::string table_name;
55 std::string description;
56};
57
58
62std::vector<std::string> sjis_to_utf8_vec(const std::vector<std::string>& str_vec);
63
69template <typename T>
70typename std::enable_if<impl::is_toml11_available_type<T>::value>::type
71SetTomlValue(::toml::basic_value<toml::preserve_comments, std::map>* v, const std::string& str, const T& value)
72{
73 (*v)[str] = value;
74}
75
81template <typename T>
82typename std::enable_if<!impl::is_toml11_available_type<T>::value&& std::is_enum<T>::value>::type
83SetTomlValue(::toml::basic_value<toml::preserve_comments, std::map>* v, const std::string& str, const T& value)
84{
85 (*v)[str] = static_cast<std::string>(magic_enum::enum_name(value));
86}
87
94template <typename T>
95typename std::enable_if<!impl::is_toml11_available_type<T>::value&& impl::has_output_operator<T>::value>::type
96SetTomlValue(::toml::basic_value<toml::preserve_comments, std::map>* v, const std::string& str, const T& value)
97{
98 std::stringstream ss;
99 ss << value;
100 (*v)[str] = ss.str();
101}
102
103template <typename T>
104typename std::enable_if<!impl::is_toml11_available_type<T>::value&& impl::is_vector_of_has_output_operator<T>::value>::type
105SetTomlValue(::toml::basic_value<toml::preserve_comments, std::map>* v, const std::string& str, const T& value)
106{
107 std::vector<std::string> str_vec(value.size());
108
109 for (int i = 0; i < value.size(); ++i)
110 {
111 std::stringstream ss;
112 ss << value[i];
113 str_vec[i] = ss.str();
114 }
115
116 (*v)[str] = str_vec;
117}
118
120template <typename T, typename Enable = void>
122
128template <typename T>
129struct GetTomlValueImpl < T, typename std::enable_if<impl::is_toml11_available_type<T>::value> ::type >
130{
131 static T Get(::toml::basic_value<toml::preserve_comments, std::map>* v, const std::string& var_str)
132 {
133 return toml::find<T>(*v, var_str);
134 }
135};
136
140template <typename T>
141struct GetTomlValueImpl<T, typename std::enable_if<!impl::is_toml11_available_type<T>::value&& std::is_enum<T>::value>::type>
142{
148 static T Get(::toml::basic_value<toml::preserve_comments, std::map>* v, const std::string& var_str)
149 {
150 std::string str = toml::find<std::string>(*v, var_str);
151 return magic_enum::enum_cast<T>(str).value();
152 }
153};
154
158template <typename T>
159struct GetTomlValueImpl<T, typename std::enable_if<!impl::is_toml11_available_type<T>::value&& impl::has_input_operator<T>::value>::type>
160{
166 static T Get(::toml::basic_value<toml::preserve_comments, std::map>* v, const std::string& var_str)
167 {
168 std::string str = toml::find<std::string>(*v, var_str);
169 std::stringstream ss;
170 ss << str;
171 T temp{};
172 ss >> temp;
173 return temp;
174 }
175};
176
177template <typename T>
178struct GetTomlValueImpl<T, typename std::enable_if<!impl::is_toml11_available_type<T>::value&& impl::is_vector_of_has_input_operator<T>::value>::type>
179{
180 static T Get(::toml::basic_value<toml::preserve_comments, std::map>* v, const std::string& var_str)
181 {
182 std::vector<std::string> str_vec = 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 {
190 std::stringstream ss;
191 ss << str_vec[i];
192 ss >> temp[i];
193 }
194
195 return temp;
196 }
197};
198
206template <typename T>
207T GetTomlValue(::toml::basic_value<toml::preserve_comments, std::map> v, const std::string& var_str)
208{
209 return GetTomlValueImpl<T>::Get(&v, var_str);
210}
211
212} // namespace designlab::toml_func
213
214
220#define DESIGNLAB_SUB_MACRO_FIND_MEMBER_VARIABLE_FROM_VALUE(VAR_NAME) \
221{ \
222 const std::string table_str = desc.VAR_NAME.table_name; \
223 \
224 if (table_str == ::designlab::toml_func::Toml11Description::kNoTable) \
225 { \
226 obj.VAR_NAME = \
227 ::designlab::toml_func::GetTomlValue<decltype(obj.VAR_NAME)>( \
228 v_, \
229 TOML11_STRINGIZE(VAR_NAME)); \
230 } \
231 else \
232 { \
233 obj.VAR_NAME = \
234 ::designlab::toml_func::GetTomlValue<decltype(obj.VAR_NAME)>( \
235 v_[table_str], \
236 TOML11_STRINGIZE(VAR_NAME)); \
237 } \
238}
239
240
241
247#define DESIGNLAB_SUB_MACRO_ASSIGN_MEMBER_VARIABLE_TO_VALUE(VAR) \
248if (desc.VAR.table_name != ::designlab::toml_func::Toml11Description::kNoTable) { \
249 if (v.count(desc.VAR.table_name) == 0) \
250 { \
251 v[desc.VAR.table_name] = toml::table{}; \
252 } \
253 \
254 ::designlab::toml_func::SetTomlValue(&v[desc.VAR.table_name], \
255 TOML11_STRINGIZE(VAR), obj.VAR); \
256} \
257else \
258{ \
259 ::designlab::toml_func::SetTomlValue( \
260 &v, TOML11_STRINGIZE(VAR), obj.VAR); \
261}
262
263
270#define DESIGNLAB_SUB_MACRO_ADD_COMMENT(VN) \
271if (desc.VN.description != "") { \
272 if (desc.VN.table_name != ::designlab::toml_func::Toml11Description::kNoTable) \
273 { \
274 v[desc.VN.table_name][#VN].comments().push_back(desc.VN.description); \
275 } \
276 else \
277 { \
278 v[#VN].comments().push_back(desc.VN.description); \
279 } \
280}
281
282
286#define DESIGNLAB_TOML11_DESCRIPTION_CLASS(CLASS) \
287struct CLASS##Description final
288
289
293#define DESIGNLAB_TOML11_FILE_NO_DESCRIPTION() \
294const ::std::vector<::std::string> file_description_vec{};
295
300#define DESIGNLAB_TOML11_FILE_ADD_DESCRIPTION(DESCRIPTION) \
301const ::std::vector<::std::string> file_description_vec{sjis_to_utf8(DESCRIPTION)};
302
307#define DESIGNLAB_TOML11_FILE_ADD_DESCRIPTION_MULTI_LINE(DESCRIPTION_VEC) \
308const ::std::vector<::std::string> file_description_vec = \
309 ::designlab::toml_func::sjis_to_utf8_vec(DESCRIPTION_VEC);
310
311
316#define DESIGNLAB_TOML11_TABLE_ADD_DESCRIPTION(...) \
317const std::vector<std::string> table_name_description_vec = \
318 ::designlab::toml_func::sjis_to_utf8_vec({ __VA_ARGS__ });
319
323#define DESIGNLAB_TOML11_TABLE_NO_DESCRIPTION() \
324const std::vector<std::string> table_name_description_vec = {};
325
326
332#define DESIGNLAB_TOML11_VARIABLE_ADD_DESCRIPTION(VARIABLE, TABLE, DESCRIPTION) \
333const ::designlab::toml_func::Toml11Description VARIABLE{ \
334 TABLE, sjis_to_utf8(DESCRIPTION) \
335}
336
341#define DESIGNLAB_TOML11_VARIABLE_NO_DESCRIPTION(VARIABLE, TABLE) \
342const ::designlab::toml_func::Toml11Description VARIABLE{TABLE, ""}
343
346#define DESIGNLAB_TOML11_NO_TABLE \
347::designlab::toml_func::Toml11Description::kNoTable
348
349
395#define DESIGNLAB_TOML11_SERIALIZE(NAME, ...) \
396namespace toml \
397{ \
398template<> \
399struct from<NAME> \
400{ \
401 static_assert(std::is_class<NAME>::value, \
402 "第1引数はクラスか構造体である必要があります."); \
403 static_assert(std::is_default_constructible<NAME>::value, \
404 "第1引数はデフォルトコンストラクタを持つ必要があります."); \
405 \
406 template<typename C, template<typename ...> class T, \
407 template<typename ...> class A> \
408 static NAME from_toml(basic_value<C, T, A>& v) \
409 { \
410 ::toml::basic_value<toml::preserve_comments, std::map> v_ = v; \
411 NAME obj; \
412 NAME##Description desc; \
413 TOML11_FOR_EACH_VA_ARGS( \
414 DESIGNLAB_SUB_MACRO_FIND_MEMBER_VARIABLE_FROM_VALUE, __VA_ARGS__) \
415 return obj; \
416 } \
417}; \
418 \
419template<> \
420struct into<NAME> \
421{ \
422 static value into_toml(const NAME& obj) \
423 { \
424 ::toml::basic_value<toml::preserve_comments, std::map> v = ::toml::table{}; \
425 \
426 NAME##Description desc; \
427 \
428 for (const auto i : desc.file_description_vec) \
429 { \
430 v.comments().push_back(i); \
431 } \
432 \
433 for (int i = 0; i < desc.table_name_description_vec.size(); ++i) \
434 { \
435 v[desc.table_name_description_vec[i]] = ::toml::table{}; \
436 v[desc.table_name_description_vec[i]].comments(). \
437 push_back(desc.table_name_description_vec[i + 1]); \
438 ++i; \
439 } \
440 \
441 TOML11_FOR_EACH_VA_ARGS( \
442 DESIGNLAB_SUB_MACRO_ASSIGN_MEMBER_VARIABLE_TO_VALUE, __VA_ARGS__) \
443 TOML11_FOR_EACH_VA_ARGS( \
444 DESIGNLAB_SUB_MACRO_ADD_COMMENT, __VA_ARGS__) \
445 return v; \
446 } \
447}; \
448 \
449} // namespace toml
450
451
452#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:24
出力ストリームが実装されているか判断するメタ関数.
出力ストリームが実装されている 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[]
テーブルがない場合に指定する文字列.
std::string table_name
テーブル名.