File indexing completed on 2025-01-18 09:29:58
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef BOOST_COMPUTE_CONTAINER_FLAT_MAP_HPP
0012 #define BOOST_COMPUTE_CONTAINER_FLAT_MAP_HPP
0013
0014 #include <cstddef>
0015 #include <utility>
0016 #include <exception>
0017
0018 #include <boost/config.hpp>
0019 #include <boost/throw_exception.hpp>
0020
0021 #include <boost/compute/exception.hpp>
0022 #include <boost/compute/algorithm/find.hpp>
0023 #include <boost/compute/algorithm/lower_bound.hpp>
0024 #include <boost/compute/algorithm/upper_bound.hpp>
0025 #include <boost/compute/container/vector.hpp>
0026 #include <boost/compute/functional/get.hpp>
0027 #include <boost/compute/iterator/transform_iterator.hpp>
0028 #include <boost/compute/types/pair.hpp>
0029 #include <boost/compute/detail/buffer_value.hpp>
0030
0031 namespace boost {
0032 namespace compute {
0033
0034 template<class Key, class T>
0035 class flat_map
0036 {
0037 public:
0038 typedef Key key_type;
0039 typedef T mapped_type;
0040 typedef typename ::boost::compute::vector<std::pair<Key, T> > vector_type;
0041 typedef typename vector_type::value_type value_type;
0042 typedef typename vector_type::size_type size_type;
0043 typedef typename vector_type::difference_type difference_type;
0044 typedef typename vector_type::reference reference;
0045 typedef typename vector_type::const_reference const_reference;
0046 typedef typename vector_type::pointer pointer;
0047 typedef typename vector_type::const_pointer const_pointer;
0048 typedef typename vector_type::iterator iterator;
0049 typedef typename vector_type::const_iterator const_iterator;
0050 typedef typename vector_type::reverse_iterator reverse_iterator;
0051 typedef typename vector_type::const_reverse_iterator const_reverse_iterator;
0052
0053 explicit flat_map(const context &context = system::default_context())
0054 : m_vector(context)
0055 {
0056 }
0057
0058 flat_map(const flat_map<Key, T> &other)
0059 : m_vector(other.m_vector)
0060 {
0061 }
0062
0063 flat_map<Key, T>& operator=(const flat_map<Key, T> &other)
0064 {
0065 if(this != &other){
0066 m_vector = other.m_vector;
0067 }
0068
0069 return *this;
0070 }
0071
0072 ~flat_map()
0073 {
0074 }
0075
0076 iterator begin()
0077 {
0078 return m_vector.begin();
0079 }
0080
0081 const_iterator begin() const
0082 {
0083 return m_vector.begin();
0084 }
0085
0086 const_iterator cbegin() const
0087 {
0088 return m_vector.cbegin();
0089 }
0090
0091 iterator end()
0092 {
0093 return m_vector.end();
0094 }
0095
0096 const_iterator end() const
0097 {
0098 return m_vector.end();
0099 }
0100
0101 const_iterator cend() const
0102 {
0103 return m_vector.cend();
0104 }
0105
0106 reverse_iterator rbegin()
0107 {
0108 return m_vector.rbegin();
0109 }
0110
0111 const_reverse_iterator rbegin() const
0112 {
0113 return m_vector.rbegin();
0114 }
0115
0116 const_reverse_iterator crbegin() const
0117 {
0118 return m_vector.crbegin();
0119 }
0120
0121 reverse_iterator rend()
0122 {
0123 return m_vector.rend();
0124 }
0125
0126 const_reverse_iterator rend() const
0127 {
0128 return m_vector.rend();
0129 }
0130
0131 const_reverse_iterator crend() const
0132 {
0133 return m_vector.crend();
0134 }
0135
0136 size_type size() const
0137 {
0138 return m_vector.size();
0139 }
0140
0141 size_type max_size() const
0142 {
0143 return m_vector.max_size();
0144 }
0145
0146 bool empty() const
0147 {
0148 return m_vector.empty();
0149 }
0150
0151 size_type capacity() const
0152 {
0153 return m_vector.capacity();
0154 }
0155
0156 void reserve(size_type size, command_queue &queue)
0157 {
0158 m_vector.reserve(size, queue);
0159 }
0160
0161 void reserve(size_type size)
0162 {
0163 command_queue queue = m_vector.default_queue();
0164 reserve(size, queue);
0165 queue.finish();
0166 }
0167
0168 void shrink_to_fit()
0169 {
0170 m_vector.shrink_to_fit();
0171 }
0172
0173 void clear()
0174 {
0175 m_vector.clear();
0176 }
0177
0178 std::pair<iterator, bool>
0179 insert(const value_type &value, command_queue &queue)
0180 {
0181 iterator location = upper_bound(value.first, queue);
0182
0183 if(location != begin()){
0184 value_type current_value;
0185 ::boost::compute::copy_n(location - 1, 1, ¤t_value, queue);
0186 if(value.first == current_value.first){
0187 return std::make_pair(location - 1, false);
0188 }
0189 }
0190
0191 m_vector.insert(location, value);
0192 return std::make_pair(location, true);
0193 }
0194
0195 std::pair<iterator, bool> insert(const value_type &value)
0196 {
0197 command_queue queue = m_vector.default_queue();
0198 std::pair<iterator, bool> result = insert(value, queue);
0199 queue.finish();
0200 return result;
0201 }
0202
0203 iterator erase(const const_iterator &position, command_queue &queue)
0204 {
0205 return erase(position, position + 1, queue);
0206 }
0207
0208 iterator erase(const const_iterator &position)
0209 {
0210 command_queue queue = m_vector.default_queue();
0211 iterator iter = erase(position, queue);
0212 queue.finish();
0213 return iter;
0214 }
0215
0216 iterator erase(const const_iterator &first,
0217 const const_iterator &last,
0218 command_queue &queue)
0219 {
0220 return m_vector.erase(first, last, queue);
0221 }
0222
0223 iterator erase(const const_iterator &first, const const_iterator &last)
0224 {
0225 command_queue queue = m_vector.default_queue();
0226 iterator iter = erase(first, last, queue);
0227 queue.finish();
0228 return iter;
0229 }
0230
0231 size_type erase(const key_type &value, command_queue &queue)
0232 {
0233 iterator position = find(value, queue);
0234
0235 if(position == end()){
0236 return 0;
0237 }
0238 else {
0239 erase(position, queue);
0240 return 1;
0241 }
0242 }
0243
0244 iterator find(const key_type &value, command_queue &queue)
0245 {
0246 ::boost::compute::get<0> get_key;
0247
0248 return ::boost::compute::find(
0249 ::boost::compute::make_transform_iterator(begin(), get_key),
0250 ::boost::compute::make_transform_iterator(end(), get_key),
0251 value,
0252 queue
0253 ).base();
0254 }
0255
0256 iterator find(const key_type &value)
0257 {
0258 command_queue queue = m_vector.default_queue();
0259 iterator iter = find(value, queue);
0260 queue.finish();
0261 return iter;
0262 }
0263
0264 const_iterator find(const key_type &value, command_queue &queue) const
0265 {
0266 ::boost::compute::get<0> get_key;
0267
0268 return ::boost::compute::find(
0269 ::boost::compute::make_transform_iterator(begin(), get_key),
0270 ::boost::compute::make_transform_iterator(end(), get_key),
0271 value,
0272 queue
0273 ).base();
0274 }
0275
0276 const_iterator find(const key_type &value) const
0277 {
0278 command_queue queue = m_vector.default_queue();
0279 const_iterator iter = find(value, queue);
0280 queue.finish();
0281 return iter;
0282 }
0283
0284 size_type count(const key_type &value, command_queue &queue) const
0285 {
0286 return find(value, queue) != end() ? 1 : 0;
0287 }
0288
0289 size_type count(const key_type &value) const
0290 {
0291 command_queue queue = m_vector.default_queue();
0292 size_type result = count(value, queue);
0293 queue.finish();
0294 return result;
0295 }
0296
0297 iterator lower_bound(const key_type &value, command_queue &queue)
0298 {
0299 ::boost::compute::get<0> get_key;
0300
0301 return ::boost::compute::lower_bound(
0302 ::boost::compute::make_transform_iterator(begin(), get_key),
0303 ::boost::compute::make_transform_iterator(end(), get_key),
0304 value,
0305 queue
0306 ).base();
0307 }
0308
0309 iterator lower_bound(const key_type &value)
0310 {
0311 command_queue queue = m_vector.default_queue();
0312 iterator iter = lower_bound(value, queue);
0313 queue.finish();
0314 return iter;
0315 }
0316
0317 const_iterator lower_bound(const key_type &value, command_queue &queue) const
0318 {
0319 ::boost::compute::get<0> get_key;
0320
0321 return ::boost::compute::lower_bound(
0322 ::boost::compute::make_transform_iterator(begin(), get_key),
0323 ::boost::compute::make_transform_iterator(end(), get_key),
0324 value,
0325 queue
0326 ).base();
0327 }
0328
0329 const_iterator lower_bound(const key_type &value) const
0330 {
0331 command_queue queue = m_vector.default_queue();
0332 const_iterator iter = lower_bound(value, queue);
0333 queue.finish();
0334 return iter;
0335 }
0336
0337 iterator upper_bound(const key_type &value, command_queue &queue)
0338 {
0339 ::boost::compute::get<0> get_key;
0340
0341 return ::boost::compute::upper_bound(
0342 ::boost::compute::make_transform_iterator(begin(), get_key),
0343 ::boost::compute::make_transform_iterator(end(), get_key),
0344 value,
0345 queue
0346 ).base();
0347 }
0348
0349 iterator upper_bound(const key_type &value)
0350 {
0351 command_queue queue = m_vector.default_queue();
0352 iterator iter = upper_bound(value, queue);
0353 queue.finish();
0354 return iter;
0355 }
0356
0357 const_iterator upper_bound(const key_type &value, command_queue &queue) const
0358 {
0359 ::boost::compute::get<0> get_key;
0360
0361 return ::boost::compute::upper_bound(
0362 ::boost::compute::make_transform_iterator(begin(), get_key),
0363 ::boost::compute::make_transform_iterator(end(), get_key),
0364 value,
0365 queue
0366 ).base();
0367 }
0368
0369 const_iterator upper_bound(const key_type &value) const
0370 {
0371 command_queue queue = m_vector.default_queue();
0372 const_iterator iter = upper_bound(value, queue);
0373 queue.finish();
0374 return iter;
0375 }
0376
0377 const mapped_type at(const key_type &key) const
0378 {
0379 const_iterator iter = find(key);
0380 if(iter == end()){
0381 BOOST_THROW_EXCEPTION(std::out_of_range("key not found"));
0382 }
0383
0384 return value_type(*iter).second;
0385 }
0386
0387 detail::buffer_value<mapped_type> operator[](const key_type &key)
0388 {
0389 iterator iter = find(key);
0390 if(iter == end()){
0391 iter = insert(std::make_pair(key, mapped_type())).first;
0392 }
0393
0394 size_t index = iter.get_index() * sizeof(value_type) + sizeof(key_type);
0395
0396 return detail::buffer_value<mapped_type>(m_vector.get_buffer(), index);
0397 }
0398
0399 private:
0400 ::boost::compute::vector<std::pair<Key, T> > m_vector;
0401 };
0402
0403 }
0404 }
0405
0406 #endif