/////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2002-2025, Open Design Alliance (the "Alliance"). // All rights reserved. // // This software and its documentation and related materials are owned by // the Alliance. The software may only be incorporated into application // programs owned by members of the Alliance, subject to a signed // Membership Agreement and Supplemental Software License Agreement with the // Alliance. The structure and organization of this software are the valuable // trade secrets of the Alliance and its suppliers. The software is also // protected by copyright law and international treaty provisions. Application // programs incorporating this software must include the following statement // with their copyright notices: // // This application incorporates Open Design Alliance software pursuant to a license // agreement with Open Design Alliance. // Open Design Alliance Copyright (C) 2002-2025 by Open Design Alliance. // All rights reserved. // // By use of this software, its documentation or related materials, you // acknowledge and accept the above terms. /////////////////////////////////////////////////////////////////////////////// #ifndef _DAI_COLLECTION_WRAPPER_H #define _DAI_COLLECTION_WRAPPER_H #include "OdPlatformSettings.h" #include "OdPlatform.h" #include "OdaCommon.h" #include "OdArray.h" #include "daiUtils/daiUnset.h" #define STL_USING_ALGORITHM #define STL_USING_FUNCTIONAL #include "OdaSTL.h" #include "TD_PackPush.h" //DOM-IGNORE-BEGIN namespace OdDAI { class Aggr; template inline void itemCleaner(TItem& /*itemToClean*/) {} template class CollectionWrapper { public: typedef typename OdArray::size_type size_type; public: ~CollectionWrapper(); void clear(); bool empty() const; size_type size() const; void resize(const size_type& newSize, const TItem& itemToFill = OdDAI::Utils::getUnset()); bool removeByValue(const TItem& erasedValue); void removeAllByHandler(std::function handler, bool runItemCleaner); void removeAllByValue(const TItem& erasedValue); void removeByIndex(const size_type& indexToRemove); void setValue(const size_type& index, const TItem& newValue); void pushBackValue(const TItem& newValue); void pushBackCollection(const OdArray& collection); void insertAfterValue(const size_type& index, const TItem& newValue); void insertBeforeValue(const size_type& index, const TItem& newValue); bool changeRange(int leftRange, int rightRange, const TItem& newValue); bool isContains(const TItem& itemToCheck) const; const TItem& operator[](const size_type& index) const; const OdArray& getCollection() const; void setCollection(const OdArray& newArray); void sortAndRemoveDuplicates() { std::sort(m_collection.begin(), m_collection.end()); typename OdArray::iterator newEnd = std::unique(m_collection.begin(), m_collection.end()); if (newEnd != m_collection.end()) { m_collection.erase(newEnd, m_collection.end()); } } private: OdArray m_collection; }; } namespace OdDAI { template inline CollectionWrapper::~CollectionWrapper() { clear(); } template inline void CollectionWrapper::clear() { typename OdArray::iterator iteratorDelete = m_collection.begin(); for (; iteratorDelete != m_collection.end(); ++iteratorDelete) { itemCleaner(*iteratorDelete); } m_collection.clear(); } template inline bool CollectionWrapper::empty() const { return m_collection.empty(); } template inline typename CollectionWrapper::size_type CollectionWrapper::size() const { return m_collection.size(); } template inline void CollectionWrapper::resize(const typename CollectionWrapper::size_type& newSize, const TItem& itemToFill) { if (m_collection.size() > newSize) { typename OdArray::iterator iteratorDelete = m_collection.begin() + newSize; for (; iteratorDelete != m_collection.end(); ++iteratorDelete) { itemCleaner(*iteratorDelete); } } m_collection.resize(newSize, itemToFill); } template inline bool CollectionWrapper::removeByValue(const TItem& erasedValue) { typename OdArray::iterator iteratorToDelete = std::find(m_collection.begin(), m_collection.end(), erasedValue); if (iteratorToDelete == m_collection.end()) { return false; } itemCleaner(*iteratorToDelete); m_collection.erase(iteratorToDelete); return true; } template inline void CollectionWrapper::removeAllByHandler(std::function handler, bool runItemCleaner) { auto newEnd = std::remove_if(m_collection.begin(), m_collection.end(), handler); if (runItemCleaner) { typename OdArray::iterator deleteIterator = newEnd; while (deleteIterator != m_collection.end()) { itemCleaner(*deleteIterator); ++deleteIterator; } } m_collection.erase(newEnd, m_collection.end()); } template inline void CollectionWrapper::removeAllByValue(const TItem& erasedValue) { typename OdArray::iterator newEnd = std::remove(m_collection.begin(), m_collection.end(), erasedValue); typename OdArray::iterator deleteIterator = newEnd; while (deleteIterator != m_collection.end()) { itemCleaner(*deleteIterator); ++deleteIterator; } m_collection.erase(newEnd, m_collection.end()); } template inline void CollectionWrapper::removeByIndex(const size_type& indexToRemove) { itemCleaner(m_collection[indexToRemove]); m_collection.erase(m_collection.begin() + indexToRemove); } template inline void CollectionWrapper::setValue(const typename CollectionWrapper::size_type& index, const TItem& newValue) { itemCleaner(m_collection[index]); m_collection[index] = newValue; } template inline void CollectionWrapper::pushBackValue(const TItem& newValue) { m_collection.push_back(newValue); } template inline void CollectionWrapper::pushBackCollection(const OdArray& collection) { m_collection.append(collection); } template inline void CollectionWrapper::insertAfterValue(const typename CollectionWrapper::size_type& index, const TItem& newValue) { typename OdArray::iterator insertionPlace = m_collection.begin() + index + 1; m_collection.insert(insertionPlace, newValue); } template inline void CollectionWrapper::insertBeforeValue(const size_type& index, const TItem& newValue) { typename OdArray::iterator insertionPlace = m_collection.begin() + index; m_collection.insert(insertionPlace, newValue); } namespace { template::value, bool>::type = true> void copyElements(const TItem* from, TItem* to, size_t copySize) { copySize *= sizeof(TItem); Od_memcpy_s(to, copySize, from, copySize); } template::value, bool>::type = true> void copyElements(const TItem* from, TItem* to, size_t copySize) { std::copy(from, from + copySize, to); } } template bool CollectionWrapper::changeRange(int diffLower, int diffUpper, const TItem& newValue) { if (diffLower == 0 && diffUpper == 0) { return true; } auto newCollectionSize = m_collection.size() - diffLower + diffUpper; if (newCollectionSize < 0 ) { return false; } OdArray oldValues(m_collection); // m_collection.clear(); m_collection.resize(newCollectionSize, newValue); auto fromSource = diffLower < 0 ? -diffLower : 0; auto fromDestination = diffLower > 0 ? diffLower : 0; auto copySizeSource = m_collection.size() - fromSource; auto copySizeDestination = oldValues.size() - fromDestination; auto copySize = std::min(copySizeSource, copySizeDestination); if (copySize == 0) { return true; } if (fromSource != 0) { std::fill(&m_collection[0], &m_collection[fromSource], newValue); } copyElements(&oldValues[fromDestination], &m_collection[fromSource], copySize); if (fromSource + copySize < m_collection.size()) { std::fill(m_collection.begin() + fromSource + copySize, m_collection.end(), newValue); } // clear for (int clearIndex = 0; clearIndex < fromDestination; ++clearIndex) { itemCleaner(oldValues[clearIndex]); } for (int clearIndex = fromDestination + copySize; clearIndex < static_cast(oldValues.size()); ++clearIndex) { itemCleaner(oldValues[clearIndex]); } return true; } template inline bool CollectionWrapper::isContains(const TItem& itemToCheck) const { return std::find(m_collection.begin(), m_collection.end(), itemToCheck) != m_collection.end(); } template inline const TItem& CollectionWrapper::operator[](const typename CollectionWrapper::size_type& index) const { return m_collection[index]; } template inline const OdArray& CollectionWrapper::getCollection() const { return m_collection; } template inline void CollectionWrapper::setCollection(const OdArray& newArray) { typename OdArray::iterator oldItem = m_collection.begin(); for (; oldItem != m_collection.end(); ++oldItem) { itemCleaner(*oldItem); } m_collection = newArray; } template<> inline void CollectionWrapper::setCollection(const OdArray& newArray) { typename OdArray::iterator oldItem = m_collection.begin(); for (; oldItem != m_collection.end(); ++oldItem) { delete *oldItem; } m_collection.clear(); for (const auto &aggrItem : newArray) { m_collection.append(aggrItem ? aggrItem->clone() : nullptr); } } template <> inline void itemCleaner(Aggr*& itemToClean) { if (itemToClean == NULL) { return; } delete itemToClean; itemToClean = NULL; } } //DOM-IGNORE-END #include "TD_PackPop.h" #endif // _DAI_ITERATOR_H