]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/tools/quickbook/src/cleanup.hpp
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / boost / tools / quickbook / src / cleanup.hpp
1 /*=============================================================================
2 Copyright (c) 2010.2017 Daniel James
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
9 #if !defined(BOOST_SPIRIT_QUICKBOOK_CLEANUP_HPP)
10 #define BOOST_SPIRIT_QUICKBOOK_CLEANUP_HPP
11
12 namespace quickbook
13 {
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
34 {
35 struct cleanup_node;
36 }
37 struct cleanup
38 {
39 cleanup() : first_(0) {}
40 ~cleanup();
41 template <typename T> T& add(T*);
42
43 private:
44 detail::cleanup_node* first_;
45
46 cleanup& operator=(cleanup const&);
47 cleanup(cleanup const&);
48 };
49
50 namespace detail
51 {
52 template <typename T> void delete_impl(void* ptr)
53 {
54 delete static_cast<T*>(ptr);
55 }
56
57 struct cleanup_node
58 {
59 void* ptr_;
60 void (*del_)(void*);
61 cleanup_node* next_;
62
63 cleanup_node() : ptr_(0), del_(0), next_(0) {}
64 cleanup_node(void* ptr, void (*del)(void* x))
65 : ptr_(ptr), del_(del), next_(0)
66 {
67 }
68 ~cleanup_node()
69 {
70 if (ptr_) del_(ptr_);
71 }
72
73 void move_assign(cleanup_node& n)
74 {
75 ptr_ = n.ptr_;
76 del_ = n.del_;
77 n.ptr_ = 0;
78 n.del_ = 0;
79 }
80
81 private:
82 cleanup_node(cleanup_node const&);
83 cleanup_node& operator=(cleanup_node const&);
84 };
85 }
86
87 template <typename T> T& cleanup::add(T* ptr)
88 {
89 detail::cleanup_node n(ptr, &detail::delete_impl<T>);
90 detail::cleanup_node* n2 = new detail::cleanup_node();
91 n2->next_ = first_;
92 first_ = n2;
93 n2->move_assign(n);
94 return *ptr;
95 }
96
97 inline cleanup::~cleanup()
98 {
99 while (first_) {
100 detail::cleanup_node* to_delete = first_;
101 first_ = first_->next_;
102 delete to_delete;
103 }
104 }
105 }
106
107 #endif