WPILibC++  unspecified
UnlimitedHandleResource.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2016-2018 FIRST. All Rights Reserved. */
3 /* Open Source Software - may be modified and shared by FRC teams. The code */
4 /* must be accompanied by the FIRST BSD license file in the root directory of */
5 /* the project. */
6 /*----------------------------------------------------------------------------*/
7 
8 #ifndef CSCORE_UNLIMITEDHANDLERESOURCE_H_
9 #define CSCORE_UNLIMITEDHANDLERESOURCE_H_
10 
11 #include <memory>
12 #include <utility>
13 #include <vector>
14 
15 #include <wpi/ArrayRef.h>
16 #include <wpi/SmallVector.h>
17 #include <wpi/mutex.h>
18 
19 namespace cs {
20 
21 // The UnlimitedHandleResource class is a way to track handles. This version
22 // allows an unlimted number of handles that are allocated sequentially. When
23 // possible, indices are reused to save memory usage and keep the array length
24 // down.
25 // However, automatic array management has not been implemented, but might be in
26 // the future.
27 // Because we have to loop through the allocator, we must use a global mutex.
28 //
29 // THandle needs to have the following attributes:
30 // Type : enum or typedef
31 // kIndexMax : static, constexpr, or enum value for the maximum index value
32 // int GetTypedIndex() const : function that returns the index of the handle
33 // THandle(int index, HandleType[int] type) : constructor for index and type
34 //
35 // @tparam THandle The Handle Type
36 // @tparam TStruct The struct type held by this resource
37 // @tparam typeValue The type value stored in the handle
38 // @tparam TMutex The mutex type to use
39 template <typename THandle, typename TStruct, int typeValue,
40  typename TMutex = wpi::mutex>
42  public:
44  UnlimitedHandleResource operator=(const UnlimitedHandleResource&) = delete;
45  UnlimitedHandleResource() = default;
46 
47  template <typename... Args>
48  THandle Allocate(Args&&... args);
49  THandle Allocate(std::shared_ptr<THandle> structure);
50 
51  std::shared_ptr<TStruct> Get(THandle handle);
52 
53  void Free(THandle handle);
54 
55  template <typename T>
57 
58  // @param func functor with (THandle, const TStruct&) parameters
59  template <typename F>
60  void ForEach(F func);
61 
62  // @pram func functor with (const TStruct&) parameter and bool return value
63  template <typename F>
64  std::pair<THandle, std::shared_ptr<TStruct>> FindIf(F func);
65 
66  private:
67  THandle MakeHandle(size_t i) {
68  return THandle{static_cast<int>(i),
69  static_cast<typename THandle::Type>(typeValue)};
70  }
71  std::vector<std::shared_ptr<TStruct>> m_structures;
72  TMutex m_handleMutex;
73 };
74 
75 template <typename THandle, typename TStruct, int typeValue, typename TMutex>
76 template <typename... Args>
78  Args&&... args) {
79  std::lock_guard<TMutex> sync(m_handleMutex);
80  size_t i;
81  for (i = 0; i < m_structures.size(); i++) {
82  if (m_structures[i] == nullptr) {
83  m_structures[i] = std::make_shared<TStruct>(std::forward<Args>(args)...);
84  return MakeHandle(i);
85  }
86  }
87  if (i >= THandle::kIndexMax) return 0;
88 
89  m_structures.emplace_back(
90  std::make_shared<TStruct>(std::forward<Args>(args)...));
91  return MakeHandle(i);
92 }
93 
94 template <typename THandle, typename TStruct, int typeValue, typename TMutex>
96  std::shared_ptr<THandle> structure) {
97  std::lock_guard<TMutex> sync(m_handleMutex);
98  size_t i;
99  for (i = 0; i < m_structures.size(); i++) {
100  if (m_structures[i] == nullptr) {
101  m_structures[i] = structure;
102  return MakeHandle(i);
103  }
104  }
105  if (i >= THandle::kIndexMax) return 0;
106 
107  m_structures.push_back(structure);
108  return MakeHandle(i);
109 }
110 
111 template <typename THandle, typename TStruct, int typeValue, typename TMutex>
112 inline std::shared_ptr<TStruct>
114  THandle handle) {
115  auto index =
116  handle.GetTypedIndex(static_cast<typename THandle::Type>(typeValue));
117  if (index < 0) return nullptr;
118  std::lock_guard<TMutex> sync(m_handleMutex);
119  if (index >= static_cast<int>(m_structures.size())) return nullptr;
120  return m_structures[index];
121 }
122 
123 template <typename THandle, typename TStruct, int typeValue, typename TMutex>
125  THandle handle) {
126  auto index =
127  handle.GetTypedIndex(static_cast<typename THandle::Type>(typeValue));
128  if (index < 0) return;
129  std::lock_guard<TMutex> sync(m_handleMutex);
130  if (index >= static_cast<int>(m_structures.size())) return;
131  m_structures[index].reset();
132 }
133 
134 template <typename THandle, typename TStruct, int typeValue, typename TMutex>
135 template <typename T>
136 inline wpi::ArrayRef<T>
139  ForEach([&](THandle handle, const TStruct& data) { vec.push_back(handle); });
140  return vec;
141 }
142 
143 template <typename THandle, typename TStruct, int typeValue, typename TMutex>
144 template <typename F>
145 inline void
147  std::lock_guard<TMutex> sync(m_handleMutex);
148  for (size_t i = 0; i < m_structures.size(); i++) {
149  if (m_structures[i] != nullptr) func(MakeHandle(i), *(m_structures[i]));
150  }
151 }
152 
153 template <typename THandle, typename TStruct, int typeValue, typename TMutex>
154 template <typename F>
155 inline std::pair<THandle, std::shared_ptr<TStruct>>
157  std::lock_guard<TMutex> sync(m_handleMutex);
158  for (size_t i = 0; i < m_structures.size(); i++) {
159  auto& structure = m_structures[i];
160  if (structure != nullptr && func(*structure))
161  return std::make_pair(MakeHandle(i), structure);
162  }
163  return std::make_pair(0, nullptr);
164 }
165 
166 template <typename THandle, typename TStruct, int typeValue,
167  typename TMutex = wpi::mutex>
169  : public UnlimitedHandleResource<THandle, TStruct, typeValue, TMutex> {
170  public:
171  static StaticUnlimitedHandleResource& GetInstance() {
172  static StaticUnlimitedHandleResource instance;
173  return instance;
174  }
175 
176  private:
177  StaticUnlimitedHandleResource() = default;
178 };
179 
180 } // namespace cs
181 
182 #endif // CSCORE_UNLIMITEDHANDLERESOURCE_H_
Definition: CvSourceImpl.h:19
Definition: UnlimitedHandleResource.h:168
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: ArrayRef.h:41
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: WindowsSupport.h:184
Definition: UnlimitedHandleResource.h:41