10 #ifndef smtk_attribute_ReferenceItem_h
11 #define smtk_attribute_ReferenceItem_h
13 #include "smtk/attribute/Item.h"
15 #include "smtk/common/UUID.h"
16 #include "smtk/resource/Lock.h"
31 class ReferenceItemDefinition;
32 class ValueItemDefinition;
68 typedef std::random_access_iterator_tag iterator_category;
70 typedef value_type reference;
71 typedef value_type pointer;
72 typedef std::ptrdiff_t difference_type;
90 reference operator*()
const;
91 pointer operator->()
const;
92 reference operator[](
const difference_type& d);
96 std::shared_ptr<T>
as()
const
99 return std::dynamic_pointer_cast<T>(this->const_iterator::operator*());
114 struct CacheIterator;
115 std::unique_ptr<CacheIterator> m_cacheIterator;
120 using Key = std::pair<smtk::common::UUID, smtk::common::UUID>;
134 std::size_t numberOfValues()
const;
136 bool setNumberOfValues(std::size_t newSize);
144 bool removeInvalidValues();
147 virtual std::shared_ptr<const ReferenceItemDefinition> definition()
const;
149 const std::multimap<std::string, std::string>& acceptableEntries()
const;
152 std::size_t numberOfRequiredValues()
const;
154 std::size_t maxNumberOfValues()
const;
185 template<
typename Container>
188 std::function<
typename Container::value_type(
const PersistentObjectPtr&)> converter =
189 [](
const PersistentObjectPtr& obj) {
return obj; })
const
191 for (
auto it = this->begin(); it != this->end(); ++it)
198 typename Container::value_type val = converter(*it);
201 result.insert(result.end(), val);
205 template<
typename Container>
211 this->as(result, converter);
222 Key objectKey(std::size_t i = 0)
const;
223 bool setObjectKey(std::size_t i,
const Key& key);
224 bool setObjectKey(std::size_t i,
const Key& key, std::size_t conditional);
229 typename T::Ptr valueAs(std::size_t i = 0)
const
231 return std::dynamic_pointer_cast<T>(this->value(i));
237 return this->isValueValid(0, entity);
253 bool setValues(I vbegin, I vend,
typename std::iterator_traits<I>::difference_type offset = 0);
255 bool appendValues(I vbegin, I vend);
257 template<
typename I,
typename T>
262 typename std::iterator_traits<I>::difference_type offset = 0);
263 template<
typename I,
typename T>
264 bool appendValuesVia(I vbegin, I vend,
const T& converter);
283 bool removeValue(std::size_t i);
285 void detachOwningResource()
override;
287 void reset()
override;
289 virtual std::string valueAsString()
const;
296 virtual std::string valueAsString(std::size_t i)
const;
306 virtual bool isSet(std::size_t i = 0)
const;
308 virtual void unset(std::size_t i = 0);
310 virtual std::size_t numberOfSetValues()
const;
319 const CopyAssignmentOptions& options,
323 bool isExtensible()
const;
328 const_iterator begin()
const;
332 const_iterator end()
const;
345 smtk::resource::LockType lockType()
const;
356 bool activeChildren =
true)
override;
365 const std::map<std::string, smtk::attribute::ItemPtr>&
childrenItems()
const
367 return m_childrenItems;
377 if (
static_cast<std::size_t
>(i) >= m_activeChildrenItems.size())
382 return m_activeChildrenItems[
static_cast<std::size_t
>(i)];
409 bool resolve()
const;
414 bool isValidInternal(
bool useCategories,
const std::set<std::string>& categories)
const override;
416 std::vector<Key> m_keys;
429 void updateActiveChildrenItems();
439 bool iteratorIsSet(
const I& iterator)
const;
441 void assignToCache(std::size_t i,
const PersistentObjectPtr& obj)
const;
442 void appendToCache(
const PersistentObjectPtr& obj)
const;
445 mutable std::unique_ptr<Cache> m_cache;
447 std::map<std::string, smtk::attribute::ItemPtr> m_childrenItems;
449 std::vector<smtk::attribute::ItemPtr> m_activeChildrenItems;
451 std::size_t m_currentConditional;
454 std::size_t m_nextUnsetPos;
458 SMTKCORE_EXPORT
bool ReferenceItem::iteratorIsSet<ReferenceItem::const_iterator>(
462 bool ReferenceItem::setValues(
465 typename std::iterator_traits<I>::difference_type offset)
468 std::size_t num = std::distance(vbegin, vend) + offset;
472 std::size_t firstUnsetPos = -1;
474 for (I it = vbegin; it != vend; ++it, ++i)
476 if (!iteratorIsSet(it))
478 if (firstUnsetPos > (offset + i))
480 firstUnsetPos = offset + i;
485 if (!this->
setValue(offset + i, *it))
488 if (firstUnsetPos > (offset + i))
490 firstUnsetPos = offset + i;
496 if (m_nextUnsetPos > firstUnsetPos)
498 m_nextUnsetPos = firstUnsetPos;
510 bool ReferenceItem::appendValues(I vbegin, I vend)
515 template<
typename I,
typename T>
516 bool ReferenceItem::setValuesVia(
520 typename std::iterator_traits<I>::difference_type offset)
523 std::size_t num = std::distance(vbegin, vend) + offset;
528 std::size_t firstUnsetPos = -1;
529 for (I it = vbegin; it != vend; ++it, ++i)
531 if (!iteratorIsSet(it))
533 if (firstUnsetPos > (offset + i))
535 firstUnsetPos = offset + i;
540 if (!this->
setValue(offset + i, converter(*it)))
542 if (firstUnsetPos > (offset + i))
544 firstUnsetPos = offset + i;
550 if (m_nextUnsetPos > firstUnsetPos)
552 m_nextUnsetPos = firstUnsetPos;
563 template<
typename I,
typename T>
564 bool ReferenceItem::appendValuesVia(I vbegin, I vend,
const T& converter)
566 return this->setValuesVia(vbegin, vend, converter, this->
numberOfValues());
570 bool ReferenceItem::iteratorIsSet(
const I& iterator)
const
572 return !!(*iterator);