Skip to content

Commit

Permalink
Recursive box seems to work
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-sparus committed Feb 19, 2024
1 parent e444c4a commit 3314eb9
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 17 deletions.
5 changes: 5 additions & 0 deletions immer/experimental/immer-archive/box/archive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ struct archive_save

immer::map<const void*, container_id> ids;

friend bool operator==(const archive_save& left, const archive_save& right)
{
return left.boxes == right.boxes;
}

template <class Archive>
void save(Archive& ar) const
{
Expand Down
22 changes: 22 additions & 0 deletions immer/experimental/immer-archive/champ/archive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ struct inner_node_save
bitmap_t datamap;
bool collisions{false};

auto tie() const
{
return std::tie(values, children, nodemap, datamap, collisions);
}

friend bool operator==(const inner_node_save& left,
const inner_node_save& right)
{
return left.tie() == right.tie();
}

template <class Archive>
void save(Archive& ar) const
{
Expand Down Expand Up @@ -79,6 +90,11 @@ struct nodes_save
immer::map<node_id, inner_node_save<T, B>> inners;

immer::map<const void*, node_id> node_ptr_to_id;

friend bool operator==(const nodes_save& left, const nodes_save& right)
{
return left.inners == right.inners;
}
};

template <typename T,
Expand Down Expand Up @@ -141,6 +157,12 @@ struct container_archive_save
// happen.
immer::vector<Container> containers;

friend bool operator==(const container_archive_save& left,
const container_archive_save& right)
{
return left.nodes == right.nodes;
}

template <class Archive>
void save(Archive& ar) const
{
Expand Down
7 changes: 7 additions & 0 deletions immer/experimental/immer-archive/common/archive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,13 @@ struct values_save
{
const T* begin = nullptr;
const T* end = nullptr;

auto tie() const { return std::tie(begin, end); }

friend bool operator==(const values_save& left, const values_save& right)
{
return left.tie() == right.tie();
}
};

template <class T>
Expand Down
36 changes: 26 additions & 10 deletions immer/experimental/immer-archive/json/json_with_archive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ struct archives_save
}
return storage[hana::type_c<T>];
}

friend bool operator==(const archives_save& left,
const archives_save& right)
{
return left.storage == right.storage;
}
};

template <class Container>
Expand Down Expand Up @@ -175,21 +181,31 @@ auto to_json_with_archive(const T& serializable)
{
auto archives =
detail::generate_archives_save(get_archives_types(serializable));
using Archives = std::decay_t<decltype(archives)>;

const auto save_archive = [&archives] {
auto os2 = std::ostringstream{};
auto ar2 =
immer_archive::json_immer_output_archive<Archives>{archives, os2};
ar2(archives);
archives = ar2.get_output_archives();
};

auto os = std::ostringstream{};

{
auto ar =
immer_archive::json_immer_output_archive<decltype(archives)>{os};
auto ar = immer_archive::json_immer_output_archive<Archives>{os};
ar(serializable);
archives = ar.get_output_archives();

{
auto os2 = std::ostringstream{};
auto ar2 =
immer_archive::json_immer_output_archive<decltype(archives)>{
archives, os2};
ar2(archives);
ar2.finalize();
archives = ar2.get_output_archives();
auto prev = archives;
while (true) {
// Keep saving archives until everything is saved.
save_archive();
if (prev == archives) {
break;
}
prev = archives;
}

ar.get_output_archives() = archives;
Expand Down
7 changes: 7 additions & 0 deletions immer/experimental/immer-archive/rbts/archive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ struct archive_save
immer::vector<immer::flex_vector<T, MemoryPolicy, B, BL>>
saved_flex_vectors;

auto tie() const { return std::tie(leaves, inners, vectors); }

friend bool operator==(const archive_save& left, const archive_save& right)
{
return left.tie() == right.tie();
}

template <class Archive>
void save(Archive& ar) const
{
Expand Down
2 changes: 1 addition & 1 deletion immer/experimental/immer-archive/rbts/load.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ class loader
throw invalid_children_count{id};
}

auto leaf = node_ptr{node_t::make_leaf_n(n),
auto leaf = node_ptr{n ? node_t::make_leaf_n(n) : rbtree::empty_tail(),
[n](auto* ptr) { node_t::delete_leaf(ptr, n); }};
immer::detail::uninitialized_copy(
node_info->data.begin(), node_info->data.end(), leaf.get()->leaf());
Expand Down
18 changes: 12 additions & 6 deletions test/experimental/immer-archive/test_special_archive.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -661,16 +661,22 @@ TEST_CASE("Test recursive type, saving the box triggers saving the box of the "
.children = {immer::box<recursive_type>{v1},
immer::box<recursive_type>{v3}},
};
const auto v5 = recursive_type{
.data = 567,
.children =
{
immer::box<recursive_type>{v4},
},
};

const auto [json_str, archives] = immer_archive::to_json_with_archive(v4);
const auto [json_str, archives] = immer_archive::to_json_with_archive(v5);
// REQUIRE(json_str == "");

{
auto full_load =
const auto full_load =
immer_archive::from_json_with_archive<recursive_type>(json_str);
REQUIRE(full_load == v4);
// XXX This must pass:
// REQUIRE(immer_archive::to_json_with_archive(full_load).first ==
// json_str);
REQUIRE(full_load == v5);
REQUIRE(immer_archive::to_json_with_archive(full_load).first ==
json_str);
}
}

0 comments on commit 3314eb9

Please sign in to comment.