summaryrefslogtreecommitdiff
path: root/tools/quickbook/src/cleanup.hpp
blob: a03cf4cd2c8af642725f1daac0f0e7c16f4dc348 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
/*=============================================================================
    Copyright (c) 2010 Daniel James

    Use, modification and distribution is subject to the Boost Software
    License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
    http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/

// This header defines a class which can will store pointers and deleters
// to a number of objects and delete them on exit. Basically stick an
// object in here, and you can use pointers and references to the object
// for the cleanup object's lifespan.

#if !defined(BOOST_SPIRIT_QUICKBOOK_CLEANUP_HPP)
#define BOOST_SPIRIT_QUICKBOOK_CLEANUP_HPP

#include <deque>
#include <cassert>
#include <utility>

namespace quickbook
{
    namespace detail
    {
        template <typename T>
        void delete_impl(void* ptr) {
            delete static_cast<T*>(ptr);
        }
        
        struct scoped_void
        {
            void* ptr_;
            void (*del_)(void*);
            
            scoped_void() : ptr_(0), del_(0) {}
            scoped_void(scoped_void const& src) : ptr_(0), del_(0) {
            ignore_variable(&src);
                assert(!src.ptr_);
            }
            ~scoped_void() {
                if(ptr_) del_(ptr_);
            }
            
            void store(void* ptr, void (*del)(void* x)) {
                ptr = ptr_;
                del = del_;
            }
        private:
            scoped_void& operator=(scoped_void const&);
        };
    }
    
    struct cleanup
    {
        cleanup() {}
    
        template <typename T>
        T& add(T* new_)
        {
            std::auto_ptr<T> obj(new_);
            cleanup_list_.push_back(detail::scoped_void());
            cleanup_list_.back().store(obj.release(), &detail::delete_impl<T>);

            return *new_;
        }

        std::deque<detail::scoped_void> cleanup_list_;
    private:
        cleanup& operator=(cleanup const&);
        cleanup(cleanup const&);
    };
}

#endif