@@ -99,23 +99,52 @@ template <typename AllocatorT> class buffer_impl {
9999 }
100100 }
101101
102+ template <typename Iterator> struct is_const_iterator {
103+ using pointer = typename std::iterator_traits<Iterator>::pointer;
104+ static constexpr bool value =
105+ std::is_const<typename std::remove_pointer<pointer>::type>::value;
106+ };
107+
108+ template <typename Iterator>
109+ using EnableIfConstIterator =
110+ typename std::enable_if<is_const_iterator<Iterator>::value,
111+ Iterator>::type;
112+
113+ template <typename Iterator>
114+ using EnableIfNotConstIterator =
115+ typename std::enable_if<!is_const_iterator<Iterator>::value,
116+ Iterator>::type;
117+
102118 template <class InputIterator >
103- buffer_impl (InputIterator first, InputIterator last, const size_t sizeInBytes ,
104- const property_list &propList,
119+ buffer_impl (EnableIfNotConstIterator< InputIterator> first, InputIterator last,
120+ const size_t sizeInBytes, const property_list &propList,
105121 AllocatorT allocator = AllocatorT())
106122 : SizeInBytes(sizeInBytes), Props(propList), MAllocator(allocator) {
107- if (Props.has_property <property::buffer::use_host_ptr>()) {
108- // TODO next line looks unsafe
109- BufPtr = &*first;
110- } else {
111- BufData.resize (get_size ());
112- BufPtr = reinterpret_cast <void *>(BufData.data ());
113- // We need cast BufPtr to pointer to the iteration type to get correct
114- // offset in std::copy when it will increment destination pointer.
115- auto *Ptr = reinterpret_cast <
116- typename std::iterator_traits<InputIterator>::pointer>(BufPtr);
117- std::copy (first, last, Ptr);
118- }
123+ BufData.resize (get_size ());
124+ BufPtr = reinterpret_cast <void *>(BufData.data ());
125+ // We need cast BufPtr to pointer to the iteration type to get correct
126+ // offset in std::copy when it will increment destination pointer.
127+ auto *Ptr =
128+ reinterpret_cast <typename std::iterator_traits<InputIterator>::pointer>(
129+ BufPtr);
130+ std::copy (first, last, Ptr);
131+ // Data is written back if InputIterator is not a const iterator.
132+ set_final_data (first);
133+ }
134+
135+ template <class InputIterator >
136+ buffer_impl (EnableIfConstIterator<InputIterator> first, InputIterator last,
137+ const size_t sizeInBytes, const property_list &propList,
138+ AllocatorT allocator = AllocatorT())
139+ : SizeInBytes(sizeInBytes), Props(propList), MAllocator(allocator) {
140+ BufData.resize (get_size ());
141+ BufPtr = reinterpret_cast <void *>(BufData.data ());
142+ // We need cast BufPtr to pointer to the iteration type to get correct
143+ // offset in std::copy when it will increment destination pointer.
144+ typedef typename std::iterator_traits<InputIterator>::value_type value;
145+ auto *Ptr = reinterpret_cast <typename std::add_pointer<
146+ typename std::remove_const<value>::type>::type>(BufPtr);
147+ std::copy (first, last, Ptr);
119148 }
120149
121150 buffer_impl (cl_mem MemObject, const context &SyclContext,
0 commit comments