1 //---------------------------------------------------------------------------// 2 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com> 3 // 4 // Distributed under the Boost Software License, Version 1.0 5 // See accompanying file LICENSE_1_0.txt or copy at 6 // http://www.boost.org/LICENSE_1_0.txt 7 // 8 // See http://boostorg.github.com/compute for more information. 9 //---------------------------------------------------------------------------// 10 11 #ifndef BOOST_COMPUTE_DETAIL_BUFFER_VALUE_HPP 12 #define BOOST_COMPUTE_DETAIL_BUFFER_VALUE_HPP 13 14 #include <boost/compute/context.hpp> 15 #include <boost/compute/command_queue.hpp> 16 #include <boost/compute/detail/device_ptr.hpp> 17 #include <boost/compute/detail/read_write_single_value.hpp> 18 19 namespace boost { 20 namespace compute { 21 namespace detail { 22 23 template<class T> 24 class buffer_value 25 { 26 public: 27 typedef T value_type; 28 buffer_value()29 buffer_value() 30 { 31 } 32 buffer_value(const value_type & value)33 buffer_value(const value_type &value) 34 : m_value(value) 35 { 36 } 37 38 // creates a reference for the value in buffer at index (in bytes). buffer_value(const buffer & buffer,size_t index)39 buffer_value(const buffer &buffer, size_t index) 40 : m_buffer(buffer.get(), false), 41 m_index(index) 42 { 43 } 44 buffer_value(const buffer_value<T> & other)45 buffer_value(const buffer_value<T> &other) 46 : m_buffer(other.m_buffer.get(), false), 47 m_index(other.m_index) 48 { 49 } 50 ~buffer_value()51 ~buffer_value() 52 { 53 // set buffer to null so that its reference count will 54 // not be decremented when its destructor is called 55 m_buffer.get() = 0; 56 } 57 operator value_type() const58 operator value_type() const 59 { 60 if(m_buffer.get()){ 61 const context &context = m_buffer.get_context(); 62 const device &device = context.get_device(); 63 command_queue queue(context, device); 64 65 return detail::read_single_value<T>(m_buffer, m_index / sizeof(T), queue); 66 } 67 else { 68 return m_value; 69 } 70 } 71 operator -() const72 buffer_value<T> operator-() const 73 { 74 return -T(*this); 75 } 76 operator <(const T & value) const77 bool operator<(const T &value) const 78 { 79 return T(*this) < value; 80 } 81 operator >(const T & value) const82 bool operator>(const T &value) const 83 { 84 return T(*this) > value; 85 } 86 operator <=(const T & value) const87 bool operator<=(const T &value) const 88 { 89 return T(*this) <= value; 90 } 91 operator >=(const T & value) const92 bool operator>=(const T &value) const 93 { 94 return T(*this) <= value; 95 } 96 operator ==(const T & value) const97 bool operator==(const T &value) const 98 { 99 return T(*this) == value; 100 } 101 operator ==(const buffer_value<T> & other) const102 bool operator==(const buffer_value<T> &other) const 103 { 104 if(m_buffer.get() != other.m_buffer.get()){ 105 return false; 106 } 107 108 if(m_buffer.get()){ 109 return m_index == other.m_index; 110 } 111 else { 112 return m_value == other.m_value; 113 } 114 } 115 operator !=(const T & value) const116 bool operator!=(const T &value) const 117 { 118 return T(*this) != value; 119 } 120 operator =(const T & value)121 buffer_value<T>& operator=(const T &value) 122 { 123 if(m_buffer.get()){ 124 const context &context = m_buffer.get_context(); 125 command_queue queue(context, context.get_device()); 126 127 detail::write_single_value<T>( 128 value, m_buffer, m_index / sizeof(T), queue 129 ).wait(); 130 131 return *this; 132 } 133 else { 134 m_value = value; 135 return *this; 136 } 137 } 138 operator =(const buffer_value<T> & value)139 buffer_value<T>& operator=(const buffer_value<T> &value) 140 { 141 return operator=(T(value)); 142 } 143 operator &() const144 detail::device_ptr<T> operator&() const 145 { 146 return detail::device_ptr<T>(m_buffer, m_index); 147 } 148 operator ++()149 buffer_value<T>& operator++() 150 { 151 if(m_buffer.get()){ 152 T value = T(*this); 153 value++; 154 *this = value; 155 } 156 else { 157 m_value++; 158 } 159 160 return *this; 161 } 162 operator ++(int)163 buffer_value<T> operator++(int) 164 { 165 buffer_value<T> result(*this); 166 ++(*this); 167 return result; 168 } 169 170 private: 171 const buffer m_buffer; 172 size_t m_index; 173 value_type m_value; 174 }; 175 176 } // end detail namespace 177 } // end compute namespace 178 } // end boost namespace 179 180 #endif // BOOST_COMPUTE_DETAIL_BUFFER_VALUE_HPP 181