VTK  9.5.20250620
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#if VTK_SMP_ENABLE_SEQUENTIAL
59 this->BackendsImpl[static_cast<int>(BackendType::Sequential)] =
60 std::make_unique<ThreadLocalSequential>();
61#endif
62#if VTK_SMP_ENABLE_STDTHREAD
63 this->BackendsImpl[static_cast<int>(BackendType::STDThread)] =
64 std::make_unique<ThreadLocalSTDThread>();
65#endif
66#if VTK_SMP_ENABLE_TBB
67 this->BackendsImpl[static_cast<int>(BackendType::TBB)] = std::make_unique<ThreadLocalTBB>();
68#endif
69#if VTK_SMP_ENABLE_OPENMP
70 this->BackendsImpl[static_cast<int>(BackendType::OpenMP)] =
71 std::make_unique<ThreadLocalOpenMP>();
72#endif
73 }
74
75 //--------------------------------------------------------------------------------
76 explicit vtkSMPThreadLocalAPI(const T& exemplar)
77 {
78#if VTK_SMP_ENABLE_SEQUENTIAL
79 this->BackendsImpl[static_cast<int>(BackendType::Sequential)] =
80 std::make_unique<ThreadLocalSequential>(exemplar);
81#endif
82#if VTK_SMP_ENABLE_STDTHREAD
83 this->BackendsImpl[static_cast<int>(BackendType::STDThread)] =
84 std::make_unique<ThreadLocalSTDThread>(exemplar);
85#endif
86#if VTK_SMP_ENABLE_TBB
87 this->BackendsImpl[static_cast<int>(BackendType::TBB)] =
88 std::make_unique<ThreadLocalTBB>(exemplar);
89#endif
90#if VTK_SMP_ENABLE_OPENMP
91 this->BackendsImpl[static_cast<int>(BackendType::OpenMP)] =
92 std::make_unique<ThreadLocalOpenMP>(exemplar);
93#endif
94 }
95
96 //--------------------------------------------------------------------------------
97 T& Local()
98 {
99 BackendType backendType = this->GetSMPBackendType();
100 return this->BackendsImpl[static_cast<int>(backendType)]->Local();
101 }
102
103 //--------------------------------------------------------------------------------
104 size_t size()
105 {
106 BackendType backendType = this->GetSMPBackendType();
107 return this->BackendsImpl[static_cast<int>(backendType)]->size();
108 }
109
110 //--------------------------------------------------------------------------------
112 {
113 public:
114 using iterator_category = std::forward_iterator_tag;
115 using value_type = T;
116 using difference_type = std::ptrdiff_t;
117 using pointer = T*;
118 using reference = T&;
119
120 iterator() = default;
121
122 iterator(const iterator& other)
123 : ImplAbstract(other.ImplAbstract->Clone())
124 {
125 }
126
128 {
129 if (this != &other)
130 {
131 this->ImplAbstract = other.ImplAbstract->Clone();
132 }
133 return *this;
134 }
135
137 {
138 this->ImplAbstract->Increment();
139 return *this;
140 }
141
143 {
144 iterator copy = *this;
145 this->ImplAbstract->Increment();
146 return copy;
147 }
148
149 bool operator==(const iterator& other) const
150 {
151 return this->ImplAbstract->Compare(other.ImplAbstract.get());
152 }
153
154 bool operator!=(const iterator& other) const
155 {
156 return !this->ImplAbstract->Compare(other.ImplAbstract.get());
157 }
158
159 T& operator*() { return this->ImplAbstract->GetContent(); }
160
161 T* operator->() { return this->ImplAbstract->GetContentPtr(); }
162
163 private:
164 std::unique_ptr<ItImplAbstract> ImplAbstract;
165
166 friend class vtkSMPThreadLocalAPI<T>;
167 };
168
169 //--------------------------------------------------------------------------------
171 {
172 BackendType backendType = this->GetSMPBackendType();
173 iterator iter;
174 iter.ImplAbstract = this->BackendsImpl[static_cast<int>(backendType)]->begin();
175 return iter;
176 }
177
178 //--------------------------------------------------------------------------------
180 {
181 BackendType backendType = this->GetSMPBackendType();
182 iterator iter;
183 iter.ImplAbstract = this->BackendsImpl[static_cast<int>(backendType)]->end();
184 return iter;
185 }
186
187 // disable copying
190
191private:
192 std::array<std::unique_ptr<vtkSMPThreadLocalImplAbstract<T>>, VTK_SMP_MAX_BACKENDS_NB>
193 BackendsImpl;
194
195 //--------------------------------------------------------------------------------
196 BackendType GetSMPBackendType()
197 {
198 auto& SMPToolsAPI = vtkSMPToolsAPI::GetInstance();
199 return SMPToolsAPI.GetBackendType();
200 }
201};
202
203VTK_ABI_NAMESPACE_END
204} // namespace smp
205} // namespace detail
206} // namespace vtk
207
208#endif
209/* 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