// Copyright (c) 2016 Google Inc. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and/or associated documentation files (the // "Materials"), to deal in the Materials without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Materials, and to // permit persons to whom the Materials are furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Materials. // // MODIFICATIONS TO THIS FILE MAY MEAN IT NO LONGER ACCURATELY REFLECTS // KHRONOS STANDARDS. THE UNMODIFIED, NORMATIVE VERSIONS OF KHRONOS // SPECIFICATIONS AND HEADER INFORMATION ARE LOCATED AT // https://www.khronos.org/registry/ // // THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE // MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. #ifndef LIBSPIRV_OPT_ITERATOR_H_ #define LIBSPIRV_OPT_ITERATOR_H_ #include #include #include namespace spvtools { namespace ir { // An ad hoc iterator class for std::vector>. The // purpose of this iterator class is to provide transparent access to those // std::unique_ptr managed elements in the vector, behaving like we are using // std::vector<|ValueType|>. template class UptrVectorIterator { public: using pointer = typename std::conditional::type; using reference = typename std::conditional::type; // Type aliases. We need to apply constness properly if |IsConst| is true. using Uptr = std::unique_ptr; using UptrVector = typename std::conditional, std::vector>::type; using UnderlyingIterator = typename std::conditional::type; // Creates a new iterator from the given |container| and its raw iterator // |it|. UptrVectorIterator(UptrVector* container, const UnderlyingIterator& it) : container_(container), iterator_(it) {} UptrVectorIterator(const UptrVectorIterator&) = default; UptrVectorIterator& operator=(const UptrVectorIterator&) = default; inline UptrVectorIterator& operator++(); inline UptrVectorIterator operator++(int); inline UptrVectorIterator& operator--(); inline UptrVectorIterator operator--(int); reference operator*() const { return **iterator_; } pointer operator->() { return (*iterator_).get(); } reference operator[](ptrdiff_t index) { return **(iterator_ + index); } inline bool operator==(const UptrVectorIterator& that) const; inline bool operator!=(const UptrVectorIterator& that) const; inline ptrdiff_t operator-(const UptrVectorIterator& that) const; inline bool operator<(const UptrVectorIterator& that) const; // Inserts the given |value| to the position pointed to by this iterator // and returns an iterator to the newly iserted |value|. // If the underlying vector changes capacity, all previous iterators will be // invalidated. Otherwise, those previous iterators pointing to after the // insertion point will be invalidated. inline UptrVectorIterator InsertBefore(Uptr value); private: UptrVector* container_; // The container we are manipulating. UnderlyingIterator iterator_; // The raw iterator from the container. }; // Handy class for a (begin, end) iterator pair. template class IteratorRange { public: IteratorRange(IteratorType b, IteratorType e) : begin_(b), end_(e) {} IteratorType begin() const { return begin_; } IteratorType end() const { return end_; } bool empty() const { return begin_ == end_; } size_t size() const { return end_ - begin_; } private: IteratorType begin_; IteratorType end_; }; template inline UptrVectorIterator& UptrVectorIterator::operator++() { ++iterator_; return *this; } template inline UptrVectorIterator UptrVectorIterator::operator++(int) { auto it = *this; ++(*this); return it; } template inline UptrVectorIterator& UptrVectorIterator::operator--() { --iterator_; return *this; } template inline UptrVectorIterator UptrVectorIterator::operator--(int) { auto it = *this; --(*this); return it; } template inline bool UptrVectorIterator::operator==( const UptrVectorIterator& that) const { return container_ == that.container_ && iterator_ == that.iterator_; } template inline bool UptrVectorIterator::operator!=( const UptrVectorIterator& that) const { return !(*this == that); } template inline ptrdiff_t UptrVectorIterator::operator-( const UptrVectorIterator& that) const { assert(container_ == that.container_); return iterator_ - that.iterator_; } template inline bool UptrVectorIterator::operator<( const UptrVectorIterator& that) const { assert(container_ == that.container_); return iterator_ < that.iterator_; } template inline UptrVectorIterator UptrVectorIterator::InsertBefore( Uptr value) { auto index = iterator_ - container_->begin(); container_->insert(iterator_, std::move(value)); return UptrVectorIterator(container_, container_->begin() + index); } } // namespace ir } // namespace spvtools #endif // LIBSPIRV_OPT_ITERATOR_H_