Unravel Engine C++ Reference
Loading...
Searching...
No Matches
yaml.hpp
Go to the documentation of this file.
1
3/*
4 Copyright (c) 2017, Matt Continisio
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions are met:
9 * Redistributions of source code must retain the above copyright
10 notice, this list of conditions and the following disclaimer.
11 * Redistributions in binary form must reproduce the above copyright
12 notice, this list of conditions and the following disclaimer in the
13 documentation and/or other materials provided with the distribution.
14 * Neither the name of ser20 nor the
15 names of its contributors may be used to endorse or promote products
16 derived from this software without specific prior written permission.
17
18 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 DISCLAIMED. IN NO EVENT SHALL RANDOLPH VOORHIES OR SHANE GRANT BE LIABLE FOR ANY
22 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29#ifndef SER20_ARCHIVES_YAML_HPP_
30#define SER20_ARCHIVES_YAML_HPP_
31
32#include <ser20/details/util.hpp>
33#include <ser20/external/base64.hpp>
34#include <ser20/ser20.hpp>
35
36#include <yaml-cpp/yaml.h>
37
38#include <cstring>
39#include <limits>
40#include <sstream>
41#include <stack>
42#include <string>
43#include <vector>
44
45namespace ser20
46{
47
49 : public OutputArchive<YAMLOutputArchive>
50 , public traits::TextArchive
51{
52 enum class NodeType
53 {
54 StartObject,
55 InObject,
56 StartArray,
57 InArray
58 };
59
60public:
61 static inline constexpr bool is_binary = false;
62
63 YAMLOutputArchive(std::ostream& stream) : OutputArchive<YAMLOutputArchive>(this), out(stream), nextName(nullptr)
64 {
65 nameCounter.push(0);
66 nodeStack.push(NodeType::StartObject);
67 }
68
70 {
71 if(nodeStack.top() == NodeType::InObject)
72 {
73 emitter << YAML::EndMap;
74 }
75 else if(nodeStack.top() == NodeType::InArray)
76 {
77 emitter << YAML::EndSeq;
78 }
79
80 out << emitter.c_str();
81 }
82
84
86 void saveBinaryValue(const void* data, size_t size, const char* name = nullptr)
87 {
89 writeName();
90
91 auto base64string = base64::encode(reinterpret_cast<const unsigned char*>(data), size);
92 saveValue(base64string);
93 };
94
96
100
102
107 {
108 writeName();
109 nodeStack.push(NodeType::StartObject);
110 nameCounter.push(0);
111 }
112
115 {
116 // if we ended up serializing an empty object or array, writeName
117 // will never have been called - so start and then immediately end
118 // the object/array.
119 //
120 // We'll also end any object/arrays we happen to be in
121 switch(nodeStack.top())
122 {
123 case NodeType::StartArray:
124 emitter << YAML::BeginSeq;
125 case NodeType::InArray:
126 emitter << YAML::EndSeq;
127 break;
128 case NodeType::StartObject:
129 emitter << YAML::BeginMap;
130 case NodeType::InObject:
131 emitter << YAML::EndMap;
132 break;
133 }
134
135 nodeStack.pop();
136 nameCounter.pop();
137 }
138
140 void setNextName(const char* name)
141 {
142 nextName = name;
143 }
144
146 void saveValue(bool b)
147 {
148 emitter << b;
149 }
151 void saveValue(int i)
152 {
153 emitter << i;
154 }
156 void saveValue(unsigned u)
157 {
158 emitter << u;
159 }
161 void saveValue(int64_t i64)
162 {
163 emitter << i64;
164 }
166 void saveValue(uint64_t u64)
167 {
168 emitter << u64;
169 }
171 void saveValue(double d)
172 {
173 emitter << d;
174 }
176 void saveValue(std::string const& s)
177 {
178 emitter << s;
179 }
181 void saveValue(char const* s)
182 {
183 emitter << s;
184 }
186 void saveValue(std::nullptr_t)
187 {
188 emitter << nullptr;
189 }
190
191private:
192 // Some compilers/OS have difficulty disambiguating the above for various flavors of longs, so we provide
193 // special overloads to handle these cases.
194
196 template<class T>
197 inline void saveLong(T l)
198 requires(sizeof(T) == sizeof(std::int32_t) && std::is_signed_v<T>)
199 {
200 saveValue(static_cast<std::int32_t>(l));
201 }
202
204 template<class T>
205 inline void saveLong(T l)
206 requires(sizeof(T) != sizeof(std::int32_t) && std::is_signed_v<T>)
207 {
208 saveValue(static_cast<std::int64_t>(l));
209 }
210
212 template<class T>
213 inline void saveLong(T lu)
214 requires(sizeof(T) == sizeof(std::int32_t) && std::is_unsigned_v<T>)
215 {
216 saveValue(static_cast<std::uint32_t>(lu));
217 }
218
220 template<class T>
221 inline void saveLong(T lu)
222 requires(sizeof(T) != sizeof(std::int32_t) && std::is_unsigned_v<T>)
223 {
224 saveValue(static_cast<std::uint64_t>(lu));
225 }
226
227public:
228#if defined(_MSC_VER) && _MSC_VER < 1916
230 void saveValue(unsigned long lu)
231 {
232 saveLong(lu);
233 };
234#else // _MSC_VER
236 template<class T>
237 inline void saveValue(T t)
238 requires(std::is_same_v<T, long> && !std::is_same_v<T, int> && !std::is_same_v<T, std::int64_t>)
239 {
240 saveLong(t);
241 }
242
244 template<class T>
245 inline void saveValue(T t)
246 requires(std::is_same_v<T, unsigned long> && !std::is_same_v<T, unsigned> && !std::is_same_v<T, std::uint64_t>)
247 {
248 saveLong(t);
249 }
250#endif // _MSC_VER
251
253
255 template<class T>
256 inline void saveValue(T const& t)
257 requires(std::is_arithmetic_v<T> && !std::is_same_v<T, long> && !std::is_same_v<T, unsigned long> &&
258 !std::is_same_v<T, std::int64_t> && !std::is_same_v<T, std::uint64_t> &&
259 !std::is_same_v<T, long long> && !std::is_same_v<T, unsigned long long> &&
260 (sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long)))
261 {
262 std::stringstream ss;
263 ss.precision(std::numeric_limits<long double>::max_digits10);
264 ss << t;
265 saveValue(ss.str());
266 }
267
269
282 {
283 NodeType& nodeType = nodeStack.top();
284
285 // Start up either an object or an array, depending on state
286 if(nodeType == NodeType::StartArray)
287 {
288 emitter << YAML::BeginSeq;
289 nodeType = NodeType::InArray;
290 }
291 else if(nodeType == NodeType::StartObject)
292 {
293 emitter << YAML::BeginMap;
294 nodeType = NodeType::InObject;
295 }
296
297 // Array types do not output names
298 if(nodeType == NodeType::InArray)
299 {
300 return;
301 }
302
303 emitter << YAML::Key;
304
305 if(nextName == nullptr)
306 {
307 std::string name = "value" + std::to_string(nameCounter.top()++) + "\0";
309 }
310 else
311 {
312 saveValue(nextName);
313 nextName = nullptr;
314 }
315
316 emitter << YAML::Value;
317 }
318
321 {
322 nodeStack.top() = NodeType::StartArray;
323 }
324
326
327private:
328 std::ostream& out;
329 YAML::Emitter emitter;
330 char const* nextName;
331 std::stack<uint32_t> nameCounter;
332 std::stack<NodeType> nodeStack;
333
334}; // YAMLOutputArchive
335
337 : public InputArchive<YAMLInputArchive>
338 , public traits::TextArchive
339{
340 typedef YAML::const_iterator YAMLIterator;
341
342public:
343 YAMLInputArchive(std::istream& stream)
344 : InputArchive<YAMLInputArchive>(this)
345 , itsNextName(nullptr)
346 , itsDocument(YAML::Load(stream))
347 {
348 if(itsDocument.IsSequence())
349 {
350 itsIteratorStack.emplace_back(itsDocument.begin(), itsDocument.end(), Iterator::Type::Value);
351 }
352
353 else
354 {
355 itsIteratorStack.emplace_back(itsDocument.begin(), itsDocument.end(), Iterator::Type::Member);
356 }
357 }
358
359 ~YAMLInputArchive() noexcept = default;
360
362
367 void loadBinaryValue(void* data, size_t size, const char* name = nullptr)
368 {
369 itsNextName = name;
370
371 std::string encoded;
372 loadValue(encoded);
373 auto decoded = base64::decode(encoded);
374
375 if(size != decoded.size())
376 {
377 throw Exception("Decoded binary data size does not match specified size");
378 }
379
380 std::memcpy(data, decoded.data(), decoded.size());
381 itsNextName = nullptr;
382 };
383
384private:
386
390
392 class Iterator
393 {
394 public:
395 enum Type
396 {
397 Value,
398 Member,
399 Null_
400 };
401
402 Iterator() : itsType(Null_)
403 {
404 }
405
406 Iterator(YAMLIterator begin, YAMLIterator end, Type type)
407 : itsItBegin(begin)
408 , itsItEnd(end)
409 , itsItCurrent(begin)
410 , itsType(type)
411 {
412 if(std::distance(begin, end) == 0)
413 {
414 itsType = Null_;
415 }
416
417 if(itsType == Member && itsItCurrent != itsItEnd)
418 {
419 currentName = itsItCurrent->first.as<std::string>();
420 }
421 }
422
424 Iterator& operator++()
425 {
426 ++itsItCurrent;
427 if(itsType == Member && itsItCurrent != itsItEnd)
428 {
429 currentName = itsItCurrent->first.as<std::string>();
430 }
431 return *this;
432 }
433
435 YAML::Node value()
436 {
437 switch(itsType)
438 {
439 case Value:
440 return *itsItCurrent;
441 case Member:
442 return itsItCurrent->second;
443 default:
444 throw ser20::Exception(
445 "YAMLInputArchive internal error: null or empty iterator to object or array!");
446 }
447 }
448
450 const char* name() const
451 {
452 if(currentName != "")
453 {
454 return currentName.c_str();
455 }
456 else
457 {
458 return nullptr;
459 }
460 }
461
463
464 inline void search(const char* searchName)
465 {
466 auto index = 0;
467 const auto len = std::strlen(searchName);
468 for(itsItCurrent = itsItBegin; itsItCurrent != itsItEnd; ++itsItCurrent, ++index)
469 {
470 currentName = itsItCurrent->first.as<std::string>();
471 if((std::strncmp(searchName, currentName.c_str(), len) == 0) &&
472 (std::strlen(currentName.c_str()) == len))
473 {
474 return;
475 }
476 }
477
478 throw Exception("YAML Parsing failed - provided NVP (" + std::string(searchName) + ") not found");
479 }
480
481 private:
482 YAMLIterator itsItBegin, itsItEnd;
483 YAMLIterator itsItCurrent;
484 std::string currentName;
485 Type itsType;
486 };
487
489
497 inline void search()
498 {
499 // The name an NVP provided with setNextName()
500 if(itsNextName)
501 {
502 // The actual name of the current node
503 auto const actualName = itsIteratorStack.back().name();
504
505 // Do a search if we don't see a name coming up, or if the names don't match
506 if(!actualName || std::strcmp(itsNextName, actualName) != 0)
507 {
508 itsIteratorStack.back().search(itsNextName);
509 }
510 }
511
512 itsNextName = nullptr;
513 }
514
515public:
517
527 {
528 search();
529
530 auto value = itsIteratorStack.back().value();
531
532 if(value.IsSequence())
533 {
534 itsIteratorStack.emplace_back(value.begin(), value.end(), Iterator::Type::Value);
535 }
536 else
537 {
538 itsIteratorStack.emplace_back(value.begin(), value.end(), Iterator::Type::Member);
539 }
540 }
541
544 {
545 itsIteratorStack.pop_back();
546 ++itsIteratorStack.back();
547 }
548
550
551 const char* getNodeName() const
552 {
553 return itsIteratorStack.back().name();
554 }
555
557 void setNextName(const char* name)
558 {
559 itsNextName = name;
560 }
561
563 template<class T>
564 inline void loadValue(T& val)
565 requires(std::is_signed<T>::value && sizeof(T) < sizeof(int64_t))
566 {
567 search();
568
569 val = static_cast<T>(itsIteratorStack.back().value().as<int>());
570 ++itsIteratorStack.back();
571 }
572
574 template<class T>
575 inline void loadValue(T& val)
576 requires(std::is_unsigned<T>::value && sizeof(T) < sizeof(uint64_t) && !std::is_same<bool, T>::value)
577 {
578 search();
579
580 val = static_cast<T>(itsIteratorStack.back().value().as<unsigned int>());
581 ++itsIteratorStack.back();
582 }
583
585 void loadValue(bool& val)
586 {
587 search();
588 val = itsIteratorStack.back().value().as<bool>();
589 ++itsIteratorStack.back();
590 }
592 void loadValue(int64_t& val)
593 {
594 search();
595 val = itsIteratorStack.back().value().as<int64_t>();
596 ++itsIteratorStack.back();
597 }
599 void loadValue(uint64_t& val)
600 {
601 search();
602 val = itsIteratorStack.back().value().as<uint64_t>();
603 ++itsIteratorStack.back();
604 }
606 void loadValue(float& val)
607 {
608 search();
609 val = static_cast<float>(itsIteratorStack.back().value().as<float>());
610 ++itsIteratorStack.back();
611 }
613 void loadValue(double& val)
614 {
615 search();
616 val = itsIteratorStack.back().value().as<double>();
617 ++itsIteratorStack.back();
618 }
620 void loadValue(std::string& val)
621 {
622 search();
623 val = itsIteratorStack.back().value().as<std::string>();
624 ++itsIteratorStack.back();
625 }
627 void loadValue(std::nullptr_t&)
628 {
629 search(); /*TodoSER20_RAPIDJSON_ASSERT(itsIteratorStack.back().value().IsNull());*/
630 ++itsIteratorStack.back();
631 }
632
633// Special cases to handle various flavors of long, which tend to conflict with
634// the int32_t or int64_t on various compiler/OS combinations. MSVC doesn't need any of this.
635#ifndef _MSC_VER
636private:
638 template<class T>
639 inline typename std::enable_if<sizeof(T) == sizeof(std::int32_t) && std::is_signed<T>::value, void>::type loadLong(
640 T& l)
641 {
642 loadValue(reinterpret_cast<std::int32_t&>(l));
643 }
644
646 template<class T>
647 inline typename std::enable_if<sizeof(T) == sizeof(std::int64_t) && std::is_signed<T>::value, void>::type loadLong(
648 T& l)
649 {
650 loadValue(reinterpret_cast<std::int64_t&>(l));
651 }
652
654 template<class T>
655 inline typename std::enable_if<sizeof(T) == sizeof(std::uint32_t) && !std::is_signed<T>::value, void>::type
656 loadLong(T& lu)
657 {
658 loadValue(reinterpret_cast<std::uint32_t&>(lu));
659 }
660
662 template<class T>
663 inline typename std::enable_if<sizeof(T) == sizeof(std::uint64_t) && !std::is_signed<T>::value, void>::type
664 loadLong(T& lu)
665 {
666 loadValue(reinterpret_cast<std::uint64_t&>(lu));
667 }
668
669public:
671 template<class T>
672 inline typename std::enable_if<std::is_same<T, long>::value && sizeof(T) >= sizeof(std::int64_t) &&
673 !std::is_same<T, std::int64_t>::value,
674 void>::type
676 {
677 loadLong(t);
678 }
679
681 template<class T>
682 inline typename std::enable_if<std::is_same<T, unsigned long>::value && sizeof(T) >= sizeof(std::uint64_t) &&
683 !std::is_same<T, std::uint64_t>::value,
684 void>::type
686 {
687 loadLong(t);
688 }
689#endif // _MSC_VER
690
691private:
693 void stringToNumber(std::string const& str, long long& val)
694 {
695 val = std::stoll(str);
696 }
698 void stringToNumber(std::string const& str, unsigned long long& val)
699 {
700 val = std::stoull(str);
701 }
703 void stringToNumber(std::string const& str, long double& val)
704 {
705 val = std::stold(str);
706 }
707
708public:
710 template<class T>
711 inline void loadValue(T& val)
712 requires(std::is_arithmetic<T>::value && !std::is_same<T, long>::value &&
713 !std::is_same<T, unsigned long>::value && !std::is_same<T, std::int64_t>::value &&
714 !std::is_same<T, std::uint64_t>::value &&
715 (sizeof(T) >= sizeof(long double) || sizeof(T) >= sizeof(long long)))
716 {
717 std::string encoded;
718 loadValue(encoded);
719 stringToNumber(encoded, val);
720 }
721
723 void loadSize(size_type& size)
724 {
725 if(itsIteratorStack.size() == 1)
726 {
727 size = itsDocument.size();
728 }
729 else
730 {
731 size = (itsIteratorStack.rbegin() + 1)->value().size();
732 }
733 }
734
736
737private:
738 const char* itsNextName;
739 std::vector<Iterator> itsIteratorStack;
740 YAML::Node itsDocument;
741
742}; // YAMLInputArchive
743
744// ######################################################################
745// YAMLArchive prologue and epilogue functions
746// ######################################################################
747
748// ######################################################################
750
751template<class T>
752inline void prologue(YAMLOutputArchive&, NameValuePair<T> const&)
753{
754}
755
757template<class T>
758inline void prologue(YAMLInputArchive&, NameValuePair<T> const&)
759{
760}
761
762// ######################################################################
764
765template<class T>
766inline void epilogue(YAMLOutputArchive&, NameValuePair<T> const&)
767{
768}
769
771
772template<class T>
773inline void epilogue(YAMLInputArchive&, NameValuePair<T> const&)
774{
775}
776
777// ######################################################################
779
781template<class T>
782inline void prologue(YAMLOutputArchive& ar, SizeTag<T> const&)
783{
784 ar.makeArray();
785}
786
788template<class T>
789inline void prologue(YAMLInputArchive&, SizeTag<T> const&)
790{
791}
792
793// ######################################################################
795
796template<class T>
797inline void epilogue(YAMLOutputArchive&, SizeTag<T> const&)
798{
799}
800
802template<class T>
803inline void epilogue(YAMLInputArchive&, SizeTag<T> const&)
804{
805}
806
807// ######################################################################
809
813template<class T>
814inline void prologue(YAMLOutputArchive& ar, T const&)
815 requires(!std::is_arithmetic_v<T> &&
816 !traits::has_minimal_base_class_serialization<T,
817 traits::has_minimal_output_serialization,
818 YAMLOutputArchive>::value &&
819 !traits::has_minimal_output_serialization<T, YAMLOutputArchive>::value)
820{
821 ar.startNode();
822}
823
825template<class T>
826inline void prologue(YAMLInputArchive& ar, T const&)
827 requires(!std::is_arithmetic_v<T> &&
828 !traits::has_minimal_base_class_serialization<T,
829 traits::has_minimal_input_serialization,
830 YAMLInputArchive>::value &&
831 !traits::has_minimal_input_serialization<T, YAMLInputArchive>::value)
832{
833 ar.startNode();
834}
835
836// ######################################################################
838
841template<class T>
842inline void epilogue(YAMLOutputArchive& ar, T const&)
843 requires(!std::is_arithmetic_v<T> &&
844 !traits::has_minimal_base_class_serialization<T,
845 traits::has_minimal_output_serialization,
846 YAMLOutputArchive>::value &&
847 !traits::has_minimal_output_serialization<T, YAMLOutputArchive>::value)
848{
849 ar.finishNode();
850}
851
853template<class T>
854inline void epilogue(YAMLInputArchive& ar, T const&)
855 requires(!std::is_arithmetic_v<T> &&
856 !traits::has_minimal_base_class_serialization<T,
857 traits::has_minimal_input_serialization,
858 YAMLInputArchive>::value &&
859 !traits::has_minimal_input_serialization<T, YAMLInputArchive>::value)
860{
861 ar.finishNode();
862}
863
864// ######################################################################
866inline void prologue(YAMLOutputArchive& ar, std::nullptr_t const&)
867{
868 ar.writeName();
869}
870
872inline void prologue(YAMLInputArchive&, std::nullptr_t const&)
873{
874}
875
876// ######################################################################
878inline void epilogue(YAMLOutputArchive&, std::nullptr_t const&)
879{
880}
881
883inline void epilogue(YAMLInputArchive&, std::nullptr_t const&)
884{
885}
886
887// ######################################################################
889template<class T>
890inline void prologue(YAMLOutputArchive& ar, T const&)
891 requires(std::is_arithmetic_v<T>)
892{
893 ar.writeName();
894}
895
897template<class T>
898inline void prologue(YAMLInputArchive&, T const&)
899 requires(std::is_arithmetic_v<T>)
900{
901}
902
903// ######################################################################
905template<class T>
906inline void epilogue(YAMLOutputArchive&, T const&)
907 requires(std::is_arithmetic_v<T>)
908{
909}
910
912template<class T>
913inline void epilogue(YAMLInputArchive&, T const&)
914 requires(std::is_arithmetic_v<T>)
915{
916}
917
918// ######################################################################
920template<class CharT, class Traits, class Alloc>
921inline void prologue(YAMLOutputArchive& ar, std::basic_string<CharT, Traits, Alloc> const&)
922{
923 ar.writeName();
924}
925
927template<class CharT, class Traits, class Alloc>
928inline void prologue(YAMLInputArchive&, std::basic_string<CharT, Traits, Alloc> const&)
929{
930}
931
932// ######################################################################
934template<class CharT, class Traits, class Alloc>
935inline void epilogue(YAMLOutputArchive&, std::basic_string<CharT, Traits, Alloc> const&)
936{
937}
938
940template<class CharT, class Traits, class Alloc>
941inline void epilogue(YAMLInputArchive&, std::basic_string<CharT, Traits, Alloc> const&)
942{
943}
944
945// ######################################################################
946// Common YAMLArchive serialization functions
947// ######################################################################
949template<class T>
950inline void SER20_SAVE_FUNCTION_NAME(YAMLOutputArchive& ar, NameValuePair<T> const& t)
951{
952 ar.setNextName(t.name);
953 ar(t.value);
954}
955
956template<class T>
957inline void SER20_LOAD_FUNCTION_NAME(YAMLInputArchive& ar, NameValuePair<T>& t)
958{
959 ar.setNextName(t.name);
960 ar(t.value);
961}
962
964inline void SER20_SAVE_FUNCTION_NAME(YAMLOutputArchive& ar, std::nullptr_t const& t)
965{
966 ar.saveValue(t);
967}
968
970inline void SER20_LOAD_FUNCTION_NAME(YAMLInputArchive& ar, std::nullptr_t& t)
971{
972 ar.loadValue(t);
973}
974
976template<class T>
977inline void SER20_SAVE_FUNCTION_NAME(YAMLOutputArchive& ar, T const& t)
978 requires(std::is_arithmetic_v<T>)
979{
980 ar.saveValue(t);
981}
982
984template<class T>
986 requires(std::is_arithmetic_v<T>)
987{
988 ar.loadValue(t);
989}
990
992template<class CharT, class Traits, class Alloc>
993inline void SER20_SAVE_FUNCTION_NAME(YAMLOutputArchive& ar, std::basic_string<CharT, Traits, Alloc> const& str)
994{
995 ar.saveValue(str);
996}
997
999template<class CharT, class Traits, class Alloc>
1000inline void SER20_LOAD_FUNCTION_NAME(YAMLInputArchive& ar, std::basic_string<CharT, Traits, Alloc>& str)
1001{
1002 ar.loadValue(str);
1003}
1004
1005// ######################################################################
1007template<class T>
1008inline void SER20_SAVE_FUNCTION_NAME(YAMLOutputArchive&, SizeTag<T> const&)
1009{
1010 // nothing to do here, we don't explicitly save the size
1011}
1012
1014template<class T>
1015inline void SER20_LOAD_FUNCTION_NAME(YAMLInputArchive& ar, SizeTag<T>& st)
1016{
1017 ar.loadSize(st.size);
1018}
1019
1020} // namespace ser20
1021
1022// register archives for polymorphic support
1023SER20_REGISTER_ARCHIVE(ser20::YAMLInputArchive)
1024SER20_REGISTER_ARCHIVE(ser20::YAMLOutputArchive)
1025
1026// tie input and output archives together
1027SER20_SETUP_ARCHIVE_TRAITS(ser20::YAMLInputArchive, ser20::YAMLOutputArchive)
1028
1029#endif // SER20_ARCHIVES_YAML_HPP_
entt::handle b
manifold_type type
void loadValue(bool &val)
Loads a value from the current node - bool overload.
Definition yaml.hpp:585
void loadValue(T &val)
Loads a value from the current node - long double and long long overloads.
Definition yaml.hpp:711
void startNode()
Starts a new node, going into its proper iterator.
Definition yaml.hpp:526
void setNextName(const char *name)
Sets the name for the next node created with startNode.
Definition yaml.hpp:557
void loadValue(T &val)
Loads a value from the current node - small unsigned overload.
Definition yaml.hpp:575
void loadValue(T &val)
Loads a value from the current node - small signed overload.
Definition yaml.hpp:564
const char * getNodeName() const
Retrieves the current node name.
Definition yaml.hpp:551
void loadValue(uint64_t &val)
Loads a value from the current node - uint64 overload.
Definition yaml.hpp:599
YAMLInputArchive(std::istream &stream)
Definition yaml.hpp:343
void loadValue(float &val)
Loads a value from the current node - float overload.
Definition yaml.hpp:606
~YAMLInputArchive() noexcept=default
void loadValue(double &val)
Loads a value from the current node - double overload.
Definition yaml.hpp:613
void loadSize(size_type &size)
Loads the size for a SizeTag.
Definition yaml.hpp:723
std::enable_if< std::is_same< T, long >::value &&sizeof(T)>=sizeof(std::int64_t)&&!std::is_same< T, std::int64_t >::value, void >::type loadValue(T &t)
Serialize a long if it would not be caught otherwise.
Definition yaml.hpp:675
void loadValue(std::nullptr_t &)
Loads a nullptr from the current node.
Definition yaml.hpp:627
void loadBinaryValue(void *data, size_t size, const char *name=nullptr)
Loads some binary data, encoded as a base64 string.
Definition yaml.hpp:367
std::enable_if< std::is_same< T, unsignedlong >::value &&sizeof(T)>=sizeof(std::uint64_t)&&!std::is_same< T, std::uint64_t >::value, void >::type loadValue(T &t)
Serialize an unsigned long if it would not be caught otherwise.
Definition yaml.hpp:685
void loadValue(int64_t &val)
Loads a value from the current node - int64 overload.
Definition yaml.hpp:592
void loadValue(std::string &val)
Loads a value from the current node - string overload.
Definition yaml.hpp:620
void finishNode()
Finishes the most recently started node.
Definition yaml.hpp:543
void saveBinaryValue(const void *data, size_t size, const char *name=nullptr)
Saves some binary data, encoded as a base64 string, with an optional name.
Definition yaml.hpp:86
void saveValue(T t)
Serialize an unsigned long if it would not be caught otherwise.
Definition yaml.hpp:245
void startNode()
Starts a new node in the YAML output.
Definition yaml.hpp:106
void saveValue(std::nullptr_t)
Saves a nullptr to the current node.
Definition yaml.hpp:186
void saveValue(int i)
Saves an int to the current node.
Definition yaml.hpp:151
void saveValue(std::string const &s)
Saves a string to the current node.
Definition yaml.hpp:176
void saveValue(int64_t i64)
Saves an int64 to the current node.
Definition yaml.hpp:161
void makeArray()
Designates that the current node should be output as an array, not an object.
Definition yaml.hpp:320
static constexpr bool is_binary
Definition yaml.hpp:61
void saveValue(T t)
Serialize a long if it would not be caught otherwise.
Definition yaml.hpp:237
YAMLOutputArchive(std::ostream &stream)
Definition yaml.hpp:63
void saveValue(bool b)
Saves a bool to the current node.
Definition yaml.hpp:146
~YAMLOutputArchive() noexcept
Definition yaml.hpp:69
void saveValue(T const &t)
Save exotic arithmetic as strings to current node.
Definition yaml.hpp:256
void setNextName(const char *name)
Sets the name for the next node created with startNode.
Definition yaml.hpp:140
void finishNode()
Designates the most recently added node as finished.
Definition yaml.hpp:114
void saveValue(double d)
Saves a double to the current node.
Definition yaml.hpp:171
void saveValue(unsigned u)
Saves a uint to the current node.
Definition yaml.hpp:156
void writeName()
Write the name of the upcoming node and prepare object/array state.
Definition yaml.hpp:281
void saveValue(uint64_t u64)
Saves a uint64 to the current node.
Definition yaml.hpp:166
void saveValue(char const *s)
Saves a const char * to the current node.
Definition yaml.hpp:181
std::string name
Definition hub.cpp:27
encoder * begin()
Definition graphics.cpp:265
void end(encoder *_encoder)
Definition graphics.cpp:270
Definition yaml.hpp:46
void prologue(YAMLOutputArchive &, NameValuePair< T > const &)
Prologue for NVPs for YAML archives.
Definition yaml.hpp:752
void SER20_LOAD_FUNCTION_NAME(YAMLInputArchive &ar, NameValuePair< T > &t)
Definition yaml.hpp:957
void SER20_SAVE_FUNCTION_NAME(YAMLOutputArchive &ar, NameValuePair< T > const &t)
Serializing NVP types to YAML.
Definition yaml.hpp:950
void epilogue(YAMLOutputArchive &, NameValuePair< T > const &)
Epilogue for NVPs for YAML archives.
Definition yaml.hpp:766
size()=default