xref: /oneTBB/include/oneapi/tbb/concurrent_map.h (revision 2713d41e)
149e08aacStbbdev /*
2b15aabb3Stbbdev     Copyright (c) 2019-2021 Intel Corporation
349e08aacStbbdev 
449e08aacStbbdev     Licensed under the Apache License, Version 2.0 (the "License");
549e08aacStbbdev     you may not use this file except in compliance with the License.
649e08aacStbbdev     You may obtain a copy of the License at
749e08aacStbbdev 
849e08aacStbbdev         http://www.apache.org/licenses/LICENSE-2.0
949e08aacStbbdev 
1049e08aacStbbdev     Unless required by applicable law or agreed to in writing, software
1149e08aacStbbdev     distributed under the License is distributed on an "AS IS" BASIS,
1249e08aacStbbdev     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1349e08aacStbbdev     See the License for the specific language governing permissions and
1449e08aacStbbdev     limitations under the License.
1549e08aacStbbdev */
1649e08aacStbbdev 
1749e08aacStbbdev #ifndef __TBB_concurrent_map_H
1849e08aacStbbdev #define __TBB_concurrent_map_H
1949e08aacStbbdev 
2049e08aacStbbdev #include "detail/_namespace_injection.h"
2149e08aacStbbdev #include "detail/_concurrent_skip_list.h"
2249e08aacStbbdev #include "tbb_allocator.h"
2349e08aacStbbdev #include <functional>
2449e08aacStbbdev #include <tuple>
2549e08aacStbbdev #include <utility>
2649e08aacStbbdev 
2749e08aacStbbdev namespace tbb {
2849e08aacStbbdev namespace detail {
29d8251013SAnton Potapov namespace d2 {
3049e08aacStbbdev 
3149e08aacStbbdev template<typename Key, typename Value, typename KeyCompare, typename RandomGenerator,
3249e08aacStbbdev          typename Allocator, bool AllowMultimapping>
3349e08aacStbbdev struct map_traits {
3449e08aacStbbdev     static constexpr std::size_t max_level = RandomGenerator::max_level;
3549e08aacStbbdev     using random_level_generator_type = RandomGenerator;
3649e08aacStbbdev     using key_type = Key;
3749e08aacStbbdev     using mapped_type = Value;
3849e08aacStbbdev     using compare_type = KeyCompare;
3949e08aacStbbdev     using value_type = std::pair<const key_type, mapped_type>;
4049e08aacStbbdev     using reference = value_type&;
4149e08aacStbbdev     using const_reference = const value_type&;
4249e08aacStbbdev     using allocator_type = Allocator;
4349e08aacStbbdev 
4449e08aacStbbdev     static constexpr bool allow_multimapping = AllowMultimapping;
4549e08aacStbbdev 
4649e08aacStbbdev     class value_compare {
4749e08aacStbbdev     public:
operatormap_traits4849e08aacStbbdev         bool operator()(const value_type& lhs, const value_type& rhs) const {
4949e08aacStbbdev             return comp(lhs.first, rhs.first);
5049e08aacStbbdev         }
5149e08aacStbbdev 
5249e08aacStbbdev     protected:
value_comparemap_traits5349e08aacStbbdev         value_compare(compare_type c) : comp(c) {}
5449e08aacStbbdev 
5549e08aacStbbdev         friend struct map_traits;
5649e08aacStbbdev 
5749e08aacStbbdev         compare_type comp;
5849e08aacStbbdev     };
5949e08aacStbbdev 
value_compmap_traits6049e08aacStbbdev     static value_compare value_comp(compare_type comp) { return value_compare(comp); }
6149e08aacStbbdev 
get_keymap_traits6249e08aacStbbdev     static const key_type& get_key(const_reference val) {
6349e08aacStbbdev         return val.first;
6449e08aacStbbdev     }
6549e08aacStbbdev }; // struct map_traits
6649e08aacStbbdev 
6749e08aacStbbdev template <typename Key, typename Value, typename Compare, typename Allocator>
6849e08aacStbbdev class concurrent_multimap;
6949e08aacStbbdev 
7049e08aacStbbdev template <typename Key, typename Value, typename Compare = std::less<Key>, typename Allocator = tbb::tbb_allocator<std::pair<const Key, Value>>>
7149e08aacStbbdev class concurrent_map : public concurrent_skip_list<map_traits<Key, Value, Compare, concurrent_geometric_level_generator<32>, Allocator, false>> {
7249e08aacStbbdev     using base_type = concurrent_skip_list<map_traits<Key, Value, Compare, concurrent_geometric_level_generator<32>, Allocator, false>>;
7349e08aacStbbdev public:
7449e08aacStbbdev     using key_type = Key;
7549e08aacStbbdev     using mapped_type = Value;
7649e08aacStbbdev     using value_type = typename base_type::value_type;
7749e08aacStbbdev     using size_type = typename base_type::size_type;
7849e08aacStbbdev     using difference_type = typename base_type::difference_type;
7949e08aacStbbdev     using key_compare = Compare;
8049e08aacStbbdev     using value_compare = typename base_type::value_compare;
8149e08aacStbbdev     using allocator_type = Allocator;
8249e08aacStbbdev 
8349e08aacStbbdev     using reference = typename base_type::reference;
8449e08aacStbbdev     using const_reference = typename base_type::const_reference;
8549e08aacStbbdev     using pointer = typename base_type::pointer;
8649e08aacStbbdev     using const_pointer = typename base_type::const_pointer;
8749e08aacStbbdev 
8849e08aacStbbdev     using iterator = typename base_type::iterator;
8949e08aacStbbdev     using const_iterator = typename base_type::const_iterator;
9049e08aacStbbdev 
9149e08aacStbbdev     using node_type = typename base_type::node_type;
9249e08aacStbbdev 
9349e08aacStbbdev     // Include constructors of base type
9449e08aacStbbdev     using base_type::base_type;
9549e08aacStbbdev 
96d86ed7fbStbbdev     // Required for implicit deduction guides
97d86ed7fbStbbdev     concurrent_map() = default;
98d86ed7fbStbbdev     concurrent_map( const concurrent_map& ) = default;
concurrent_map(const concurrent_map & other,const allocator_type & alloc)99d86ed7fbStbbdev     concurrent_map( const concurrent_map& other, const allocator_type& alloc ) : base_type(other, alloc) {}
100d86ed7fbStbbdev     concurrent_map( concurrent_map&& ) = default;
concurrent_map(concurrent_map && other,const allocator_type & alloc)101d86ed7fbStbbdev     concurrent_map( concurrent_map&& other, const allocator_type& alloc ) : base_type(std::move(other), alloc) {}
102d86ed7fbStbbdev     // Required to respect the rule of 5
103d86ed7fbStbbdev     concurrent_map& operator=( const concurrent_map& ) = default;
104d86ed7fbStbbdev     concurrent_map& operator=( concurrent_map&& ) = default;
105d86ed7fbStbbdev 
106*2713d41eSIlya Isaev     concurrent_map& operator=( std::initializer_list<value_type> il ) {
107*2713d41eSIlya Isaev         base_type::operator= (il);
108*2713d41eSIlya Isaev         return *this;
109*2713d41eSIlya Isaev     }
110*2713d41eSIlya Isaev 
11149e08aacStbbdev     // Observers
at(const key_type & key)11249e08aacStbbdev     mapped_type& at(const key_type& key) {
11349e08aacStbbdev         iterator it = this->find(key);
11449e08aacStbbdev 
11549e08aacStbbdev         if (it == this->end()) {
11649e08aacStbbdev             throw_exception(exception_id::invalid_key);
11749e08aacStbbdev         }
11849e08aacStbbdev         return it->second;
11949e08aacStbbdev     }
12049e08aacStbbdev 
at(const key_type & key)12149e08aacStbbdev     const mapped_type& at(const key_type& key) const {
12249e08aacStbbdev         return const_cast<concurrent_map*>(this)->at(key);
12349e08aacStbbdev     }
12449e08aacStbbdev 
12549e08aacStbbdev     mapped_type& operator[](const key_type& key) {
12649e08aacStbbdev         iterator it = this->find(key);
12749e08aacStbbdev 
12849e08aacStbbdev         if (it == this->end()) {
12949e08aacStbbdev             it = this->emplace(std::piecewise_construct, std::forward_as_tuple(key), std::tuple<>()).first;
13049e08aacStbbdev         }
13149e08aacStbbdev         return it->second;
13249e08aacStbbdev     }
13349e08aacStbbdev 
13449e08aacStbbdev     mapped_type& operator[](key_type&& key) {
13549e08aacStbbdev         iterator it = this->find(key);
13649e08aacStbbdev 
13749e08aacStbbdev         if (it == this->end()) {
13849e08aacStbbdev             it = this->emplace(std::piecewise_construct, std::forward_as_tuple(std::move(key)), std::tuple<>()).first;
13949e08aacStbbdev         }
14049e08aacStbbdev         return it->second;
14149e08aacStbbdev     }
14249e08aacStbbdev 
14349e08aacStbbdev     using base_type::insert;
14449e08aacStbbdev 
14549e08aacStbbdev     template <typename P>
14649e08aacStbbdev     typename std::enable_if<std::is_constructible<value_type, P&&>::value,
insert(P && value)14749e08aacStbbdev                             std::pair<iterator, bool>>::type insert( P&& value )
14849e08aacStbbdev     {
14949e08aacStbbdev         return this->emplace(std::forward<P>(value));
15049e08aacStbbdev     }
15149e08aacStbbdev 
15249e08aacStbbdev     template <typename P>
15349e08aacStbbdev     typename std::enable_if<std::is_constructible<value_type, P&&>::value,
insert(const_iterator hint,P && value)15449e08aacStbbdev                             iterator>::type insert( const_iterator hint, P&& value )
15549e08aacStbbdev     {
15649e08aacStbbdev         return this->emplace_hint(hint, std::forward<P>(value));
15749e08aacStbbdev     }
15849e08aacStbbdev 
15949e08aacStbbdev     template<typename OtherCompare>
merge(concurrent_map<key_type,mapped_type,OtherCompare,Allocator> & source)16049e08aacStbbdev     void merge(concurrent_map<key_type, mapped_type, OtherCompare, Allocator>& source) {
16149e08aacStbbdev         this->internal_merge(source);
16249e08aacStbbdev     }
16349e08aacStbbdev 
16449e08aacStbbdev     template<typename OtherCompare>
merge(concurrent_map<key_type,mapped_type,OtherCompare,Allocator> && source)16549e08aacStbbdev     void merge(concurrent_map<key_type, mapped_type, OtherCompare, Allocator>&& source) {
16649e08aacStbbdev         this->internal_merge(std::move(source));
16749e08aacStbbdev     }
16849e08aacStbbdev 
16949e08aacStbbdev     template<typename OtherCompare>
merge(concurrent_multimap<key_type,mapped_type,OtherCompare,Allocator> & source)17049e08aacStbbdev     void merge(concurrent_multimap<key_type, mapped_type, OtherCompare, Allocator>& source) {
17149e08aacStbbdev         this->internal_merge(source);
17249e08aacStbbdev     }
17349e08aacStbbdev 
17449e08aacStbbdev     template<typename OtherCompare>
merge(concurrent_multimap<key_type,mapped_type,OtherCompare,Allocator> && source)17549e08aacStbbdev     void merge(concurrent_multimap<key_type, mapped_type, OtherCompare, Allocator>&& source) {
17649e08aacStbbdev         this->internal_merge(std::move(source));
17749e08aacStbbdev     }
17849e08aacStbbdev }; // class concurrent_map
17949e08aacStbbdev 
18049e08aacStbbdev #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
18149e08aacStbbdev 
182d86ed7fbStbbdev template <typename It,
183d86ed7fbStbbdev           typename Comp = std::less<iterator_key_t<It>>,
184d86ed7fbStbbdev           typename Alloc = tbb::tbb_allocator<iterator_alloc_pair_t<It>>,
185d86ed7fbStbbdev           typename = std::enable_if_t<is_input_iterator_v<It>>,
186d86ed7fbStbbdev           typename = std::enable_if_t<is_allocator_v<Alloc>>,
187d86ed7fbStbbdev           typename = std::enable_if_t<!is_allocator_v<Comp>>>
188d86ed7fbStbbdev concurrent_map( It, It, Comp = Comp(), Alloc = Alloc() )
189d86ed7fbStbbdev -> concurrent_map<iterator_key_t<It>, iterator_mapped_t<It>, Comp, Alloc>;
19049e08aacStbbdev 
191d86ed7fbStbbdev template <typename Key, typename T,
192d86ed7fbStbbdev           typename Comp = std::less<std::remove_const_t<Key>>,
193d86ed7fbStbbdev           typename Alloc = tbb::tbb_allocator<std::pair<const Key, T>>,
194d86ed7fbStbbdev           typename = std::enable_if_t<is_allocator_v<Alloc>>,
195d86ed7fbStbbdev           typename = std::enable_if_t<!is_allocator_v<Comp>>>
196d86ed7fbStbbdev concurrent_map( std::initializer_list<std::pair<Key, T>>, Comp = Comp(), Alloc = Alloc() )
197d86ed7fbStbbdev -> concurrent_map<std::remove_const_t<Key>, T, Comp, Alloc>;
19849e08aacStbbdev 
199d86ed7fbStbbdev template <typename It, typename Alloc,
200d86ed7fbStbbdev           typename = std::enable_if_t<is_input_iterator_v<It>>,
201d86ed7fbStbbdev           typename = std::enable_if_t<is_allocator_v<Alloc>>>
202d86ed7fbStbbdev concurrent_map( It, It, Alloc )
203d86ed7fbStbbdev -> concurrent_map<iterator_key_t<It>, iterator_mapped_t<It>,
204d86ed7fbStbbdev                   std::less<iterator_key_t<It>>, Alloc>;
205d86ed7fbStbbdev 
206d86ed7fbStbbdev template <typename Key, typename T, typename Alloc,
207d86ed7fbStbbdev           typename = std::enable_if_t<is_allocator_v<Alloc>>>
208d86ed7fbStbbdev concurrent_map( std::initializer_list<std::pair<Key, T>>, Alloc )
209d86ed7fbStbbdev -> concurrent_map<std::remove_const_t<Key>, T, std::less<std::remove_const_t<Key>>, Alloc>;
21049e08aacStbbdev 
21149e08aacStbbdev #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
21249e08aacStbbdev 
21349e08aacStbbdev template <typename Key, typename Value, typename Compare, typename Allocator>
swap(concurrent_map<Key,Value,Compare,Allocator> & lhs,concurrent_map<Key,Value,Compare,Allocator> & rhs)21449e08aacStbbdev void swap( concurrent_map<Key, Value, Compare, Allocator>& lhs,
21549e08aacStbbdev            concurrent_map<Key, Value, Compare, Allocator>& rhs )
21649e08aacStbbdev {
21749e08aacStbbdev     lhs.swap(rhs);
21849e08aacStbbdev }
21949e08aacStbbdev 
22049e08aacStbbdev template <typename Key, typename Value, typename Compare = std::less<Key>, typename Allocator = tbb::tbb_allocator<std::pair<const Key, Value>>>
22149e08aacStbbdev class concurrent_multimap : public concurrent_skip_list<map_traits<Key, Value, Compare, concurrent_geometric_level_generator<32>, Allocator, true>> {
22249e08aacStbbdev     using base_type = concurrent_skip_list<map_traits<Key, Value, Compare, concurrent_geometric_level_generator<32>, Allocator, true>>;
22349e08aacStbbdev public:
22449e08aacStbbdev     using key_type = Key;
22549e08aacStbbdev     using mapped_type = Value;
22649e08aacStbbdev     using value_type = typename base_type::value_type;
22749e08aacStbbdev     using size_type = typename base_type::size_type;
22849e08aacStbbdev     using difference_type = typename base_type::difference_type;
22949e08aacStbbdev     using key_compare = Compare;
23049e08aacStbbdev     using value_compare = typename base_type::value_compare;
23149e08aacStbbdev     using allocator_type = Allocator;
23249e08aacStbbdev 
23349e08aacStbbdev     using reference = typename base_type::reference;
23449e08aacStbbdev     using const_reference = typename base_type::const_reference;
23549e08aacStbbdev     using pointer = typename base_type::pointer;
23649e08aacStbbdev     using const_pointer = typename base_type::const_pointer;
23749e08aacStbbdev 
23849e08aacStbbdev     using iterator = typename base_type::iterator;
23949e08aacStbbdev     using const_iterator = typename base_type::const_iterator;
24049e08aacStbbdev 
24149e08aacStbbdev     using node_type = typename base_type::node_type;
24249e08aacStbbdev 
24349e08aacStbbdev     // Include constructors of base_type
24449e08aacStbbdev     using base_type::base_type;
24549e08aacStbbdev     using base_type::insert;
24649e08aacStbbdev 
247d86ed7fbStbbdev     // Required for implicit deduction guides
248d86ed7fbStbbdev     concurrent_multimap() = default;
249d86ed7fbStbbdev     concurrent_multimap( const concurrent_multimap& ) = default;
concurrent_multimap(const concurrent_multimap & other,const allocator_type & alloc)250d86ed7fbStbbdev     concurrent_multimap( const concurrent_multimap& other, const allocator_type& alloc ) : base_type(other, alloc) {}
251d86ed7fbStbbdev     concurrent_multimap( concurrent_multimap&& ) = default;
concurrent_multimap(concurrent_multimap && other,const allocator_type & alloc)252d86ed7fbStbbdev     concurrent_multimap( concurrent_multimap&& other, const allocator_type& alloc ) : base_type(std::move(other), alloc) {}
253d86ed7fbStbbdev     // Required to respect the rule of 5
254d86ed7fbStbbdev     concurrent_multimap& operator=( const concurrent_multimap& ) = default;
255d86ed7fbStbbdev     concurrent_multimap& operator=( concurrent_multimap&& ) = default;
256d86ed7fbStbbdev 
257*2713d41eSIlya Isaev     concurrent_multimap& operator=( std::initializer_list<value_type> il ) {
258*2713d41eSIlya Isaev         base_type::operator= (il);
259*2713d41eSIlya Isaev         return *this;
260*2713d41eSIlya Isaev     }
261*2713d41eSIlya Isaev 
26249e08aacStbbdev     template <typename P>
26349e08aacStbbdev     typename std::enable_if<std::is_constructible<value_type, P&&>::value,
insert(P && value)26449e08aacStbbdev                             std::pair<iterator, bool>>::type insert( P&& value )
26549e08aacStbbdev     {
26649e08aacStbbdev         return this->emplace(std::forward<P>(value));
26749e08aacStbbdev     }
26849e08aacStbbdev 
26949e08aacStbbdev     template <typename P>
27049e08aacStbbdev     typename std::enable_if<std::is_constructible<value_type, P&&>::value,
insert(const_iterator hint,P && value)27149e08aacStbbdev                             iterator>::type insert( const_iterator hint, P&& value )
27249e08aacStbbdev     {
27349e08aacStbbdev         return this->emplace_hint(hint, std::forward<P>(value));
27449e08aacStbbdev     }
27549e08aacStbbdev 
27649e08aacStbbdev     template<typename OtherCompare>
merge(concurrent_multimap<key_type,mapped_type,OtherCompare,Allocator> & source)27749e08aacStbbdev     void merge(concurrent_multimap<key_type, mapped_type, OtherCompare, Allocator>& source) {
27849e08aacStbbdev         this->internal_merge(source);
27949e08aacStbbdev     }
28049e08aacStbbdev 
28149e08aacStbbdev     template<typename OtherCompare>
merge(concurrent_multimap<key_type,mapped_type,OtherCompare,Allocator> && source)28249e08aacStbbdev     void merge(concurrent_multimap<key_type, mapped_type, OtherCompare, Allocator>&& source) {
28349e08aacStbbdev         this->internal_merge(std::move(source));
28449e08aacStbbdev     }
28549e08aacStbbdev 
28649e08aacStbbdev     template<typename OtherCompare>
merge(concurrent_map<key_type,mapped_type,OtherCompare,Allocator> & source)28749e08aacStbbdev     void merge(concurrent_map<key_type, mapped_type, OtherCompare, Allocator>& source) {
28849e08aacStbbdev         this->internal_merge(source);
28949e08aacStbbdev     }
29049e08aacStbbdev 
29149e08aacStbbdev     template<typename OtherCompare>
merge(concurrent_map<key_type,mapped_type,OtherCompare,Allocator> && source)29249e08aacStbbdev     void merge(concurrent_map<key_type, mapped_type, OtherCompare, Allocator>&& source) {
29349e08aacStbbdev         this->internal_merge(std::move(source));
29449e08aacStbbdev     }
29549e08aacStbbdev }; // class concurrent_multimap
29649e08aacStbbdev 
29749e08aacStbbdev #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
29849e08aacStbbdev 
299d86ed7fbStbbdev template <typename It,
300d86ed7fbStbbdev           typename Comp = std::less<iterator_key_t<It>>,
301d86ed7fbStbbdev           typename Alloc = tbb::tbb_allocator<iterator_alloc_pair_t<It>>,
302d86ed7fbStbbdev           typename = std::enable_if_t<is_input_iterator_v<It>>,
303d86ed7fbStbbdev           typename = std::enable_if_t<is_allocator_v<Alloc>>,
304d86ed7fbStbbdev           typename = std::enable_if_t<!is_allocator_v<Comp>>>
305d86ed7fbStbbdev concurrent_multimap( It, It, Comp = Comp(), Alloc = Alloc() )
306d86ed7fbStbbdev -> concurrent_multimap<iterator_key_t<It>, iterator_mapped_t<It>, Comp, Alloc>;
30749e08aacStbbdev 
308d86ed7fbStbbdev template <typename Key, typename T,
309d86ed7fbStbbdev           typename Comp = std::less<std::remove_const_t<Key>>,
310d86ed7fbStbbdev           typename Alloc = tbb::tbb_allocator<std::pair<const Key, T>>,
311d86ed7fbStbbdev           typename = std::enable_if_t<is_allocator_v<Alloc>>,
312d86ed7fbStbbdev           typename = std::enable_if_t<!is_allocator_v<Comp>>>
313d86ed7fbStbbdev concurrent_multimap( std::initializer_list<std::pair<Key, T>>, Comp = Comp(), Alloc = Alloc() )
314d86ed7fbStbbdev -> concurrent_multimap<std::remove_const_t<Key>, T, Comp, Alloc>;
315d86ed7fbStbbdev 
316d86ed7fbStbbdev template <typename It, typename Alloc,
317d86ed7fbStbbdev           typename = std::enable_if_t<is_input_iterator_v<It>>,
318d86ed7fbStbbdev           typename = std::enable_if_t<is_allocator_v<Alloc>>>
319d86ed7fbStbbdev concurrent_multimap( It, It, Alloc )
320d86ed7fbStbbdev -> concurrent_multimap<iterator_key_t<It>, iterator_mapped_t<It>,
321d86ed7fbStbbdev                        std::less<iterator_key_t<It>>, Alloc>;
322d86ed7fbStbbdev 
323d86ed7fbStbbdev template <typename Key, typename T, typename Alloc,
324d86ed7fbStbbdev           typename = std::enable_if_t<is_allocator_v<Alloc>>>
325d86ed7fbStbbdev concurrent_multimap( std::initializer_list<std::pair<Key, T>>, Alloc )
326d86ed7fbStbbdev -> concurrent_multimap<std::remove_const_t<Key>, T, std::less<std::remove_const_t<Key>>, Alloc>;
327d86ed7fbStbbdev 
32849e08aacStbbdev 
32949e08aacStbbdev #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
33049e08aacStbbdev 
33149e08aacStbbdev template <typename Key, typename Value, typename Compare, typename Allocator>
swap(concurrent_multimap<Key,Value,Compare,Allocator> & lhs,concurrent_multimap<Key,Value,Compare,Allocator> & rhs)33249e08aacStbbdev void swap( concurrent_multimap<Key, Value, Compare, Allocator>& lhs,
33349e08aacStbbdev            concurrent_multimap<Key, Value, Compare, Allocator>& rhs )
33449e08aacStbbdev {
33549e08aacStbbdev     lhs.swap(rhs);
33649e08aacStbbdev }
33749e08aacStbbdev 
338d8251013SAnton Potapov } // namespace d2
33949e08aacStbbdev } // namespace detail
34049e08aacStbbdev 
34149e08aacStbbdev inline namespace v1 {
34249e08aacStbbdev 
343d8251013SAnton Potapov using detail::d2::concurrent_map;
344d8251013SAnton Potapov using detail::d2::concurrent_multimap;
34549e08aacStbbdev using detail::split;
34649e08aacStbbdev 
34749e08aacStbbdev } // inline namespace v1
34849e08aacStbbdev } // namespace tbb
34949e08aacStbbdev 
35049e08aacStbbdev #endif // __TBB_concurrent_map_H
351