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