/* * Copyright 2008-2013 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 #if defined(_CCCL_IMPLICIT_SYSTEM_HEADER_GCC) # pragma GCC system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_CLANG) # pragma clang system_header #elif defined(_CCCL_IMPLICIT_SYSTEM_HEADER_MSVC) # pragma system_header #endif // no system header #include #include #include #include THRUST_NAMESPACE_BEGIN namespace detail { template class join_iterator; namespace join_iterator_detail { template struct join_iterator_base { typedef ::cuda::std::__libcpp_remove_reference_t value_type; typedef typename thrust::iterator_system::type system1; typedef typename thrust::iterator_system::type system2; typedef typename thrust::detail::minimum_system::type system; typedef thrust::iterator_adaptor, thrust::counting_iterator, value_type, system, thrust::random_access_traversal_tag, Reference, Difference> type; }; // end join_iterator_base } // namespace join_iterator_detail template ::type, typename Reference = typename thrust::iterator_value::type> class join_iterator : public join_iterator_detail:: join_iterator_base::type { private: typedef typename join_iterator_detail:: join_iterator_base::type super_t; typedef typename super_t::difference_type size_type; public: inline _CCCL_HOST_DEVICE join_iterator(RandomAccessIterator1 first1, size_type n, RandomAccessIterator2 first2) : super_t(thrust::counting_iterator(0)) , m_n1(n) , m_iter1(first1) , m_iter2(first2 - m_n1) {} inline _CCCL_HOST_DEVICE join_iterator(const join_iterator& other) : super_t(other) , m_n1(other.m_n1) , m_iter1(other.m_iter1) , m_iter2(other.m_iter2) {} private: friend class thrust::iterator_core_access; // MSVC 2013 and 2015 incorrectly warning about returning a reference to // a local/temporary here. // See goo.gl/LELTNp THRUST_DISABLE_MSVC_WARNING_BEGIN(4172) _CCCL_HOST_DEVICE typename super_t::reference dereference() const { size_type i = *super_t::base(); return (i < m_n1) ? m_iter1[i] : static_cast(m_iter2[i]); } // end dereference() THRUST_DISABLE_MSVC_WARNING_END(4172) size_type m_n1; RandomAccessIterator1 m_iter1; RandomAccessIterator2 m_iter2; }; // end join_iterator template _CCCL_HOST_DEVICE join_iterator make_join_iterator(RandomAccessIterator1 first1, Size n1, RandomAccessIterator2 first2) { return join_iterator(first1, n1, first2); } // end make_join_iterator() } // namespace detail THRUST_NAMESPACE_END