53 #include <cereal/cereal.hpp> 55 #include <bsoncxx/builder/core.hpp> 56 #include <bsoncxx/types.hpp> 57 #include <bsoncxx/types/value.hpp> 59 #include <boson/stdx/optional.hpp> 62 #include <cereal/types/deque.hpp> 63 #include <cereal/types/forward_list.hpp> 64 #include <cereal/types/list.hpp> 65 #include <cereal/types/set.hpp> 66 #include <cereal/types/unordered_set.hpp> 67 #include <cereal/types/valarray.hpp> 68 #include <cereal/types/vector.hpp> 76 explicit Exception(
const std::string& desc) : std::runtime_error(desc) {
78 explicit Exception(
const char* desc) : std::runtime_error(desc) {
92 void setUnderlyingBSONData(std::shared_ptr<uint8_t> ptr,
size_t size) {
93 _underlyingBSONData = ptr;
94 _underlyingBSONDataSize = size;
97 const bsoncxx::document::view getUnderlyingBSONData() {
98 return bsoncxx::document::view{_underlyingBSONData.get(), _underlyingBSONDataSize};
102 std::shared_ptr<uint8_t> _underlyingBSONData;
106 size_t _underlyingBSONDataSize;
113 template <
class BsonT>
115 static constexpr
auto value = std::is_same<BsonT, bsoncxx::types::b_double>::value ||
116 std::is_same<BsonT, bsoncxx::types::b_utf8>::value ||
117 std::is_same<BsonT, bsoncxx::types::b_document>::value ||
118 std::is_same<BsonT, bsoncxx::types::b_array>::value ||
119 std::is_same<BsonT, bsoncxx::types::b_binary>::value ||
120 std::is_same<BsonT, bsoncxx::types::b_oid>::value ||
121 std::is_same<BsonT, bsoncxx::types::b_bool>::value ||
122 std::is_same<BsonT, bsoncxx::types::b_date>::value ||
123 std::is_same<BsonT, bsoncxx::types::b_int32>::value ||
124 std::is_same<BsonT, bsoncxx::types::b_int64>::value ||
125 std::is_same<BsonT, bsoncxx::oid>::value ||
126 std::is_same<BsonT, bsoncxx::types::b_undefined>::value ||
127 std::is_same<BsonT, bsoncxx::types::b_null>::value ||
128 std::is_same<BsonT, bsoncxx::types::b_regex>::value ||
129 std::is_same<BsonT, bsoncxx::types::b_code>::value ||
130 std::is_same<BsonT, bsoncxx::types::b_symbol>::value ||
131 std::is_same<BsonT, bsoncxx::types::b_codewscope>::value ||
132 std::is_same<BsonT, bsoncxx::types::b_timestamp>::value ||
133 std::is_same<BsonT, bsoncxx::types::b_minkey>::value ||
134 std::is_same<BsonT, bsoncxx::types::b_maxkey>::value ||
135 std::is_same<BsonT, bsoncxx::types::b_dbpointer>::value;
142 template <
class BsonT>
144 static constexpr
auto value = std::is_same<BsonT, bsoncxx::types::b_utf8>::value ||
145 std::is_same<BsonT, bsoncxx::types::b_document>::value ||
146 std::is_same<BsonT, bsoncxx::types::b_array>::value ||
147 std::is_same<BsonT, bsoncxx::types::b_binary>::value ||
148 std::is_same<BsonT, bsoncxx::types::b_regex>::value ||
149 std::is_same<BsonT, bsoncxx::types::b_dbpointer>::value ||
150 std::is_same<BsonT, bsoncxx::types::b_code>::value ||
151 std::is_same<BsonT, bsoncxx::types::b_symbol>::value ||
152 std::is_same<BsonT, bsoncxx::types::b_codewscope>::value;
159 enum class OutputNodeType { StartObject, InObject, StartArray, InArray };
161 using BSONBuilder = bsoncxx::builder::core;
185 _writeStream{stream},
187 _objAsRootElement{
false},
188 _dotNotationMode{dotNotationMode},
189 _arrayNestingLevel{0} {
198 _writeStream.write(reinterpret_cast<const char*>(_bsonBuilder.view_document().data()),
199 _bsonBuilder.view_document().length());
200 _bsonBuilder.clear();
208 void writeDocIfRoot() {
209 if (_nodeTypeStack.empty()) {
221 void startNode(
bool inheritsUnderlyingBSONDataBase) {
223 _nodeTypeStack.push(OutputNodeType::StartObject);
224 _curNodeInheritsUnderlyingBSONDataBase.push(inheritsUnderlyingBSONDataBase);
239 if (_nodeTypeStack.empty()) {
243 switch (_nodeTypeStack.top()) {
244 case OutputNodeType::StartArray:
245 _bsonBuilder.open_array();
246 ++_arrayNestingLevel;
248 case OutputNodeType::InArray:
249 _bsonBuilder.close_array();
250 --_arrayNestingLevel;
252 case OutputNodeType::StartObject:
255 if (!_dotNotationMode || _arrayNestingLevel > 0) {
256 if (_nodeTypeStack.size() > 1 || _objAsRootElement) {
257 _bsonBuilder.open_document();
259 }
else if (_nodeTypeStack.size() > 1) {
262 _embeddedNameStack.push_back(
"");
265 case OutputNodeType::InObject:
268 if (!_dotNotationMode || _arrayNestingLevel > 0) {
269 if (_nodeTypeStack.size() > 1) {
270 _bsonBuilder.close_document();
271 }
else if (_objAsRootElement) {
272 _bsonBuilder.close_document();
274 }
else if (_nodeTypeStack.size() > 1) {
276 _embeddedNameStack.pop_back();
281 _nodeTypeStack.pop();
282 _curNodeInheritsUnderlyingBSONDataBase.pop();
285 if (_nodeTypeStack.empty()) {
286 _objAsRootElement =
false;
297 void setNextName(
const char* name) {
309 typename std::enable_if<!is_bson_view<typename std::decay<T>::type>::value>::type saveValue(
311 _bsonBuilder.append(std::forward<T>(t));
322 typename std::enable_if<is_bson_view<typename std::decay<T>::type>::value>::type saveValue(
324 if (_curNodeInheritsUnderlyingBSONDataBase.empty() ||
325 !_curNodeInheritsUnderlyingBSONDataBase.top()) {
327 "Cannot serialize bsoncxx view type (b_utf8, b_document, b_array, b_binary) unless " 328 "that type is wrapped in a class that inherits UnderlyingBSONDataBase.");
330 _bsonBuilder.append(std::forward<T>(t));
338 void saveValue(std::chrono::system_clock::time_point tp) {
339 _bsonBuilder.append(bsoncxx::types::b_date{tp});
360 void writeName(
bool isNewNode =
false) {
361 if (!_nodeTypeStack.empty()) {
362 const auto& topType = _nodeTypeStack.top();
365 if (topType == OutputNodeType::StartArray) {
366 _bsonBuilder.open_array();
367 ++_arrayNestingLevel;
368 _nodeTypeStack.top() = OutputNodeType::InArray;
369 }
else if (topType == OutputNodeType::StartObject) {
370 _nodeTypeStack.top() = OutputNodeType::InObject;
373 if (_nodeTypeStack.size() > 1 || _objAsRootElement) {
374 if (_dotNotationMode && _arrayNestingLevel == 0) {
375 _embeddedNameStack.push_back(_nextPotentialNodeName);
377 _bsonBuilder.open_document();
383 if (topType == OutputNodeType::InArray)
return;
386 if (!_nextName && _nodeTypeStack.empty() && isNewNode) {
390 }
else if (!_nextName) {
396 if (!_dotNotationMode || _embeddedNameStack.empty() || _arrayNestingLevel > 0) {
397 _bsonBuilder.key_view(_nextName);
401 std::stringstream key;
402 for (
const auto& name : _embeddedNameStack) {
406 _bsonBuilder.key_owned(key.str());
410 _nextPotentialNodeName = _nextName;
416 if (_nodeTypeStack.empty() && isNewNode) {
417 _objAsRootElement =
true;
427 _nodeTypeStack.top() = OutputNodeType::StartArray;
432 BSONBuilder _bsonBuilder;
435 std::ostream& _writeStream;
438 char const* _nextName;
442 char const* _nextPotentialNodeName;
445 std::stack<OutputNodeType> _nodeTypeStack;
449 std::stack<bool> _curNodeInheritsUnderlyingBSONDataBase;
453 std::vector<std::string> _embeddedNameStack;
457 bool _objAsRootElement;
461 bool _dotNotationMode;
465 uint8_t _arrayNestingLevel;
470 enum class InputNodeType { InObject, InEmbeddedObject, InEmbeddedArray, InRootElement };
483 _readFirstDoc(false) {
495 char docsize_buf[
sizeof(docsize)];
496 _readStream.read(docsize_buf,
sizeof(docsize));
497 std::memcpy(&docsize, docsize_buf,
sizeof(docsize));
500 if (_readStream.eof() || !_readStream || docsize < 5) {
506 std::shared_ptr<uint8_t>{
new uint8_t[docsize], [](uint8_t* p) {
delete[] p; }};
509 std::memcpy(_curBsonData.get(), docsize_buf,
sizeof(docsize));
510 _readStream.read(reinterpret_cast<char*>(_curBsonData.get() +
sizeof(docsize)),
511 docsize -
sizeof(docsize));
514 if (_readStream.eof() || !_readStream) {
519 _curBsonDoc = bsoncxx::document::view{_curBsonData.get(),
static_cast<size_t>(docsize)};
520 _curBsonDataSize = docsize;
523 _readFirstDoc =
true;
532 inline bsoncxx::types::value search() {
534 if (_cachedSearchResult) {
535 auto val = *_cachedSearchResult;
536 _cachedSearchResult = stdx::nullopt;
541 if (_nodeTypeStack.empty()) {
546 if (!_readFirstDoc) {
547 throw boson::Exception(
"Error in element search, never loaded BSON data from file.");
552 const char* nextName = _nextName;
555 if (_nodeTypeStack.top() == InputNodeType::InObject ||
556 _nodeTypeStack.top() == InputNodeType::InRootElement) {
559 const auto& elemFromDoc = _curBsonDoc[nextName];
561 return elemFromDoc.get_value();
563 }
else if (_nodeTypeStack.top() == InputNodeType::InEmbeddedObject) {
566 const auto& elemFromDoc = _embeddedBsonDocStack.top()[nextName];
568 return elemFromDoc.get_value();
573 std::stringstream error_msg;
574 error_msg <<
"No element found with the key ";
575 error_msg << nextName;
579 }
else if (_nodeTypeStack.top() == InputNodeType::InEmbeddedArray) {
583 auto& iter = _embeddedBsonArrayIteratorStack.top();
584 const auto elemFromArr = *iter;
588 return elemFromArr.get_value();
591 throw boson::Exception(
"Invalid element found in array, or array is out of bounds.");
610 if (_nodeTypeStack.empty()) {
615 if (!_readFirstDoc) {
616 throw boson::Exception(
"Error in element search, never loaded BSON data from file.");
619 if (_nodeTypeStack.top() == InputNodeType::InEmbeddedArray) {
620 throw cereal::Exception(
621 "Should not be checking if search() will yield next value from an embedded array.");
625 const char* nextName = _nextName;
628 bsoncxx::document::element val{};
630 if (_nodeTypeStack.top() == InputNodeType::InObject ||
631 _nodeTypeStack.top() == InputNodeType::InRootElement) {
632 val = _curBsonDoc[nextName];
635 val = _embeddedBsonDocStack.top()[nextName];
639 _cachedSearchResult = val.get_value();
644 _cachedSearchResult = stdx::nullopt;
654 if (_nodeTypeStack.empty()) {
656 _nodeTypeStack.push(InputNodeType::InRootElement);
667 if (!_nodeTypeStack.empty() && _nodeTypeStack.top() == InputNodeType::InRootElement) {
668 _nodeTypeStack.pop();
677 if (_nodeTypeStack.empty()) {
685 _nodeTypeStack.push(InputNodeType::InRootElement);
686 auto newNode = search();
688 if (newNode.type() == bsoncxx::type::k_array) {
689 _embeddedBsonArrayStack.push(newNode.get_array().value);
690 _embeddedBsonArrayIteratorStack.push(_embeddedBsonArrayStack.top().begin());
691 _nodeTypeStack.push(InputNodeType::InEmbeddedArray);
692 }
else if (newNode.type() == bsoncxx::type::k_document) {
693 _embeddedBsonDocStack.push(newNode.get_document().value);
694 _nodeTypeStack.push(InputNodeType::InEmbeddedObject);
699 _nodeTypeStack.push(InputNodeType::InObject);
706 auto newNode = search();
708 if (newNode.type() == bsoncxx::type::k_document) {
709 _embeddedBsonDocStack.push(newNode.get_document().value);
710 _nodeTypeStack.push(InputNodeType::InEmbeddedObject);
711 }
else if (newNode.type() == bsoncxx::type::k_array) {
712 _embeddedBsonArrayStack.push(newNode.get_array().value);
713 _embeddedBsonArrayIteratorStack.push(_embeddedBsonArrayStack.top().begin());
714 _nodeTypeStack.push(InputNodeType::InEmbeddedArray);
728 if (_nodeTypeStack.top() == InputNodeType::InEmbeddedObject) {
729 _embeddedBsonDocStack.pop();
730 }
else if (_nodeTypeStack.top() == InputNodeType::InEmbeddedArray) {
731 _embeddedBsonArrayStack.pop();
732 _embeddedBsonArrayIteratorStack.pop();
736 _nodeTypeStack.pop();
738 if (!_nodeTypeStack.empty() && _nodeTypeStack.top() == InputNodeType::InRootElement) {
739 _nodeTypeStack.pop();
757 inline void assert_type(
const bsoncxx::types::value& v, bsoncxx::type t) {
770 #define BOSON_BSON_LOAD_VALUE_FUNC(btype) \ 771 void loadValue(bsoncxx::types::b_##btype& val) { \ 772 auto bsonVal = search(); \ 773 assert_type(bsonVal, bsoncxx::type::k_##btype); \ 774 val = bsonVal.get_##btype(); \ 779 BOSON_BSON_LOAD_VALUE_FUNC(
double)
780 BOSON_BSON_LOAD_VALUE_FUNC(utf8)
781 BOSON_BSON_LOAD_VALUE_FUNC(document)
782 BOSON_BSON_LOAD_VALUE_FUNC(array)
783 BOSON_BSON_LOAD_VALUE_FUNC(binary)
784 BOSON_BSON_LOAD_VALUE_FUNC(oid)
785 BOSON_BSON_LOAD_VALUE_FUNC(
bool)
786 BOSON_BSON_LOAD_VALUE_FUNC(date)
787 BOSON_BSON_LOAD_VALUE_FUNC(int32)
788 BOSON_BSON_LOAD_VALUE_FUNC(int64)
789 BOSON_BSON_LOAD_VALUE_FUNC(undefined)
790 BOSON_BSON_LOAD_VALUE_FUNC(null)
791 BOSON_BSON_LOAD_VALUE_FUNC(regex)
792 BOSON_BSON_LOAD_VALUE_FUNC(code)
793 BOSON_BSON_LOAD_VALUE_FUNC(symbol)
794 BOSON_BSON_LOAD_VALUE_FUNC(codewscope)
795 BOSON_BSON_LOAD_VALUE_FUNC(timestamp)
796 BOSON_BSON_LOAD_VALUE_FUNC(minkey)
797 BOSON_BSON_LOAD_VALUE_FUNC(maxkey)
798 BOSON_BSON_LOAD_VALUE_FUNC(dbpointer)
800 #undef BOSON_BSON_LOAD_VALUE_FUNC 808 #define BOSON_NON_BSON_LOAD_VALUE_FUNC(cxxtype, btype) \ 809 void loadValue(cxxtype& val) { \ 810 auto bsonVal = search(); \ 811 assert_type(bsonVal, bsoncxx::type::k_##btype); \ 812 val = bsonVal.get_##btype().value; \ 815 BOSON_NON_BSON_LOAD_VALUE_FUNC(bsoncxx::oid, oid)
816 BOSON_NON_BSON_LOAD_VALUE_FUNC(
bool,
bool)
817 BOSON_NON_BSON_LOAD_VALUE_FUNC(std::int32_t, int32)
818 BOSON_NON_BSON_LOAD_VALUE_FUNC(std::int64_t, int64)
819 BOSON_NON_BSON_LOAD_VALUE_FUNC(
double,
double)
821 #undef BOSON_NON_BSON_LOAD_VALUE_FUNC 830 void loadValue(std::chrono::system_clock::time_point& val) {
831 auto bsonVal = search();
832 assert_type(bsonVal, bsoncxx::type::k_date);
833 val = std::chrono::system_clock::time_point(
834 std::chrono::milliseconds{bsonVal.get_date().value});
844 auto bsonVal = search();
845 assert_type(bsonVal, bsoncxx::type::k_utf8);
846 val = bsonVal.get_utf8().value.to_string();
858 if (!_nodeTypeStack.empty() && _nodeTypeStack.top() != InputNodeType::InEmbeddedArray) {
861 size = std::distance(_embeddedBsonArrayStack.top().begin(),
862 _embeddedBsonArrayStack.top().end());
870 if (_nodeTypeStack.empty()) {
874 switch (_nodeTypeStack.top()) {
875 case InputNodeType::InObject:
876 case InputNodeType::InRootElement:
877 underlyingData.setUnderlyingBSONData(std::shared_ptr<uint8_t>(_curBsonData),
880 case InputNodeType::InEmbeddedObject:
883 underlyingData.setUnderlyingBSONData(
884 std::shared_ptr<uint8_t>(
885 _curBsonData, const_cast<uint8_t*>(_embeddedBsonDocStack.top().data())),
886 _embeddedBsonDocStack.top().length());
888 case InputNodeType::InEmbeddedArray:
890 "Underlying BSON data does not support array views. Wrap the b_array, or your " 891 "container holding other bsoncxx view types in a class that inherits " 892 "boson::UnderlyingBSONDataBase");
899 const char* _nextName;
902 std::istream& _readStream;
908 stdx::optional<bsoncxx::types::value> _cachedSearchResult;
911 std::shared_ptr<uint8_t> _curBsonData;
912 size_t _curBsonDataSize;
913 bsoncxx::document::view _curBsonDoc;
916 std::stack<bsoncxx::document::view> _embeddedBsonDocStack;
920 std::stack<bsoncxx::array::view> _embeddedBsonArrayStack;
921 std::stack<bsoncxx::array::view::iterator> _embeddedBsonArrayIteratorStack;
924 std::stack<InputNodeType> _nodeTypeStack;
1012 template <
class BsonT, cereal::traits::EnableIf<
1014 std::is_same<BsonT, std::chrono::system_clock::time_point>::value> =
1015 cereal::traits::sfinae>
1020 template <
class BsonT, cereal::traits::EnableIf<
1022 std::is_same<BsonT, std::chrono::system_clock::time_point>::value> =
1023 cereal::traits::sfinae>
1025 ar.writeDocIfRoot();
1028 template <
class BsonT, cereal::traits::EnableIf<
1030 std::is_same<BsonT, std::chrono::system_clock::time_point>::value> =
1031 cereal::traits::sfinae>
1036 "Cannot deserialize a BSON view type into a root element. The BSON view type must " 1037 "be wrapped in a class that inherits boson::UnderlyingBSONDataBase");
1042 template <
class BsonT, cereal::traits::EnableIf<
1044 std::is_same<BsonT, std::chrono::system_clock::time_point>::value> =
1045 cereal::traits::sfinae>
1057 template <class T, cereal::traits::EnableIf<std::is_base_of<UnderlyingBSONDataBase, T>::value> =
1058 cereal::traits::sfinae>
1064 cereal::traits::DisableIf<
1065 std::is_arithmetic<T>::value ||
1066 cereal::traits::has_minimal_base_class_serialization<
1067 T, cereal::traits::has_minimal_output_serialization,
BSONOutputArchive>::value ||
1068 cereal::traits::has_minimal_output_serialization<T, BSONOutputArchive>::value ||
1069 is_bson<T>::value || std::is_same<T, std::chrono::system_clock::time_point>::value ||
1070 std::is_base_of<UnderlyingBSONDataBase, T>::value> = cereal::traits::sfinae>
1072 ar.startNode(
false);
1076 template <class T, cereal::traits::EnableIf<std::is_base_of<UnderlyingBSONDataBase, T>::value> =
1077 cereal::traits::sfinae>
1085 cereal::traits::DisableIf<
1086 std::is_arithmetic<T>::value ||
1087 cereal::traits::has_minimal_base_class_serialization<
1088 T, cereal::traits::has_minimal_input_serialization,
BSONInputArchive>::value ||
1089 cereal::traits::has_minimal_input_serialization<T, BSONInputArchive>::value ||
1090 is_bson<T>::value || std::is_same<T, std::chrono::system_clock::time_point>::value ||
1091 std::is_base_of<UnderlyingBSONDataBase, T>::value> = cereal::traits::sfinae>
1103 cereal::traits::DisableIf<
1104 std::is_arithmetic<T>::value ||
1105 cereal::traits::has_minimal_base_class_serialization<
1106 T, cereal::traits::has_minimal_output_serialization,
BSONOutputArchive>::value ||
1107 cereal::traits::has_minimal_output_serialization<T, BSONOutputArchive>::value ||
1108 is_bson<T>::value || std::is_same<T, std::chrono::system_clock::time_point>::value> =
1109 cereal::traits::sfinae>
1116 cereal::traits::DisableIf<
1117 std::is_arithmetic<T>::value ||
1118 cereal::traits::has_minimal_base_class_serialization<
1119 T, cereal::traits::has_minimal_input_serialization,
BSONInputArchive>::value ||
1120 cereal::traits::has_minimal_input_serialization<T, BSONInputArchive>::value ||
1121 is_bson<T>::value || std::is_same<T, std::chrono::system_clock::time_point>::value> =
1122 cereal::traits::sfinae>
1129 template <class T, cereal::traits::EnableIf<std::is_arithmetic<T>::value> = cereal::traits::sfinae>
1135 template <class T, cereal::traits::EnableIf<std::is_arithmetic<T>::value> = cereal::traits::sfinae>
1142 template <class T, cereal::traits::EnableIf<std::is_arithmetic<T>::value> = cereal::traits::sfinae>
1144 ar.writeDocIfRoot();
1148 template <class T, cereal::traits::EnableIf<std::is_arithmetic<T>::value> = cereal::traits::sfinae>
1155 template <
class CharT,
class Traits,
class Alloc>
1156 inline void prologue(
BSONOutputArchive& ar, std::basic_string<CharT, Traits, Alloc>
const&) {
1161 template <
class CharT,
class Traits,
class Alloc>
1162 inline void prologue(
BSONInputArchive& ar, std::basic_string<CharT, Traits, Alloc>
const&) {
1168 template <
class CharT,
class Traits,
class Alloc>
1169 inline void epilogue(
BSONOutputArchive& ar, std::basic_string<CharT, Traits, Alloc>
const&) {
1170 ar.writeDocIfRoot();
1174 template <
class CharT,
class Traits,
class Alloc>
1175 inline void epilogue(
BSONInputArchive& ar, std::basic_string<CharT, Traits, Alloc>
const&) {
1184 inline void CEREAL_SAVE_FUNCTION_NAME(
BSONOutputArchive& ar, cereal::NameValuePair<T>
const& t) {
1185 ar.setNextName(t.name);
1191 inline void CEREAL_LOAD_FUNCTION_NAME(
BSONInputArchive& ar, cereal::NameValuePair<T>& t) {
1198 inline void CEREAL_SAVE_FUNCTION_NAME(
BSONOutputArchive& ar, stdx::optional<T>
const& t) {
1212 cereal::traits::DisableIf<is_bson<T>::value && !std::is_default_constructible<T>::value> =
1213 cereal::traits::sfinae>
1214 inline void CEREAL_LOAD_FUNCTION_NAME(
BSONInputArchive& ar, stdx::optional<T>& t) {
1228 stdx::optional<bsoncxx::types::b_utf8>& t) {
1230 bsoncxx::types::b_utf8 value{
""};
1238 stdx::optional<bsoncxx::types::b_date>& t) {
1240 bsoncxx::types::b_date value{std::chrono::system_clock::time_point{}};
1248 stdx::optional<bsoncxx::types::b_regex>& t) {
1250 bsoncxx::types::b_regex value{
"",
""};
1258 stdx::optional<bsoncxx::types::b_code>& t) {
1260 bsoncxx::types::b_code value{
""};
1268 stdx::optional<bsoncxx::types::b_codewscope>& t) {
1270 bsoncxx::types::b_codewscope value{
"", bsoncxx::document::view()};
1278 stdx::optional<bsoncxx::types::b_symbol>& t) {
1280 bsoncxx::types::b_symbol value{
""};
1289 template <class T, cereal::traits::EnableIf<std::is_arithmetic<T>::value> = cereal::traits::sfinae>
1295 template <class T, cereal::traits::EnableIf<std::is_arithmetic<T>::value> = cereal::traits::sfinae>
1301 template <
class CharT,
class Traits,
class Alloc>
1303 std::basic_string<CharT, Traits, Alloc>
const& str) {
1308 template <
class CharT,
class Traits,
class Alloc>
1310 std::basic_string<CharT, Traits, Alloc>& str) {
1317 inline void CEREAL_SAVE_FUNCTION_NAME(
BSONOutputArchive&, cereal::SizeTag<T>
const&) {
1323 inline void CEREAL_LOAD_FUNCTION_NAME(
BSONInputArchive& ar, cereal::SizeTag<T>& st) {
1329 template <
class BsonT, cereal::traits::EnableIf<
1331 std::is_same<BsonT, std::chrono::system_clock::time_point>::value> =
1332 cereal::traits::sfinae>
1333 inline void CEREAL_SAVE_FUNCTION_NAME(
BSONOutputArchive& ar, BsonT
const& bsonVal) {
1334 ar.saveValue(bsonVal);
1338 template <
class BsonT, cereal::traits::EnableIf<
1340 std::is_same<BsonT, std::chrono::system_clock::time_point>::value> =
1341 cereal::traits::sfinae>
1342 inline void CEREAL_LOAD_FUNCTION_NAME(
BSONInputArchive& ar, BsonT& bsonVal) {
A templated struct containing a bool value that specifies whether the provided template parameter is ...
Definition: bson_archiver.hpp:114
An exception class thrown when things go wrong at runtime.
Definition: bson_archiver.hpp:75
A base class that holds a shared_ptr to the binary data for a BSON document.
Definition: bson_archiver.hpp:90
BSONOutputArchive(std::ostream &stream, bool dotNotationMode=false)
Construct a BSONOutputArchive that will output serialized classes as BSON to the provided stream...
Definition: bson_archiver.hpp:182
A templated struct containing a bool value that specifies whether the provided template parameter is ...
Definition: bson_archiver.hpp:143
Definition: bson_archiver.hpp:70
Definition: bson_archiver.hpp:155