diff options
Diffstat (limited to 'immer/memory_policy.hpp')
-rw-r--r-- | immer/memory_policy.hpp | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/immer/memory_policy.hpp b/immer/memory_policy.hpp new file mode 100644 index 000000000000..b4f665bf621c --- /dev/null +++ b/immer/memory_policy.hpp @@ -0,0 +1,135 @@ +// +// immer: immutable data structures for C++ +// Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente +// +// This software is distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt +// + +#pragma once + +#include <immer/heap/cpp_heap.hpp> +#include <immer/heap/heap_policy.hpp> +#include <immer/refcount/no_refcount_policy.hpp> +#include <immer/refcount/refcount_policy.hpp> +#include <immer/refcount/unsafe_refcount_policy.hpp> +#include <immer/transience/gc_transience_policy.hpp> +#include <immer/transience/no_transience_policy.hpp> +#include <type_traits> + +namespace immer { + +/*! + * Metafunction that returns the best *transience policy* to use for a + * given *refcount policy*. + */ +template <typename RefcountPolicy> +struct get_transience_policy + : std::conditional<std::is_same<RefcountPolicy, no_refcount_policy>::value, + gc_transience_policy, + no_transience_policy> +{}; + +template <typename T> +using get_transience_policy_t = typename get_transience_policy<T>::type; + +/*! + * Metafunction that returns wether to *prefer fewer bigger objects* + * to use for a given *heap policy*. + */ +template <typename HeapPolicy> +struct get_prefer_fewer_bigger_objects + : std::integral_constant< + bool, + std::is_same<HeapPolicy, heap_policy<cpp_heap>>::value> +{}; + +template <typename T> +constexpr auto get_prefer_fewer_bigger_objects_v = + get_prefer_fewer_bigger_objects<T>::value; + +/*! + * Metafunction that returns wether to use *transient R-Values* + * for a given *refcount policy*. + */ +template <typename RefcountPolicy> +struct get_use_transient_rvalues + : std::integral_constant< + bool, + !std::is_same<RefcountPolicy, no_refcount_policy>::value> +{}; + +template <typename T> +constexpr auto get_use_transient_rvalues_v = + get_use_transient_rvalues<T>::value; + +/*! + * This is a default implementation of a *memory policy*. A memory + * policy is just a bag of other policies plus some flags with hints + * to the user about the best way to use these strategies. + * + * @tparam HeapPolicy A *heap policy*, for example, @ref heap_policy. + * @tparam RefcountPolicy A *reference counting policy*, for example, + * @ref refcount_policy. + * @tparam TransiencePolicy A *transience policy*, for example, + * @ref no_transience_policy. + * @tparam PreferFewerBiggerObjects Boolean flag indicating whether + * the user should prefer to allocate memory in bigger chungs + * --e.g. by putting various objects in the same memory + * region-- or not. + * @tparam UseTransientRValues Boolean flag indicating whether + * immutable containers should try to modify contents in-place + * when manipulating an r-value reference. + */ +template <typename HeapPolicy, + typename RefcountPolicy, + typename TransiencePolicy = get_transience_policy_t<RefcountPolicy>, + bool PreferFewerBiggerObjects = + get_prefer_fewer_bigger_objects_v<HeapPolicy>, + bool UseTransientRValues = + get_use_transient_rvalues_v<RefcountPolicy>> +struct memory_policy +{ + using heap = HeapPolicy; + using refcount = RefcountPolicy; + using transience = TransiencePolicy; + + static constexpr bool prefer_fewer_bigger_objects = + PreferFewerBiggerObjects; + + static constexpr bool use_transient_rvalues = UseTransientRValues; + + using transience_t = typename transience::template apply<heap>::type; +}; + +/*! + * The default *heap policy* just uses the standard heap with a + * @ref free_list_heap_policy. If `IMMER_NO_FREE_LIST` is defined to `1` + * then it just uses the standard heap. + */ +#if IMMER_NO_FREE_LIST +using default_heap_policy = heap_policy<debug_size_heap<cpp_heap>>; +#else +#if IMMER_NO_THREAD_SAFETY +using default_heap_policy = unsafe_free_list_heap_policy<cpp_heap>; +#else +using default_heap_policy = free_list_heap_policy<cpp_heap>; +#endif +#endif + +/*! + * By default we use thread safe reference counting. + */ +#if IMMER_NO_THREAD_SAFETY +using default_refcount_policy = unsafe_refcount_policy; +#else +using default_refcount_policy = refcount_policy; +#endif + +/*! + * The default memory policy. + */ +using default_memory_policy = + memory_policy<default_heap_policy, default_refcount_policy>; + +} // namespace immer |