From 9642ba7103eef6fe9f01386ed769ffeecb3d2b8e Mon Sep 17 00:00:00 2001 From: Glen Fernandes <glen.fernandes@gmail.com> Date: Tue, 19 Feb 2019 00:54:36 -0500 Subject: [PATCH] Add test cases for allocators --- doc/test_cases.html | 7 ++ test/Jamfile.v2 | 1 + test/allocators.cpp | 151 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 159 insertions(+) create mode 100644 test/allocators.cpp diff --git a/doc/test_cases.html b/doc/test_cases.html index f0ad9d3..f0a1226 100644 --- a/doc/test_cases.html +++ b/doc/test_cases.html @@ -179,6 +179,13 @@ by library users. </td> </tr> +<tr> +<td><a href="../test/allocators.cpp">libs/multi_array/test/allocators.cpp</a></td> +<td> +Test support for custom allocators. +</td> +</tr> + <tr> <td><a href="../test/generative_tests.hpp">libs/multi_array/test/generative_tests.hpp</a></td> <td> diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 1c90413..ef1260e 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -46,5 +46,6 @@ run stl_interaction.cpp ; run resize.cpp ; run assert.cpp ; run reverse_view.cpp ; +run allocators.cpp ; compile concept_checks.cpp ; diff --git a/test/allocators.cpp b/test/allocators.cpp new file mode 100644 index 0000000..8bb099f --- /dev/null +++ b/test/allocators.cpp @@ -0,0 +1,151 @@ +// Copyright 2019 Glen Joseph Fernandes +// (glenjofe@gmail.com) +// +// Distributed under 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) + +#include <boost/core/lightweight_test.hpp> +#include <boost/multi_array.hpp> +#include <algorithm> + +template<class T> +class creator { +public: + typedef T value_type; + typedef T* pointer; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + + template<class U> + struct rebind { + typedef creator<U> other; + }; + + creator(int state) + : state_(state) { } + + template<class U> + creator(const creator<U>& other) + : state_(other.state()) { } + + T* allocate(std::size_t size) { + return static_cast<T*>(::operator new(sizeof(T) * size)); + } + + void deallocate(T* ptr, std::size_t) { + ::operator delete(ptr); + } + + int state() const { + return state_; + } + +private: + int state_; +}; + +template<class T, class U> +inline bool +operator==(const creator<T>& a, const creator<U>& b) +{ + return a.state() == b.state(); +} + +template<class T, class U> +inline bool +operator!=(const creator<T>& a, const creator<U>& b) +{ + return !(a == b); +} + +void test(const double&, std::size_t*, int*, unsigned) +{ +} + +template<class Array> +void test(const Array& array, std::size_t* sizes, int* strides, + unsigned elements) +{ + BOOST_TEST(array.num_elements() == elements); + BOOST_TEST(array.size() == *sizes); + BOOST_TEST(std::equal(sizes, sizes + array.num_dimensions(), array.shape())); + BOOST_TEST(std::equal(strides, strides + array.num_dimensions(), + array.strides())); + test(array[0], ++sizes, ++strides, elements / array.size()); +} + +bool test(const double& a, const double& b) +{ + return a == b; +} + +template<class A1, class A2> +bool test(const A1& a1, const A2& a2) +{ + typename A1::const_iterator i1 = a1.begin(); + typename A2::const_iterator i2 = a2.begin(); + for (; i1 != a1.end(); ++i1, ++i2) { + if (!test(*i1, *i2)) { + return false; + } + } + return true; +} + +int main() +{ + typedef boost::multi_array<double, 3, creator<double> > type; + creator<double> state(1); + { + type array(state); + } + boost::array<type::size_type, 3> sizes = { { 3, 3, 3 } }; + type::size_type elements = 27; + { + int strides[] = { 9, 3, 1 }; + type array(sizes, state); + test(array, &sizes[0], strides, elements); + } + { + int strides[] = { 1, 3, 9 }; + type array(sizes, boost::fortran_storage_order(), state); + test(array, &sizes[0], strides, elements); + } + { + int strides[] = { 9, 3, 1 }; + type::extent_gen extents; + type array(extents[3][3][3], state); + test(array, &sizes[0], strides, elements); + } + { + type array1(sizes, state); + std::vector<double> values(elements, 4.5); + array1.assign(values.begin(), values.end()); + type array2(array1); + int strides[] = { 9, 3, 1 }; + test(array2, &sizes[0], strides, elements); + BOOST_TEST(test(array1, array2)); + } + { + type array1(sizes, state); + type array2(sizes, state); + std::vector<double> values(elements, 4.5); + array1.assign(values.begin(), values.end()); + array2 = array1; + int strides[] = { 9, 3, 1 }; + test(array2, &sizes[0], strides, elements); + BOOST_TEST(test(array1, array2)); + } + { + type array1(sizes, state); + std::vector<double> values(elements, 4.5); + array1.assign(values.begin(), values.end()); + typedef type::subarray<2>::type other; + other array2 = array1[1]; + other::value_type value = array2[0]; + BOOST_TEST(test(array1[1][0], value)); + BOOST_TEST(test(array2[0], value)); + } + return boost::report_errors(); +}