VTK  9.1.0
vtkSMPThreadLocalImpl.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkSMPThreadLocalImpl.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
15 // .NAME vtkSMPThreadLocalImpl - A thread local storage implementation using
16 // platform specific facilities.
17 
18 #ifndef STDThreadvtkSMPThreadLocalImpl_h
19 #define STDThreadvtkSMPThreadLocalImpl_h
20 
23 #include "SMP/STDThread/vtkSMPToolsImpl.txx"
24 
25 #include <iterator>
26 #include <utility> // For std::move
27 
28 namespace vtk
29 {
30 namespace detail
31 {
32 namespace smp
33 {
34 
35 template <typename T>
37 {
39 
40 public:
42  : Backend(GetNumberOfThreadsSTDThread())
43  {
44  }
45 
46  explicit vtkSMPThreadLocalImpl(const T& exemplar)
47  : Backend(GetNumberOfThreadsSTDThread())
48  , Exemplar(exemplar)
49  {
50  }
51 
53  {
55  it.SetThreadSpecificStorage(this->Backend);
56  for (it.SetToBegin(); !it.GetAtEnd(); it.Forward())
57  {
58  delete reinterpret_cast<T*>(it.GetStorage());
59  }
60  }
61 
62  T& Local() override
63  {
64  vtk::detail::smp::STDThread::StoragePointerType& ptr = this->Backend.GetStorage();
65  T* local = reinterpret_cast<T*>(ptr);
66  if (!ptr)
67  {
68  ptr = local = new T(this->Exemplar);
69  }
70  return *local;
71  }
72 
73  size_t size() const override { return this->Backend.GetSize(); }
74 
76  {
77  public:
78  void Increment() override { this->Impl.Forward(); }
79 
80  bool Compare(ItImplAbstract* other) override
81  {
82  return this->Impl == static_cast<ItImpl*>(other)->Impl;
83  }
84 
85  T& GetContent() override { return *reinterpret_cast<T*>(this->Impl.GetStorage()); }
86 
87  T* GetContentPtr() override { return reinterpret_cast<T*>(this->Impl.GetStorage()); }
88 
89  protected:
90  virtual ItImpl* CloneImpl() const override { return new ItImpl(*this); };
91 
92  private:
94 
96  };
97 
98  std::unique_ptr<ItImplAbstract> begin() override
99  {
100  // XXX(c++14): use std::make_unique
101  auto it = std::unique_ptr<ItImpl>(new ItImpl());
102  it->Impl.SetThreadSpecificStorage(this->Backend);
103  it->Impl.SetToBegin();
104  // XXX(c++14): remove std::move and cast variable
105  std::unique_ptr<ItImplAbstract> abstractIt(std::move(it));
106  return abstractIt;
107  }
108 
109  std::unique_ptr<ItImplAbstract> end() override
110  {
111  // XXX(c++14): use std::make_unique
112  auto it = std::unique_ptr<ItImpl>(new ItImpl());
113  it->Impl.SetThreadSpecificStorage(this->Backend);
114  it->Impl.SetToEnd();
115  // XXX(c++14): remove std::move and cast variable
116  std::unique_ptr<ItImplAbstract> abstractIt(std::move(it));
117  return abstractIt;
118  }
119 
120 private:
122  T Exemplar;
123 
124  // disable copying
126  void operator=(const vtkSMPThreadLocalImpl&) = delete;
127 };
128 
129 } // namespace smp
130 } // namespace detail
131 } // namespace vtk
132 
133 #endif
virtual std::unique_ptr< ItImpl > begin()=0
Specialization of tuple ranges and iterators for vtkAOSDataArrayTemplate.