Skip to content

Commit

Permalink
Merge pull request NVIDIA#216 from jaredhoberock/safe-temporary_array
Browse files Browse the repository at this point in the history
Safe temporary array
  • Loading branch information
jaredhoberock committed Aug 14, 2012
2 parents 3003d2e + 7d8fc77 commit 3d3b54a
Show file tree
Hide file tree
Showing 12 changed files with 577 additions and 149 deletions.
54 changes: 53 additions & 1 deletion testing/allocator.cu
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ DECLARE_UNITTEST(TestAllocatorCustomCopyConstruct);
static int g_state;

struct my_allocator_with_custom_destroy
: std::allocator<int>
{
typedef int value_type;
typedef int & reference;
typedef const int & const_reference;

template<typename T>
__host__ __device__
void destroy(T *p)
Expand All @@ -66,6 +69,21 @@ struct my_allocator_with_custom_destroy
g_state = 13;
#endif
}

value_type *allocate(std::ptrdiff_t n)
{
return use_me_to_alloc.allocate(n);
}

void deallocate(value_type *ptr, std::ptrdiff_t n)
{
use_me_to_alloc.deallocate(ptr,n);
}

// use composition rather than inheritance
// to avoid inheriting std::allocator's member
// function construct
std::allocator<int> use_me_to_alloc;
};

void TestAllocatorCustomDestroy()
Expand All @@ -79,3 +97,37 @@ void TestAllocatorCustomDestroy()
}
DECLARE_UNITTEST(TestAllocatorCustomDestroy);

struct my_minimal_allocator
{
typedef int value_type;

// XXX ideally, we shouldn't require
// these two typedefs
typedef int & reference;
typedef const int & const_reference;

value_type *allocate(std::ptrdiff_t n)
{
return use_me_to_alloc.allocate(n);
}

void deallocate(value_type *ptr, std::ptrdiff_t n)
{
use_me_to_alloc.deallocate(ptr,n);
}

std::allocator<int> use_me_to_alloc;
};

void TestAllocatorMinimal()
{
thrust::cpp::vector<int, my_minimal_allocator> vec(10, 13);

// XXX copy to h_vec because ASSERT_EQUAL doesn't know about cpp::vector
thrust::host_vector<int> h_vec(vec.begin(), vec.end());
thrust::host_vector<int> ref(10, 13);

ASSERT_EQUAL(ref, h_vec);
}
DECLARE_UNITTEST(TestAllocatorMinimal);

14 changes: 14 additions & 0 deletions thrust/detail/allocator/allocator_traits.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ namespace allocator_traits_detail

__THRUST_DEFINE_HAS_NESTED_TYPE(has_pointer, pointer);
__THRUST_DEFINE_HAS_NESTED_TYPE(has_const_pointer, const_pointer);
__THRUST_DEFINE_HAS_NESTED_TYPE(has_reference, reference);
__THRUST_DEFINE_HAS_NESTED_TYPE(has_const_reference, const_reference);
__THRUST_DEFINE_HAS_NESTED_TYPE(has_void_pointer, void_pointer);
__THRUST_DEFINE_HAS_NESTED_TYPE(has_const_void_pointer, const_void_pointer);
__THRUST_DEFINE_HAS_NESTED_TYPE(has_difference_type, difference_type);
Expand All @@ -51,6 +53,18 @@ template<typename T>
typedef typename T::const_pointer type;
};

template<typename T>
struct nested_reference
{
typedef typename T::reference type;
};

template<typename T>
struct nested_const_reference
{
typedef typename T::const_reference type;
};

template<typename T>
struct nested_void_pointer
{
Expand Down
84 changes: 39 additions & 45 deletions thrust/detail/allocator/allocator_traits.inl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <thrust/detail/config.h>
#include <thrust/detail/allocator/allocator_traits.h>
#include <thrust/detail/type_traits/has_member_function.h>
#include <thrust/detail/type_traits/is_call_possible.h>
#include <new>
#include <limits>

Expand All @@ -27,17 +28,19 @@ namespace detail
namespace allocator_traits_detail
{

__THRUST_DEFINE_HAS_MEMBER_FUNCTION2(has_member_allocate_with_hint_impl, allocate);
__THRUST_DEFINE_IS_CALL_POSSIBLE(has_member_allocate_with_hint_impl, allocate)

template<typename Alloc>
struct has_member_allocate_with_hint
: has_member_allocate_with_hint_impl<
Alloc,
typename allocator_traits<Alloc>::pointer,
typename allocator_traits<Alloc>::size_type,
typename allocator_traits<Alloc>::const_void_pointer
>
{};
class has_member_allocate_with_hint
{
typedef typename allocator_traits<Alloc>::pointer pointer;
typedef typename allocator_traits<Alloc>::size_type size_type;
typedef typename allocator_traits<Alloc>::const_void_pointer const_void_pointer;

public:
typedef typename has_member_allocate_with_hint_impl<Alloc, pointer(size_type,const_void_pointer)>::type type;
static const bool value = type::value;
};

template<typename Alloc>
typename enable_if<
Expand All @@ -60,15 +63,11 @@ template<typename Alloc>
}


__THRUST_DEFINE_HAS_MEMBER_FUNCTION1(has_member_construct1_impl, construct);
__THRUST_DEFINE_IS_CALL_POSSIBLE(has_member_construct1_impl, construct)

template<typename Alloc, typename T>
struct has_member_construct1
: has_member_construct1_impl<
Alloc,
void,
T*
>
: has_member_construct1_impl<Alloc, void(T*)>
{};

template<typename Alloc, typename T>
Expand All @@ -92,16 +91,11 @@ template<typename Alloc, typename T>
}


__THRUST_DEFINE_HAS_MEMBER_FUNCTION2(has_member_construct2_impl, construct);
__THRUST_DEFINE_IS_CALL_POSSIBLE(has_member_construct2_impl, construct)

template<typename Alloc, typename T, typename Arg1>
struct has_member_construct2
: has_member_construct2_impl<
Alloc,
void,
T*,
const Arg1 &
>
: has_member_construct2_impl<Alloc, void(T*,const Arg1 &)>
{};

template<typename Alloc, typename T, typename Arg1>
Expand All @@ -125,21 +119,17 @@ template<typename Alloc, typename T, typename Arg1>
}


__THRUST_DEFINE_HAS_MEMBER_FUNCTION1(has_member_destroy1_impl, destroy);
__THRUST_DEFINE_IS_CALL_POSSIBLE(has_member_destroy_impl, destroy)

template<typename Alloc, typename T>
struct has_member_destroy1
: has_member_destroy1_impl<
Alloc,
void,
T*
>
struct has_member_destroy
: has_member_destroy_impl<Alloc, void(T*)>
{};

template<typename Alloc, typename T>
inline __host__ __device__
typename enable_if<
has_member_destroy1<Alloc,T>::value
has_member_destroy<Alloc,T>::value
>::type
destroy(Alloc &a, T *p)
{
Expand All @@ -149,23 +139,25 @@ template<typename Alloc, typename T>
template<typename Alloc, typename T>
inline __host__ __device__
typename disable_if<
has_member_destroy1<Alloc,T>::value
has_member_destroy<Alloc,T>::value
>::type
destroy(Alloc &, T *p)
{
p->~T();
}


__THRUST_DEFINE_HAS_MEMBER_FUNCTION0(has_member_max_size0_impl, max_size);
__THRUST_DEFINE_IS_CALL_POSSIBLE(has_member_max_size_impl, max_size);

template<typename Alloc>
struct has_member_max_size
: has_member_max_size0_impl<
Alloc,
typename allocator_traits<Alloc>::size_type
>
{};
class has_member_max_size
{
typedef typename allocator_traits<Alloc>::size_type size_type;

public:
typedef typename has_member_max_size_impl<Alloc, size_type(void)>::type type;
static const bool value = type::value;
};

template<typename Alloc>
typename enable_if<
Expand All @@ -188,15 +180,17 @@ template<typename Alloc>
return std::numeric_limits<size_type>::max();
}

__THRUST_DEFINE_HAS_MEMBER_FUNCTION0(has_member_system0_impl, system);
__THRUST_DEFINE_HAS_MEMBER_FUNCTION(has_member_system_impl, system);

template<typename Alloc>
struct has_member_system
: has_member_system0_impl<
Alloc,
typename allocator_system<Alloc>::type &
>
{};
class has_member_system
{
typedef typename allocator_system<Alloc>::type system_type;

public:
typedef typename has_member_system_impl<Alloc, system_type&(void)>::type type;
static const bool value = type::value;
};

template<typename Alloc>
typename enable_if<
Expand Down
7 changes: 7 additions & 0 deletions thrust/detail/allocator/copy_construct_range.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ template<typename System, typename Allocator, typename InputIterator, typename P
InputIterator last,
Pointer result);

template<typename System, typename Allocator, typename InputIterator, typename Size, typename Pointer>
Pointer copy_construct_range_n(thrust::dispatchable<System> &from_system,
Allocator &a,
InputIterator first,
Size n,
Pointer result);

} // end detail
} // end thrust

Expand Down
Loading

0 comments on commit 3d3b54a

Please sign in to comment.