]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/tools/quickbook/src/cleanup.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / tools / quickbook / src / cleanup.hpp
CommitLineData
7c673cae 1/*=============================================================================
b32b8144 2 Copyright (c) 2010.2017 Daniel James
7c673cae
FG
3
4 Use, modification and distribution is subject to the Boost Software
5 License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt)
7=============================================================================*/
8
7c673cae
FG
9#if !defined(BOOST_SPIRIT_QUICKBOOK_CLEANUP_HPP)
10#define BOOST_SPIRIT_QUICKBOOK_CLEANUP_HPP
11
7c673cae
FG
12namespace quickbook
13{
b32b8144
FG
14 // This header defines a class which will store pointers and delete what
15 // they're pointing to on destruction. Add an object, and you can use
16 // pointers and references to it during the cleanup object's lifespan.
17 //
18 // Example use:
19 //
20 // struct wonder_struct {
21 // quickbook::cleanup cleanup;
22 // };
23 //
24 // wonder_struct w;
25 // thing& t = w.cleanup.add(new thing());
26 //
27 // Can now use 't' until the wonder_struct is destroyed.
28 //
29 // Anything added to cleanup is destroyed in reverse order, so it
30 // should be okay for an object to depend on something that was previously
31 // added.
32
33 namespace detail { struct cleanup_node; }
34 struct cleanup
35 {
36 cleanup() : first_(0) {}
37 ~cleanup();
38 template <typename T> T& add(T*);
39
40 private:
41 detail::cleanup_node* first_;
42
43 cleanup& operator=(cleanup const&);
44 cleanup(cleanup const&);
45 };
46
7c673cae
FG
47 namespace detail
48 {
49 template <typename T>
50 void delete_impl(void* ptr) {
51 delete static_cast<T*>(ptr);
52 }
53
b32b8144 54 struct cleanup_node
7c673cae
FG
55 {
56 void* ptr_;
57 void (*del_)(void*);
b32b8144 58 cleanup_node* next_;
7c673cae 59
b32b8144
FG
60 cleanup_node() : ptr_(0), del_(0), next_(0) {}
61 cleanup_node(void* ptr, void (*del)(void* x))
62 : ptr_(ptr), del_(del), next_(0) {}
63 ~cleanup_node() {
7c673cae
FG
64 if(ptr_) del_(ptr_);
65 }
66
b32b8144
FG
67 void move_assign(cleanup_node& n) {
68 ptr_ = n.ptr_;
69 del_ = n.del_;
70 n.ptr_ = 0;
71 n.del_ = 0;
7c673cae
FG
72 }
73 private:
b32b8144
FG
74 cleanup_node(cleanup_node const&);
75 cleanup_node& operator=(cleanup_node const&);
7c673cae
FG
76 };
77 }
78
b32b8144
FG
79 template <typename T>
80 T& cleanup::add(T* ptr)
7c673cae 81 {
b32b8144
FG
82 detail::cleanup_node n(ptr, &detail::delete_impl<T>);
83 detail::cleanup_node* n2 = new detail::cleanup_node();
84 n2->next_ = first_;
85 first_ = n2;
86 n2->move_assign(n);
87 return *ptr;
88 }
7c673cae 89
b32b8144
FG
90 inline cleanup::~cleanup() {
91 while(first_) {
92 detail::cleanup_node* to_delete = first_;
93 first_ = first_->next_;
94 delete to_delete;
7c673cae 95 }
b32b8144 96 }
7c673cae
FG
97}
98
99#endif