Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:29:58

0001 //---------------------------------------------------------------------------//
0002 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
0003 //
0004 // Distributed under the Boost Software License, Version 1.0
0005 // See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt
0007 //
0008 // See http://boostorg.github.com/compute for more information.
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, &current_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 } // end compute namespace
0404 } // end boost namespace
0405 
0406 #endif // BOOST_COMPUTE_CONTAINER_FLAT_MAP_HPP