| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- /*
- Copyright (c) 2019-2020 Intel Corporation
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- #ifndef __TBB_concurrent_map_H
- #define __TBB_concurrent_map_H
- #define __TBB_concurrent_map_H_include_area
- #include "internal/_warning_suppress_enable_notice.h"
- #if !TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS
- #error Set TBB_PREVIEW_CONCURRENT_ORDERED_CONTAINERS to include concurrent_map.h
- #endif
- #include "tbb_config.h"
- // concurrent_map requires C++11 support
- #if __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT
- #include "internal/_concurrent_skip_list_impl.h"
- namespace tbb {
- namespace interface10 {
- template<typename Key, typename Value, typename KeyCompare, typename RandomGenerator,
- size_t MAX_LEVELS, typename Allocator, bool AllowMultimapping>
- class map_traits {
- public:
- static constexpr size_t MAX_LEVEL = MAX_LEVELS;
- using random_level_generator_type = RandomGenerator;
- using key_type = Key;
- using mapped_type = Value;
- using compare_type = KeyCompare;
- using value_type = std::pair<const key_type, mapped_type>;
- using reference = value_type&;
- using const_reference = const value_type&;
- using allocator_type = Allocator;
- using mutex_type = tbb::spin_mutex;
- using node_type = tbb::internal::node_handle<key_type, value_type, internal::skip_list_node<value_type, mutex_type>, allocator_type>;
- static const bool allow_multimapping = AllowMultimapping;
- class value_compare {
- public:
- // TODO: these member types are deprecated in C++17, do we need to let them
- using result_type = bool;
- using first_argument_type = value_type;
- using second_argument_type = value_type;
- bool operator()(const value_type& lhs, const value_type& rhs) const {
- return comp(lhs.first, rhs.first);
- }
- protected:
- value_compare(compare_type c) : comp(c) {}
- friend class map_traits;
- compare_type comp;
- };
- static value_compare value_comp(compare_type comp) { return value_compare(comp); }
- static const key_type& get_key(const_reference val) {
- return val.first;
- }
- }; // class map_traits
- template <typename Key, typename Value, typename Comp, typename Allocator>
- class concurrent_multimap;
- template <typename Key, typename Value, typename Comp = std::less<Key>, typename Allocator = tbb_allocator<std::pair<const Key, Value>>>
- class concurrent_map
- : public internal::concurrent_skip_list<map_traits<Key, Value, Comp, internal::concurrent_geometric_level_generator<64>, 64, Allocator, false>> {
- using traits_type = map_traits<Key, Value, Comp, internal::concurrent_geometric_level_generator<64>, 64, Allocator, false>;
- using base_type = internal::concurrent_skip_list<traits_type>;
- #if __TBB_EXTRA_DEBUG
- public:
- #endif
- using base_type::allow_multimapping;
- public:
- using key_type = Key;
- using mapped_type = Value;
- using value_type = typename traits_type::value_type;
- using size_type = typename base_type::size_type;
- using difference_type = typename base_type::difference_type;
- using key_compare = Comp;
- using value_compare = typename base_type::value_compare;
- using allocator_type = Allocator;
- using reference = typename base_type::reference;
- using const_reference = typename base_type::const_reference;
- using pointer = typename base_type::pointer;
- using const_pointer = typename base_type::pointer;
- using iterator = typename base_type::iterator;
- using const_iterator = typename base_type::const_iterator;
- using reverse_iterator = typename base_type::reverse_iterator;
- using const_reverse_iterator = typename base_type::const_reverse_iterator;
- using node_type = typename base_type::node_type;
- using base_type::end;
- using base_type::find;
- using base_type::emplace;
- using base_type::insert;
- concurrent_map() = default;
- explicit concurrent_map(const key_compare& comp, const allocator_type& alloc = allocator_type()) : base_type(comp, alloc) {}
- explicit concurrent_map(const allocator_type& alloc) : base_type(key_compare(), alloc) {}
- template< class InputIt >
- concurrent_map(InputIt first, InputIt last, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type())
- : base_type(first, last, comp, alloc) {}
- template< class InputIt >
- concurrent_map(InputIt first, InputIt last, const allocator_type& alloc) : base_type(first, last, key_compare(), alloc) {}
- /** Copy constructor */
- concurrent_map(const concurrent_map&) = default;
- concurrent_map(const concurrent_map& other, const allocator_type& alloc) : base_type(other, alloc) {}
- concurrent_map(concurrent_map&&) = default;
- concurrent_map(concurrent_map&& other, const allocator_type& alloc) : base_type(std::move(other), alloc) {}
- concurrent_map(std::initializer_list<value_type> init, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type())
- : base_type(comp, alloc) {
- insert(init);
- }
- concurrent_map(std::initializer_list<value_type> init, const allocator_type& alloc)
- : base_type(key_compare(), alloc) {
- insert(init);
- }
- concurrent_map& operator=(const concurrent_map& other) {
- return static_cast<concurrent_map&>(base_type::operator=(other));
- }
- concurrent_map& operator=(concurrent_map&& other) {
- return static_cast<concurrent_map&>(base_type::operator=(std::move(other)));
- }
- mapped_type& at(const key_type& key) {
- iterator it = find(key);
- if (it == end()) {
- tbb::internal::throw_exception(tbb::internal::eid_invalid_key);
- }
- return it->second;
- }
- const mapped_type& at(const key_type& key) const {
- const_iterator it = find(key);
- if (it == end()) {
- tbb::internal::throw_exception(tbb::internal::eid_invalid_key);
- }
- return it->second;
- }
- mapped_type& operator[](const key_type& key) {
- iterator it = find(key);
- if (it == end()) {
- it = emplace(std::piecewise_construct, std::forward_as_tuple(key), std::tuple<>()).first;
- }
- return it->second;
- }
- mapped_type& operator[](key_type&& key) {
- iterator it = find(key);
- if (it == end()) {
- it = emplace(std::piecewise_construct, std::forward_as_tuple(std::move(key)), std::tuple<>()).first;
- }
- return it->second;
- }
- template<typename P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type>
- std::pair<iterator, bool> insert(P&& value) {
- return emplace(std::forward<P>(value));
- }
- template<typename P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type>
- iterator insert(const_iterator hint, P&& value) {
- return emplace_hint(hint, std::forward<P>(value));
- return end();
- }
- template<typename C2>
- void merge(concurrent_map<key_type, mapped_type, C2, Allocator>& source) {
- this->internal_merge(source);
- }
- template<typename C2>
- void merge(concurrent_map<key_type, mapped_type, C2, Allocator>&& source) {
- this->internal_merge(std::move(source));
- }
- template<typename C2>
- void merge(concurrent_multimap<key_type, mapped_type, C2, Allocator>& source) {
- this->internal_merge(source);
- }
- template<typename C2>
- void merge(concurrent_multimap<key_type, mapped_type, C2, Allocator>&& source) {
- this->internal_merge(std::move(source));
- }
- }; // class concurrent_map
- #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
- namespace internal {
- using namespace tbb::internal;
- template<template<typename...> typename Map, typename Key, typename T, typename... Args>
- using c_map_t = Map<Key, T,
- std::conditional_t< (sizeof...(Args) > 0) && !is_allocator_v<pack_element_t<0, Args...> >,
- pack_element_t<0, Args...>, std::less<Key> >,
- std::conditional_t< (sizeof...(Args) > 0) && is_allocator_v<pack_element_t<sizeof...(Args)-1, Args...> >,
- pack_element_t<sizeof...(Args)-1, Args...>, tbb_allocator<std::pair<const Key, T> > > >;
- } // namespace internal
- template<typename It, typename... Args>
- concurrent_map(It, It, Args...)
- -> internal::c_map_t<concurrent_map, internal::iterator_key_t<It>, internal::iterator_mapped_t<It>, Args...>;
- template<typename Key, typename T, typename... Args>
- concurrent_map(std::initializer_list<std::pair<const Key, T>>, Args...)
- -> internal::c_map_t<concurrent_map, Key, T, Args...>;
- #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
- template <typename Key, typename Value, typename Comp = std::less<Key>, typename Allocator = tbb_allocator<std::pair<const Key, Value>>>
- class concurrent_multimap
- : public internal::concurrent_skip_list<map_traits<Key, Value, Comp, internal::concurrent_geometric_level_generator<64>, 64, Allocator, true>> {
- using traits_type = map_traits<Key, Value, Comp, internal::concurrent_geometric_level_generator<64>, 64, Allocator, true>;
- using base_type = internal::concurrent_skip_list<traits_type>;
- #if __TBB_EXTRA_DEBUG
- public:
- #endif
- using base_type::allow_multimapping;
- public:
- using key_type = Key;
- using mapped_type = Value;
- using value_type = typename traits_type::value_type;
- using size_type = typename base_type::size_type;
- using difference_type = typename base_type::difference_type;
- using key_compare = Comp;
- using value_compare = typename base_type::value_compare;
- using allocator_type = Allocator;
- using reference = typename base_type::reference;
- using const_reference = typename base_type::const_reference;
- using pointer = typename base_type::pointer;
- using const_pointer = typename base_type::pointer;
- using iterator = typename base_type::iterator;
- using const_iterator = typename base_type::const_iterator;
- using reverse_iterator = typename base_type::reverse_iterator;
- using const_reverse_iterator = typename base_type::const_reverse_iterator;
- using node_type = typename base_type::node_type;
- using base_type::end;
- using base_type::find;
- using base_type::emplace;
- using base_type::insert;
- concurrent_multimap() = default;
- explicit concurrent_multimap(const key_compare& comp, const allocator_type& alloc = allocator_type()) : base_type(comp, alloc) {}
- explicit concurrent_multimap(const allocator_type& alloc) : base_type(key_compare(), alloc) {}
- template< class InputIt >
- concurrent_multimap(InputIt first, InputIt last, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type())
- : base_type(first, last, comp, alloc) {}
- template< class InputIt >
- concurrent_multimap(InputIt first, InputIt last, const allocator_type& alloc) : base_type(first, last, key_compare(), alloc) {}
- /** Copy constructor */
- concurrent_multimap(const concurrent_multimap&) = default;
- concurrent_multimap(const concurrent_multimap& other, const allocator_type& alloc) : base_type(other, alloc) {}
- concurrent_multimap(concurrent_multimap&&) = default;
- concurrent_multimap(concurrent_multimap&& other, const allocator_type& alloc) : base_type(std::move(other), alloc) {}
- concurrent_multimap(std::initializer_list<value_type> init, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type())
- : base_type(comp, alloc) {
- insert(init);
- }
- concurrent_multimap(std::initializer_list<value_type> init, const allocator_type& alloc)
- : base_type(key_compare(), alloc) {
- insert(init);
- }
- concurrent_multimap& operator=(const concurrent_multimap& other) {
- return static_cast<concurrent_multimap&>(base_type::operator=(other));
- }
- concurrent_multimap& operator=(concurrent_multimap&& other) {
- return static_cast<concurrent_multimap&>(base_type::operator=(std::move(other)));
- }
- template<typename P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type>
- std::pair<iterator, bool> insert(P&& value) {
- return emplace(std::forward<P>(value));
- }
- template<typename P, typename std::enable_if<std::is_constructible<value_type, P&&>::value>::type>
- iterator insert(const_iterator hint, P&& value) {
- return emplace_hint(hint, std::forward<P>(value));
- return end();
- }
- template<typename C2>
- void merge(concurrent_multimap<key_type, mapped_type, C2, Allocator>& source) {
- this->internal_merge(source);
- }
- template<typename C2>
- void merge(concurrent_multimap<key_type, mapped_type, C2, Allocator>&& source) {
- this->internal_merge(std::move(source));
- }
- template<typename C2>
- void merge(concurrent_map<key_type, mapped_type, C2, Allocator>& source) {
- this->internal_merge(source);
- }
- template<typename C2>
- void merge(concurrent_map<key_type, mapped_type, C2, Allocator>&& source) {
- this->internal_merge(std::move(source));
- }
- }; // class concurrent_multimap
- #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
- template<typename It, typename... Args>
- concurrent_multimap(It, It, Args...)
- -> internal::c_map_t<concurrent_multimap, internal::iterator_key_t<It>, internal::iterator_mapped_t<It>, Args...>;
- template<typename Key, typename T, typename... Args>
- concurrent_multimap(std::initializer_list<std::pair<const Key, T>>, Args...)
- -> internal::c_map_t<concurrent_multimap, Key, T, Args...>;
- #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
- } // namespace interface10
- using interface10::concurrent_map;
- using interface10::concurrent_multimap;
- } // namespace tbb
- #include "internal/_warning_suppress_disable_notice.h"
- #undef __TBB_concurrent_map_H_include_area
- #endif // __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT
- #endif // __TBB_concurrent_map_H
|