NamedData-inl.h
Go to the documentation of this file.
1 // This file is a part of the OpenSurgSim project.
2 // Copyright 2012-2013, SimQuest Solutions Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #ifndef SURGSIM_DATASTRUCTURES_NAMEDDATA_INL_H
17 #define SURGSIM_DATASTRUCTURES_NAMEDDATA_INL_H
18 
19 #include <type_traits>
20 
23 
24 namespace SurgSim
25 {
26 namespace DataStructures
27 {
28 
29 template <typename T>
31 {
32 }
33 
34 template <typename T>
35 inline NamedData<T>::NamedData(std::shared_ptr<const IndexDirectory> directory) :
36  m_directory(directory)
37 {
39  m_data.resize(m_directory->getNumEntries());
40  m_isDataValid.resize(m_directory->getNumEntries(), false);
41 }
42 
43 template <typename T>
44 inline NamedData<T>::NamedData(const std::vector<std::string>& names) :
45  m_directory(std::make_shared<const IndexDirectory>(names))
46 {
48  m_data.resize(m_directory->getNumEntries());
49  m_isDataValid.resize(m_directory->getNumEntries(), false);
50 }
51 
52 template <typename T>
53 inline NamedData<T>::NamedData(const NamedData& namedData) :
54  m_directory(namedData.m_directory),
55  m_data(namedData.m_data),
56  m_isDataValid(namedData.m_isDataValid)
57 {
59 }
60 
61 template <typename T>
63 {
64  SURGSIM_ASSERT(namedData.isValid()) <<
65  "Cannot use an invalid (empty) NamedData on the right-hand side of an assignment!";
66 
67  if (!isValid())
68  {
69  m_directory = namedData.m_directory;
70  }
71  else
72  {
73  SURGSIM_ASSERT(m_directory == namedData.m_directory) << "Incompatible NamedData contents in assignment!";
74  }
75 
76  m_data = namedData.m_data;
77  m_isDataValid = namedData.m_isDataValid;
78 
79  SURGSIM_ASSERT(isValid()) << "NamedData is not valid after assignment!";
80  SURGSIM_ASSERT(m_data.size() == m_directory->size() && m_isDataValid.size() == m_directory->size()) <<
81  "NamedData is not correctly sized after assignment!";
82 
83  return *this;
84 }
85 
86 template <typename T>
87 inline NamedData<T>::NamedData(NamedData&& namedData) :
88  m_directory(std::move(namedData.m_directory)),
89  m_data(std::move(namedData.m_data)),
90  m_isDataValid(std::move(namedData.m_isDataValid))
91 {
93 }
94 
95 template <typename T>
97 {
98  SURGSIM_ASSERT(namedData.isValid()) <<
99  "Cannot use an invalid (empty) NamedData on the right-hand side of an assignment!";
100 
101  if (!isValid())
102  {
103  m_directory = std::move(namedData.m_directory);
104  }
105  else
106  {
107  SURGSIM_ASSERT(m_directory == namedData.m_directory) << "Incompatible NamedData contents in assignment!";
108  }
109 
110  m_data = std::move(namedData.m_data);
111  m_isDataValid = std::move(namedData.m_isDataValid);
112 
113  SURGSIM_ASSERT(isValid()) << "NamedData is not valid after assignment!";
114  SURGSIM_ASSERT(m_data.size() == m_directory->size() && m_isDataValid.size() == m_directory->size()) <<
115  "NamedData is not correctly sized after assignment!";
116 
117  return *this;
118 }
119 
120 template <typename T>
121 inline bool NamedData<T>::isValid() const
122 {
123  return static_cast<bool>(m_directory);
124 }
125 
126 template <typename T>
127 inline std::shared_ptr<const IndexDirectory> NamedData<T>::getDirectory() const
128 {
129  return m_directory;
130 }
131 
132 template <typename T>
133 inline int NamedData<T>::getIndex(const std::string& name) const
134 {
135  if (! isValid())
136  {
137  return -1;
138  }
139  return m_directory->getIndex(name);
140 }
141 
142 template <typename T>
143 inline std::string NamedData<T>::getName(int index) const
144 {
145  if (! isValid())
146  {
147  return "";
148  }
149  return m_directory->getName(index);
150 }
151 
152 template <typename T>
153 inline bool NamedData<T>::hasEntry(int index) const
154 {
155  return ((index >= 0) && (index < static_cast<int>(m_data.size())));
156 }
157 
158 template <typename T>
159 inline bool NamedData<T>::hasEntry(const std::string& name) const
160 {
161  if (! isValid())
162  {
163  return false;
164  }
165  return m_directory->hasEntry(name);
166 }
167 
168 template <typename T>
169 inline bool NamedData<T>::hasData(int index) const
170 {
171  return hasEntry(index) && m_isDataValid[index];
172 }
173 
174 template <typename T>
175 inline bool NamedData<T>::hasData(const std::string& name) const
176 {
177  if (! isValid())
178  {
179  return false;
180  }
181  int index = m_directory->getIndex(name);
182  if (index < 0)
183  {
184  return false;
185  }
186  else
187  {
188  SURGSIM_ASSERT(hasEntry(index));
189  return m_isDataValid[index];
190  }
191 }
192 
193 template <typename T>
194 inline bool NamedData<T>::get(int index, T* value) const
195 {
196  if (! hasData(index))
197  {
198  return false;
199  }
200  else
201  {
202  *value = m_data[index];
203  return true;
204  }
205 }
206 
207 template <typename T>
208 inline bool NamedData<T>::get(const std::string& name, T* value) const
209 {
210  if (! isValid())
211  {
212  return false;
213  }
214  int index = m_directory->getIndex(name);
215  if ((index < 0) || ! m_isDataValid[index])
216  {
217  return false;
218  }
219  else
220  {
221  SURGSIM_ASSERT(hasEntry(index));
222  *value = m_data[index];
223  return true;
224  }
225 }
226 
227 template <typename T>
228 inline bool NamedData<T>::set(int index, const T& value)
229 {
230  if (! hasEntry(index))
231  {
232  return false;
233  }
234  else
235  {
236  m_data[index] = value;
237  m_isDataValid[index] = true;
238  return true;
239  }
240 }
241 
242 template <typename T>
243 inline bool NamedData<T>::set(const std::string& name, const T& value)
244 {
245  if (! isValid())
246  {
247  return false;
248  }
249  int index = m_directory->getIndex(name);
250  if (index < 0)
251  {
252  return false;
253  }
254  else
255  {
256  SURGSIM_ASSERT(hasEntry(index));
257  m_data[index] = value;
258  m_isDataValid[index] = true;
259  return true;
260  }
261 }
262 
263 template <typename T>
264 inline bool NamedData<T>::reset(int index)
265 {
266  if (! hasEntry(index))
267  {
268  return false;
269  }
270  else
271  {
272  m_isDataValid[index] = false;
273  return true;
274  }
275 }
276 
277 template <typename T>
278 inline bool NamedData<T>::reset(const std::string& name)
279 {
280  if (! isValid())
281  {
282  return false;
283  }
284  int index = m_directory->getIndex(name);
285  if (index < 0)
286  {
287  return false;
288  }
289  else
290  {
291  SURGSIM_ASSERT(hasEntry(index));
292  m_isDataValid[index] = false;
293  return true;
294  }
295 }
296 
297 template <typename T>
299 {
300  m_isDataValid.assign(m_data.size(), false);
301 }
302 
303 template <typename T>
304 inline size_t NamedData<T>::size() const
305 {
306  return m_data.size();
307 }
308 
309 template <typename T>
310 inline int NamedData<T>::getNumEntries() const
311 {
312  return static_cast<int>(m_data.size());
313 }
314 
315 template <typename T>
316 template <typename N>
317 inline void NamedData<T>::copy(const NamedData<N>& source, const NamedDataCopyMap& map)
318 {
319  static_assert(std::is_same<T, N>::value, "NamedData<T>::copy can only copy from another NamedData<T>.");
320  for (auto it = map.cbegin(); it != map.cend(); ++it)
321  {
322  T value;
323  if (source.get(it->first, &value))
324  {
325  set(it->second, value);
326  }
327  else
328  {
329  reset(it->second);
330  }
331  }
332 }
333 
334 template <typename T>
335 void SurgSim::DataStructures::NamedData<T>::cacheIndex(const std::string& name, int* index) const
336 {
337  if (*index < 0)
338  {
339  *index = getIndex(name);
340  }
341 }
342 
343 }; // namespace Input
344 }; // namespace SurgSim
345 
346 #endif // SURGSIM_DATASTRUCTURES_NAMEDDATA_INL_H
Definition: DriveElementFromInputBehavior.cpp:27
A templated dictionary in which data can be accessed by name or index, with immutable names & indices...
Definition: NamedData.h:95
std::vector< T > m_data
The array of values.
Definition: NamedData.h:292
bool hasData(int index) const
Check whether the entry with the specified index contains valid data.
Definition: NamedData-inl.h:169
STL namespace.
bool hasEntry(int index) const
Check whether the object contains an entry with the specified index.
Definition: NamedData-inl.h:153
#define SURGSIM_ASSERT(condition)
Assert that condition is true.
Definition: Assert.h:77
std::shared_ptr< const IndexDirectory > getDirectory() const
Return the object's layout directory, which is its collection of names and indices.
Definition: NamedData-inl.h:127
std::string getName(int index) const
Given an index, return the corresponding name (or "").
Definition: NamedData-inl.h:143
bool set(int index, const T &value)
Record the data for an entry specified by an index.
Definition: NamedData-inl.h:228
int getNumEntries() const
Check the number of existing entries.
Definition: NamedData-inl.h:310
std::unordered_map< int, int > NamedDataCopyMap
The type used for copying values between two NamedData objects that cannot assign to each other...
Definition: NamedData.h:32
bool isValid() const
Check if the object has been initialized, which means it has a set of entries (i.e., names, indices, and the map between them).
Definition: NamedData-inl.h:121
int getIndex(const std::string &name) const
Given a name, return the corresponding index (or -1).
Definition: NamedData-inl.h:133
NamedData & operator=(const NamedData &namedData)
Copy the data from another object.
Definition: NamedData-inl.h:62
std::vector< bool > m_isDataValid
The array storing whether the data is currently valid.
Definition: NamedData.h:295
bool isValid(float value)
Check if a float value is valid.
Definition: Valid-inl.h:98
A simple bidirectional mapping between names (strings) and distinct consecutive non-negative indices...
Definition: IndexDirectory.h:32
void resetAll()
Invalidate all entries— mark everything as not containing any valid data.
Definition: NamedData-inl.h:298
void copy(const NamedData< N > &source, const NamedDataCopyMap &map)
Copy the data from another NamedData, based on a map of indices.
Definition: NamedData-inl.h:317
bool reset(int index)
Invalidate an entry— mark it as not containing any valid data.
Definition: NamedData-inl.h:264
The header that provides the assertion API.
void cacheIndex(const std::string &name, int *index) const
Caches an entry's index if it is not already cached.
Definition: NamedData-inl.h:335
std::shared_ptr< const IndexDirectory > m_directory
The mapping between names and indices.
Definition: NamedData.h:289
NamedData()
Create an empty object, with no associated names and indices yet.
Definition: NamedData-inl.h:30
bool get(int index, T *value) const
Given an index, get the corresponding value.
Definition: NamedData-inl.h:194
size_t size() const
Check the number of existing entries.
Definition: NamedData-inl.h:304