Skip to content

Commit

Permalink
XXX Dirty but the idea is there
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-sparus committed Apr 9, 2024
1 parent b86a974 commit 6ab55af
Show file tree
Hide file tree
Showing 9 changed files with 347 additions and 133 deletions.
43 changes: 36 additions & 7 deletions immer/extra/archive/box/archive.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

#include <cereal/cereal.hpp>

#include <boost/hana/functional/id.hpp>

namespace immer::archive::box {

template <typename T, typename MemoryPolicy>
Expand Down Expand Up @@ -115,25 +117,48 @@ save_to_archive(immer::box<T, MemoryPolicy> box,
return {std::move(archive), id};
}

template <typename T, typename MemoryPolicy>
template <typename T,
typename MemoryPolicy,
typename Archive = archive_load<T, MemoryPolicy>,
typename TransformF = boost::hana::id_t>
class loader
{
public:
explicit loader(archive_load<T, MemoryPolicy> ar)
explicit loader(Archive ar)
requires std::is_same_v<TransformF, boost::hana::id_t>
: ar_{std::move(ar)}
{
}

explicit loader(Archive ar, TransformF transform)
: ar_{std::move(ar)}
, transform_{std::move(transform)}
{
}

immer::box<T, MemoryPolicy> load(container_id id) const
immer::box<T, MemoryPolicy> load(container_id id)
{
if (id.value >= ar_.boxes.size()) {
throw invalid_container_id{id};
}
return ar_.boxes[id.value];
if constexpr (std::is_same_v<TransformF, boost::hana::id_t>) {
return ar_.boxes[id.value];
} else {
if (auto* b = boxes.find(id)) {
return *b;
}
const auto& old_box = ar_.boxes[id.value];
auto new_box =
immer::box<T, MemoryPolicy>{transform_(old_box.get())};
boxes = std::move(boxes).set(id, new_box);
return new_box;
}
}

private:
const archive_load<T, MemoryPolicy> ar_;
const Archive ar_;
const TransformF transform_;
immer::map<container_id, immer::box<T, MemoryPolicy>> boxes;
};

template <typename T, typename MemoryPolicy>
Expand Down Expand Up @@ -166,8 +191,12 @@ struct container_traits<immer::box<T, MemoryPolicy>>
{
using save_archive_t = box::archive_save<T, MemoryPolicy>;
using load_archive_t = box::archive_load<T, MemoryPolicy>;
using loader_t = box::loader<T, MemoryPolicy>;
using container_id = immer::archive::container_id;

template <typename Archive = load_archive_t,
typename TransformF = boost::hana::id_t>
using loader_t = box::loader<T, MemoryPolicy, Archive, TransformF>;

using container_id = immer::archive::container_id;

template <class F>
static auto transform(F&& func)
Expand Down
23 changes: 23 additions & 0 deletions immer/extra/archive/cereal/immer_box.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#pragma once

#include <cereal/cereal.hpp>
#include <immer/box.hpp>

namespace cereal {

template <typename Archive, typename T, typename MemoryPolicy>
void CEREAL_LOAD_FUNCTION_NAME(Archive& ar, immer::box<T, MemoryPolicy>& m)
{
T x;
ar(x);
m = x;
}

template <typename Archive, typename T, typename MemoryPolicy>
void CEREAL_SAVE_FUNCTION_NAME(Archive& ar,
const immer::box<T, MemoryPolicy>& m)
{
ar(m.get());
}

} // namespace cereal
22 changes: 18 additions & 4 deletions immer/extra/archive/champ/champ.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,9 @@ class hash_validation_failed_exception : public archive_exception
}
};

template <class Container>
template <class Container,
typename Archive = container_archive_load<Container>,
typename TransformF = boost::hana::id_t>
class container_loader
{
using champ_t = std::decay_t<decltype(std::declval<Container>().impl())>;
Expand All @@ -61,12 +63,19 @@ class container_loader
};

public:
explicit container_loader(container_archive_load<Container> archive)
explicit container_loader(Archive archive)
requires std::is_same_v<TransformF, boost::hana::id_t>
: archive_{std::move(archive)}
, nodes_{archive_.nodes}
{
}

explicit container_loader(Archive archive, TransformF transform)
: archive_{std::move(archive)}
, nodes_{archive_.nodes, std::move(transform)}
{
}

Container load(node_id root_id)
{
if (root_id.value >= archive_.nodes.size()) {
Expand Down Expand Up @@ -106,15 +115,20 @@ class container_loader
}

private:
const container_archive_load<Container> archive_;
const Archive archive_;
nodes_loader<typename node_t::value_t,
typename traits::Hash,
typename traits::Equal,
typename traits::MemoryPolicy,
traits::bits>
traits::bits,
TransformF>
nodes_;
};

template <class Container>
container_loader(container_archive_load<Container> archive)
-> container_loader<Container>;

template <class Container>
std::pair<container_archive_save<Container>, node_id>
save_to_archive(Container container, container_archive_save<Container> archive)
Expand Down
13 changes: 12 additions & 1 deletion immer/extra/archive/champ/load.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

#include <immer/flex_vector.hpp>

#include <boost/hana/functional/id.hpp>
#include <boost/range/adaptor/indexed.hpp>

#include <spdlog/spdlog.h>

namespace immer::archive {
Expand Down Expand Up @@ -54,7 +56,8 @@ template <class T,
typename Hash = std::hash<T>,
typename Equal = std::equal_to<T>,
typename MemoryPolicy = immer::default_memory_policy,
immer::detail::hamts::bits_t B = immer::default_bits>
immer::detail::hamts::bits_t B = immer::default_bits,
typename TransformF = boost::hana::id_t>
class nodes_loader
{
public:
Expand All @@ -66,7 +69,14 @@ class nodes_loader
using values_t = immer::flex_vector<immer::array<T>>;

explicit nodes_loader(nodes_load<T, B> archive)
requires std::is_same_v<TransformF, boost::hana::id_t>
: archive_{std::move(archive)}
{
}

explicit nodes_loader(nodes_load<T, B> archive, TransformF transform)
: archive_{std::move(archive)}
, transform_{std::move(transform)}
{
}

Expand Down Expand Up @@ -219,6 +229,7 @@ class nodes_loader

private:
const nodes_load<T, B> archive_;
const TransformF transform_;
immer::map<node_id, std::pair<node_ptr, values_t>> collisions_;
immer::map<node_id, std::pair<node_ptr, values_t>> inners_;
};
Expand Down
8 changes: 7 additions & 1 deletion immer/extra/archive/champ/traits.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
#include <immer/extra/archive/champ/champ.hpp>
#include <immer/extra/archive/traits.hpp>

#include <boost/hana/functional/id.hpp>

namespace immer::archive {

template <class Container>
Expand All @@ -13,8 +15,12 @@ struct champ_traits
immer::archive::champ::container_archive_save<Container>;
using load_archive_t =
immer::archive::champ::container_archive_load<Container>;
using loader_t = immer::archive::champ::container_loader<Container>;
using container_id = immer::archive::node_id;

template <typename Archive = load_archive_t,
typename TransformF = boost::hana::id_t>
using loader_t =
immer::archive::champ::container_loader<Container, Archive, TransformF>;
};

template <typename K,
Expand Down
Loading

0 comments on commit 6ab55af

Please sign in to comment.