| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304 |
- /*
- 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_set_H
- #define __TBB_concurrent_set_H
- #define __TBB_concurrent_set_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_set.h
- #endif
- #include "tbb/tbb_config.h"
- // concurrent_set requires C++11 support
- #if __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT
- #include "internal/_concurrent_skip_list_impl.h"
- namespace tbb {
- namespace interface10 {
- // TODO: test this class
- template<typename Key, typename KeyCompare, typename RandomGenerator, size_t MAX_LEVELS, typename Allocator, bool AllowMultimapping>
- class set_traits {
- public:
- static constexpr size_t MAX_LEVEL = MAX_LEVELS;
- using random_level_generator_type = RandomGenerator;
- using key_type = Key;
- using value_type = key_type;
- using compare_type = KeyCompare;
- using value_compare = compare_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;
- static const key_type& get_key(const_reference val) {
- return val;
- }
- static value_compare value_comp(compare_type comp) { return comp; }
- };
- template <typename Key, typename Comp, typename Allocator>
- class concurrent_multiset;
- template <typename Key, typename Comp = std::less<Key>, typename Allocator = tbb_allocator<Key>>
- class concurrent_set
- : public internal::concurrent_skip_list<set_traits<Key, Comp, internal::concurrent_geometric_level_generator<64>, 64, Allocator, false>> {
- using traits_type = set_traits<Key, 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 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::insert;
- concurrent_set() = default;
- explicit concurrent_set(const key_compare& comp, const allocator_type& alloc = allocator_type()) : base_type(comp, alloc) {}
- explicit concurrent_set(const allocator_type& alloc) : base_type(key_compare(), alloc) {}
- template< class InputIt >
- concurrent_set(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_set(InputIt first, InputIt last, const allocator_type& alloc) : base_type(first, last, key_compare(), alloc) {}
- /** Copy constructor */
- concurrent_set(const concurrent_set&) = default;
- concurrent_set(const concurrent_set& other, const allocator_type& alloc) : base_type(other, alloc) {}
- concurrent_set(concurrent_set&&) = default;
- concurrent_set(concurrent_set&& other, const allocator_type& alloc) : base_type(std::move(other), alloc) {}
- concurrent_set(std::initializer_list<value_type> init, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type())
- : base_type(comp, alloc) {
- insert(init);
- }
- concurrent_set(std::initializer_list<value_type> init, const allocator_type& alloc)
- : base_type(key_compare(), alloc) {
- insert(init);
- }
- concurrent_set& operator=(const concurrent_set& other) {
- return static_cast<concurrent_set&>(base_type::operator=(other));
- }
- concurrent_set& operator=(concurrent_set&& other) {
- return static_cast<concurrent_set&>(base_type::operator=(std::move(other)));
- }
- template<typename C2>
- void merge(concurrent_set<key_type, C2, Allocator>& source) {
- this->internal_merge(source);
- }
- template<typename C2>
- void merge(concurrent_set<key_type, C2, Allocator>&& source) {
- this->internal_merge(std::move(source));
- }
- template<typename C2>
- void merge(concurrent_multiset<key_type, C2, Allocator>& source) {
- this->internal_merge(source);
- }
- template<typename C2>
- void merge(concurrent_multiset<key_type, C2, Allocator>&& source) {
- this->internal_merge(std::move(source));
- }
- }; // class concurrent_set
- #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
- namespace internal {
- using namespace tbb::internal;
- template<template<typename...> typename Set, typename Key, typename... Args>
- using c_set_t = Set<Key,
- 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<Key> > >;
- } // namespace internal
- template<typename It, typename... Args>
- concurrent_set(It, It, Args...)
- -> internal::c_set_t<concurrent_set, internal::iterator_value_t<It>, Args...>;
- template<typename Key, typename... Args>
- concurrent_set(std::initializer_list<Key>, Args...)
- -> internal::c_set_t<concurrent_set, Key, Args...>;
- #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
- template <typename Key, typename Comp = std::less<Key>, typename Allocator = tbb_allocator<Key>>
- class concurrent_multiset
- : public internal::concurrent_skip_list<set_traits<Key, Comp, internal::concurrent_geometric_level_generator<64>, 64, Allocator, true>> {
- using traits_type = set_traits<Key, 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 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::insert;
- concurrent_multiset() = default;
- explicit concurrent_multiset(const key_compare& comp, const allocator_type& alloc = allocator_type()) : base_type(comp, alloc) {}
- explicit concurrent_multiset(const allocator_type& alloc) : base_type(key_compare(), alloc) {}
- template< class InputIt >
- concurrent_multiset(InputIt first, InputIt last, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type())
- : base_type(comp, alloc) {
- insert(first, last);
- }
- template< class InputIt >
- concurrent_multiset(InputIt first, InputIt last, const allocator_type& alloc) : base_type(key_compare(), alloc) {
- insert(first, last);
- }
- /** Copy constructor */
- concurrent_multiset(const concurrent_multiset&) = default;
- concurrent_multiset(const concurrent_multiset& other, const allocator_type& alloc) : base_type(other, alloc) {}
- concurrent_multiset(concurrent_multiset&&) = default;
- concurrent_multiset(concurrent_multiset&& other, const allocator_type& alloc) : base_type(std::move(other), alloc) {}
- concurrent_multiset(std::initializer_list<value_type> init, const key_compare& comp = Comp(), const allocator_type& alloc = allocator_type())
- : base_type(comp, alloc) {
- insert(init);
- }
- concurrent_multiset(std::initializer_list<value_type> init, const allocator_type& alloc)
- : base_type(key_compare(), alloc) {
- insert(init);
- }
- concurrent_multiset& operator=(const concurrent_multiset& other) {
- return static_cast<concurrent_multiset&>(base_type::operator=(other));
- }
- concurrent_multiset& operator=(concurrent_multiset&& other) {
- return static_cast<concurrent_multiset&>(base_type::operator=(std::move(other)));
- }
- template<typename C2>
- void merge(concurrent_set<key_type, C2, Allocator>& source) {
- this->internal_merge(source);
- }
- template<typename C2>
- void merge(concurrent_set<key_type, C2, Allocator>&& source) {
- this->internal_merge(std::move(source));
- }
- template<typename C2>
- void merge(concurrent_multiset<key_type, C2, Allocator>& source) {
- this->internal_merge(source);
- }
- template<typename C2>
- void merge(concurrent_multiset<key_type, C2, Allocator>&& source) {
- this->internal_merge(std::move(source));
- }
- }; // class concurrent_multiset
- #if __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
- template<typename It, typename... Args>
- concurrent_multiset(It, It, Args...)
- -> internal::c_set_t<concurrent_multiset, internal::iterator_value_t<It>, Args...>;
- template<typename Key, typename... Args>
- concurrent_multiset(std::initializer_list<Key>, Args...)
- -> internal::c_set_t<concurrent_multiset, Key, Args...>;
- #endif // __TBB_CPP17_DEDUCTION_GUIDES_PRESENT
- } // namespace interface10
- using interface10::concurrent_set;
- using interface10::concurrent_multiset;
- } // namespace tbb
- #endif // __TBB_CONCURRENT_ORDERED_CONTAINERS_PRESENT
- #include "internal/_warning_suppress_disable_notice.h"
- #undef __TBB_concurrent_set_H_include_area
- #endif // __TBB_concurrent_set_H
|