xref: /oneTBB/include/oneapi/tbb/combinable.h (revision b15aabb3)
149e08aacStbbdev /*
2*b15aabb3Stbbdev     Copyright (c) 2005-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_combinable_H
1849e08aacStbbdev #define __TBB_combinable_H
1949e08aacStbbdev 
2049e08aacStbbdev #include "detail/_namespace_injection.h"
2149e08aacStbbdev 
2249e08aacStbbdev #include "enumerable_thread_specific.h"
2349e08aacStbbdev #include "cache_aligned_allocator.h"
2449e08aacStbbdev 
2549e08aacStbbdev namespace tbb {
2649e08aacStbbdev namespace detail {
2749e08aacStbbdev namespace d1 {
2849e08aacStbbdev /** \name combinable **/
2949e08aacStbbdev //@{
3049e08aacStbbdev //! Thread-local storage with optional reduction
3149e08aacStbbdev /** @ingroup containers */
3249e08aacStbbdev template <typename T>
3349e08aacStbbdev class combinable {
3449e08aacStbbdev     using my_alloc = typename tbb::cache_aligned_allocator<T>;
3549e08aacStbbdev     using my_ets_type = typename tbb::enumerable_thread_specific<T, my_alloc, ets_no_key>;
3649e08aacStbbdev     my_ets_type my_ets;
3749e08aacStbbdev 
3849e08aacStbbdev public:
3949e08aacStbbdev     combinable() = default;
4049e08aacStbbdev 
4149e08aacStbbdev     template <typename Finit>
combinable(Finit _finit)4249e08aacStbbdev     explicit combinable(Finit _finit) : my_ets(_finit) { }
4349e08aacStbbdev 
clear()4449e08aacStbbdev     void clear() { my_ets.clear(); }
4549e08aacStbbdev 
local()4649e08aacStbbdev     T& local() { return my_ets.local(); }
4749e08aacStbbdev 
local(bool & exists)4849e08aacStbbdev     T& local(bool& exists) { return my_ets.local(exists); }
4949e08aacStbbdev 
5049e08aacStbbdev     // combine_func_t has signature T(T,T) or T(const T&, const T&)
5149e08aacStbbdev     template <typename CombineFunc>
combine(CombineFunc f_combine)5249e08aacStbbdev     T combine(CombineFunc f_combine) { return my_ets.combine(f_combine); }
5349e08aacStbbdev 
5449e08aacStbbdev     // combine_func_t has signature void(T) or void(const T&)
5549e08aacStbbdev     template <typename CombineFunc>
combine_each(CombineFunc f_combine)5649e08aacStbbdev     void combine_each(CombineFunc f_combine) { my_ets.combine_each(f_combine); }
5749e08aacStbbdev };
5849e08aacStbbdev 
5949e08aacStbbdev } // namespace d1
6049e08aacStbbdev } // namespace detail
6149e08aacStbbdev 
6249e08aacStbbdev inline namespace v1 {
6349e08aacStbbdev using detail::d1::combinable;
6449e08aacStbbdev } // inline namespace v1
6549e08aacStbbdev 
6649e08aacStbbdev } // namespace tbb
6749e08aacStbbdev 
6849e08aacStbbdev #endif /* __TBB_combinable_H */
6949e08aacStbbdev 
70