VTK  9.3.20231211
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 
29 namespace vtk
30 {
31 namespace detail
32 {
33 namespace smp
34 {
35 VTK_ABI_NAMESPACE_BEGIN
36 
37 template <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 
54 public:
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  //--------------------------------------------------------------------------------
114  class iterator
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 
130  iterator& operator=(const iterator& other)
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)
153  {
154  return this->ImplAbstract->Compare(other.ImplAbstract.get());
155  }
156 
157  bool operator!=(const iterator& other)
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 
194 private:
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 
206 VTK_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