SMTK  @SMTK_VERSION@
Simulation Modeling Tool Kit
ValueItemDefinitionTemplate.h
1 //=========================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //=========================================================================
10 // .NAME ValueItemDefinitionTemplate.h -
11 // .SECTION Description
12 // .SECTION See Also
13 
14 #ifndef smtk_attribute_ValueItemDefinitionTemplate_h
15 #define smtk_attribute_ValueItemDefinitionTemplate_h
16 
17 #include "smtk/attribute/ValueItemDefinition.h"
18 #include "smtk/common/CompilerInformation.h"
19 
20 #include <cassert>
21 #include <sstream>
22 
23 namespace smtk
24 {
25 namespace attribute
26 {
27 template<typename DataT>
29 {
30 public:
31  typedef DataT DataType;
32 
33  ~ValueItemDefinitionTemplate() override = default;
34 
35  const DataT& defaultValue() const;
36  const DataT& defaultValue(std::size_t element) const;
37  const std::vector<DataT>& defaultValues() const;
38  bool setDefaultValue(const DataT& val);
39  bool setDefaultValue(const std::vector<DataT>& val);
40  const DataT& discreteValue(std::size_t element) const { return m_discreteValues[element]; }
41  void addDiscreteValue(const DataT& val);
42  void addDiscreteValue(const DataT& val, const std::string& discreteEnum);
43  void clearDiscreteValues();
44  bool hasRange() const override { return m_minRangeSet || m_maxRangeSet; }
45  bool hasMinRange() const { return m_minRangeSet; }
46  const DataT& minRange() const { return m_minRange; }
47  bool minRangeInclusive() const { return m_minRangeInclusive; }
48  bool setMinRange(const DataT& minVal, bool isInclusive);
49  bool hasMaxRange() const { return m_maxRangeSet; }
50  const DataT& maxRange() const { return m_maxRange; }
51  bool maxRangeInclusive() const { return m_maxRangeInclusive; }
52  bool setMaxRange(const DataT& maxVal, bool isInclusive);
53  void clearRange();
54  int findDiscreteIndex(const DataT& val) const;
55  bool isValueValid(const DataT& val) const;
56 
57 protected:
58  ValueItemDefinitionTemplate(const std::string& myname);
60  void updateDiscreteValue() override;
61  std::vector<DataT> m_defaultValue;
62  DataT m_minRange;
63  bool m_minRangeSet;
64  bool m_minRangeInclusive;
65  DataT m_maxRange;
66  bool m_maxRangeSet;
67  bool m_maxRangeInclusive;
68  std::vector<DataT> m_discreteValues;
69  DataT m_dummy;
70 
71 private:
72 };
73 
74 template<typename DataT>
76  : ValueItemDefinition(myname)
77 {
78  m_minRangeSet = false;
79  m_minRangeInclusive = false;
80  m_maxRangeSet = false;
81  m_maxRangeInclusive = false;
82  m_dummy = DataT();
83 }
84 
88 template<typename DataT>
90 {
91  std::vector<DataT> defaultTuple(1, dvalue);
92  return this->setDefaultValue(defaultTuple);
93 }
94 
95 template<typename DataT>
97 {
98  assert(static_cast<int>(m_discreteValues.size()) > m_defaultDiscreteIndex);
99  this->setDefaultValue(m_discreteValues[m_defaultDiscreteIndex]);
100 }
101 
116 template<typename DataT>
117 bool ValueItemDefinitionTemplate<DataT>::setDefaultValue(const std::vector<DataT>& dvalue)
118 {
119  if (dvalue.empty())
120  return false; // *some* value must be provided.
121  if (dvalue.size() > 1 && (this->isDiscrete() || this->isExtensible()))
122  return false; // only fixed-size attributes can have vector defaults.
123  typename std::vector<DataT>::const_iterator it;
124  for (it = dvalue.begin(); it != dvalue.end(); ++it)
125  {
126  if (!this->isValueValid(*it))
127  {
128  return false; // Is each value valid?
129  }
130  }
131  m_defaultValue = dvalue;
132  m_hasDefault = true;
133  return true;
134 }
135 
136 template<typename DataT>
138 {
139  // Set the label to be based on the value
140  std::ostringstream oss;
141  oss << dvalue;
142  this->addDiscreteValue(dvalue, oss.str());
143 }
144 
145 template<typename DataT>
146 void ValueItemDefinitionTemplate<DataT>::addDiscreteValue(
147  const DataT& dvalue,
148  const std::string& dlabel)
149 {
150  m_discreteValues.push_back(dvalue);
151  m_discreteValueEnums.push_back(dlabel);
152 }
153 
154 template<typename DataT>
155 void ValueItemDefinitionTemplate<DataT>::clearDiscreteValues()
156 {
157  m_discreteValues.clear();
158  m_discreteValueEnums.clear();
159 }
160 
161 template<typename DataT>
162 bool ValueItemDefinitionTemplate<DataT>::setMinRange(const DataT& minVal, bool isInclusive)
163 {
164  // If there is a default value is it within the new range?
165  if (m_hasDefault)
166  {
167  typename std::vector<DataT>::const_iterator it;
168  for (it = m_defaultValue.begin(); it != m_defaultValue.end(); ++it)
169  {
170  if (*it < minVal)
171  return false;
172  if ((!isInclusive) && (*it == minVal))
173  return false;
174  }
175  }
176  if ((!m_maxRangeSet) || (minVal < m_maxRange))
177  {
178  m_minRangeSet = true;
179  m_minRange = minVal;
180  m_minRangeInclusive = isInclusive;
181  return true;
182  }
183  return false;
184 }
185 
186 template<typename DataT>
187 bool ValueItemDefinitionTemplate<DataT>::setMaxRange(const DataT& maxVal, bool isInclusive)
188 {
189  // If there is a default value is it within the new range?
190  if (m_hasDefault)
191  {
192  typename std::vector<DataT>::const_iterator it;
193  for (it = m_defaultValue.begin(); it != m_defaultValue.end(); ++it)
194  {
195  if (*it > maxVal)
196  return false;
197  if ((!isInclusive) && (*it == maxVal))
198  return false;
199  }
200  }
201  if ((!m_minRangeSet) || (maxVal > m_minRange))
202  {
203  m_maxRangeSet = true;
204  m_maxRange = maxVal;
205  m_maxRangeInclusive = isInclusive;
206  return true;
207  }
208  return false;
209 }
210 
211 template<typename DataT>
212 void ValueItemDefinitionTemplate<DataT>::clearRange()
213 {
214  m_minRangeSet = false;
215  m_maxRangeSet = false;
216 }
217 
218 template<typename DataT>
219 int ValueItemDefinitionTemplate<DataT>::findDiscreteIndex(const DataT& val) const
220 {
221  // Are we dealing with Discrete Values?
222  if (!this->isDiscrete())
223  {
224  return -1;
225  }
226  std::size_t i, n = m_discreteValues.size();
227  for (i = 0; i < n; i++)
228  {
229  if (m_discreteValues[i] == val)
230  {
231  return static_cast<int>(i);
232  }
233  }
234  return -1;
235 }
236 
237 template<typename DataT>
238 bool ValueItemDefinitionTemplate<DataT>::isValueValid(const DataT& val) const
239 {
240  // Are we dealing with Discrete Values?
241  if (this->isDiscrete())
242  {
243  return (this->findDiscreteIndex(val) != -1);
244  }
245  if (!this->hasRange())
246  {
247  return true;
248  }
249  if (m_minRangeSet && ((val < m_minRange) || ((!m_minRangeInclusive) && (val == m_minRange))))
250  {
251  return false;
252  }
253  if (m_maxRangeSet && ((val > m_maxRange) || ((!m_maxRangeInclusive) && (val == m_maxRange))))
254  {
255  return false;
256  }
257  return true;
258 }
259 
260 template<typename DataT>
261 const DataT& ValueItemDefinitionTemplate<DataT>::defaultValue() const
262 {
263  return m_defaultValue.empty() ? m_dummy : m_defaultValue[0];
264 }
265 
266 template<typename DataT>
267 const DataT& ValueItemDefinitionTemplate<DataT>::defaultValue(std::size_t element) const
268 {
269  bool vectorDefault = m_defaultValue.size() == this->numberOfRequiredValues();
270  assert(!vectorDefault || m_defaultValue.size() > element);
271  return m_defaultValue.empty() ? m_dummy : m_defaultValue[vectorDefault ? element : 0];
272 }
273 
274 template<typename DataT>
275 const std::vector<DataT>& ValueItemDefinitionTemplate<DataT>::defaultValues() const
276 {
277  return m_defaultValue;
278 }
279 
280 // Copies my contents to input definition
281 // Input argument is ValueItemDefinition shared pointer, which must be
282 // cast to (raw) ValueItemTemplateDefinition pointer.
283 template<typename DataT>
284 void ValueItemDefinitionTemplate<DataT>::copyTo(
287 {
288  // Get raw pointer and cast to ValueItemDefinitionTemplate*
289  ValueItemDefinition* rawDef = def.get();
290  ValueItemDefinitionTemplate<DataT>* vdef =
291  dynamic_cast<ValueItemDefinitionTemplate<DataT>*>(rawDef);
292 
293  if (this->hasDefault())
294  {
295  vdef->setDefaultValue(m_defaultValue);
296  }
297 
298  if (m_minRangeSet)
299  {
300  vdef->setMinRange(m_minRange, m_minRangeInclusive);
301  }
302 
303  if (m_maxRangeSet)
304  {
305  vdef->setMaxRange(m_maxRange, m_maxRangeInclusive);
306  }
307 
308  if (this->isDiscrete())
309  {
310  // Copy values & labels
311  DataT value;
312  std::string labelStr;
313  assert(m_discreteValueEnums.size() >= m_discreteValues.size());
314  for (std::size_t i = 0; i < m_discreteValues.size(); ++i)
315  {
316  value = m_discreteValues[i];
317  labelStr = m_discreteValueEnums[i];
318  vdef->addDiscreteValue(value, labelStr);
319  }
320  if (this->hasDefault())
321  {
322  vdef->setDefaultDiscreteIndex(m_defaultDiscreteIndex);
323  }
324  }
325 
326  // Copy superclass *after* our stuff, so that discrete values are set up
327  ValueItemDefinition::copyTo(def, info);
328 }
329 
330 } // namespace attribute
331 } // namespace smtk
332 
333 #endif /* smtk_attribute_ValueItemDefinitionTemplate_h */
smtk
The main namespace for the Simulation Modeling Tool Kit (SMTK).
Definition: doc.h:33
smtk::attribute::ValueItemDefinitionTemplate::setDefaultValue
bool setDefaultValue(const DataT &val)
Set the default value for an attribute.
Definition: ValueItemDefinitionTemplate.h:89
smtk::attribute::ItemDefinition::CopyInfo
Definition: ItemDefinition.h:47
smtk::attribute::ValueItemDefinition
Definition: ValueItemDefinition.h:41
smtk::attribute::ValueItemDefinitionPtr
smtk::shared_ptr< smtk::attribute::ValueItemDefinition > ValueItemDefinitionPtr
Definition: PublicPointerDefs.h:484
smtk::attribute::ValueItemDefinitionTemplate
Definition: ValueItemDefinitionTemplate.h:28