Code

fix parameter ranges, copyedit
[inkscape.git] / src / gc-allocator.h
1 /** @file
2  * @brief Garbage-collected STL allocator for standard containers
3  */
4 /* Authors:
5  *   Krzysztof KosiƄski <tweenk.pl@gmail.com>
6  *
7  * Copyright 2008 Authors
8  *
9  * This program is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU General Public License
11  * as published by the Free Software Foundation; either version 2
12  * of the License, or (at your option) any later version.
13  *
14  * See the file COPYING for details.
15  */
17 #ifndef SEEN_INKSCAPE_GC_ALLOCATOR_H
18 #define SEEN_INKSCAPE_GC_ALLOCATOR_H
20 #include <cstddef>
21 #include <limits>
22 #include "gc-core.h"
24 namespace Inkscape {
25 namespace GC {
27 /**
28  * @brief Garbage-collected allocator for the standard containers
29  *
30  * STL containers with default parameters cannot be used as members in garbage-collected
31  * objects, because by default the destructors are not called, causing a memory leak
32  * (the memory allocated by the container is not freed). To address this, STL containers
33  * can be told to use this garbage-collected allocator. It usually is the last template
34  * parameter. For example, to define a GC-managed map of ints to Unicode strings:
35  *
36  * @code typedef std::map<int, Glib::ustring, less<int>, Inkscape::GC::Allocator> gcmap; @endcode
37  *
38  * Afterwards, you can place gcmap as a member in a non-finalized GC-managed object, because
39  * all memory used by gcmap will also be reclaimable by the garbage collector, therefore
40  * avoiding memory leaks.
41  */
42 template <typename T>
43 class Allocator {
44     // required typedefs
45     typedef T           value_type;
46     typedef size_t      size_type;
47     typedef ptrdiff_t   difference_type;
48     typedef T *         pointer;
49     typedef T const *   const_pointer;
50     typedef T &         reference;
51     typedef T const &   const_reference;
52     
53     // required structure that allows accessing the same allocator for a different type
54     template <typename U>
55     struct rebind {
56         typedef Allocator<U> other;
57     };
58     
59     // constructors - no-ops since the allocator doesn't have any state
60     Allocator() throw() {}
61     Allocator(Allocator const &) throw() {}
62     template <typename U> Allocator(Allocator<U> const &) throw() {}
63     ~Allocator() throw() {}
64     
65     // trivial required methods
66     pointer address(reference ref) { return &ref; }
67     const_pointer address(const_reference ref) { return &ref; }
68     void construct(pointer p, T const &value) { new (static_cast<void*>(p)) T(value); }
69     void destroy(pointer p) { p->~T(); }
70     
71     // maximum meaningful memory amount that can be requested from the allocator
72     size_type max_size() {
73         return numeric_limits<size_type>::max() / sizeof(T);
74     }
75     
76     // allocate memory for num elements without initializing them
77     pointer allocate(size_type num, Allocator<void>::const_pointer) {
78         return static_cast<pointer>( Inkscape::GC::Core::malloc(num * sizeof(T)) );
79     }
80     
81     // deallocate memory at p
82     void deallocate(pointer p, size_type) {
83         Inkscape::GC::Core::free(p);
84     }
85 };
87 // required comparison operators
88 template <typename T1, typename T2>
89 bool operator==(Allocator<T1> const &, Allocator<T2> const &) { return true; }
90 template <typename T1, typename T2>
91 bool operator!=(Allocator<T1> const &, Allocator<T2> const &) { return false; }
93 } // namespace GC
94 } // namespace Inkscape
96 #endif // !SEEN_INKSCAPE_GC_ALLOCATOR_H
97 /*
98   Local Variables:
99   mode:c++
100   c-file-style:"stroustrup"
101   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
102   indent-tabs-mode:nil
103   fill-column:99
104   End:
105 */
106 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :