Skip to content

Commit

Permalink
Document the missing public API parts
Browse files Browse the repository at this point in the history
  • Loading branch information
alex-sparus committed Aug 19, 2024
1 parent c756b75 commit e5d7156
Show file tree
Hide file tree
Showing 12 changed files with 150 additions and 43 deletions.
2 changes: 2 additions & 0 deletions doc/doxygen.config
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ INPUT = \
../immer/heap \
../immer/refcount \
../immer/transience \
../immer/extra/persist \
../immer/extra/persist/xxhash \
../immer/extra/persist/cereal
INCLUDE_PATH = ..
QUIET = YES
Expand Down
29 changes: 24 additions & 5 deletions doc/persist.rst
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,10 @@ The next component we need is the pools of all the containers from the value:

.. literalinclude:: ../test/extra/persist/test_for_docs.cpp
:language: c++
:start-after: start-get_auto_pool
:end-before: end-get_auto_pool
:start-after: start-get_output_pools
:end-before: end-get_output_pools

The ``get_auto_pool`` function returns the output pools of all ``immer`` containers that would be serialized using
The ``get_output_pools`` function returns the output pools of all ``immer`` containers that would be serialized using
pools, as controlled by the policy. Here we use the default policy ``hana_struct_auto_policy`` which will use pools for
all ``immer`` containers inside of the document type which must be a ``hana::Struct``.

Expand Down Expand Up @@ -232,8 +232,8 @@ The first two steps are the same as in the previous example:

.. literalinclude:: ../test/extra/persist/test_for_docs.cpp
:language: c++
:start-after: start-get_auto_pool
:end-before: end-get_auto_pool
:start-after: start-get_output_pools
:end-before: end-get_output_pools

Only this time the transforming function will convert an integer into a string:

Expand Down Expand Up @@ -266,6 +266,7 @@ And serialize it with pools:

In the resulting JSON we can confirm that the node ``{"key": 2, "value": ["_1_", "_2_"]}`` is reused for both vectors.

.. _transforming-hash-based-containers:

Transforming hash-based containers
----------------------------------
Expand Down Expand Up @@ -376,6 +377,7 @@ Finally, to convert the ``value`` with the defined ``conversion_map`` we prepare

We can see that the ``new_value`` table contains the transformed data from the original ``value`` table.

.. _modifying-the-hash-of-the-id:

Modifying the hash of the ID
----------------------------
Expand Down Expand Up @@ -416,6 +418,7 @@ a ``immer::persist::incompatible_hash_wrapper`` as the result of the ``immer::pe

We can see that the transformation has been applied, the keys have the ``_key`` suffix.

.. _transforming-nested-containers:

Transforming nested containers
------------------------------
Expand Down Expand Up @@ -496,3 +499,19 @@ API Overview
.. doxygengroup:: persist-api
:project: immer
:content-only:


Transform API
---------------

.. doxygengroup:: Persist-transform
:project: immer
:content-only:


Exceptions
----------

.. doxygengroup:: Persist-exceptions
:project: immer
:content-only:
11 changes: 4 additions & 7 deletions immer/extra/persist/cereal/archives.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,12 @@ constexpr bool is_pool_empty()
} // namespace detail

/**
* Adapted from cereal/archives/adapters.hpp
*/

/**
* @brief An output archive wrapper that provides access to the ``Pools`` stored
* inside. And serializes the ``pools`` object alongside the user document.
* @brief A wrapper type that wraps a `cereal::OutputArchive` (for example,
* `JSONOutputArchive`), provides access to the `Pools` object stored inside,
* and serializes the `pools` object alongside the user document.
*
* Normally, the function `cereal_save_with_pools` should be used instead of
* using wrapper directly.
* using this wrapper directly.
*
* @see cereal_save_with_pools
*
Expand Down
26 changes: 20 additions & 6 deletions immer/extra/persist/cereal/with_pools.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ namespace immer::persist {
*/

/**
* @brief Serialize the provided value using the provided policy to JSON
* outputting into the provided stream.
* @brief Serialize the provided value with pools using the provided policy
* outputting into the provided stream. By default, `cereal::JSONOutputArchive`
* is used but a different `cereal` output archive can be provided.
*
* @see Policy
* @ingroup persist-api
Expand Down Expand Up @@ -44,7 +45,9 @@ void cereal_save_with_pools(std::ostream& os,
}

/**
* @brief Serialize the provided value using the provided policy to JSON.
* @brief Serialize the provided value with pools using the provided policy. By
* default, `cereal::JSONOutputArchive` is used but a different `cereal` output
* archive can be provided.
*
* @return std::string The resulting JSON.
* @ingroup persist-api
Expand All @@ -62,7 +65,9 @@ std::string cereal_save_with_pools(const T& value0,

/**
* @brief Load a value of the given type `T` from the provided stream using
* pools.
* pools. By default, `cereal::JSONInputArchive` is used but a different
* `cereal` input archive can be provided.
*
* @ingroup persist-api
*/
template <class T,
Expand Down Expand Up @@ -94,7 +99,9 @@ T cereal_load_with_pools(std::istream& is, const Policy& policy = Policy{})

/**
* @brief Load a value of the given type `T` from the provided string using
* pools.
* pools. By default, `cereal::JSONInputArchive` is used but a different
* `cereal` input archive can be provided.
*
* @ingroup persist-api
*/
template <class T,
Expand All @@ -107,8 +114,15 @@ T cereal_load_with_pools(const std::string& input,
return cereal_load_with_pools<T, Archive>(is, policy);
}

/**
* @brief Return just the pools of all the containers of the provided value
* serialized using the provided policy.
*
* @ingroup persist-transform
* @see convert_container
*/
template <typename T, Policy<T> Policy = hana_struct_auto_policy>
auto get_auto_pool(const T& value0, const Policy& policy = Policy{})
auto get_output_pools(const T& value0, const Policy& policy = Policy{})
{
const auto types = policy.get_pool_types(value0);
auto pools = detail::generate_output_pools(types);
Expand Down
34 changes: 34 additions & 0 deletions immer/extra/persist/errors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,26 @@

namespace immer::persist {

/**
* @defgroup persist-exceptions
*/

/**
* Base class from which all the exceptions in `immer::persist` are derived.
*
* @ingroup persist-exceptions
*/
class pool_exception : public std::invalid_argument
{
public:
using invalid_argument::invalid_argument;
};

/**
* Thrown when a cycle is detected in the pool of vectors.
*
* @ingroup persist-exceptions
*/
class pool_has_cycles : public pool_exception
{
public:
Expand All @@ -23,6 +37,11 @@ class pool_has_cycles : public pool_exception
}
};

/**
* Thrown when a non-existent node is mentioned.
*
* @ingroup persist-exceptions
*/
class invalid_node_id : public pool_exception
{
public:
Expand All @@ -32,6 +51,11 @@ class invalid_node_id : public pool_exception
}
};

/**
* Thrown when a non-existent container is mentioned.
*
* @ingroup persist-exceptions
*/
class invalid_container_id : public pool_exception
{
public:
Expand All @@ -41,6 +65,11 @@ class invalid_container_id : public pool_exception
}
};

/**
* Thrown when a node has more children than expected.
*
* @ingroup persist-exceptions
*/
class invalid_children_count : public pool_exception
{
public:
Expand All @@ -51,6 +80,11 @@ class invalid_children_count : public pool_exception
}
};

/**
* Thrown when duplicate pool name is detected.
*
* @ingroup persist-exceptions
*/
class duplicate_name_pool_detected : public pool_exception
{
public:
Expand Down
24 changes: 19 additions & 5 deletions immer/extra/persist/hash_container_conversion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,33 @@
namespace immer::persist {

/**
* The wrapper is used to enable the incompatible_hash_mode, which is required
* The wrapper is used to enable the incompatible hash mode which is required
* when the key of a hash-based container transformed in a way that changes its
* hash.
*
* A value of this type should be returned from a transforming function
* accepting `target_container_type_request`.
*
* @ingroup persist-transform
* @see
* @rst
* :ref:`modifying-the-hash-of-the-id`
* @endrst
*/
template <class Container>
struct incompatible_hash_wrapper
{};

/**
* A bit of a hack but currently this is the simplest way to request a type of
* the hash function to be used after the transformation. Maybe the whole thing
* would change later. Right now everything is driven by the single function,
* which seems to be convenient otherwise.
* This type is used as an argument for a transforming function.
* The return type of the function is used to specify the desired container type
* to contain the transformed values.
*
* @ingroup persist-transform
* @see
* @rst
* :ref:`transforming-hash-based-containers`
* @endrst
*/
struct target_container_type_request
{};
Expand Down
36 changes: 28 additions & 8 deletions immer/extra/persist/transform.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,22 @@
namespace immer::persist {

/**
* Given an output_pools and a map of transformations, produce a new type of
* load pool with those transformations applied
* @defgroup persist-transform
*/

/**
* Given output_pools and a map of transformations, produce a new type of
* input pools with those transformations applied.
*
* `conversion_map` is a `boost::hana::map` where keys are types of `immer`
* containers and values are the transforming functions.
*
* @ingroup persist-transform
* @see get_output_pools
* @rst
* :ref:`transformations-with-pools`
* :ref:`transforming-nested-containers`
* @endrst
*/
template <class Storage, class ConversionMap>
inline auto
Expand All @@ -23,18 +37,24 @@ transform_output_pool(const detail::output_pools<Storage>& old_pools,
}

/**
* Given an old save pools and a new (transformed) load pools, effectively
* Given output_pools and new (transformed) input_pools, effectively
* convert the given container.
*
* @ingroup persist-transform
* @see get_output_pools
* @rst
* :ref:`transformations-with-pools`
* :ref:`transforming-nested-containers`
* @endrst
*/
template <class SaveStorage, class LoadStorage, class Container>
auto convert_container(const detail::output_pools<SaveStorage>& old_save_pools,
detail::input_pools<LoadStorage>& new_load_pools,
auto convert_container(const detail::output_pools<SaveStorage>& output_pools,
detail::input_pools<LoadStorage>& new_input_pools,
const Container& container)
{
const auto container_id =
detail::get_container_id(old_save_pools, container);
const auto container_id = detail::get_container_id(output_pools, container);
auto& loader =
new_load_pools
new_input_pools
.template get_loader_by_old_container<std::decay_t<Container>>();
auto result = loader.load(container_id);
return result;
Expand Down
7 changes: 7 additions & 0 deletions immer/extra/persist/xxhash/xxhash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@

namespace immer::persist {

/**
* xxHash is a good option to be used with `immer::persist` as it produces
* hashes identical across all platforms.
*
* @see https://xxhash.com/
* @ingroup persist-api
*/
template <class T>
struct xx_hash
{
Expand Down
4 changes: 2 additions & 2 deletions test/extra/persist/test_circular_dependency_conversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ TEST_CASE("Test exception while circular converting")

const auto names = immer::persist::detail::get_named_pools_for_hana_type<
model::value_one>();
const auto model_pool = immer::persist::get_auto_pool(value);
const auto model_pool = immer::persist::get_output_pools(value);

SECTION("Try to load")
{
Expand Down Expand Up @@ -409,7 +409,7 @@ TEST_CASE("Test circular dependency pools", "[conversion]")

const auto names = immer::persist::detail::get_named_pools_for_hana_type<
model::value_one>();
const auto model_pools = immer::persist::get_auto_pool(value);
const auto model_pools = immer::persist::get_output_pools(value);

/**
* NOTE: There is a circular dependency between pools: to convert
Expand Down
4 changes: 2 additions & 2 deletions test/extra/persist/test_conversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ TEST_CASE("Convert between two hierarchies via JSON compatibility",

const auto value = model::make_example_history();

const auto model_pools = immer::persist::get_auto_pool(value);
const auto model_pools = immer::persist::get_output_pools(value);

const auto map = hana::make_map(
hana::make_pair(hana::type_c<vector_one<model::snapshot>>,
Expand Down Expand Up @@ -201,7 +201,7 @@ struct two_vectors

TEST_CASE("Not every type is converted", "[conversion]")
{
const auto pools = immer::persist::get_auto_pool(two_vectors{});
const auto pools = immer::persist::get_output_pools(two_vectors{});

const auto map =
hana::make_map(hana::make_pair(hana::type_c<vector_one<int>>,
Expand Down
Loading

0 comments on commit e5d7156

Please sign in to comment.