Author: brane
Date: Fri Jul 26 08:42:08 2013
New Revision: 1507217

URL: http://svn.apache.org/r1507217
Log:
Introduce a pool wrapper for the iteration pool idiom in the C++HL APR wrapper.

* subversion/bindings/cxxhl/src/aprwrap/pool.hpp
  (IterationPool): New class; a pool wrapper that hides its API.
  (Pool::Pool): Make non-default constructor explicit and accept a non-const
   reference to the parent pool instead of a const pointer.
  (Pool::Iteration): New nested class; a proxy for the pool in IterationPool.
* subversion/bindings/cxxhl/src/exception.cpp
  (Error::compile_messages): Use IterationPool and Pool::Iteration in the loop.
* subversion/bindings/cxxhl/tests/test_aprwrap.cpp
  (CreateSubpool): Adapt to changed pool constructor signature.

Modified:
    subversion/trunk/subversion/bindings/cxxhl/src/aprwrap/pool.hpp
    subversion/trunk/subversion/bindings/cxxhl/src/exception.cpp
    subversion/trunk/subversion/bindings/cxxhl/tests/test_aprwrap.cpp

Modified: subversion/trunk/subversion/bindings/cxxhl/src/aprwrap/pool.hpp
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxxhl/src/aprwrap/pool.hpp?rev=1507217&r1=1507216&r2=1507217&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxxhl/src/aprwrap/pool.hpp (original)
+++ subversion/trunk/subversion/bindings/cxxhl/src/aprwrap/pool.hpp Fri Jul 26 
08:42:08 2013
@@ -37,6 +37,9 @@ namespace subversion {
 namespace cxxhl {
 namespace apr {
 
+// Forward declaration
+class IterationPool;
+
 /**
  * Encapsulates an APR pool.
  */
@@ -53,24 +56,33 @@ public:
   /**
    * Create a pool as a child of @a parent.
    */
-  Pool(const Pool* parent) throw()
-    : m_pool(svn_pool_create(parent->m_pool))
+  explicit Pool(Pool& parent) throw()
+    : m_pool(svn_pool_create(parent.m_pool))
     {}
 
   /**
    * Destroy the pool.
    */
-  ~Pool() throw() { svn_pool_destroy(m_pool); }
+  ~Pool() throw()
+    {
+      svn_pool_destroy(m_pool);
+    }
 
   /**
    * Clear the pool.
    */
-  void clear() throw() { apr_pool_clear(m_pool); }
+  void clear() throw()
+    {
+      apr_pool_clear(m_pool);
+    }
 
   /**
    * Retuurn a pool pointer that can be used by the C APIs.
    */
-  apr_pool_t* get() const throw() { return m_pool; }
+  apr_pool_t* get() const throw()
+    {
+      return m_pool;
+    }
 
   /**
    * Allocate space for @a count elements of type @a T from the pool.
@@ -95,8 +107,88 @@ public:
 private:
   static apr_pool_t* get_root_pool();
   apr_pool_t* const m_pool;
+
+public:
+  /**
+   * Pool proxy used for iteration scratch pools.
+   *
+   * Construct this object inside a loop body in order to clear the
+   * proxied pool on every iteration.
+   */
+  class Iteration
+  {
+  public:
+    /**
+     * The constructor clears the proxied pool.
+     */
+    explicit Iteration(IterationPool& iterbase) throw();
+
+    /**
+     * Returns a reference to the proxied pool.
+     */
+    Pool& pool() const throw()
+      {
+        return m_pool;
+      }
+
+    /**
+     * Proxy method for Pool::get
+     */
+    apr_pool_t* get() const throw()
+      {
+        return m_pool.get();
+      }
+
+    /**
+     * Proxy method for Pool::alloc
+     */
+    template<typename T>
+    T* alloc(std::size_t count) throw()
+      {
+        return m_pool.alloc<T>(count);
+      }
+
+    /**
+     * Proxy method for Pool::allocz
+     */
+    template<typename T>
+    T* allocz(std::size_t count) throw()
+      {
+        return m_pool.allocz<T>(count);
+      }
+
+  private:
+    Pool& m_pool;
+  };
+};
+
+/**
+ * Pool wrapper that hides the pool implementation, except for construction.
+ *
+ * Construct this object outside a loop body, then within the body,
+ * use Pool::Iteration to access the wrapped pool.
+ */
+class IterationPool
+{
+public:
+  IterationPool() {}
+
+  explicit IterationPool(Pool& parent) throw()
+    : m_pool(parent)
+    {}
+
+private:
+  friend class Pool::Iteration;
+  Pool m_pool;
 };
 
+// Pool::Iteration constructor implementation
+inline Pool::Iteration::Iteration(IterationPool& iterbase) throw()
+  : m_pool(iterbase.m_pool)
+{
+  m_pool.clear();
+}
+
 } // namespace apr
 } // namespace cxxhl
 } // namespace subversion

Modified: subversion/trunk/subversion/bindings/cxxhl/src/exception.cpp
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxxhl/src/exception.cpp?rev=1507217&r1=1507216&r2=1507217&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxxhl/src/exception.cpp (original)
+++ subversion/trunk/subversion/bindings/cxxhl/src/exception.cpp Fri Jul 26 
08:42:08 2013
@@ -334,9 +334,11 @@ Error::MessageList Error::compile_messag
   std::vector<int> empties;
   empties.reserve(max_length);
 
-  APR::Pool iterpool;
+  APR::IterationPool iterbase;
   for (const Error* err = this; err; err = err->m_nested.get())
     {
+      APR::Pool::Iteration iterpool(iterbase);
+
       if (!err->m_description->what())
         {
           // Non-specific messages are printed only once.
@@ -348,8 +350,7 @@ Error::MessageList Error::compile_messag
         }
       handle_one_error(ml, show_traces,
                        err->m_errno, err->m_description,
-                       iterpool);
-      iterpool.clear();
+                       iterpool.pool());
     }
   return ml;
 }

Modified: subversion/trunk/subversion/bindings/cxxhl/tests/test_aprwrap.cpp
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxxhl/tests/test_aprwrap.cpp?rev=1507217&r1=1507216&r2=1507217&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxxhl/tests/test_aprwrap.cpp (original)
+++ subversion/trunk/subversion/bindings/cxxhl/tests/test_aprwrap.cpp Fri Jul 
26 08:42:08 2013
@@ -40,7 +40,7 @@ TEST(Pools, InitializeGlobalPool)
 TEST(Pools, CreateSubpool)
 {
   APR::Pool pool;
-  APR::Pool subpool(&pool);
+  APR::Pool subpool(pool);
   EXPECT_EQ(pool.get(), apr_pool_parent_get(subpool.get()));
 }
 


Reply via email to