diff --git a/immer/extra/archive/json/archivable.hpp b/immer/extra/archive/json/archivable.hpp index 2c6820f0..decc815e 100644 --- a/immer/extra/archive/json/archivable.hpp +++ b/immer/extra/archive/json/archivable.hpp @@ -84,14 +84,16 @@ struct archivable // } }; -template +template auto save_minimal( - const json_immer_output_archive>& ar, + const json_immer_output_archive>& ar, const archivable& value) { auto& save_archive = const_cast< - json_immer_output_archive>&>( + json_immer_output_archive>&>( ar) .get_output_archives() .template get_save_archive(); @@ -110,24 +112,26 @@ auto save_minimal(const json_immer_auto_output_archive& ar, // This function must exist because cereal does some checks and it's not // possible to have only load_minimal for a type without having save_minimal. -template +template auto save_minimal( - const json_immer_output_archive>& ar, + const json_immer_output_archive>& ar, const archivable& value) -> typename container_traits::container_id::rep_t { throw std::logic_error{"Should never be called"}; } -template +template void load_minimal( - const json_immer_input_archive& ar, + const json_immer_input_archive& ar, archivable& value, const typename container_traits::container_id::rep_t& id) { - auto& loader = const_cast&>(ar) - .get_input_archives() - .template get_loader(); + auto& loader = + const_cast&>(ar) + .get_input_archives() + .template get_loader(); // Have to be specific because for vectors container_id is different from // node_id, but for hash-based containers, a container is identified just by diff --git a/immer/extra/archive/json/json_immer.hpp b/immer/extra/archive/json/json_immer.hpp index 02cda830..2f58e895 100644 --- a/immer/extra/archive/json/json_immer.hpp +++ b/immer/extra/archive/json/json_immer.hpp @@ -9,41 +9,60 @@ namespace immer::archive { +struct blackhole_output_archive +{ + void startNode() const {} + void writeName() const {} + void finishNode() const {} + void setNextName(const char* name) const {} + void makeArray() const {} + + template + void saveValue(const T& value) + { + } +}; + /** * Adapted from cereal/archives/adapters.hpp */ -template +template class json_immer_output_archive - : public cereal::OutputArchive> + : public cereal::OutputArchive< + json_immer_output_archive> , public cereal::traits::TextArchive { public: - json_immer_output_archive(std::ostream& stream) - : cereal::OutputArchive>{this} - , archive{stream} + template + explicit json_immer_output_archive(Args&&... args) + : cereal::OutputArchive< + json_immer_output_archive>{this} + , previous{std::forward(args)...} { } - json_immer_output_archive(ImmerArchives archives, std::ostream& stream) - : cereal::OutputArchive>{this} - , archive{stream} + template + json_immer_output_archive(ImmerArchives archives, Args&&... args) + : cereal::OutputArchive< + json_immer_output_archive>{this} + , previous{std::forward(args)...} , archives{std::move(archives)} { } ~json_immer_output_archive() {} - void startNode() { archive.startNode(); } - void writeName() { archive.writeName(); } - void finishNode() { archive.finishNode(); } - void setNextName(const char* name) { archive.setNextName(name); } - void makeArray() { archive.makeArray(); } + void startNode() { previous.startNode(); } + void writeName() { previous.writeName(); } + void finishNode() { previous.finishNode(); } + void setNextName(const char* name) { previous.setNextName(name); } + void makeArray() { previous.makeArray(); } template void saveValue(const T& value) { - archive.saveValue(value); + previous.saveValue(value); } ImmerArchives& get_output_archives() & { return archives; } @@ -57,41 +76,43 @@ class json_immer_output_archive } private: - cereal::JSONOutputArchive archive; + Previous previous; ImmerArchives archives; }; -template +template class json_immer_input_archive - : public cereal::InputArchive> + : public cereal::InputArchive< + json_immer_input_archive> , public cereal::traits::TextArchive { public: template json_immer_input_archive(ImmerArchives archives_, Args&&... args) - : cereal::InputArchive>{this} - , archive{std::forward(args)...} + : cereal::InputArchive< + json_immer_input_archive>{this} + , previous{std::forward(args)...} , archives{std::move(archives_)} { } - void startNode() { archive.startNode(); } - void finishNode() { archive.finishNode(); } - void setNextName(const char* name) { archive.setNextName(name); } - void loadSize(cereal::size_type& size) { archive.loadSize(size); } - bool hasName(const char* name) { return archive.hasName(name); } + void startNode() { previous.startNode(); } + void finishNode() { previous.finishNode(); } + void setNextName(const char* name) { previous.setNextName(name); } + void loadSize(cereal::size_type& size) { previous.loadSize(size); } + bool hasName(const char* name) { return previous.hasName(name); } template void loadValue(T& value) { - archive.loadValue(value); + previous.loadValue(value); } ImmerArchives& get_input_archives() { return archives; } const ImmerArchives& get_input_archives() const { return archives; } private: - cereal::JSONInputArchive archive; + Previous previous; ImmerArchives archives; }; @@ -100,8 +121,8 @@ class json_immer_input_archive * serializing functions specifically for this type of archive that provides * access to the immer-related archive. * - * template - * void load(json_immer_input_archive& ar, + * template + * void load(json_immer_input_archive& ar, * vector_one_archivable& value) */ @@ -112,15 +133,15 @@ class json_immer_input_archive // ###################################################################### //! Prologue for NVPs for JSON archives /*! NVPs do not start or finish nodes - they just set up the names */ -template -inline void prologue(json_immer_output_archive&, +template +inline void prologue(json_immer_output_archive&, cereal::NameValuePair const&) { } //! Prologue for NVPs for JSON archives -template -inline void prologue(json_immer_input_archive&, +template +inline void prologue(json_immer_input_archive&, cereal::NameValuePair const&) { } @@ -128,16 +149,16 @@ inline void prologue(json_immer_input_archive&, // ###################################################################### //! Epilogue for NVPs for JSON archives /*! NVPs do not start or finish nodes - they just set up the names */ -template -inline void epilogue(json_immer_output_archive&, +template +inline void epilogue(json_immer_output_archive&, cereal::NameValuePair const&) { } //! Epilogue for NVPs for JSON archives /*! NVPs do not start or finish nodes - they just set up the names */ -template -inline void epilogue(json_immer_input_archive&, +template +inline void epilogue(json_immer_input_archive&, cereal::NameValuePair const&) { } @@ -145,15 +166,15 @@ inline void epilogue(json_immer_input_archive&, // ###################################################################### //! Prologue for deferred data for JSON archives /*! Do nothing for the defer wrapper */ -template -inline void prologue(json_immer_output_archive&, +template +inline void prologue(json_immer_output_archive&, cereal::DeferredData const&) { } //! Prologue for deferred data for JSON archives -template -inline void prologue(json_immer_input_archive&, +template +inline void prologue(json_immer_input_archive&, cereal::DeferredData const&) { } @@ -161,16 +182,16 @@ inline void prologue(json_immer_input_archive&, // ###################################################################### //! Epilogue for deferred for JSON archives /*! NVPs do not start or finish nodes - they just set up the names */ -template -inline void epilogue(json_immer_output_archive&, +template +inline void epilogue(json_immer_output_archive&, cereal::DeferredData const&) { } //! Epilogue for deferred for JSON archives /*! Do nothing for the defer wrapper */ -template -inline void epilogue(json_immer_input_archive&, +template +inline void epilogue(json_immer_input_archive&, cereal::DeferredData const&) { } @@ -179,16 +200,16 @@ inline void epilogue(json_immer_input_archive&, //! Prologue for SizeTags for JSON archives /*! SizeTags are strictly ignored for JSON, they just indicate that the current node should be made into an array */ -template -inline void prologue(json_immer_output_archive& ar, +template +inline void prologue(json_immer_output_archive& ar, cereal::SizeTag const&) { ar.makeArray(); } //! Prologue for SizeTags for JSON archives -template -inline void prologue(json_immer_input_archive&, +template +inline void prologue(json_immer_input_archive&, cereal::SizeTag const&) { } @@ -196,15 +217,15 @@ inline void prologue(json_immer_input_archive&, // ###################################################################### //! Epilogue for SizeTags for JSON archives /*! SizeTags are strictly ignored for JSON */ -template -inline void epilogue(json_immer_output_archive&, +template +inline void epilogue(json_immer_output_archive&, cereal::SizeTag const&) { } //! Epilogue for SizeTags for JSON archives -template -inline void epilogue(json_immer_input_archive&, +template +inline void epilogue(json_immer_input_archive&, cereal::SizeTag const&) { } @@ -215,37 +236,41 @@ inline void epilogue(json_immer_input_archive&, that may be given data by the type about to be archived Minimal types do not start or finish nodes */ -template ::value, !cereal::traits::has_minimal_base_class_serialization< T, cereal::traits::has_minimal_output_serialization, - json_immer_output_archive>::value, + json_immer_output_archive>::value, !cereal::traits::has_minimal_output_serialization< T, - json_immer_output_archive>::value> = + json_immer_output_archive>::value> = cereal::traits::sfinae> -inline void prologue(json_immer_output_archive& ar, T const&) +inline void prologue(json_immer_output_archive& ar, + T const&) { ar.startNode(); } //! Prologue for all other types for JSON archives -template ::value, !cereal::traits::has_minimal_base_class_serialization< T, cereal::traits::has_minimal_input_serialization, - json_immer_input_archive>::value, + json_immer_input_archive>::value, !cereal::traits::has_minimal_input_serialization< T, - json_immer_input_archive>::value> = + json_immer_input_archive>::value> = cereal::traits::sfinae> -inline void prologue(json_immer_input_archive& ar, T const&) +inline void prologue(json_immer_input_archive& ar, + T const&) { ar.startNode(); } @@ -255,138 +280,166 @@ inline void prologue(json_immer_input_archive& ar, T const&) /*! Finishes the node created in the prologue Minimal types do not start or finish nodes */ -template ::value, !cereal::traits::has_minimal_base_class_serialization< T, cereal::traits::has_minimal_output_serialization, - json_immer_output_archive>::value, + json_immer_output_archive>::value, !cereal::traits::has_minimal_output_serialization< T, - json_immer_output_archive>::value> = + json_immer_output_archive>::value> = cereal::traits::sfinae> -inline void epilogue(json_immer_output_archive& ar, T const&) +inline void epilogue(json_immer_output_archive& ar, + T const&) { ar.finishNode(); } //! Epilogue for all other types other for JSON archives -template ::value, !cereal::traits::has_minimal_base_class_serialization< T, cereal::traits::has_minimal_input_serialization, - json_immer_input_archive>::value, + json_immer_input_archive>::value, !cereal::traits::has_minimal_input_serialization< T, - json_immer_input_archive>::value> = + json_immer_input_archive>::value> = cereal::traits::sfinae> -inline void epilogue(json_immer_input_archive& ar, T const&) +inline void epilogue(json_immer_input_archive& ar, + T const&) { ar.finishNode(); } // ###################################################################### //! Prologue for arithmetic types for JSON archives -template -inline void prologue(json_immer_output_archive& ar, +template +inline void prologue(json_immer_output_archive& ar, std::nullptr_t const&) { ar.writeName(); } //! Prologue for arithmetic types for JSON archives -template -inline void prologue(json_immer_input_archive&, +template +inline void prologue(json_immer_input_archive&, std::nullptr_t const&) { } // ###################################################################### //! Epilogue for arithmetic types for JSON archives -template -inline void epilogue(json_immer_output_archive&, +template +inline void epilogue(json_immer_output_archive&, std::nullptr_t const&) { } //! Epilogue for arithmetic types for JSON archives -template -inline void epilogue(json_immer_input_archive&, +template +inline void epilogue(json_immer_input_archive&, std::nullptr_t const&) { } // ###################################################################### //! Prologue for arithmetic types for JSON archives -template ::value> = cereal::traits::sfinae> -inline void prologue(json_immer_output_archive& ar, T const&) +inline void prologue(json_immer_output_archive& ar, + T const&) { ar.writeName(); } //! Prologue for arithmetic types for JSON archives -template ::value> = cereal::traits::sfinae> -inline void prologue(json_immer_input_archive&, T const&) +inline void prologue(json_immer_input_archive&, + T const&) { } // ###################################################################### //! Epilogue for arithmetic types for JSON archives -template ::value> = cereal::traits::sfinae> -inline void epilogue(json_immer_output_archive&, T const&) +inline void epilogue(json_immer_output_archive&, + T const&) { } //! Epilogue for arithmetic types for JSON archives -template ::value> = cereal::traits::sfinae> -inline void epilogue(json_immer_input_archive&, T const&) +inline void epilogue(json_immer_input_archive&, + T const&) { } // ###################################################################### //! Prologue for strings for JSON archives -template -inline void prologue(json_immer_output_archive& ar, +template +inline void prologue(json_immer_output_archive& ar, std::basic_string const&) { ar.writeName(); } //! Prologue for strings for JSON archives -template -inline void prologue(json_immer_input_archive&, +template +inline void prologue(json_immer_input_archive&, std::basic_string const&) { } // ###################################################################### //! Epilogue for strings for JSON archives -template -inline void epilogue(json_immer_output_archive&, +template +inline void epilogue(json_immer_output_archive&, std::basic_string const&) { } //! Epilogue for strings for JSON archives -template -inline void epilogue(json_immer_input_archive&, +template +inline void epilogue(json_immer_input_archive&, std::basic_string const&) { } @@ -395,18 +448,18 @@ inline void epilogue(json_immer_input_archive&, // Common JSONArchive serialization functions // ###################################################################### //! Serializing NVP types to JSON -template -inline void -CEREAL_SAVE_FUNCTION_NAME(json_immer_output_archive& ar, - cereal::NameValuePair const& t) +template +inline void CEREAL_SAVE_FUNCTION_NAME( + json_immer_output_archive& ar, + cereal::NameValuePair const& t) { ar.setNextName(t.name); ar(t.value); } -template +template inline void -CEREAL_LOAD_FUNCTION_NAME(json_immer_input_archive& ar, +CEREAL_LOAD_FUNCTION_NAME(json_immer_input_archive& ar, cereal::NameValuePair& t) { ar.setNextName(t.name); @@ -414,59 +467,69 @@ CEREAL_LOAD_FUNCTION_NAME(json_immer_input_archive& ar, } //! Saving for nullptr to JSON -template -inline void -CEREAL_SAVE_FUNCTION_NAME(json_immer_output_archive& ar, - std::nullptr_t const& t) +template +inline void CEREAL_SAVE_FUNCTION_NAME( + json_immer_output_archive& ar, + std::nullptr_t const& t) { ar.saveValue(t); } //! Loading arithmetic from JSON -template +template inline void -CEREAL_LOAD_FUNCTION_NAME(json_immer_input_archive& ar, +CEREAL_LOAD_FUNCTION_NAME(json_immer_input_archive& ar, std::nullptr_t& t) { ar.loadValue(t); } //! Saving for arithmetic to JSON -template ::value> = cereal::traits::sfinae> -inline void -CEREAL_SAVE_FUNCTION_NAME(json_immer_output_archive& ar, - T const& t) +inline void CEREAL_SAVE_FUNCTION_NAME( + json_immer_output_archive& ar, T const& t) { ar.saveValue(t); } //! Loading arithmetic from JSON -template ::value> = cereal::traits::sfinae> inline void -CEREAL_LOAD_FUNCTION_NAME(json_immer_input_archive& ar, T& t) +CEREAL_LOAD_FUNCTION_NAME(json_immer_input_archive& ar, + T& t) { ar.loadValue(t); } //! saving string to JSON -template -inline void -CEREAL_SAVE_FUNCTION_NAME(json_immer_output_archive& ar, - std::basic_string const& str) +template +inline void CEREAL_SAVE_FUNCTION_NAME( + json_immer_output_archive& ar, + std::basic_string const& str) { ar.saveValue(str); } //! loading string from JSON -template +template inline void -CEREAL_LOAD_FUNCTION_NAME(json_immer_input_archive& ar, +CEREAL_LOAD_FUNCTION_NAME(json_immer_input_archive& ar, std::basic_string& str) { ar.loadValue(str); @@ -474,17 +537,18 @@ CEREAL_LOAD_FUNCTION_NAME(json_immer_input_archive& ar, // ###################################################################### //! Saving SizeTags to JSON -template -inline void CEREAL_SAVE_FUNCTION_NAME(json_immer_output_archive&, - cereal::SizeTag const&) +template +inline void +CEREAL_SAVE_FUNCTION_NAME(json_immer_output_archive&, + cereal::SizeTag const&) { // nothing to do here, we don't explicitly save the size } //! Loading SizeTags from JSON -template +template inline void -CEREAL_LOAD_FUNCTION_NAME(json_immer_input_archive& ar, +CEREAL_LOAD_FUNCTION_NAME(json_immer_input_archive& ar, cereal::SizeTag& st) { ar.loadSize(st.size); @@ -496,17 +560,19 @@ CEREAL_LOAD_FUNCTION_NAME(json_immer_input_archive& ar, namespace cereal { namespace traits { namespace detail { -template +template struct get_output_from_input< - immer::archive::json_immer_input_archive> + immer::archive::json_immer_input_archive> { - using type = immer::archive::json_immer_output_archive; + using type = + immer::archive::json_immer_output_archive; }; -template +template struct get_input_from_output< - immer::archive::json_immer_output_archive> + immer::archive::json_immer_output_archive> { - using type = immer::archive::json_immer_input_archive; + using type = + immer::archive::json_immer_input_archive; }; } // namespace detail } // namespace traits diff --git a/immer/extra/archive/json/json_with_archive.hpp b/immer/extra/archive/json/json_with_archive.hpp index 769503c0..02fe8204 100644 --- a/immer/extra/archive/json/json_with_archive.hpp +++ b/immer/extra/archive/json/json_with_archive.hpp @@ -456,8 +456,8 @@ constexpr bool is_archive_empty() } // Recursively serializes the archives but not calling finalize -template -void save_archives_impl(json_immer_output_archive& ar, +template +void save_archives_impl(json_immer_output_archive& ar, const SaveArchiveF& save_archive) { using Names = typename Archives::names_t; @@ -488,17 +488,19 @@ auto to_json_with_archive(const T& serializable) detail::generate_archives_save(get_archives_types(serializable)); using Archives = std::decay_t; - auto os = std::ostringstream{}; - const auto save_archive = [](auto archives) { - auto os2 = std::ostringstream{}; - auto ar2 = json_immer_output_archive{archives, os2}; + auto ar2 = + json_immer_output_archive{ + archives}; ar2(archives); return std::move(ar2).get_output_archives(); }; + auto os = std::ostringstream{}; { - auto ar = immer::archive::json_immer_output_archive{os}; + auto ar = + immer::archive::json_immer_output_archive{os}; ar(serializable); if constexpr (!is_archive_empty()) { save_archives_impl(ar, save_archive); @@ -558,7 +560,8 @@ constexpr auto reload_archive = using Archives = std::decay_t; auto restore = util::istream_snapshot{is}; archives.ignore_archive_exceptions = ignore_archive_exceptions; - auto ar = json_immer_input_archive{std::move(archives), is}; + auto ar = json_immer_input_archive{ + std::move(archives), is}; /** * NOTE: Critical to clear the archives before loading into it * again. I hit a bug when archives contained a vector and every @@ -577,7 +580,8 @@ T from_json_with_archive(std::istream& is) auto archives = load_archives(is, load_initial_archives(is), reload_archive); - auto ar = immer::archive::json_immer_input_archive{ + auto ar = immer::archive::json_immer_input_archive{ std::move(archives), is}; auto r = T{}; ar(r); @@ -603,7 +607,8 @@ T from_json_with_archive_with_conversion(std::istream& is, auto archives = archives_old.transform(map); using Archives = decltype(archives); - auto ar = immer::archive::json_immer_input_archive{ + auto ar = immer::archive::json_immer_input_archive{ std::move(archives), is}; auto r = T{}; ar(r); diff --git a/immer/extra/archive/json/json_with_archive_auto.hpp b/immer/extra/archive/json/json_with_archive_auto.hpp index 8804389a..cde83159 100644 --- a/immer/extra/archive/json/json_with_archive_auto.hpp +++ b/immer/extra/archive/json/json_with_archive_auto.hpp @@ -187,8 +187,9 @@ auto to_json_with_auto_archive(const T& serializable, using Archives = std::decay_t; const auto save_archive = [wrap](auto archives) { - auto os = std::ostringstream{}; - auto previous = json_immer_output_archive{archives, os}; + auto previous = + json_immer_output_archive{ + archives}; auto ar = json_immer_auto_output_archive{ previous, wrap}; @@ -198,7 +199,8 @@ auto to_json_with_auto_archive(const T& serializable, auto os = std::ostringstream{}; { - auto previous = json_immer_output_archive{os}; + auto previous = + json_immer_output_archive{os}; auto ar = json_immer_auto_output_archive{ previous, wrap}; // value0 because that's now cereal saves the unnamed object by default, @@ -213,6 +215,56 @@ auto to_json_with_auto_archive(const T& serializable, return std::make_pair(os.str(), std::move(archives)); } +// Same as to_json_with_auto_archive but we don't generate any JSON. +template +auto get_auto_archive(const T& serializable, + const ArchivesTypes& archives_types) +{ + namespace hana = boost::hana; + + // In the future, wrap function may ignore certain user-provided types that + // should not be archived. + constexpr auto wrap = wrap_for_saving; + static_assert( + std::is_same_v())), + const std::string&>, + "wrap must return a reference when it's not wrapping the type"); + static_assert(std::is_same_v{})), + archivable>>, + "and a value when it's wrapping"); + + using WrapF = std::decay_t; + + auto archives = detail::generate_archives_save(archives_types); + using Archives = std::decay_t; + + const auto save_archive = [wrap](auto archives) { + auto previous = + json_immer_output_archive{ + archives}; + auto ar = json_immer_auto_output_archive{ + previous, wrap}; + ar(archives); + return std::move(previous).get_output_archives(); + }; + + { + auto previous = + json_immer_output_archive{}; + auto ar = json_immer_auto_output_archive{ + previous, wrap}; + // value0 because that's now cereal saves the unnamed object by default, + // maybe change later. + ar(cereal::make_nvp("value0", serializable)); + if constexpr (!is_archive_empty()) { + save_archives_impl(previous, save_archive); + ar.finalize(); + } + archives = std::move(previous).get_output_archives(); + } + return archives; +} + template auto load_initial_auto_archives(std::istream& is, WrapF wrap) { @@ -238,7 +290,8 @@ constexpr auto reload_archive_auto = [](auto wrap) { auto restore = util::istream_snapshot{is}; archives.ignore_archive_exceptions = ignore_archive_exceptions; auto previous = - json_immer_input_archive{std::move(archives), is}; + json_immer_input_archive{ + std::move(archives), is}; auto ar = json_immer_auto_input_archive{ previous, wrap}; /** @@ -268,7 +321,9 @@ T from_json_with_auto_archive(std::istream& is, load_initial_auto_archives(is, wrap), reload_archive_auto(wrap)); - auto previous = json_immer_input_archive{std::move(archives), is}; + auto previous = + json_immer_input_archive{ + std::move(archives), is}; auto ar = json_immer_auto_input_archive{previous, wrap}; // value0 because that's now cereal saves the unnamed object by default, @@ -309,7 +364,9 @@ T from_json_with_auto_archive_with_conversion( auto archives = archives_old.transform(map); using Archives = decltype(archives); - auto previous = json_immer_input_archive{std::move(archives), is}; + auto previous = + json_immer_input_archive{ + std::move(archives), is}; auto ar = json_immer_auto_input_archive{previous, wrap}; auto r = T{}; diff --git a/test/extra/archive/test_circular_dependency_conversion.cpp b/test/extra/archive/test_circular_dependency_conversion.cpp index cf35499b..0dabea45 100644 --- a/test/extra/archive/test_circular_dependency_conversion.cpp +++ b/test/extra/archive/test_circular_dependency_conversion.cpp @@ -401,10 +401,7 @@ TEST_CASE("Test circular dependency archives", "[conversion]") const auto names = immer::archive::get_archives_for_types( hana::tuple_t, hana::make_map()); - const auto [json_str, model_archives_] = - immer::archive::to_json_with_auto_archive(value, names); - const auto& model_archives = model_archives_; - // REQUIRE(json_str == ""); + const auto model_archives = immer::archive::get_auto_archive(value, names); /** * NOTE: There is a circular dependency between archives: to convert @@ -668,6 +665,8 @@ TEST_CASE("Test circular dependency archives", "[conversion]") const auto [format_json_str, model_archives] = immer::archive::to_json_with_auto_archive(format_value, format_names); + const auto [json_str, model_archives_] = + immer::archive::to_json_with_auto_archive(value, names); REQUIRE(format_json_str == json_str); } } diff --git a/test/extra/archive/test_special_archive.cpp b/test/extra/archive/test_special_archive.cpp index 76d07636..d9a247ec 100644 --- a/test/extra/archive/test_special_archive.cpp +++ b/test/extra/archive/test_special_archive.cpp @@ -320,6 +320,7 @@ TEST_CASE("Save with a special archive") auto os = std::ostringstream{}; { auto ar = immer::archive::json_immer_output_archive< + cereal::JSONOutputArchive, std::decay_t>{os}; ar(123); ar(CEREAL_NVP(archives)); @@ -341,8 +342,9 @@ TEST_CASE("Save with a special archive") { auto is = std::istringstream{archives_json}; - auto ar = immer::archive::json_immer_input_archive{ - archives, is}; + auto ar = immer::archive::json_immer_input_archive< + cereal::JSONInputArchive, + Archives>{archives, is}; ar(CEREAL_NVP(archives)); } diff --git a/test/extra/archive/test_special_archive_auto.cpp b/test/extra/archive/test_special_archive_auto.cpp index a1c4e6b3..34ebd8e6 100644 --- a/test/extra/archive/test_special_archive_auto.cpp +++ b/test/extra/archive/test_special_archive_auto.cpp @@ -891,9 +891,7 @@ TEST_CASE("Converting between incompatible keys") const auto names = immer::archive::get_archives_for_types( hana::tuple_t, hana::make_map()); - const auto [json_str, ar] = - immer::archive::to_json_with_auto_archive(value, names); - // REQUIRE(json_str == ""); + const auto ar = immer::archive::get_auto_archive(value, names); constexpr auto convert_pair = [](const std::pair& old) { return std::make_pair(fmt::format("_{}_", old.first), old.second);