Author: brane
Date: Fri Dec 28 15:13:24 2018
New Revision: 1849865

URL: http://svn.apache.org/viewvc?rev=1849865&view=rev
Log:
Replace the APR array wrapper in SVN++:

 - renames to apr::array from APR::Array;
 - removes APR::ConstArray;
 - removes array iterations and adds compliant iterators instead.
 - updates all array tests.

Removed:
    
subversion/trunk/subversion/bindings/cxx/tests/test_aprwrap_array_helpers.hpp
    subversion/trunk/subversion/bindings/cxx/tests/test_aprwrap_const_arrays.cpp
Modified:
    subversion/trunk/subversion/bindings/cxx/src/aprwrap/array.hpp
    subversion/trunk/subversion/bindings/cxx/tests/test_aprwrap_arrays.cpp

Modified: subversion/trunk/subversion/bindings/cxx/src/aprwrap/array.hpp
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/src/aprwrap/array.hpp?rev=1849865&r1=1849864&r2=1849865&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/src/aprwrap/array.hpp (original)
+++ subversion/trunk/subversion/bindings/cxx/src/aprwrap/array.hpp Fri Dec 28 
15:13:24 2018
@@ -26,10 +26,9 @@
 
 #include <stdexcept>
 
-#include <apr_tables.h>
 #include "pool.hpp"
 
-#include "svn_private_config.h"
+#include <apr_tables.h>
 
 namespace apache {
 namespace subversion {
@@ -37,59 +36,68 @@ namespace svnxx {
 namespace apr {
 
 /**
- * Proxy for an APR array.
+ * @brief Proxy for an APR array.
  *
  * This class does not own the array. The array's lifetime is tied to
  * its pool. The caller is responsible for making sure that the
  * array's lifetime is longer than this proxy object's.
  */
-template<typename T> class Array
+template<typename T> class array
 {
 public:
-  typedef T value_type;
-  typedef int size_type;
+  using value_type = T;
+  using size_type = int;
+  using iterator = value_type*;
+  using const_iterator = const value_type*;
 
   /**
    * Create and proxy a new APR array allocated from @a result_pool.
    * Reserve space for @a nelts array elements.
    */
-  explicit Array(const pool& result_pool, size_type nelts = 0) throw()
-    : m_array(apr_array_make(result_pool.get(), nelts, sizeof(value_type)))
+  explicit array(const pool& result_pool, size_type nelts = 0)
+    : proxied(apr_array_make(result_pool.get(), nelts, sizeof(value_type)))
     {}
 
   /**
-   * Create a new proxy for the APR array @a array.
+   * Create a new proxy for the APR array @a array_.
    */
-  explicit Array(apr_array_header_t* array)
-    : m_array(array)
+  explicit array(apr_array_header_t* array_)
+    : proxied(array_)
     {
-      if (m_array->elt_size != sizeof(value_type))
-        throw std::invalid_argument(
-            _("APR array element size does not match template parameter"));
+      if (proxied->elt_size != sizeof(value_type))
+        throw std::invalid_argument("apr::array element size mismatch");
     }
 
   /**
    * @return The wrapped APR array.
    */
-  apr_array_header_t* array() const throw()
+  apr_array_header_t* get_array() const noexcept
     {
-      return m_array;
+      return proxied;
     }
 
   /**
    * @return the number of elements in the wrapped APR array.
    */
-  size_type size() const throw()
+  size_type size() const noexcept
+    {
+      return proxied->nelts;
+    }
+
+  /**
+   * @return the reserved space in the wrapped APR array.
+   */
+  size_type capacity() const noexcept
     {
-      return m_array->nelts;
+      return proxied->nalloc;
     }
 
   /**
    * @return An immutable reference to the array element at @a index.
    */
-  const value_type& operator[](size_type index) const throw()
+  const value_type& operator[](size_type index) const noexcept
     {
-      return APR_ARRAY_IDX(m_array, index, value_type);
+      return APR_ARRAY_IDX(proxied, index, value_type);
     }
 
   /**
@@ -99,16 +107,16 @@ public:
   const value_type& at(size_type index) const
     {
       if (index < 0 || index >= size())
-        throw std::out_of_range(_("APR array index is out of range"));
+        throw std::out_of_range("apr::array index out of range");
       return (*this)[index];
     }
 
   /**
    * @return A mutable reference to the array element at @a index.
    */
-  value_type& operator[](size_type index) throw()
+  value_type& operator[](size_type index) noexcept
     {
-      return APR_ARRAY_IDX(m_array, index, value_type);
+      return APR_ARRAY_IDX(proxied, index, value_type);
     }
 
   /**
@@ -118,16 +126,16 @@ public:
   value_type& at(size_type index)
     {
       if (index < 0 || index >= size())
-        throw std::out_of_range(_("APR array index is out of range"));
+        throw std::out_of_range("apr::array index out of range");
       return (*this)[index];
     }
 
   /**
    * Push @a value onto the end of the APR array.
    */
-  void push(const value_type& value) throw()
+  void push(const value_type& value)
     {
-      APR_ARRAY_PUSH(m_array, value_type) = value;
+      APR_ARRAY_PUSH(proxied, value_type) = value;
     }
 
   /**
@@ -135,153 +143,61 @@ public:
    * @return A pointer to the value that was removed, or @c NULL if
    * the array was empty.
    */
-  value_type* pop() throw()
+  value_type* pop() noexcept
     {
-      return static_cast<value_type*>(apr_array_pop(m_array));
+      return static_cast<value_type*>(apr_array_pop(proxied));
     }
 
   /**
-   * Abstract base class for mutable iteration callback functors.
-   *
-   * FIXME: obsolete; see below.
-   */
-  struct Iteration
-  {
-    /**
-     * Called by Array::iterate for every value in the array.
-     * @return @c false to terminate the iteration, @c true otherwise.
-     */
-    virtual bool operator() (value_type& value) = 0;
-  };
-
-  /**
-   * Iterate over all the values pairs in the array, invoking
-   * @a callback for each one.
-   *
-   * FIXME: should use std::function instead.
+   * @brief Return an interator to the beginning of the array.
    */
-  void iterate(Iteration& callback)
+  iterator begin() noexcept
     {
-      for (size_type n = 0; n < size(); ++n)
-        if (!callback((*this)[n]))
-          break;
+      return &APR_ARRAY_IDX(proxied, 0, value_type);
     }
 
   /**
-   * Abstract base class for immutable iteration callback functors.
-   *
-   * FIXME: obsolete; see below.
-   */
-  struct ConstIteration
-  {
-    /**
-     * Called by Array::iterate for every value in the array.
-     * @return @c false to terminate the iteration, @c true otherwise.
-     */
-    virtual bool operator() (const value_type& value) = 0;
-  };
-
-  /**
-   * Iterate over all the values pairs in the array, invoking
-   * @a callback for each one.
-   *
-   * FIXME: should use std::function instead.
+   * @brief Return a constant interator to the beginning of the array.
    */
-  void iterate(ConstIteration& callback) const
+  const_iterator begin() const noexcept
     {
-      for (size_type n = 0; n < size(); ++n)
-        if (!callback((*this)[n]))
-          break;
+      return &APR_ARRAY_IDX(proxied, 0, const value_type);
     }
 
-private:
-  apr_array_header_t* const m_array; ///< The wrapperd APR array.
-};
-
-
-/**
- * Proxy for an immutable APR array.
- */
-template<typename T>
-class ConstArray : private Array<T>
-{
-  typedef Array<T> inherited;
-
-public:
-  typedef typename inherited::value_type value_type;
-  typedef typename inherited::size_type size_type;
-
-  /**
-   * Create a new proxy for the APR array wrapped by @a that.
-   */
-  ConstArray(const ConstArray& that) throw()
-    : inherited(that)
-    {}
-
-  /**
-   * Create a new proxy for the APR array wrapped by @a that.
-   */
-  explicit ConstArray(const inherited& that) throw()
-    : inherited(that)
-    {}
-
-  /**
-   * Create a new proxy for the APR array @a array.
-   */
-  explicit ConstArray(const apr_array_header_t* array)
-    : inherited(const_cast<apr_array_header_t*>(array))
-    {}
-
   /**
-   * @return The wrapped APR array.
+   * @brief Return a constant interator to the beginning of the array.
    */
-  const apr_array_header_t* array() const throw()
+  const_iterator cbegin() const noexcept
     {
-      return inherited::array();
+      return begin();
     }
 
   /**
-   * @return The number of elements in the wrapped APR array.
+   * @brief Return an interator to the end of the array.
    */
-  size_type size() const throw()
+  iterator end() noexcept
     {
-      return inherited::size();
+      return &APR_ARRAY_IDX(proxied, size(), value_type);
     }
 
   /**
-   * @return An immutable reference to the array element at @a index.
+   * @brief Return a constant interator to the end of the array.
    */
-  const value_type& operator[](size_type index) const throw()
+  const_iterator end() const noexcept
     {
-      return inherited::operator[](index);
+      return &APR_ARRAY_IDX(proxied, size(), const value_type);
     }
 
   /**
-   * @return An immutable reference to the array element at @a index.
-   * Like operator[] but perfoms a range check on the index.
+   * @brief Return a constant interator to the end of the array.
    */
-  const value_type& at(size_type index) const
+  const_iterator cend() const noexcept
     {
-      return inherited::at(index);
+      return end();
     }
 
-  /**
-   * Abstract base class for immutable iteration callback functors.
-   *
-   * FIXME: obsolete; see below.
-   */
-  typedef typename inherited::ConstIteration Iteration;
-
-  /**
-   * Iterate over all the values pairs in the array, invoking
-   * @a callback for each one.
-   *
-   * FIXME: should use std::function instead.
-   */
-  void iterate(Iteration& callback) const
-    {
-      inherited::iterate(callback);
-    }
+private:
+  apr_array_header_t* const proxied; ///< The wrapperd APR array.
 };
 
 } // namespace apr

Modified: subversion/trunk/subversion/bindings/cxx/tests/test_aprwrap_arrays.cpp
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/bindings/cxx/tests/test_aprwrap_arrays.cpp?rev=1849865&r1=1849864&r2=1849865&view=diff
==============================================================================
--- subversion/trunk/subversion/bindings/cxx/tests/test_aprwrap_arrays.cpp 
(original)
+++ subversion/trunk/subversion/bindings/cxx/tests/test_aprwrap_arrays.cpp Fri 
Dec 28 15:13:24 2018
@@ -28,189 +28,169 @@
 
 #include "fixture_init.hpp"
 
-#include "test_aprwrap_array_helpers.hpp"
-
 BOOST_AUTO_TEST_SUITE(aprwrap_arrays,
                       * boost::unit_test::fixture<init>());
 
+namespace {
+// Create a randomly-ordered array of constant strings.
+apr_array_header_t* fill_array(apr::pool& pool)
+{
+  apr_array_header_t* a = apr_array_make(pool.get(), 0, sizeof(const char*));
+  APR_ARRAY_PUSH(a, const char*) = "primus";
+  APR_ARRAY_PUSH(a, const char*) = "secundus";
+  APR_ARRAY_PUSH(a, const char*) = "tertius";
+  APR_ARRAY_PUSH(a, const char*) = "quartus";
+  APR_ARRAY_PUSH(a, const char*) = "quintus";
+  APR_ARRAY_PUSH(a, const char*) = "sextus";
+  APR_ARRAY_PUSH(a, const char*) = "septimus";
+  std::random_shuffle(&APR_ARRAY_IDX(a, 0, const char*),
+                      &APR_ARRAY_IDX(a, a->nelts, const char*));
+  return a;
+}
+} // anonymous namespace
+
 BOOST_AUTO_TEST_CASE(create_array)
 {
-  typedef APR::Array<unsigned char> Array;
+  typedef apr::array<unsigned char> array;
 
   apr::pool pool;
-  Array array(pool);
+  array a(pool);
 
-  BOOST_TEST(array.array() != nullptr);
-  BOOST_TEST(array.size() == 0);
-  BOOST_TEST(sizeof(Array::value_type) == sizeof(unsigned char));
-  BOOST_TEST(array.array()->elt_size == sizeof(Array::value_type));
+  BOOST_TEST(a.get_array() != nullptr);
+  BOOST_TEST(a.size() == 0);
+  BOOST_TEST(sizeof(array::value_type) == sizeof(unsigned char));
+  BOOST_TEST(a.get_array()->elt_size == sizeof(array::value_type));
 }
 
 BOOST_AUTO_TEST_CASE(wrap_array)
 {
-  typedef APR::Array<unsigned char> Array;
+  typedef apr::array<unsigned char> array;
 
   apr::pool pool;
   apr_array_header_t* apr_array =
-    apr_array_make(pool.get(), 0, sizeof(Array::value_type));
+    apr_array_make(pool.get(), 0, sizeof(array::value_type));
   BOOST_TEST_REQUIRE(apr_array != nullptr);
 
-  Array array(apr_array);
-  BOOST_TEST(array.array() == apr_array);
-  BOOST_TEST(array.size() == 0);
+  array a(apr_array);
+  BOOST_TEST(a.get_array() == apr_array);
+  BOOST_TEST(a.size() == 0);
 }
 
 BOOST_AUTO_TEST_CASE(rewrap_type_mismatch)
 {
-  typedef APR::Array<unsigned char> ByteArray;
-  typedef APR::Array<int> IntArray;
+  typedef apr::array<unsigned char> byte_array;
+  typedef apr::array<int> int_array;
 
   apr::pool pool;
-  BOOST_CHECK_THROW(ByteArray array(IntArray(pool).array()),
+  BOOST_CHECK_THROW(byte_array{int_array(pool).get_array()},
                     std::invalid_argument);
 }
 
 BOOST_AUTO_TEST_CASE(out_of_bounds)
 {
-  typedef APR::Array<unsigned char> Array;
+  typedef apr::array<unsigned char> array;
 
   apr::pool pool;
-  Array array(pool);
+  array a(pool);
 
-  BOOST_CHECK_THROW(array.at(-1), std::out_of_range);
-  BOOST_CHECK_THROW(array.at(array.size()), std::out_of_range);
+  BOOST_CHECK_THROW(a.at(-1), std::out_of_range);
+  BOOST_CHECK_THROW(a.at(a.size()), std::out_of_range);
 }
 
 BOOST_AUTO_TEST_CASE(indexing)
 {
-  typedef APR::Array<const char*> Array;
+  typedef apr::array<const char*> array;
 
   apr::pool pool;
-  Array array(fill_array(pool));
+  array a(fill_array(pool));
 
-  BOOST_TEST(array[0] == APR_ARRAY_IDX(array.array(), 0, Array::value_type));
-  BOOST_TEST(array[array.size() - 1] == APR_ARRAY_IDX(array.array(),
-                                                      array.array()->nelts - 1,
-                                                      Array::value_type));
+  BOOST_TEST(a[0] == APR_ARRAY_IDX(a.get_array(), 0, array::value_type));
+  BOOST_TEST(a[a.size() - 1] == APR_ARRAY_IDX(a.get_array(),
+                                              a.get_array()->nelts - 1,
+                                              array::value_type));
 }
 
 BOOST_AUTO_TEST_CASE(checked_indexing)
 {
-  typedef APR::Array<const char*> Array;
+  typedef apr::array<const char*> array;
 
   apr::pool pool;
-  Array array(fill_array(pool));
+  array a(fill_array(pool));
 
-  BOOST_TEST(array.at(0) == APR_ARRAY_IDX(array.array(), 0, 
Array::value_type));
-  BOOST_TEST(array.at(array.size() - 1) == APR_ARRAY_IDX(array.array(),
-                                                         array.array()->nelts 
- 1,
-                                                         Array::value_type));
+  BOOST_TEST(a.at(0) == APR_ARRAY_IDX(a.get_array(), 0, array::value_type));
+  BOOST_TEST(a.at(a.size() - 1) == APR_ARRAY_IDX(a.get_array(),
+                                                 a.get_array()->nelts - 1,
+                                                 array::value_type));
 }
 
 BOOST_AUTO_TEST_CASE(iteration)
 {
-  typedef APR::Array<const char*> Array;
+  typedef apr::array<const char*> array;
 
   apr::pool pool;
-  Array array(fill_array(pool));
+  array a(fill_array(pool));
 
-  struct Iteration : public Array::Iteration
-  {
-    Iteration(apr_array_header_t* raw_array)
-      : m_index(0), m_raw_array(raw_array)
-      {}
-
-    bool operator()(Array::value_type& value)
-      {
-        BOOST_TEST(value == APR_ARRAY_IDX(m_raw_array, m_index,
-                                          Array::value_type));
-        ++m_index;
-        return true;
-      }
-
-  private:
-    Array::size_type m_index;
-    apr_array_header_t* m_raw_array;
-  } callback(array.array());
-
-  array.iterate(callback);
-
-  // TODO: Fix iteration to take std::function.
-  // Array::size_type index = 0;
-  // apr_array_header_t* raw_array = array.array();
-  // array.iterate(
-  //     [&index, &raw_array](Array::value_type& value) {
-  //       BOOST_TEST(value == APR_ARRAY_IDX(raw_array, index, 
Array::value_type));
-  //       ++index;
-  //       return true;
-  //     });
+  const auto raw_array = a.get_array();
+  array::size_type index = 0;
+  for (auto& value : a)
+    {
+      BOOST_TEST(value == APR_ARRAY_IDX(raw_array, index, array::value_type));
+      ++index;
+    }
 }
 
 BOOST_AUTO_TEST_CASE(const_iteration)
 {
-  typedef APR::Array<const char*> Array;
+  typedef apr::array<const char*> array;
 
   apr::pool pool;
-  Array array(fill_array(pool));
-
-  struct Iteration : public Array::ConstIteration
-  {
-    Iteration(const  apr_array_header_t* raw_array)
-      : m_index(0), m_raw_array(raw_array)
-      {}
-
-    bool operator()(const Array::value_type& value)
-      {
-        BOOST_TEST(value == APR_ARRAY_IDX(m_raw_array, m_index,
-                                          Array::value_type));
-        ++m_index;
-        return true;
-      }
-
-  private:
-    Array::size_type m_index;
-    const apr_array_header_t* m_raw_array;
-  } callback(array.array());
+  const array a(fill_array(pool));
 
-  array.iterate(callback);
+  const auto raw_array = a.get_array();
+  array::size_type index = 0;
+  for (const auto& value : a)
+    {
+      BOOST_TEST(value == APR_ARRAY_IDX(raw_array, index, array::value_type));
+      ++index;
+    }
 }
 
 BOOST_AUTO_TEST_CASE(push)
 {
-  typedef APR::Array<const char*> Array;
+  typedef apr::array<const char*> array;
 
   apr::pool pool;
-  Array array(fill_array(pool));
+  array a(fill_array(pool));
 
-  const Array::size_type point = array.size();
-  const Array::value_type first = array[0];
-  const Array::value_type last = array[point - 1];
+  const array::size_type point = a.size();
+  const array::value_type first = a[0];
+  const array::value_type last = a[point - 1];
 
-  array.push("octavius");
-  array.push("nonus");
-  array.push("decimus");
+  a.push("octavius");
+  a.push("nonus");
+  a.push("decimus");
 
-  BOOST_TEST(array.size() == point + 3);
-  BOOST_TEST(array[0] == first);
-  BOOST_TEST(array[point - 1] == last);
-  BOOST_TEST(array[point] == "octavius");
-  BOOST_TEST(array[array.size() - 1] == "decimus");
+  BOOST_TEST(a.size() == point + 3);
+  BOOST_TEST(a[0] == first);
+  BOOST_TEST(a[point - 1] == last);
+  BOOST_TEST(a[point] == "octavius");
+  BOOST_TEST(a[a.size() - 1] == "decimus");
 }
 
 BOOST_AUTO_TEST_CASE(pop)
 {
-  typedef APR::Array<const char*> Array;
+  typedef apr::array<const char*> array;
 
   apr::pool pool;
-  Array array(fill_array(pool));
+  array a(fill_array(pool));
 
-  for (Array::size_type i = 0, z = array.size(); i <= z; ++i)
+  for (array::size_type i = 0, z = a.size(); i <= z; ++i)
     {
-      const char** last = (!array.array()->nelts ? nullptr
-                           : &APR_ARRAY_IDX(array.array(),
-                                            array.array()->nelts - 1,
-                                            Array::value_type));
-      BOOST_TEST(array.pop() == last);
+      const char** last = (!a.get_array()->nelts ? nullptr
+                           : &APR_ARRAY_IDX(a.get_array(),
+                                            a.get_array()->nelts - 1,
+                                            array::value_type));
+      BOOST_TEST(a.pop() == last);
     }
 }
 


Reply via email to