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_set_H
1849e08aacStbbdev #define __TBB_concurrent_set_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 <utility>
2549e08aacStbbdev
2649e08aacStbbdev namespace tbb {
2749e08aacStbbdev namespace detail {
28d8251013SAnton Potapov namespace d2 {
2949e08aacStbbdev
3049e08aacStbbdev template<typename Key, typename KeyCompare, typename RandomGenerator, typename Allocator, bool AllowMultimapping>
3149e08aacStbbdev struct set_traits {
3249e08aacStbbdev static constexpr std::size_t max_level = RandomGenerator::max_level;
3349e08aacStbbdev using random_level_generator_type = RandomGenerator;
3449e08aacStbbdev using key_type = Key;
3549e08aacStbbdev using value_type = key_type;
3649e08aacStbbdev using compare_type = KeyCompare;
3749e08aacStbbdev using value_compare = compare_type;
3849e08aacStbbdev using reference = value_type&;
3949e08aacStbbdev using const_reference = const value_type&;
4049e08aacStbbdev using allocator_type = Allocator;
4149e08aacStbbdev
4249e08aacStbbdev static constexpr bool allow_multimapping = AllowMultimapping;
4349e08aacStbbdev
get_keyset_traits4449e08aacStbbdev static const key_type& get_key(const_reference val) {
4549e08aacStbbdev return val;
4649e08aacStbbdev }
4749e08aacStbbdev
value_compset_traits4849e08aacStbbdev static value_compare value_comp(compare_type comp) { return comp; }
4949e08aacStbbdev }; // struct set_traits
5049e08aacStbbdev
5149e08aacStbbdev template <typename Key, typename Compare, typename Allocator>
5249e08aacStbbdev class concurrent_multiset;
5349e08aacStbbdev
5449e08aacStbbdev template <typename Key, typename Compare = std::less<Key>, typename Allocator = tbb::tbb_allocator<Key>>
5549e08aacStbbdev class concurrent_set : public concurrent_skip_list<set_traits<Key, Compare, concurrent_geometric_level_generator<32>, Allocator, false>> {
5649e08aacStbbdev using base_type = concurrent_skip_list<set_traits<Key, Compare, concurrent_geometric_level_generator<32>, Allocator, false>>;
5749e08aacStbbdev public:
5849e08aacStbbdev using key_type = Key;
5949e08aacStbbdev using value_type = typename base_type::value_type;
6049e08aacStbbdev using size_type = typename base_type::size_type;
6149e08aacStbbdev using difference_type = typename base_type::difference_type;
6249e08aacStbbdev using key_compare = Compare;
6349e08aacStbbdev using value_compare = typename base_type::value_compare;
6449e08aacStbbdev using allocator_type = Allocator;
6549e08aacStbbdev
6649e08aacStbbdev using reference = typename base_type::reference;
6749e08aacStbbdev using const_reference = typename base_type::const_reference;
6849e08aacStbbdev using pointer = typename base_type::pointer;
6949e08aacStbbdev using const_pointer = typename base_type::const_pointer;
7049e08aacStbbdev
7149e08aacStbbdev using iterator = typename base_type::iterator;
7249e08aacStbbdev using const_iterator = typename base_type::const_iterator;
7349e08aacStbbdev
7449e08aacStbbdev using node_type = typename base_type::node_type;
7549e08aacStbbdev
7649e08aacStbbdev // Include constructors of base_type
7749e08aacStbbdev using base_type::base_type;
7849e08aacStbbdev
79d86ed7fbStbbdev // Required for implicit deduction guides
80d86ed7fbStbbdev concurrent_set() = default;
81d86ed7fbStbbdev concurrent_set( const concurrent_set& ) = default;
concurrent_set(const concurrent_set & other,const allocator_type & alloc)82d86ed7fbStbbdev concurrent_set( const concurrent_set& other, const allocator_type& alloc ) : base_type(other, alloc) {}
83d86ed7fbStbbdev concurrent_set( concurrent_set&& ) = default;
concurrent_set(concurrent_set && other,const allocator_type & alloc)84d86ed7fbStbbdev concurrent_set( concurrent_set&& other, const allocator_type& alloc ) : base_type(std::move(other), alloc) {}
85d86ed7fbStbbdev // Required to respect the rule of 5
86d86ed7fbStbbdev concurrent_set& operator=( const concurrent_set& ) = default;
87d86ed7fbStbbdev concurrent_set& operator=( concurrent_set&& ) = default;
88d86ed7fbStbbdev
89*2713d41eSIlya Isaev concurrent_set& operator=( std::initializer_list<value_type> il ) {
90*2713d41eSIlya Isaev base_type::operator= (il);
91*2713d41eSIlya Isaev return *this;
92*2713d41eSIlya Isaev }
93*2713d41eSIlya Isaev
9449e08aacStbbdev template<typename OtherCompare>
merge(concurrent_set<key_type,OtherCompare,Allocator> & source)9549e08aacStbbdev void merge(concurrent_set<key_type, OtherCompare, Allocator>& source) {
9649e08aacStbbdev this->internal_merge(source);
9749e08aacStbbdev }
9849e08aacStbbdev
9949e08aacStbbdev template<typename OtherCompare>
merge(concurrent_set<key_type,OtherCompare,Allocator> && source)10049e08aacStbbdev void merge(concurrent_set<key_type, OtherCompare, Allocator>&& source) {
10149e08aacStbbdev this->internal_merge(std::move(source));
10249e08aacStbbdev }
10349e08aacStbbdev
10449e08aacStbbdev template<typename OtherCompare>
merge(concurrent_multiset<key_type,OtherCompare,Allocator> & source)10549e08aacStbbdev void merge(concurrent_multiset<key_type, OtherCompare, Allocator>& source) {
10649e08aacStbbdev this->internal_merge(source);
10749e08aacStbbdev }
10849e08aacStbbdev
10949e08aacStbbdev template<typename OtherCompare>
merge(concurrent_multiset<key_type,OtherCompare,Allocator> && source)11049e08aacStbbdev void merge(concurrent_multiset<key_type, OtherCompare, Allocator>&& source) {
11149e08aacStbbdev this->internal_merge(std::move(source));
11249e08aacStbbdev }
11349e08aacStbbdev }; // class concurrent_set
11449e08aacStbbdev
11549e08aacStbbdev #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
11649e08aacStbbdev
117d86ed7fbStbbdev template <typename It,
118d86ed7fbStbbdev typename Comp = std::less<iterator_value_t<It>>,
119d86ed7fbStbbdev typename Alloc = tbb::tbb_allocator<iterator_value_t<It>>,
120d86ed7fbStbbdev typename = std::enable_if_t<is_input_iterator_v<It>>,
121d86ed7fbStbbdev typename = std::enable_if_t<is_allocator_v<Alloc>>,
122d86ed7fbStbbdev typename = std::enable_if_t<!is_allocator_v<Comp>>>
123d86ed7fbStbbdev concurrent_set( It, It, Comp = Comp(), Alloc = Alloc() )
124d86ed7fbStbbdev -> concurrent_set<iterator_value_t<It>, Comp, Alloc>;
12549e08aacStbbdev
126d86ed7fbStbbdev template <typename Key,
127d86ed7fbStbbdev typename Comp = std::less<Key>,
128d86ed7fbStbbdev typename Alloc = tbb::tbb_allocator<Key>,
129d86ed7fbStbbdev typename = std::enable_if_t<is_allocator_v<Alloc>>,
130d86ed7fbStbbdev typename = std::enable_if_t<!is_allocator_v<Comp>>>
131d86ed7fbStbbdev concurrent_set( std::initializer_list<Key>, Comp = Comp(), Alloc = Alloc() )
132d86ed7fbStbbdev -> concurrent_set<Key, Comp, Alloc>;
13349e08aacStbbdev
134d86ed7fbStbbdev template <typename It, typename Alloc,
135d86ed7fbStbbdev typename = std::enable_if_t<is_input_iterator_v<It>>,
136d86ed7fbStbbdev typename = std::enable_if_t<is_allocator_v<Alloc>>>
137d86ed7fbStbbdev concurrent_set( It, It, Alloc )
138d86ed7fbStbbdev -> concurrent_set<iterator_value_t<It>,
139d86ed7fbStbbdev std::less<iterator_value_t<It>>, Alloc>;
140d86ed7fbStbbdev
141d86ed7fbStbbdev template <typename Key, typename Alloc,
142d86ed7fbStbbdev typename = std::enable_if_t<is_allocator_v<Alloc>>>
143d86ed7fbStbbdev concurrent_set( std::initializer_list<Key>, Alloc )
144d86ed7fbStbbdev -> concurrent_set<Key, std::less<Key>, Alloc>;
14549e08aacStbbdev
14649e08aacStbbdev #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
14749e08aacStbbdev
14849e08aacStbbdev template <typename Key, typename Compare, typename Allocator>
swap(concurrent_set<Key,Compare,Allocator> & lhs,concurrent_set<Key,Compare,Allocator> & rhs)14949e08aacStbbdev void swap( concurrent_set<Key, Compare, Allocator>& lhs,
15049e08aacStbbdev concurrent_set<Key, Compare, Allocator>& rhs )
15149e08aacStbbdev {
15249e08aacStbbdev lhs.swap(rhs);
15349e08aacStbbdev }
15449e08aacStbbdev
15549e08aacStbbdev template <typename Key, typename Compare = std::less<Key>, typename Allocator = tbb::tbb_allocator<Key>>
15649e08aacStbbdev class concurrent_multiset : public concurrent_skip_list<set_traits<Key, Compare, concurrent_geometric_level_generator<32>, Allocator, true>> {
15749e08aacStbbdev using base_type = concurrent_skip_list<set_traits<Key, Compare, concurrent_geometric_level_generator<32>, Allocator, true>>;
15849e08aacStbbdev public:
15949e08aacStbbdev using key_type = Key;
16049e08aacStbbdev using value_type = typename base_type::value_type;
16149e08aacStbbdev using size_type = typename base_type::size_type;
16249e08aacStbbdev using difference_type = typename base_type::difference_type;
16349e08aacStbbdev using key_compare = Compare;
16449e08aacStbbdev using value_compare = typename base_type::value_compare;
16549e08aacStbbdev using allocator_type = Allocator;
16649e08aacStbbdev
16749e08aacStbbdev using reference = typename base_type::reference;
16849e08aacStbbdev using const_reference = typename base_type::const_reference;
16949e08aacStbbdev using pointer = typename base_type::pointer;
17049e08aacStbbdev using const_pointer = typename base_type::const_pointer;
17149e08aacStbbdev
17249e08aacStbbdev using iterator = typename base_type::iterator;
17349e08aacStbbdev using const_iterator = typename base_type::const_iterator;
17449e08aacStbbdev
17549e08aacStbbdev using node_type = typename base_type::node_type;
17649e08aacStbbdev
17749e08aacStbbdev // Include constructors of base_type;
17849e08aacStbbdev using base_type::base_type;
17949e08aacStbbdev
180d86ed7fbStbbdev // Required for implicit deduction guides
181d86ed7fbStbbdev concurrent_multiset() = default;
182d86ed7fbStbbdev concurrent_multiset( const concurrent_multiset& ) = default;
concurrent_multiset(const concurrent_multiset & other,const allocator_type & alloc)183d86ed7fbStbbdev concurrent_multiset( const concurrent_multiset& other, const allocator_type& alloc ) : base_type(other, alloc) {}
184d86ed7fbStbbdev concurrent_multiset( concurrent_multiset&& ) = default;
concurrent_multiset(concurrent_multiset && other,const allocator_type & alloc)185d86ed7fbStbbdev concurrent_multiset( concurrent_multiset&& other, const allocator_type& alloc ) : base_type(std::move(other), alloc) {}
186d86ed7fbStbbdev // Required to respect the rule of 5
187d86ed7fbStbbdev concurrent_multiset& operator=( const concurrent_multiset& ) = default;
188d86ed7fbStbbdev concurrent_multiset& operator=( concurrent_multiset&& ) = default;
189d86ed7fbStbbdev
190*2713d41eSIlya Isaev concurrent_multiset& operator=( std::initializer_list<value_type> il ) {
191*2713d41eSIlya Isaev base_type::operator= (il);
192*2713d41eSIlya Isaev return *this;
193*2713d41eSIlya Isaev }
194*2713d41eSIlya Isaev
19549e08aacStbbdev template<typename OtherCompare>
merge(concurrent_set<key_type,OtherCompare,Allocator> & source)19649e08aacStbbdev void merge(concurrent_set<key_type, OtherCompare, Allocator>& source) {
19749e08aacStbbdev this->internal_merge(source);
19849e08aacStbbdev }
19949e08aacStbbdev
20049e08aacStbbdev template<typename OtherCompare>
merge(concurrent_set<key_type,OtherCompare,Allocator> && source)20149e08aacStbbdev void merge(concurrent_set<key_type, OtherCompare, Allocator>&& source) {
20249e08aacStbbdev this->internal_merge(std::move(source));
20349e08aacStbbdev }
20449e08aacStbbdev
20549e08aacStbbdev template<typename OtherCompare>
merge(concurrent_multiset<key_type,OtherCompare,Allocator> & source)20649e08aacStbbdev void merge(concurrent_multiset<key_type, OtherCompare, Allocator>& source) {
20749e08aacStbbdev this->internal_merge(source);
20849e08aacStbbdev }
20949e08aacStbbdev
21049e08aacStbbdev template<typename OtherCompare>
merge(concurrent_multiset<key_type,OtherCompare,Allocator> && source)21149e08aacStbbdev void merge(concurrent_multiset<key_type, OtherCompare, Allocator>&& source) {
21249e08aacStbbdev this->internal_merge(std::move(source));
21349e08aacStbbdev }
21449e08aacStbbdev }; // class concurrent_multiset
21549e08aacStbbdev
21649e08aacStbbdev #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
21749e08aacStbbdev
218d86ed7fbStbbdev template <typename It,
219d86ed7fbStbbdev typename Comp = std::less<iterator_value_t<It>>,
220d86ed7fbStbbdev typename Alloc = tbb::tbb_allocator<iterator_value_t<It>>,
221d86ed7fbStbbdev typename = std::enable_if_t<is_input_iterator_v<It>>,
222d86ed7fbStbbdev typename = std::enable_if_t<is_allocator_v<Alloc>>,
223d86ed7fbStbbdev typename = std::enable_if_t<!is_allocator_v<Comp>>>
224d86ed7fbStbbdev concurrent_multiset( It, It, Comp = Comp(), Alloc = Alloc() )
225d86ed7fbStbbdev -> concurrent_multiset<iterator_value_t<It>, Comp, Alloc>;
22649e08aacStbbdev
227d86ed7fbStbbdev template <typename Key,
228d86ed7fbStbbdev typename Comp = std::less<Key>,
229d86ed7fbStbbdev typename Alloc = tbb::tbb_allocator<Key>,
230d86ed7fbStbbdev typename = std::enable_if_t<is_allocator_v<Alloc>>,
231d86ed7fbStbbdev typename = std::enable_if_t<!is_allocator_v<Comp>>>
232d86ed7fbStbbdev concurrent_multiset( std::initializer_list<Key>, Comp = Comp(), Alloc = Alloc() )
233d86ed7fbStbbdev -> concurrent_multiset<Key, Comp, Alloc>;
234d86ed7fbStbbdev
235d86ed7fbStbbdev template <typename It, typename Alloc,
236d86ed7fbStbbdev typename = std::enable_if_t<is_input_iterator_v<It>>,
237d86ed7fbStbbdev typename = std::enable_if_t<is_allocator_v<Alloc>>>
238d86ed7fbStbbdev concurrent_multiset( It, It, Alloc )
239d86ed7fbStbbdev -> concurrent_multiset<iterator_value_t<It>, std::less<iterator_value_t<It>>, Alloc>;
240d86ed7fbStbbdev
241d86ed7fbStbbdev template <typename Key, typename Alloc,
242d86ed7fbStbbdev typename = std::enable_if_t<is_allocator_v<Alloc>>>
243d86ed7fbStbbdev concurrent_multiset( std::initializer_list<Key>, Alloc )
244d86ed7fbStbbdev -> concurrent_multiset<Key, std::less<Key>, Alloc>;
24549e08aacStbbdev
24649e08aacStbbdev #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
24749e08aacStbbdev
24849e08aacStbbdev template <typename Key, typename Compare, typename Allocator>
swap(concurrent_multiset<Key,Compare,Allocator> & lhs,concurrent_multiset<Key,Compare,Allocator> & rhs)24949e08aacStbbdev void swap( concurrent_multiset<Key, Compare, Allocator>& lhs,
25049e08aacStbbdev concurrent_multiset<Key, Compare, Allocator>& rhs )
25149e08aacStbbdev {
25249e08aacStbbdev lhs.swap(rhs);
25349e08aacStbbdev }
25449e08aacStbbdev
255d8251013SAnton Potapov } // namespace d2
25649e08aacStbbdev } // namespace detail
25749e08aacStbbdev
25849e08aacStbbdev inline namespace v1 {
25949e08aacStbbdev
260d8251013SAnton Potapov using detail::d2::concurrent_set;
261d8251013SAnton Potapov using detail::d2::concurrent_multiset;
26249e08aacStbbdev using detail::split;
26349e08aacStbbdev
26449e08aacStbbdev } // inline namespace v1
26549e08aacStbbdev } // namespace tbb
26649e08aacStbbdev
26749e08aacStbbdev #endif // __TBB_concurrent_set_H
268