]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/tools/quickbook/src/cleanup.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / tools / quickbook / src / cleanup.hpp
index a03cf4cd2c8af642725f1daac0f0e7c16f4dc348..9e952b7cab37a0500b3bab6cb2b0c5402868e188 100644 (file)
@@ -1,25 +1,49 @@
 /*=============================================================================
-    Copyright (c) 2010 Daniel James
+    Copyright (c) 2010.2017 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
 {
+    // This header defines a class which will store pointers and delete what
+    // they're pointing to on destruction. Add an object, and you can use
+    // pointers and references to it during the cleanup object's lifespan.
+    //
+    // Example use:
+    //
+    // struct wonder_struct {
+    //     quickbook::cleanup cleanup;
+    // };
+    //
+    // wonder_struct w;
+    // thing& t = w.cleanup.add(new thing());
+    //
+    // Can now use 't' until the wonder_struct is destroyed.
+    //
+    // Anything added to cleanup is destroyed in reverse order, so it
+    // should be okay for an object to depend on something that was previously
+    // added.
+
+    namespace detail { struct cleanup_node; }
+    struct cleanup
+    {
+        cleanup() : first_(0) {}
+        ~cleanup();
+        template <typename T> T& add(T*);
+
+    private:
+        detail::cleanup_node* first_;
+
+        cleanup& operator=(cleanup const&);
+        cleanup(cleanup const&);
+    };
+
     namespace detail
     {
         template <typename T>
@@ -27,48 +51,49 @@ namespace quickbook
             delete static_cast<T*>(ptr);
         }
         
-        struct scoped_void
+        struct cleanup_node
         {
             void* ptr_;
             void (*del_)(void*);
+            cleanup_node* next_;
             
-            scoped_void() : ptr_(0), del_(0) {}
-            scoped_void(scoped_void const& src) : ptr_(0), del_(0) {
-            ignore_variable(&src);
-                assert(!src.ptr_);
-            }
-            ~scoped_void() {
+            cleanup_node() : ptr_(0), del_(0), next_(0) {}
+            cleanup_node(void* ptr, void (*del)(void* x))
+                : ptr_(ptr), del_(del), next_(0) {}
+            ~cleanup_node() {
                 if(ptr_) del_(ptr_);
             }
             
-            void store(void* ptr, void (*del)(void* x)) {
-                ptr = ptr_;
-                del = del_;
+            void move_assign(cleanup_node& n) {
+                ptr_ = n.ptr_;
+                del_ = n.del_;
+                n.ptr_ = 0;
+                n.del_ = 0;
             }
         private:
-            scoped_void& operator=(scoped_void const&);
+            cleanup_node(cleanup_node const&);
+            cleanup_node& operator=(cleanup_node const&);
         };
     }
     
-    struct cleanup
+    template <typename T>
+    T& cleanup::add(T* ptr)
     {
-        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>);
+        detail::cleanup_node n(ptr, &detail::delete_impl<T>);
+        detail::cleanup_node* n2 = new detail::cleanup_node();
+        n2->next_ = first_;
+        first_ = n2;
+        n2->move_assign(n);
+        return *ptr;
+    }
 
-            return *new_;
+    inline cleanup::~cleanup() {
+        while(first_) {
+            detail::cleanup_node* to_delete = first_;
+            first_ = first_->next_;
+            delete to_delete;
         }
-
-        std::deque<detail::scoped_void> cleanup_list_;
-    private:
-        cleanup& operator=(cleanup const&);
-        cleanup(cleanup const&);
-    };
+    }
 }
 
 #endif