WPILibC++  2018.4.1-20180819203220-1159-g83cfb8b
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
NotifyListenerVector.h
1 /*----------------------------------------------------------------------------*/
2 /* Copyright (c) 2017-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 #pragma once
9 
10 #ifndef __FRC_ROBORIO__
11 
12 #include <memory>
13 
14 #include <wpi/SmallVector.h>
15 
16 #include "NotifyListener.h"
17 
18 namespace hal {
19 // Vector which provides an integrated freelist for removal and reuse of
20 // individual elements.
21 
22 template <typename ListenerType>
24  struct private_init {};
25 
26  public:
27  typedef typename wpi::SmallVectorImpl<
28  HalCallbackListener<ListenerType>>::size_type size_type;
29 
30  // Constructor for creating copies of the vector
32  const private_init&);
33 
34  // Delete all default constructors so they cannot be used
36  const HalCallbackListenerVectorImpl&) = delete;
39 
40  // Create a new vector with a single callback inside of it
41  HalCallbackListenerVectorImpl(void* param, ListenerType callback,
42  unsigned int* newUid) {
43  *newUid = emplace_back_impl(param, callback);
44  }
45 
46  size_type size() const { return m_vector.size(); }
47  HalCallbackListener<ListenerType>& operator[](size_type i) {
48  return m_vector[i];
49  }
50  const HalCallbackListener<ListenerType>& operator[](size_type i) const {
51  return m_vector[i];
52  }
53 
54  // Add a new NotifyListener to a copy of the vector. If there are elements on
55  // the freelist,
56  // reuses the last one; otherwise adds to the end of the vector.
57  // Returns the resulting element index (+1).
58  std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>> emplace_back(
59  void* param, ListenerType callback, unsigned int* newUid);
60 
61  // Removes the identified element by replacing it with a default-constructed
62  // one. The element is added to the freelist for later reuse. Returns a copy
63  std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>> erase(
64  unsigned int uid);
65 
66  private:
69 
70  // Add a new NotifyListener to the vector. If there are elements on the
71  // freelist,
72  // reuses the last one; otherwise adds to the end of the vector.
73  // Returns the resulting element index (+1).
74  unsigned int emplace_back_impl(void* param, ListenerType callback);
75 
76  // Removes the identified element by replacing it with a default-constructed
77  // one. The element is added to the freelist for later reuse.
78  void erase_impl(unsigned int uid);
79 };
80 
81 template <typename ListenerType>
84  const private_init&)
85  : m_vector(copyFrom->m_vector), m_free(copyFrom->m_free) {}
86 
87 template <typename ListenerType>
88 std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>>
89 HalCallbackListenerVectorImpl<ListenerType>::emplace_back(
90  void* param, ListenerType callback, unsigned int* newUid) {
91  auto newVector =
92  std::make_shared<HalCallbackListenerVectorImpl<ListenerType>>(
93  this, private_init());
94  newVector->m_vector = m_vector;
95  newVector->m_free = m_free;
96  *newUid = newVector->emplace_back_impl(param, callback);
97  return newVector;
98 }
99 
100 template <typename ListenerType>
101 std::shared_ptr<HalCallbackListenerVectorImpl<ListenerType>>
102 HalCallbackListenerVectorImpl<ListenerType>::erase(unsigned int uid) {
103  auto newVector =
104  std::make_shared<HalCallbackListenerVectorImpl<ListenerType>>(
105  this, private_init());
106  newVector->m_vector = m_vector;
107  newVector->m_free = m_free;
108  newVector->erase_impl(uid);
109  return newVector;
110 }
111 
112 template <typename ListenerType>
113 unsigned int HalCallbackListenerVectorImpl<ListenerType>::emplace_back_impl(
114  void* param, ListenerType callback) {
115  unsigned int uid;
116  if (m_free.empty()) {
117  uid = m_vector.size();
118  m_vector.emplace_back(param, callback);
119  } else {
120  uid = m_free.back();
121  m_free.pop_back();
122  m_vector[uid] = HalCallbackListener<ListenerType>(param, callback);
123  }
124  return uid + 1;
125 }
126 
127 template <typename ListenerType>
128 void HalCallbackListenerVectorImpl<ListenerType>::erase_impl(unsigned int uid) {
129  --uid;
130  if (uid >= m_vector.size() || !m_vector[uid]) return;
131  m_free.push_back(uid);
132  m_vector[uid] = HalCallbackListener<ListenerType>();
133 }
134 
135 typedef HalCallbackListenerVectorImpl<HAL_NotifyCallback> NotifyListenerVector;
136 typedef HalCallbackListenerVectorImpl<HAL_BufferCallback> BufferListenerVector;
137 typedef HalCallbackListenerVectorImpl<HAL_ConstBufferCallback>
138  ConstBufferListenerVector;
139 
140 } // namespace hal
141 
142 #endif
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: hostname.h:17
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:868
WPILib Hardware Abstraction Layer (HAL) namespace.
Definition: NotifyListenerVector.h:18
Definition: NotifyListenerVector.h:23
Definition: NotifyListener.h:27