You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
361 lines
11 KiB
361 lines
11 KiB
/* |
|
* 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. |
|
*/ |
|
|
|
#include <thrust/detail/config.h> |
|
#include <thrust/detail/reference.h> |
|
#include <thrust/detail/type_traits.h> |
|
#include <thrust/iterator/iterator_traits.h> |
|
#include <thrust/system/detail/generic/select_system.h> |
|
#include <thrust/system/detail/generic/memory.h> |
|
#include <thrust/system/detail/adl/get_value.h> |
|
#include <thrust/system/detail/adl/assign_value.h> |
|
#include <thrust/system/detail/adl/iter_swap.h> |
|
|
|
|
|
namespace thrust |
|
{ |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
template<typename OtherElement, typename OtherPointer, typename OtherDerived> |
|
reference<Element,Pointer,Derived> |
|
::reference(const reference<OtherElement,OtherPointer,OtherDerived> &other, |
|
typename thrust::detail::enable_if_convertible< |
|
typename reference<OtherElement,OtherPointer,OtherDerived>::pointer, |
|
pointer |
|
>::type *) |
|
: m_ptr(other.m_ptr) |
|
{} |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
reference<Element,Pointer,Derived> |
|
::reference(const pointer &ptr) |
|
: m_ptr(ptr) |
|
{} |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::pointer |
|
reference<Element,Pointer,Derived> |
|
::operator&() const |
|
{ |
|
return m_ptr; |
|
} // end reference::operator&() |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator=(const value_type &v) |
|
{ |
|
assign_from(&v); |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator=() |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator=(const reference &other) |
|
{ |
|
assign_from(&other); |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator=() |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
template<typename OtherElement, typename OtherPointer, typename OtherDerived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator=(const reference<OtherElement,OtherPointer,OtherDerived> &other) |
|
{ |
|
assign_from(&other); |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator=() |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
template<typename System> |
|
typename reference<Element,Pointer,Derived>::value_type |
|
reference<Element,Pointer,Derived> |
|
::convert_to_value_type(System *system) const |
|
{ |
|
using thrust::system::detail::generic::select_system; |
|
return strip_const_get_value(select_system(*system)); |
|
} // end convert_to_value_type() |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
reference<Element,Pointer,Derived> |
|
::operator typename reference<Element,Pointer,Derived>::value_type () const |
|
{ |
|
typedef typename thrust::iterator_system<pointer>::type System; |
|
|
|
// XXX avoid default-constructing a system |
|
// XXX use null a reference for dispatching |
|
// XXX this assumes that the eventual invocation of |
|
// XXX get_value will not access system state |
|
System *system = 0; |
|
|
|
return convert_to_value_type(system); |
|
} // end reference::operator value_type () |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
template<typename System> |
|
typename reference<Element,Pointer,Derived>::value_type |
|
reference<Element,Pointer,Derived> |
|
::strip_const_get_value(const System &system) const |
|
{ |
|
System &non_const_system = const_cast<System&>(system); |
|
|
|
using thrust::system::detail::generic::get_value; |
|
|
|
return get_value(thrust::detail::derived_cast(non_const_system), m_ptr); |
|
} // end reference::strip_const_get_value() |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
template<typename System1, typename System2, typename OtherPointer> |
|
void reference<Element,Pointer,Derived> |
|
::assign_from(System1 *system1, System2 *system2, OtherPointer src) |
|
{ |
|
using thrust::system::detail::generic::select_system; |
|
|
|
strip_const_assign_value(select_system(*system1, *system2), src); |
|
} // end assign_from() |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
template<typename OtherPointer> |
|
void reference<Element,Pointer,Derived> |
|
::assign_from(OtherPointer src) |
|
{ |
|
typedef typename thrust::iterator_system<pointer>::type System1; |
|
typedef typename thrust::iterator_system<OtherPointer>::type System2; |
|
|
|
// XXX avoid default-constructing a system |
|
// XXX use null references for dispatching |
|
// XXX this assumes that the eventual invocation of |
|
// XXX assign_value will not access system state |
|
System1 *system1 = 0; |
|
System2 *system2 = 0; |
|
|
|
assign_from(system1, system2, src); |
|
} // end assign_from() |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
template<typename System, typename OtherPointer> |
|
void reference<Element,Pointer,Derived> |
|
::strip_const_assign_value(const System &system, OtherPointer src) |
|
{ |
|
System &non_const_system = const_cast<System&>(system); |
|
|
|
using thrust::system::detail::generic::assign_value; |
|
|
|
assign_value(thrust::detail::derived_cast(non_const_system), m_ptr, src); |
|
} // end strip_const_assign_value() |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
template<typename System> |
|
void reference<Element,Pointer,Derived> |
|
::swap(System *system, derived_type &other) |
|
{ |
|
using thrust::system::detail::generic::select_system; |
|
using thrust::system::detail::generic::iter_swap; |
|
|
|
iter_swap(select_system(*system, *system), m_ptr, other.m_ptr); |
|
} // end reference::swap() |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
void reference<Element,Pointer,Derived> |
|
::swap(derived_type &other) |
|
{ |
|
typedef typename thrust::iterator_system<pointer>::type System; |
|
|
|
// XXX avoid default-constructing a system |
|
// XXX use null references for dispatching |
|
// XXX this assumes that the eventual invocation |
|
// XXX of iter_swap will not access system state |
|
System *system = 0; |
|
|
|
swap(system, other); |
|
} // end reference::swap() |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator++(void) |
|
{ |
|
value_type temp = *this; |
|
++temp; |
|
*this = temp; |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator++() |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::value_type |
|
reference<Element,Pointer,Derived> |
|
::operator++(int) |
|
{ |
|
value_type temp = *this; |
|
value_type result = temp++; |
|
*this = temp; |
|
return result; |
|
} // end reference::operator++() |
|
|
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator+=(const value_type &rhs) |
|
{ |
|
value_type temp = *this; |
|
temp += rhs; |
|
*this = temp; |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator+=() |
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator--(void) |
|
{ |
|
value_type temp = *this; |
|
--temp; |
|
*this = temp; |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator--() |
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::value_type |
|
reference<Element,Pointer,Derived> |
|
::operator--(int) |
|
{ |
|
value_type temp = *this; |
|
value_type result = temp--; |
|
*this = temp; |
|
return result; |
|
} // end reference::operator--() |
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator-=(const value_type &rhs) |
|
{ |
|
value_type temp = *this; |
|
temp -= rhs; |
|
*this = temp; |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator-=() |
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator*=(const value_type &rhs) |
|
{ |
|
value_type temp = *this; |
|
temp *= rhs; |
|
*this = temp; |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator*=() |
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator/=(const value_type &rhs) |
|
{ |
|
value_type temp = *this; |
|
temp /= rhs; |
|
*this = temp; |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator/=() |
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator%=(const value_type &rhs) |
|
{ |
|
value_type temp = *this; |
|
temp %= rhs; |
|
*this = temp; |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator%=() |
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator<<=(const value_type &rhs) |
|
{ |
|
value_type temp = *this; |
|
temp <<= rhs; |
|
*this = temp; |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator<<=() |
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator>>=(const value_type &rhs) |
|
{ |
|
value_type temp = *this; |
|
temp >>= rhs; |
|
*this = temp; |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator>>=() |
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator&=(const value_type &rhs) |
|
{ |
|
value_type temp = *this; |
|
temp &= rhs; |
|
*this = temp; |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator&=() |
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator|=(const value_type &rhs) |
|
{ |
|
value_type temp = *this; |
|
temp |= rhs; |
|
*this = temp; |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator|=() |
|
|
|
template<typename Element, typename Pointer, typename Derived> |
|
typename reference<Element,Pointer,Derived>::derived_type & |
|
reference<Element,Pointer,Derived> |
|
::operator^=(const value_type &rhs) |
|
{ |
|
value_type temp = *this; |
|
temp ^= rhs; |
|
*this = temp; |
|
return static_cast<derived_type&>(*this); |
|
} // end reference::operator^=() |
|
|
|
|
|
} // end thrust |
|
|
|
|