diff --git a/include/boost/compute/container/vector.hpp b/include/boost/compute/container/vector.hpp index 9110501e..47d649ad 100644 --- a/include/boost/compute/container/vector.hpp +++ b/include/boost/compute/container/vector.hpp @@ -188,14 +188,29 @@ public: } /// Creates a new vector and copies the values from \p other. - vector(const vector &other) + vector(const vector &other, + command_queue &queue = system::default_queue()) : m_size(other.m_size), m_allocator(other.m_allocator) { m_data = m_allocator.allocate((std::max)(m_size, _minimum_capacity())); if(!other.empty()){ - command_queue queue = default_queue(); + ::boost::compute::copy(other.begin(), other.end(), begin(), queue); + queue.finish(); + } + } + + /// Creates a new vector and copies the values from \p other. + template + vector(const vector &other, + command_queue &queue = system::default_queue()) + : m_size(other.size()), + m_allocator(queue.get_context()) + { + m_data = m_allocator.allocate((std::max)(m_size, _minimum_capacity())); + + if(!other.empty()){ ::boost::compute::copy(other.begin(), other.end(), begin(), queue); queue.finish(); } @@ -225,7 +240,7 @@ public: } #endif // BOOST_COMPUTE_NO_HDR_INITIALIZER_LIST - vector& operator=(const vector &other) + vector& operator=(const vector &other) { if(this != &other){ command_queue queue = default_queue(); @@ -238,7 +253,7 @@ public: } template - vector& operator=(const std::vector &vector) + vector& operator=(const std::vector &vector) { command_queue queue = default_queue(); resize(vector.size(), queue); @@ -249,7 +264,7 @@ public: #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES /// Move-constructs a new vector from \p other. - vector(vector&& other) + vector(vector&& other) : m_data(std::move(other.m_data)), m_size(other.m_size), m_allocator(std::move(other.m_allocator)) @@ -258,7 +273,7 @@ public: } /// Move-assigns the data from \p other to \c *this. - vector& operator=(vector&& other) + vector& operator=(vector&& other) { if(m_size){ m_allocator.deallocate(m_data, m_size); @@ -549,7 +564,7 @@ public: ::boost::compute::copy_n(&value, 1, position, queue); } else { - ::boost::compute::vector tmp(position, end(), queue); + ::boost::compute::vector tmp(position, end(), queue); resize(m_size + 1, queue); position = begin() + position.get_index(); ::boost::compute::copy_n(&value, 1, position, queue); @@ -572,7 +587,7 @@ public: const T &value, command_queue &queue) { - ::boost::compute::vector tmp(position, end(), queue); + ::boost::compute::vector tmp(position, end(), queue); resize(size() + count, queue); position = begin() + position.get_index(); @@ -601,7 +616,7 @@ public: InputIterator last, command_queue &queue) { - ::boost::compute::vector tmp(position, end(), queue); + ::boost::compute::vector tmp(position, end(), queue); size_type count = detail::iterator_range_size(first, last); resize(size() + count, queue); @@ -642,7 +657,7 @@ public: iterator erase(iterator first, iterator last, command_queue &queue) { if(last != end()){ - ::boost::compute::vector tmp(last, end(), queue); + ::boost::compute::vector tmp(last, end(), queue); ::boost::compute::copy(tmp.begin(), tmp.end(), first, queue); } @@ -661,7 +676,7 @@ public: } /// Swaps the contents of \c *this with \p other. - void swap(vector &other) + void swap(vector &other) { std::swap(m_data, other.m_data); std::swap(m_size, other.m_size); diff --git a/test/test_vector.cpp b/test/test_vector.cpp index 2f9bd009..4cbe5e23 100644 --- a/test/test_vector.cpp +++ b/test/test_vector.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "check_macros.hpp" @@ -184,11 +185,27 @@ BOOST_AUTO_TEST_CASE(max_size) BOOST_AUTO_TEST_CASE(move_ctor) { int data[] = { 11, 12, 13, 14 }; - bc::vector a(data, data + 4); + bc::vector a(data, data + 4, queue); BOOST_CHECK_EQUAL(a.size(), size_t(4)); CHECK_RANGE_EQUAL(int, 4, a, (11, 12, 13, 14)); bc::vector b(std::move(a)); + BOOST_CHECK(a.size() == 0); + BOOST_CHECK(a.get_buffer().get() == 0); + BOOST_CHECK_EQUAL(b.size(), size_t(4)); + CHECK_RANGE_EQUAL(int, 4, b, (11, 12, 13, 14)); +} + +BOOST_AUTO_TEST_CASE(move_ctor_custom_alloc) +{ + int data[] = { 11, 12, 13, 14 }; + bc::vector > a(data, data + 4, queue); + BOOST_CHECK_EQUAL(a.size(), size_t(4)); + CHECK_RANGE_EQUAL(int, 4, a, (11, 12, 13, 14)); + + bc::vector > b(std::move(a)); + BOOST_CHECK(a.size() == 0); + BOOST_CHECK(a.get_buffer().get() == 0); BOOST_CHECK_EQUAL(b.size(), size_t(4)); CHECK_RANGE_EQUAL(int, 4, b, (11, 12, 13, 14)); } @@ -330,4 +347,92 @@ BOOST_AUTO_TEST_CASE(resize_throw_exception) CHECK_RANGE_EQUAL(int, 8, vec, (1, 2, 3, 4, 5, 6, 7, 8)); } +BOOST_AUTO_TEST_CASE(copy_ctor_custom_alloc) +{ + int data[] = { 11, 12, 13, 14 }; + bc::vector > a(data, data + 4, queue); + BOOST_CHECK_EQUAL(a.size(), size_t(4)); + CHECK_RANGE_EQUAL(int, 4, a, (11, 12, 13, 14)); + + bc::vector > b(a, queue); + BOOST_CHECK_EQUAL(b.size(), size_t(4)); + CHECK_RANGE_EQUAL(int, 4, b, (11, 12, 13, 14)); +} + +BOOST_AUTO_TEST_CASE(copy_ctor_different_alloc) +{ + int data[] = { 11, 12, 13, 14 }; + bc::vector a(data, data + 4, queue); + BOOST_CHECK_EQUAL(a.size(), size_t(4)); + CHECK_RANGE_EQUAL(int, 4, a, (11, 12, 13, 14)); + + bc::vector > b(a, queue); + BOOST_CHECK_EQUAL(b.size(), size_t(4)); + CHECK_RANGE_EQUAL(int, 4, b, (11, 12, 13, 14)); + + std::vector host_vector; + host_vector.push_back(1); + host_vector.push_back(9); + host_vector.push_back(7); + host_vector.push_back(9); + + bc::vector > c(host_vector, queue); + BOOST_CHECK_EQUAL(c.size(), size_t(4)); + CHECK_RANGE_EQUAL(int, 4, c, (1, 9, 7, 9)); +} + +BOOST_AUTO_TEST_CASE(assignment_operator) +{ + int adata[] = { 11, 12, 13, 14 }; + bc::vector a(adata, adata + 4, queue); + BOOST_CHECK_EQUAL(a.size(), size_t(4)); + CHECK_RANGE_EQUAL(int, 4, a, (11, 12, 13, 14)); + + bc::vector b = a; + BOOST_CHECK_EQUAL(b.size(), size_t(4)); + CHECK_RANGE_EQUAL(int, 4, b, (11, 12, 13, 14)); + + bc::vector > c = b; + BOOST_CHECK_EQUAL(c.size(), size_t(4)); + CHECK_RANGE_EQUAL(int, 4, c, (11, 12, 13, 14)); + + int ddata[] = { 21, 22, 23 }; + bc::vector > d(ddata, ddata + 3, queue); + BOOST_CHECK_EQUAL(d.size(), size_t(3)); + CHECK_RANGE_EQUAL(int, 3, d, (21, 22, 23)); + + a = d; + BOOST_CHECK_EQUAL(a.size(), size_t(3)); + CHECK_RANGE_EQUAL(int, 3, a, (21, 22, 23)); + + std::vector host_vector; + host_vector.push_back(1); + host_vector.push_back(9); + host_vector.push_back(7); + host_vector.push_back(9); + + d = host_vector; + BOOST_CHECK_EQUAL(d.size(), size_t(4)); + CHECK_RANGE_EQUAL(int, 4, d, (1, 9, 7, 9)); +} + +BOOST_AUTO_TEST_CASE(swap_ctor_custom_alloc) +{ + int adata[] = { 11, 12, 13, 14 }; + bc::vector > a(adata, adata + 4, queue); + BOOST_CHECK_EQUAL(a.size(), size_t(4)); + CHECK_RANGE_EQUAL(int, 4, a, (11, 12, 13, 14)); + + int bdata[] = { 21, 22, 23 }; + bc::vector > b(bdata, bdata + 3, queue); + BOOST_CHECK_EQUAL(b.size(), size_t(3)); + CHECK_RANGE_EQUAL(int, 3, b, (21, 22, 23)); + + a.swap(b); + BOOST_CHECK_EQUAL(a.size(), size_t(3)); + CHECK_RANGE_EQUAL(int, 3, a, (21, 22, 23)); + BOOST_CHECK_EQUAL(b.size(), size_t(4)); + CHECK_RANGE_EQUAL(int, 4, b, (11, 12, 13, 14)); +} + BOOST_AUTO_TEST_SUITE_END()