1 | //===-- YAMLGenerator.cpp - ClangDoc YAML -----------------------*- C++ -*-===// |
---|---|
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // Implementation of the YAML generator, converting decl info into YAML output. |
9 | //===----------------------------------------------------------------------===// |
10 | |
11 | #include "Generators.h" |
12 | #include "Representation.h" |
13 | #include "llvm/Support/YAMLTraits.h" |
14 | #include "llvm/Support/raw_ostream.h" |
15 | #include <optional> |
16 | |
17 | using namespace clang::doc; |
18 | |
19 | // These define YAML traits for decoding the listed values within a vector. |
20 | LLVM_YAML_IS_SEQUENCE_VECTOR(FieldTypeInfo) |
21 | LLVM_YAML_IS_SEQUENCE_VECTOR(MemberTypeInfo) |
22 | LLVM_YAML_IS_SEQUENCE_VECTOR(Reference) |
23 | LLVM_YAML_IS_SEQUENCE_VECTOR(Location) |
24 | LLVM_YAML_IS_SEQUENCE_VECTOR(CommentInfo) |
25 | LLVM_YAML_IS_SEQUENCE_VECTOR(FunctionInfo) |
26 | LLVM_YAML_IS_SEQUENCE_VECTOR(EnumInfo) |
27 | LLVM_YAML_IS_SEQUENCE_VECTOR(EnumValueInfo) |
28 | LLVM_YAML_IS_SEQUENCE_VECTOR(TemplateParamInfo) |
29 | LLVM_YAML_IS_SEQUENCE_VECTOR(TypedefInfo) |
30 | LLVM_YAML_IS_SEQUENCE_VECTOR(BaseRecordInfo) |
31 | LLVM_YAML_IS_SEQUENCE_VECTOR(std::unique_ptr<CommentInfo>) |
32 | LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::SmallString<16>) |
33 | |
34 | namespace llvm { |
35 | namespace yaml { |
36 | |
37 | // Enumerations to YAML output. |
38 | |
39 | template <> struct ScalarEnumerationTraits<clang::AccessSpecifier> { |
40 | static void enumeration(IO &IO, clang::AccessSpecifier &Value) { |
41 | IO.enumCase(Val&: Value, Str: "Public", ConstVal: clang::AccessSpecifier::AS_public); |
42 | IO.enumCase(Val&: Value, Str: "Protected", ConstVal: clang::AccessSpecifier::AS_protected); |
43 | IO.enumCase(Val&: Value, Str: "Private", ConstVal: clang::AccessSpecifier::AS_private); |
44 | IO.enumCase(Val&: Value, Str: "None", ConstVal: clang::AccessSpecifier::AS_none); |
45 | } |
46 | }; |
47 | |
48 | template <> struct ScalarEnumerationTraits<clang::TagTypeKind> { |
49 | static void enumeration(IO &IO, clang::TagTypeKind &Value) { |
50 | IO.enumCase(Val&: Value, Str: "Struct", ConstVal: clang::TagTypeKind::Struct); |
51 | IO.enumCase(Val&: Value, Str: "Interface", ConstVal: clang::TagTypeKind::Interface); |
52 | IO.enumCase(Val&: Value, Str: "Union", ConstVal: clang::TagTypeKind::Union); |
53 | IO.enumCase(Val&: Value, Str: "Class", ConstVal: clang::TagTypeKind::Class); |
54 | IO.enumCase(Val&: Value, Str: "Enum", ConstVal: clang::TagTypeKind::Enum); |
55 | } |
56 | }; |
57 | |
58 | template <> struct ScalarEnumerationTraits<InfoType> { |
59 | static void enumeration(IO &IO, InfoType &Value) { |
60 | IO.enumCase(Val&: Value, Str: "Namespace", ConstVal: InfoType::IT_namespace); |
61 | IO.enumCase(Val&: Value, Str: "Record", ConstVal: InfoType::IT_record); |
62 | IO.enumCase(Val&: Value, Str: "Function", ConstVal: InfoType::IT_function); |
63 | IO.enumCase(Val&: Value, Str: "Enum", ConstVal: InfoType::IT_enum); |
64 | IO.enumCase(Val&: Value, Str: "Default", ConstVal: InfoType::IT_default); |
65 | } |
66 | }; |
67 | |
68 | template <> struct ScalarEnumerationTraits<clang::doc::CommentKind> { |
69 | static void enumeration(IO &IO, clang::doc::CommentKind &Value) { |
70 | IO.enumCase(Val&: Value, Str: "FullComment", ConstVal: clang::doc::CommentKind::CK_FullComment); |
71 | IO.enumCase(Val&: Value, Str: "ParagraphComment", |
72 | ConstVal: clang::doc::CommentKind::CK_ParagraphComment); |
73 | IO.enumCase(Val&: Value, Str: "TextComment", ConstVal: clang::doc::CommentKind::CK_TextComment); |
74 | IO.enumCase(Val&: Value, Str: "InlineCommandComment", |
75 | ConstVal: clang::doc::CommentKind::CK_InlineCommandComment); |
76 | IO.enumCase(Val&: Value, Str: "HTMLStartTagComment", |
77 | ConstVal: clang::doc::CommentKind::CK_HTMLStartTagComment); |
78 | IO.enumCase(Val&: Value, Str: "HTMLEndTagComment", |
79 | ConstVal: clang::doc::CommentKind::CK_HTMLEndTagComment); |
80 | IO.enumCase(Val&: Value, Str: "BlockCommandComment", |
81 | ConstVal: clang::doc::CommentKind::CK_BlockCommandComment); |
82 | IO.enumCase(Val&: Value, Str: "ParamCommandComment", |
83 | ConstVal: clang::doc::CommentKind::CK_ParamCommandComment); |
84 | IO.enumCase(Val&: Value, Str: "TParamCommandComment", |
85 | ConstVal: clang::doc::CommentKind::CK_TParamCommandComment); |
86 | IO.enumCase(Val&: Value, Str: "VerbatimBlockComment", |
87 | ConstVal: clang::doc::CommentKind::CK_VerbatimBlockComment); |
88 | IO.enumCase(Val&: Value, Str: "VerbatimBlockLineComment", |
89 | ConstVal: clang::doc::CommentKind::CK_VerbatimBlockLineComment); |
90 | IO.enumCase(Val&: Value, Str: "VerbatimLineComment", |
91 | ConstVal: clang::doc::CommentKind::CK_VerbatimLineComment); |
92 | IO.enumCase(Val&: Value, Str: "Unknown", ConstVal: clang::doc::CommentKind::CK_Unknown); |
93 | } |
94 | }; |
95 | |
96 | // Scalars to YAML output. |
97 | template <unsigned U> struct ScalarTraits<SmallString<U>> { |
98 | |
99 | static void output(const SmallString<U> &S, void *, llvm::raw_ostream &OS) { |
100 | for (const auto &C : S) |
101 | OS << C; |
102 | } |
103 | |
104 | static StringRef input(StringRef Scalar, void *, SmallString<U> &Value) { |
105 | Value.assign(Scalar.begin(), Scalar.end()); |
106 | return StringRef(); |
107 | } |
108 | |
109 | static QuotingType mustQuote(StringRef) { return QuotingType::Single; } |
110 | }; |
111 | |
112 | template <> struct ScalarTraits<std::array<unsigned char, 20>> { |
113 | |
114 | static void output(const std::array<unsigned char, 20> &S, void *, |
115 | llvm::raw_ostream &OS) { |
116 | OS << toHex(Input: toStringRef(Input: S)); |
117 | } |
118 | |
119 | static StringRef input(StringRef Scalar, void *, |
120 | std::array<unsigned char, 20> &Value) { |
121 | if (Scalar.size() != 40) |
122 | return "Error: Incorrect scalar size for USR."; |
123 | Value = stringToSymbol(Value: Scalar); |
124 | return StringRef(); |
125 | } |
126 | |
127 | static SymbolID stringToSymbol(llvm::StringRef Value) { |
128 | SymbolID USR; |
129 | std::string HexString = fromHex(Input: Value); |
130 | std::copy(first: HexString.begin(), last: HexString.end(), result: USR.begin()); |
131 | return SymbolID(USR); |
132 | } |
133 | |
134 | static QuotingType mustQuote(StringRef) { return QuotingType::Single; } |
135 | }; |
136 | |
137 | // Helper functions to map infos to YAML. |
138 | |
139 | static void typeInfoMapping(IO &IO, TypeInfo &I) { |
140 | IO.mapOptional(Key: "Type", Val&: I.Type, Default: Reference()); |
141 | } |
142 | |
143 | static void fieldTypeInfoMapping(IO &IO, FieldTypeInfo &I) { |
144 | typeInfoMapping(IO, I); |
145 | IO.mapOptional(Key: "Name", Val&: I.Name, Default: SmallString<16>()); |
146 | IO.mapOptional(Key: "DefaultValue", Val&: I.DefaultValue, Default: SmallString<16>()); |
147 | } |
148 | |
149 | static void infoMapping(IO &IO, Info &I) { |
150 | IO.mapRequired(Key: "USR", Val&: I.USR); |
151 | IO.mapOptional(Key: "Name", Val&: I.Name, Default: SmallString<16>()); |
152 | IO.mapOptional(Key: "Path", Val&: I.Path, Default: SmallString<128>()); |
153 | IO.mapOptional(Key: "Namespace", Val&: I.Namespace, Default: llvm::SmallVector<Reference, 4>()); |
154 | IO.mapOptional(Key: "Description", Val&: I.Description); |
155 | } |
156 | |
157 | static void symbolInfoMapping(IO &IO, SymbolInfo &I) { |
158 | infoMapping(IO, I); |
159 | IO.mapOptional(Key: "DefLocation", Val&: I.DefLoc, Default: std::optional<Location>()); |
160 | IO.mapOptional(Key: "Location", Val&: I.Loc, Default: llvm::SmallVector<Location, 2>()); |
161 | } |
162 | |
163 | static void recordInfoMapping(IO &IO, RecordInfo &I) { |
164 | symbolInfoMapping(IO, I); |
165 | IO.mapOptional(Key: "TagType", Val&: I.TagType); |
166 | IO.mapOptional(Key: "IsTypeDef", Val&: I.IsTypeDef, Default: false); |
167 | IO.mapOptional(Key: "Members", Val&: I.Members); |
168 | IO.mapOptional(Key: "Bases", Val&: I.Bases); |
169 | IO.mapOptional(Key: "Parents", Val&: I.Parents, Default: llvm::SmallVector<Reference, 4>()); |
170 | IO.mapOptional(Key: "VirtualParents", Val&: I.VirtualParents, |
171 | Default: llvm::SmallVector<Reference, 4>()); |
172 | IO.mapOptional(Key: "ChildRecords", Val&: I.Children.Records, Default: std::vector<Reference>()); |
173 | IO.mapOptional(Key: "ChildFunctions", Val&: I.Children.Functions); |
174 | IO.mapOptional(Key: "ChildEnums", Val&: I.Children.Enums); |
175 | IO.mapOptional(Key: "ChildTypedefs", Val&: I.Children.Typedefs); |
176 | IO.mapOptional(Key: "Template", Val&: I.Template); |
177 | } |
178 | |
179 | static void commentInfoMapping(IO &IO, CommentInfo &I) { |
180 | IO.mapOptional(Key: "Kind", Val&: I.Kind, Default: CommentKind::CK_Unknown); |
181 | IO.mapOptional(Key: "Text", Val&: I.Text, Default: SmallString<64>()); |
182 | IO.mapOptional(Key: "Name", Val&: I.Name, Default: SmallString<16>()); |
183 | IO.mapOptional(Key: "Direction", Val&: I.Direction, Default: SmallString<8>()); |
184 | IO.mapOptional(Key: "ParamName", Val&: I.ParamName, Default: SmallString<16>()); |
185 | IO.mapOptional(Key: "CloseName", Val&: I.CloseName, Default: SmallString<16>()); |
186 | IO.mapOptional(Key: "SelfClosing", Val&: I.SelfClosing, Default: false); |
187 | IO.mapOptional(Key: "Explicit", Val&: I.Explicit, Default: false); |
188 | IO.mapOptional(Key: "Args", Val&: I.Args, Default: llvm::SmallVector<SmallString<16>, 4>()); |
189 | IO.mapOptional(Key: "AttrKeys", Val&: I.AttrKeys, |
190 | Default: llvm::SmallVector<SmallString<16>, 4>()); |
191 | IO.mapOptional(Key: "AttrValues", Val&: I.AttrValues, |
192 | Default: llvm::SmallVector<SmallString<16>, 4>()); |
193 | IO.mapOptional(Key: "Children", Val&: I.Children); |
194 | } |
195 | |
196 | // Template specialization to YAML traits for Infos. |
197 | |
198 | template <> struct MappingTraits<Location> { |
199 | static void mapping(IO &IO, Location &Loc) { |
200 | IO.mapOptional(Key: "LineNumber", Val&: Loc.StartLineNumber, Default: 0); |
201 | IO.mapOptional(Key: "Filename", Val&: Loc.Filename, Default: SmallString<32>()); |
202 | } |
203 | }; |
204 | |
205 | template <> struct MappingTraits<Reference> { |
206 | static void mapping(IO &IO, Reference &Ref) { |
207 | IO.mapOptional(Key: "Type", Val&: Ref.RefType, Default: InfoType::IT_default); |
208 | IO.mapOptional(Key: "Name", Val&: Ref.Name, Default: SmallString<16>()); |
209 | IO.mapOptional(Key: "QualName", Val&: Ref.QualName, Default: SmallString<16>()); |
210 | IO.mapOptional(Key: "USR", Val&: Ref.USR, Default: SymbolID()); |
211 | IO.mapOptional(Key: "Path", Val&: Ref.Path, Default: SmallString<128>()); |
212 | } |
213 | }; |
214 | |
215 | template <> struct MappingTraits<TypeInfo> { |
216 | static void mapping(IO &IO, TypeInfo &I) { typeInfoMapping(IO, I); } |
217 | }; |
218 | |
219 | template <> struct MappingTraits<FieldTypeInfo> { |
220 | static void mapping(IO &IO, FieldTypeInfo &I) { |
221 | typeInfoMapping(IO, I); |
222 | IO.mapOptional(Key: "Name", Val&: I.Name, Default: SmallString<16>()); |
223 | IO.mapOptional(Key: "DefaultValue", Val&: I.DefaultValue, Default: SmallString<16>()); |
224 | } |
225 | }; |
226 | |
227 | template <> struct MappingTraits<MemberTypeInfo> { |
228 | static void mapping(IO &IO, MemberTypeInfo &I) { |
229 | fieldTypeInfoMapping(IO, I); |
230 | // clang::AccessSpecifier::AS_none is used as the default here because it's |
231 | // the AS that shouldn't be part of the output. Even though AS_public is the |
232 | // default in the struct, it should be displayed in the YAML output. |
233 | IO.mapOptional(Key: "Access", Val&: I.Access, Default: clang::AccessSpecifier::AS_none); |
234 | IO.mapOptional(Key: "Description", Val&: I.Description); |
235 | } |
236 | }; |
237 | |
238 | template <> struct MappingTraits<NamespaceInfo> { |
239 | static void mapping(IO &IO, NamespaceInfo &I) { |
240 | infoMapping(IO, I); |
241 | IO.mapOptional(Key: "ChildNamespaces", Val&: I.Children.Namespaces, |
242 | Default: std::vector<Reference>()); |
243 | IO.mapOptional(Key: "ChildRecords", Val&: I.Children.Records, |
244 | Default: std::vector<Reference>()); |
245 | IO.mapOptional(Key: "ChildFunctions", Val&: I.Children.Functions); |
246 | IO.mapOptional(Key: "ChildEnums", Val&: I.Children.Enums); |
247 | IO.mapOptional(Key: "ChildTypedefs", Val&: I.Children.Typedefs); |
248 | } |
249 | }; |
250 | |
251 | template <> struct MappingTraits<RecordInfo> { |
252 | static void mapping(IO &IO, RecordInfo &I) { recordInfoMapping(IO, I); } |
253 | }; |
254 | |
255 | template <> struct MappingTraits<BaseRecordInfo> { |
256 | static void mapping(IO &IO, BaseRecordInfo &I) { |
257 | recordInfoMapping(IO, I); |
258 | IO.mapOptional(Key: "IsVirtual", Val&: I.IsVirtual, Default: false); |
259 | // clang::AccessSpecifier::AS_none is used as the default here because it's |
260 | // the AS that shouldn't be part of the output. Even though AS_public is the |
261 | // default in the struct, it should be displayed in the YAML output. |
262 | IO.mapOptional(Key: "Access", Val&: I.Access, Default: clang::AccessSpecifier::AS_none); |
263 | IO.mapOptional(Key: "IsParent", Val&: I.IsParent, Default: false); |
264 | } |
265 | }; |
266 | |
267 | template <> struct MappingTraits<EnumValueInfo> { |
268 | static void mapping(IO &IO, EnumValueInfo &I) { |
269 | IO.mapOptional(Key: "Name", Val&: I.Name); |
270 | IO.mapOptional(Key: "Value", Val&: I.Value); |
271 | IO.mapOptional(Key: "Expr", Val&: I.ValueExpr, Default: SmallString<16>()); |
272 | } |
273 | }; |
274 | |
275 | template <> struct MappingTraits<EnumInfo> { |
276 | static void mapping(IO &IO, EnumInfo &I) { |
277 | symbolInfoMapping(IO, I); |
278 | IO.mapOptional(Key: "Scoped", Val&: I.Scoped, Default: false); |
279 | IO.mapOptional(Key: "BaseType", Val&: I.BaseType); |
280 | IO.mapOptional(Key: "Members", Val&: I.Members); |
281 | } |
282 | }; |
283 | |
284 | template <> struct MappingTraits<TypedefInfo> { |
285 | static void mapping(IO &IO, TypedefInfo &I) { |
286 | symbolInfoMapping(IO, I); |
287 | IO.mapOptional(Key: "Underlying", Val&: I.Underlying.Type); |
288 | IO.mapOptional(Key: "IsUsing", Val&: I.IsUsing, Default: false); |
289 | } |
290 | }; |
291 | |
292 | template <> struct MappingTraits<FunctionInfo> { |
293 | static void mapping(IO &IO, FunctionInfo &I) { |
294 | symbolInfoMapping(IO, I); |
295 | IO.mapOptional(Key: "IsMethod", Val&: I.IsMethod, Default: false); |
296 | IO.mapOptional(Key: "Parent", Val&: I.Parent, Default: Reference()); |
297 | IO.mapOptional(Key: "Params", Val&: I.Params); |
298 | IO.mapOptional(Key: "ReturnType", Val&: I.ReturnType); |
299 | // clang::AccessSpecifier::AS_none is used as the default here because it's |
300 | // the AS that shouldn't be part of the output. Even though AS_public is the |
301 | // default in the struct, it should be displayed in the YAML output. |
302 | IO.mapOptional(Key: "Access", Val&: I.Access, Default: clang::AccessSpecifier::AS_none); |
303 | IO.mapOptional(Key: "Template", Val&: I.Template); |
304 | } |
305 | }; |
306 | |
307 | template <> struct MappingTraits<TemplateParamInfo> { |
308 | static void mapping(IO &IO, TemplateParamInfo &I) { |
309 | IO.mapOptional(Key: "Contents", Val&: I.Contents); |
310 | } |
311 | }; |
312 | |
313 | template <> struct MappingTraits<TemplateSpecializationInfo> { |
314 | static void mapping(IO &IO, TemplateSpecializationInfo &I) { |
315 | IO.mapOptional(Key: "SpecializationOf", Val&: I.SpecializationOf); |
316 | IO.mapOptional(Key: "Params", Val&: I.Params); |
317 | } |
318 | }; |
319 | |
320 | template <> struct MappingTraits<TemplateInfo> { |
321 | static void mapping(IO &IO, TemplateInfo &I) { |
322 | IO.mapOptional(Key: "Params", Val&: I.Params); |
323 | IO.mapOptional(Key: "Specialization", Val&: I.Specialization, |
324 | Default: std::optional<TemplateSpecializationInfo>()); |
325 | } |
326 | }; |
327 | |
328 | template <> struct MappingTraits<CommentInfo> { |
329 | static void mapping(IO &IO, CommentInfo &I) { commentInfoMapping(IO, I); } |
330 | }; |
331 | |
332 | template <> struct MappingTraits<std::unique_ptr<CommentInfo>> { |
333 | static void mapping(IO &IO, std::unique_ptr<CommentInfo> &I) { |
334 | if (I) |
335 | commentInfoMapping(IO, I&: *I); |
336 | } |
337 | }; |
338 | |
339 | } // end namespace yaml |
340 | } // end namespace llvm |
341 | |
342 | namespace clang { |
343 | namespace doc { |
344 | |
345 | /// Generator for YAML documentation. |
346 | class YAMLGenerator : public Generator { |
347 | public: |
348 | static const char *Format; |
349 | |
350 | llvm::Error generateDocs(StringRef RootDir, |
351 | llvm::StringMap<std::unique_ptr<doc::Info>> Infos, |
352 | const ClangDocContext &CDCtx) override; |
353 | llvm::Error generateDocForInfo(Info *I, llvm::raw_ostream &OS, |
354 | const ClangDocContext &CDCtx) override; |
355 | }; |
356 | |
357 | const char *YAMLGenerator::Format = "yaml"; |
358 | |
359 | llvm::Error |
360 | YAMLGenerator::generateDocs(StringRef RootDir, |
361 | llvm::StringMap<std::unique_ptr<doc::Info>> Infos, |
362 | const ClangDocContext &CDCtx) { |
363 | for (const auto &Group : Infos) { |
364 | doc::Info *Info = Group.getValue().get(); |
365 | |
366 | // Output file names according to the USR except the global namesapce. |
367 | // Anonymous namespaces are taken care of in serialization, so here we can |
368 | // safely assume an unnamed namespace is the global one. |
369 | llvm::SmallString<128> Path; |
370 | llvm::sys::path::native(path: RootDir, result&: Path); |
371 | if (Info->IT == InfoType::IT_namespace && Info->Name.empty()) { |
372 | llvm::sys::path::append(path&: Path, a: "index.yaml"); |
373 | } else { |
374 | llvm::sys::path::append(path&: Path, a: Group.getKey() + ".yaml"); |
375 | } |
376 | |
377 | std::error_code FileErr; |
378 | llvm::raw_fd_ostream InfoOS(Path, FileErr, llvm::sys::fs::OF_Text); |
379 | if (FileErr) { |
380 | return llvm::createStringError(EC: FileErr, Fmt: "Error opening file '%s'", |
381 | Vals: Path.c_str()); |
382 | } |
383 | |
384 | if (llvm::Error Err = generateDocForInfo(I: Info, OS&: InfoOS, CDCtx)) { |
385 | return Err; |
386 | } |
387 | } |
388 | |
389 | return llvm::Error::success(); |
390 | } |
391 | |
392 | llvm::Error YAMLGenerator::generateDocForInfo(Info *I, llvm::raw_ostream &OS, |
393 | const ClangDocContext &CDCtx) { |
394 | llvm::yaml::Output InfoYAML(OS); |
395 | switch (I->IT) { |
396 | case InfoType::IT_namespace: |
397 | InfoYAML << *static_cast<clang::doc::NamespaceInfo *>(I); |
398 | break; |
399 | case InfoType::IT_record: |
400 | InfoYAML << *static_cast<clang::doc::RecordInfo *>(I); |
401 | break; |
402 | case InfoType::IT_enum: |
403 | InfoYAML << *static_cast<clang::doc::EnumInfo *>(I); |
404 | break; |
405 | case InfoType::IT_function: |
406 | InfoYAML << *static_cast<clang::doc::FunctionInfo *>(I); |
407 | break; |
408 | case InfoType::IT_typedef: |
409 | InfoYAML << *static_cast<clang::doc::TypedefInfo *>(I); |
410 | break; |
411 | case InfoType::IT_default: |
412 | return llvm::createStringError(EC: llvm::inconvertibleErrorCode(), |
413 | S: "unexpected InfoType"); |
414 | } |
415 | return llvm::Error::success(); |
416 | } |
417 | |
418 | static GeneratorRegistry::Add<YAMLGenerator> YAML(YAMLGenerator::Format, |
419 | "Generator for YAML output."); |
420 | |
421 | // This anchor is used to force the linker to link in the generated object file |
422 | // and thus register the generator. |
423 | volatile int YAMLGeneratorAnchorSource = 0; |
424 | |
425 | } // namespace doc |
426 | } // namespace clang |
427 |
Definitions
- ScalarEnumerationTraits
- enumeration
- ScalarEnumerationTraits
- enumeration
- ScalarEnumerationTraits
- enumeration
- ScalarEnumerationTraits
- enumeration
- ScalarTraits
- output
- input
- mustQuote
- ScalarTraits
- output
- input
- stringToSymbol
- mustQuote
- typeInfoMapping
- fieldTypeInfoMapping
- infoMapping
- symbolInfoMapping
- recordInfoMapping
- commentInfoMapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- MappingTraits
- mapping
- YAMLGenerator
- Format
- generateDocs
- generateDocForInfo
- YAML
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more