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); } }