1 | // |
2 | // immer: immutable data structures for C++ |
3 | // Copyright (C) 2016, 2017, 2018 Juan Pedro Bolivar Puente |
4 | // |
5 | // This software is distributed under the Boost Software License, Version 1.0. |
6 | // See accompanying file LICENSE or copy at http://boost.org/LICENSE_1_0.txt |
7 | // |
8 | |
9 | #pragma once |
10 | |
11 | #include <cstdio> |
12 | |
13 | namespace immer { |
14 | |
15 | /*! |
16 | * Appends a default constructed extra object of type `T` at the |
17 | * *before* the requested region. |
18 | * |
19 | * @tparam T Type of the appended data. |
20 | * @tparam Base Type of the parent heap. |
21 | */ |
22 | template <typename T, typename Base> |
23 | struct with_data : Base |
24 | { |
25 | using base_t = Base; |
26 | |
27 | template <typename... Tags> |
28 | static void* allocate(std::size_t size, Tags... tags) |
29 | { |
30 | auto p = base_t::allocate(size + sizeof(T), tags...); |
31 | return new (p) T{} + 1; |
32 | } |
33 | |
34 | template <typename... Tags> |
35 | static void deallocate(std::size_t size, void* p, Tags... tags) |
36 | { |
37 | auto dp = static_cast<T*>(p) - 1; |
38 | dp->~T(); |
39 | base_t::deallocate(size + sizeof(T), dp, tags...); |
40 | } |
41 | }; |
42 | |
43 | } // namespace immer |
44 | |