/* * Copyright 2008-2012 NVIDIA Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #include #include #include #include #include #include #include #include // for use of std::swap in the WAR below namespace thrust { namespace detail { template contiguous_storage ::contiguous_storage(const Alloc &alloc) :m_allocator(alloc), m_begin(pointer(static_cast(0))), m_size(0) { ; } // end contiguous_storage::contiguous_storage() template contiguous_storage ::contiguous_storage(size_type n, const Alloc &alloc) :m_allocator(alloc), m_begin(pointer(static_cast(0))), m_size(0) { allocate(n); } // end contiguous_storage::contiguous_storage() template contiguous_storage ::~contiguous_storage(void) { deallocate(); } // end contiguous_storage::~contiguous_storage() template typename contiguous_storage::size_type contiguous_storage ::size(void) const { return m_size; } // end contiguous_storage::size() template typename contiguous_storage::size_type contiguous_storage ::max_size(void) const { return alloc_traits::max_size(m_allocator); } // end contiguous_storage::max_size() template typename contiguous_storage::iterator contiguous_storage ::begin(void) { return m_begin; } // end contiguous_storage::begin() template typename contiguous_storage::const_iterator contiguous_storage ::begin(void) const { return m_begin; } // end contiguous_storage::begin() template typename contiguous_storage::iterator contiguous_storage ::end(void) { return m_begin + size(); } // end contiguous_storage::end() template typename contiguous_storage::const_iterator contiguous_storage ::end(void) const { return m_begin + size(); } // end contiguous_storage::end() template typename contiguous_storage::reference contiguous_storage ::operator[](size_type n) { return m_begin[n]; } // end contiguous_storage::operator[]() template typename contiguous_storage::const_reference contiguous_storage ::operator[](size_type n) const { return m_begin[n]; } // end contiguous_storage::operator[]() template typename contiguous_storage::allocator_type contiguous_storage ::get_allocator(void) const { return m_allocator; } // end contiguous_storage::get_allocator() template void contiguous_storage ::allocate(size_type n) { if(n > 0) { m_begin = iterator(m_allocator.allocate(n)); m_size = n; } // end if else { m_begin = iterator(pointer(static_cast(0))); m_size = 0; } // end else } // end contiguous_storage::allocate() template void contiguous_storage ::deallocate(void) { if(size() > 0) { m_allocator.deallocate(m_begin.base(), size()); m_begin = iterator(pointer(static_cast(0))); m_size = 0; } // end if } // end contiguous_storage::deallocate() template void contiguous_storage ::swap(contiguous_storage &x) { thrust::swap(m_begin, x.m_begin); thrust::swap(m_size, x.m_size); // XXX WAR nvcc 4.0's "calling a __host__ function from a __host__ __device__ function is not allowed" warning //thrust::swap(m_allocator, x.m_allocator); std::swap(m_allocator, x.m_allocator); } // end contiguous_storage::swap() template void contiguous_storage ::default_construct_n(iterator first, size_type n) { default_construct_range(m_allocator, first.base(), n); } // end contiguous_storage::default_construct_n() template void contiguous_storage ::uninitialized_fill_n(iterator first, size_type n, const value_type &x) { fill_construct_range(m_allocator, first.base(), n, x); } // end contiguous_storage::uninitialized_fill() template template typename contiguous_storage::iterator contiguous_storage ::uninitialized_copy(thrust::execution_policy &from_system, InputIterator first, InputIterator last, iterator result) { return iterator(copy_construct_range(from_system, m_allocator, first, last, result.base())); } // end contiguous_storage::uninitialized_copy() template template typename contiguous_storage::iterator contiguous_storage ::uninitialized_copy(InputIterator first, InputIterator last, iterator result) { // XXX assumes InputIterator's associated System is default-constructible typename thrust::iterator_system::type from_system; return iterator(copy_construct_range(from_system, m_allocator, first, last, result.base())); } // end contiguous_storage::uninitialized_copy() template template typename contiguous_storage::iterator contiguous_storage ::uninitialized_copy_n(thrust::execution_policy &from_system, InputIterator first, Size n, iterator result) { return iterator(copy_construct_range_n(from_system, m_allocator, first, n, result.base())); } // end contiguous_storage::uninitialized_copy_n() template template typename contiguous_storage::iterator contiguous_storage ::uninitialized_copy_n(InputIterator first, Size n, iterator result) { // XXX assumes InputIterator's associated System is default-constructible typename thrust::iterator_system::type from_system; return iterator(copy_construct_range_n(from_system, m_allocator, first, n, result.base())); } // end contiguous_storage::uninitialized_copy_n() template void contiguous_storage ::destroy(iterator first, iterator last) { destroy_range(m_allocator, first.base(), last - first); } // end contiguous_storage::destroy() } // end detail template void swap(detail::contiguous_storage &lhs, detail::contiguous_storage &rhs) { lhs.swap(rhs); } // end swap() } // end thrust