VTK  9.4.20241016
vtkSMPThreadLocalAPI.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2// SPDX-License-Identifier: BSD-3-Clause
3
4#ifndef vtkSMPThreadLocalAPI_h
5#define vtkSMPThreadLocalAPI_h
6
7#include <array>
8#include <iterator>
9#include <memory>
10
12#include "SMP/Common/vtkSMPToolsAPI.h" // For GetBackendType(), DefaultBackend
13#include "vtkSMP.h"
14#include "vtkSystemIncludes.h"
15
16#if VTK_SMP_ENABLE_SEQUENTIAL
18#endif
19#if VTK_SMP_ENABLE_STDTHREAD
21#endif
22#if VTK_SMP_ENABLE_TBB
24#endif
25#if VTK_SMP_ENABLE_OPENMP
27#endif
28
29namespace vtk
30{
31namespace detail
32{
33namespace smp
34{
35VTK_ABI_NAMESPACE_BEGIN
36
37template <typename T>
39{
40#if VTK_SMP_ENABLE_SEQUENTIAL
41 using ThreadLocalSequential = vtkSMPThreadLocalImpl<BackendType::Sequential, T>;
42#endif
43#if VTK_SMP_ENABLE_STDTHREAD
44 using ThreadLocalSTDThread = vtkSMPThreadLocalImpl<BackendType::STDThread, T>;
45#endif
46#if VTK_SMP_ENABLE_TBB
47 using ThreadLocalTBB = vtkSMPThreadLocalImpl<BackendType::TBB, T>;
48#endif
49#if VTK_SMP_ENABLE_OPENMP
50 using ThreadLocalOpenMP = vtkSMPThreadLocalImpl<BackendType::OpenMP, T>;
51#endif
53
54public:
55 //--------------------------------------------------------------------------------
57 {
58 // XXX(c++14): use std::make_unique
59#if VTK_SMP_ENABLE_SEQUENTIAL
60 this->BackendsImpl[static_cast<int>(BackendType::Sequential)] =
61 std::unique_ptr<ThreadLocalSequential>(new ThreadLocalSequential());
62#endif
63#if VTK_SMP_ENABLE_STDTHREAD
64 this->BackendsImpl[static_cast<int>(BackendType::STDThread)] =
65 std::unique_ptr<ThreadLocalSTDThread>(new ThreadLocalSTDThread());
66#endif
67#if VTK_SMP_ENABLE_TBB
68 this->BackendsImpl[static_cast<int>(BackendType::TBB)] =
69 std::unique_ptr<ThreadLocalTBB>(new ThreadLocalTBB());
70#endif
71#if VTK_SMP_ENABLE_OPENMP
72 this->BackendsImpl[static_cast<int>(BackendType::OpenMP)] =
73 std::unique_ptr<ThreadLocalOpenMP>(new ThreadLocalOpenMP());
74#endif
75 }
76
77 //--------------------------------------------------------------------------------
78 explicit vtkSMPThreadLocalAPI(const T& exemplar)
79 {
80 // XXX(c++14): use std::make_unique
81#if VTK_SMP_ENABLE_SEQUENTIAL
82 this->BackendsImpl[static_cast<int>(BackendType::Sequential)] =
83 std::unique_ptr<ThreadLocalSequential>(new ThreadLocalSequential(exemplar));
84#endif
85#if VTK_SMP_ENABLE_STDTHREAD
86 this->BackendsImpl[static_cast<int>(BackendType::STDThread)] =
87 std::unique_ptr<ThreadLocalSTDThread>(new ThreadLocalSTDThread(exemplar));
88#endif
89#if VTK_SMP_ENABLE_TBB
90 this->BackendsImpl[static_cast<int>(BackendType::TBB)] =
91 std::unique_ptr<ThreadLocalTBB>(new ThreadLocalTBB(exemplar));
92#endif
93#if VTK_SMP_ENABLE_OPENMP
94 this->BackendsImpl[static_cast<int>(BackendType::OpenMP)] =
95 std::unique_ptr<ThreadLocalOpenMP>(new ThreadLocalOpenMP(exemplar));
96#endif
97 }
98
99 //--------------------------------------------------------------------------------
100 T& Local()
101 {
102 BackendType backendType = this->GetSMPBackendType();
103 return this->BackendsImpl[static_cast<int>(backendType)]->Local();
104 }
105
106 //--------------------------------------------------------------------------------
107 size_t size()
108 {
109 BackendType backendType = this->GetSMPBackendType();
110 return this->BackendsImpl[static_cast<int>(backendType)]->size();
111 }
112
113 //--------------------------------------------------------------------------------
115 {
116 public:
117 using iterator_category = std::forward_iterator_tag;
118 using value_type = T;
119 using difference_type = std::ptrdiff_t;
120 using pointer = T*;
121 using reference = T&;
122
123 iterator() = default;
124
125 iterator(const iterator& other)
126 : ImplAbstract(other.ImplAbstract->Clone())
127 {
128 }
129
131 {
132 if (this != &other)
133 {
134 this->ImplAbstract = other.ImplAbstract->Clone();
135 }
136 return *this;
137 }
138
140 {
141 this->ImplAbstract->Increment();
142 return *this;
143 }
144
146 {
147 iterator copy = *this;
148 this->ImplAbstract->Increment();
149 return copy;
150 }
151
152 bool operator==(const iterator& other) const
153 {
154 return this->ImplAbstract->Compare(other.ImplAbstract.get());
155 }
156
157 bool operator!=(const iterator& other) const
158 {
159 return !this->ImplAbstract->Compare(other.ImplAbstract.get());
160 }
161
162 T& operator*() { return this->ImplAbstract->GetContent(); }
163
164 T* operator->() { return this->ImplAbstract->GetContentPtr(); }
165
166 private:
167 std::unique_ptr<ItImplAbstract> ImplAbstract;
168
169 friend class vtkSMPThreadLocalAPI<T>;
170 };
171
172 //--------------------------------------------------------------------------------
174 {
175 BackendType backendType = this->GetSMPBackendType();
176 iterator iter;
177 iter.ImplAbstract = this->BackendsImpl[static_cast<int>(backendType)]->begin();
178 return iter;
179 }
180
181 //--------------------------------------------------------------------------------
183 {
184 BackendType backendType = this->GetSMPBackendType();
185 iterator iter;
186 iter.ImplAbstract = this->BackendsImpl[static_cast<int>(backendType)]->end();
187 return iter;
188 }
189
190 // disable copying
193
194private:
195 std::array<std::unique_ptr<vtkSMPThreadLocalImplAbstract<T>>, VTK_SMP_MAX_BACKENDS_NB>
196 BackendsImpl;
197
198 //--------------------------------------------------------------------------------
199 BackendType GetSMPBackendType()
200 {
201 auto& SMPToolsAPI = vtkSMPToolsAPI::GetInstance();
202 return SMPToolsAPI.GetBackendType();
203 }
204};
205
206VTK_ABI_NAMESPACE_END
207} // namespace smp
208} // namespace detail
209} // namespace vtk
210
211#endif
212/* VTK-HeaderTest-Exclude: vtkSMPThreadLocalAPI.h */
vtkSMPThreadLocalAPI & operator=(const vtkSMPThreadLocalAPI &)=delete
vtkSMPThreadLocalAPI(const vtkSMPThreadLocalAPI &)=delete
static vtkSMPToolsAPI & GetInstance()
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.
#define VTK_SMP_MAX_BACKENDS_NB