152 lines
3.5 KiB
C++
152 lines
3.5 KiB
C++
// 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();
|
|
}
|