/** * PANDA 3D SOFTWARE * Copyright (c) Carnegie Mellon University. All rights reserved. * * All use of this software is subject to the terms of the revised BSD * license. You should have received a copy of this license along * with this source code in a file named "LICENSE." * * @file ordered_vector.I * @author drose * @date 2002-02-20 */ /** * */ template INLINE ordered_vector:: ordered_vector(TypeHandle type_handle) : _compare(Compare()), _vector(type_handle) { } /** * */ template INLINE ordered_vector:: ordered_vector(const Compare &compare, TypeHandle type_handle) : _compare(compare), _vector(type_handle) { } /** * Returns the iterator that marks the first element in the ordered vector. */ template INLINE typename ordered_vector::ITERATOR ordered_vector:: begin() { return _vector.begin(); } /** * Returns the iterator that marks the end of the ordered vector. */ template INLINE typename ordered_vector::ITERATOR ordered_vector:: end() { return _vector.end(); } /** * Returns the iterator that marks the first element in the ordered vector, * when viewed in reverse order. */ template INLINE typename ordered_vector::REVERSE_ITERATOR ordered_vector:: rbegin() { return _vector.rbegin(); } /** * Returns the iterator that marks the end of the ordered vector, when viewed * in reverse order. */ template INLINE typename ordered_vector::REVERSE_ITERATOR ordered_vector:: rend() { return _vector.rend(); } /** * Returns the iterator that marks the first element in the ordered vector. */ template INLINE typename ordered_vector::CONST_ITERATOR ordered_vector:: begin() const { return _vector.begin(); } /** * Returns the iterator that marks the end of the ordered vector. */ template INLINE typename ordered_vector::CONST_ITERATOR ordered_vector:: end() const { return _vector.end(); } /** * Returns the iterator that marks the first element in the ordered vector, * when viewed in reverse order. */ template INLINE typename ordered_vector::CONST_REVERSE_ITERATOR ordered_vector:: rbegin() const { return _vector.rbegin(); } /** * Returns the iterator that marks the end of the ordered vector, when viewed * in reverse order. */ template INLINE typename ordered_vector::CONST_REVERSE_ITERATOR ordered_vector:: rend() const { return _vector.rend(); } /** * Returns the iterator that marks the first element in the ordered vector. */ template INLINE typename ordered_vector::CONST_ITERATOR ordered_vector:: cbegin() const { return _vector.begin(); } /** * Returns the iterator that marks the end of the ordered vector. */ template INLINE typename ordered_vector::CONST_ITERATOR ordered_vector:: cend() const { return _vector.end(); } /** * Returns the iterator that marks the first element in the ordered vector, * when viewed in reverse order. */ template INLINE typename ordered_vector::CONST_REVERSE_ITERATOR ordered_vector:: crbegin() const { return _vector.rbegin(); } /** * Returns the iterator that marks the end of the ordered vector, when viewed * in reverse order. */ template INLINE typename ordered_vector::CONST_REVERSE_ITERATOR ordered_vector:: crend() const { return _vector.rend(); } /** * Returns the nth element. */ template INLINE typename ordered_vector::REFERENCE ordered_vector:: operator [] (typename ordered_vector::SIZE_TYPE n) { return _vector[n]; } /** * Returns the nth element. */ template INLINE typename ordered_vector::CONST_REFERENCE ordered_vector:: operator [] (typename ordered_vector::SIZE_TYPE n) const { return _vector[n]; } /** * Returns a reference to the first element. */ template INLINE typename ordered_vector::REFERENCE ordered_vector:: front() { #ifdef _DEBUG assert(!_vector.empty()); #endif return _vector[0]; } /** * Returns a const reference to the first element. */ template INLINE typename ordered_vector::CONST_REFERENCE ordered_vector:: front() const { #ifdef _DEBUG assert(!_vector.empty()); #endif return _vector[0]; } /** * Returns a reference to the first element. */ template INLINE typename ordered_vector::REFERENCE ordered_vector:: back() { #ifdef _DEBUG assert(!_vector.empty()); #endif return _vector[_vector.size() - 1]; } /** * Returns a const reference to the last element. */ template INLINE typename ordered_vector::CONST_REFERENCE ordered_vector:: back() const { #ifdef _DEBUG assert(!_vector.empty()); #endif return _vector[_vector.size() - 1]; } /** * Returns the number of elements in the ordered vector. */ template INLINE typename ordered_vector::SIZE_TYPE ordered_vector:: size() const { return _vector.size(); } /** * Returns the maximum number of elements that can possibly be stored in an * ordered vector. */ template INLINE typename ordered_vector::SIZE_TYPE ordered_vector:: max_size() const { return _vector.max_size(); } /** * Returns true if the ordered vector is empty, false otherwise. */ template INLINE bool ordered_vector:: empty() const { return _vector.empty(); } /** * Returns true if the two ordered vectors are memberwise equivalent, false * otherwise. */ template INLINE bool ordered_vector:: operator == (const ordered_vector &other) const { return _vector == other._vector; } /** * Returns true if the two ordered vectors are not memberwise equivalent, * false if they are. */ template INLINE bool ordered_vector:: operator != (const ordered_vector &other) const { return _vector != other._vector; } /** * Returns true if this ordered vector sorts lexicographically before the * other one, false otherwise. */ template INLINE bool ordered_vector:: operator < (const ordered_vector &other) const { return _vector < other._vector; } /** * Returns true if this ordered vector sorts lexicographically after the other * one, false otherwise. */ template INLINE bool ordered_vector:: operator > (const ordered_vector &other) const { return _vector > other._vector; } /** * Returns true if this ordered vector sorts lexicographically before the * other one or is equivalent, false otherwise. */ template INLINE bool ordered_vector:: operator <= (const ordered_vector &other) const { return _vector <= other._vector; } /** * Returns true if this ordered vector sorts lexicographically after the other * one or is equivalent, false otherwise. */ template INLINE bool ordered_vector:: operator >= (const ordered_vector &other) const { return _vector >= other._vector; } /** * Inserts the indicated key into the ordered vector, at the appropriate * place. If there is already an element sorting equivalent to the key in the * vector, the new key is not inserted. * * The return value is a pair, where the first component is the iterator * referencing the new element (or the original element), and the second * componet is true if the insert operation has taken place. */ template INLINE std::pair::ITERATOR, bool> ordered_vector:: insert_unique(const typename ordered_vector::VALUE_TYPE &key) { TAU_PROFILE("ordered_vector::insert_unique(const value_type &)", " ", TAU_USER); ITERATOR position = find_insert_position(begin(), end(), key); #ifdef NDEBUG std::pair bogus_result(end(), false); nassertr(position >= begin() && position <= end(), bogus_result); #endif // If there's already an equivalent key in the vector, it's at *(position - // 1). if (position != begin() && !_compare(*(position - 1), key)) { std::pair result(position - 1, false); nassertr(!_compare(key, *(position - 1)), result); return result; } ITERATOR result = _vector.insert(position, key); return std::pair(result, true); } /** * Inserts the indicated key into the ordered vector, at the appropriate * place. If there are already elements sorting equivalent to the key in the * vector, the new value is inserted following them. * * The return value is the iterator referencing the new element. */ template INLINE typename ordered_vector::ITERATOR ordered_vector:: insert_nonunique(const typename ordered_vector::VALUE_TYPE &key) { TAU_PROFILE("ordered_vector::insert_nonunique(const value_type &)", " ", TAU_USER); ITERATOR position = find_insert_position(begin(), end(), key); nassertr(position >= begin() && position <= end(), end()); ITERATOR result = _vector.insert(position, key); return result; } /** * Inserts the indicated key into the ordered vector at the indicated place. * The user is trusted to have already verified that this is the correct * sorting position; no checks are made. */ template INLINE typename ordered_vector::ITERATOR ordered_vector:: insert_unverified(typename ordered_vector::ITERATOR position, const typename ordered_vector::VALUE_TYPE &key) { TAU_PROFILE("ordered_vector::insert_unverified(iterator, const value_type &)", " ", TAU_USER); ITERATOR result = _vector.insert(position, key); return result; } /** * Removes the element indicated by the given iterator, and returns the next * sequential iterator. */ template INLINE typename ordered_vector::ITERATOR ordered_vector:: erase(typename ordered_vector::ITERATOR position) { TAU_PROFILE("ordered_vector::erase(iterator)", " ", TAU_USER); SIZE_TYPE count = position - begin(); _vector.erase(position); return begin() + count; } /** * Removes all elements matching the indicated key; returns the number of * elements removed. */ template INLINE typename ordered_vector::SIZE_TYPE ordered_vector:: erase(const typename ordered_vector::KEY_TYPE &key) { TAU_PROFILE("ordered_vector::erase(const key_type &)", " ", TAU_USER); std::pair result = equal_range(key); SIZE_TYPE count = result.second - result.first; erase(result.first, result.second); return count; } /** * Removes all elements indicated by the given iterator range. */ template INLINE void ordered_vector:: erase(typename ordered_vector::ITERATOR first, typename ordered_vector::ITERATOR last) { TAU_PROFILE("ordered_vector::erase(iterator, iterator)", " ", TAU_USER); _vector.erase(first, last); } /** * Removes all elements from the ordered vector. */ template INLINE void ordered_vector:: clear() { TAU_PROFILE("ordered_vector::clear()", " ", TAU_USER); _vector.erase(_vector.begin(), _vector.end()); } /** * Searches for an element with the indicated key and returns its iterator if * it is found, or end() if it is not. If there are multiple elements * matching the key, the particular iterator returned is not defined. */ template INLINE typename ordered_vector::ITERATOR ordered_vector:: find(const typename ordered_vector::KEY_TYPE &key) { TAU_PROFILE("ordered_vector::find(const key_type &)", " ", TAU_USER); return nci(r_find(begin(), end(), end(), key)); } /** * Searches for an element with the indicated key and returns its iterator if * it is found, or end() if it is not. If there are multiple elements * matching the key, the particular iterator returned is not defined. */ template INLINE typename ordered_vector::CONST_ITERATOR ordered_vector:: find(const typename ordered_vector::KEY_TYPE &key) const { TAU_PROFILE("ordered_vector::find(const key_type &)", " ", TAU_USER); return r_find(begin(), end(), end(), key); } /** * Searches for a particular element and returns its iterator if it is found, * or end() if it is not. * * First, the Compare function is used to narrow down the range of elements * the element might be located within; then the element is compared * elementwise, via ==, until the exact matching element is found. If * multiple matches exist within the vector, the particular iterator returned * is not defined. * * The assumption is that == implies !Compare(a, b) and !Compare(b, a), but * not necessarily the converse. */ template INLINE typename ordered_vector::ITERATOR ordered_vector:: find_particular(const typename ordered_vector::KEY_TYPE &key) { TAU_PROFILE("ordered_vector::find_particular(const key_type &)", " ", TAU_USER); return nci(r_find_particular(begin(), end(), end(), key)); } /** * Searches for a particular element and returns its iterator if it is found, * or end() if it is not. * * First, the Compare function is used to narrow down the range of elements * the element might be located within; then the element is compared * elementwise, via ==, until the exact matching element is found. If * multiple matches exist within the vector, the particular iterator returned * is not defined. */ template INLINE typename ordered_vector::CONST_ITERATOR ordered_vector:: find_particular(const typename ordered_vector::KEY_TYPE &key) const { TAU_PROFILE("ordered_vector::find_particular(const key_type &)", " ", TAU_USER); return r_find_particular(begin(), end(), end(), key); } /** * Returns the number of elements that sort equivalent to the key that are in * the vector. */ template INLINE typename ordered_vector::SIZE_TYPE ordered_vector:: count(const key_type &key) const { TAU_PROFILE("ordered_vector::count(const key_type &)", " ", TAU_USER); return r_count(begin(), end(), key); } /** * Returns the iterator for the first element not less than key, or end() if * all elements are less than key. */ template INLINE typename ordered_vector::ITERATOR ordered_vector:: lower_bound(const typename ordered_vector::KEY_TYPE &key) { TAU_PROFILE("ordered_vector::lower_bound(const key_type &)", " ", TAU_USER); return nci(r_lower_bound(begin(), end(), key)); } /** * Returns the iterator for the first element not less than key, or end() if * all elements are less than key. */ template INLINE typename ordered_vector::CONST_ITERATOR ordered_vector:: lower_bound(const typename ordered_vector::KEY_TYPE &key) const { TAU_PROFILE("ordered_vector::lower_bound(const key_type &)", " ", TAU_USER); return r_lower_bound(begin(), end(), key); } /** * Returns the iterator for the first element greater than key, or end() if no * element is greater than key. */ template INLINE typename ordered_vector::ITERATOR ordered_vector:: upper_bound(const typename ordered_vector::KEY_TYPE &key) { TAU_PROFILE("ordered_vector::upper_bound(const key_type &)", " ", TAU_USER); return nci(r_upper_bound(begin(), end(), key)); } /** * Returns the iterator for the first element greater than key, or end() if no * element is greater than key. */ template INLINE typename ordered_vector::CONST_ITERATOR ordered_vector:: upper_bound(const typename ordered_vector::KEY_TYPE &key) const { TAU_PROFILE("ordered_vector::upper_bound(const key_type &)", " ", TAU_USER); return r_upper_bound(begin(), end(), key); } /** * Returns the pair (lower_bound(key), upper_bound(key)). */ template INLINE std::pair::ITERATOR, typename ordered_vector::ITERATOR> ordered_vector:: equal_range(const typename ordered_vector::KEY_TYPE &key) { TAU_PROFILE("ordered_vector::equal_range(const key_type &)", " ", TAU_USER); std::pair::CONST_ITERATOR, typename ordered_vector::CONST_ITERATOR> result; result = r_equal_range(begin(), end(), key); return std::pair::ITERATOR, typename ordered_vector::ITERATOR>(nci(result.first), nci(result.second)); } /** * Returns the pair (lower_bound(key), upper_bound(key)). */ template INLINE std::pair::CONST_ITERATOR, typename ordered_vector::CONST_ITERATOR> ordered_vector:: equal_range(const typename ordered_vector::KEY_TYPE &key) const { TAU_PROFILE("ordered_vector::equal_range(const key_type &)", " ", TAU_USER); return r_equal_range(begin(), end(), key); } /** * Exchanges the contents of this vector and the other vector, in constant * time (e.g., with a pointer swap). */ template INLINE void ordered_vector:: swap(ordered_vector ©) { TAU_PROFILE("ordered_vector::swap(ordered_vector &)", " ", TAU_USER); _vector.swap(copy._vector); } /** * Informs the vector of a planned change in size; ensures that the capacity * of the vector is greater than or equal to n. */ template INLINE void ordered_vector:: reserve(typename ordered_vector::SIZE_TYPE n) { TAU_PROFILE("ordered_vector::reserve(size_type)", " ", TAU_USER); _vector.reserve(n); } /** * Ensures that the vector is properly sorted after a potentially damaging * operation. This should not normally need to be called, unless the user has * written to the vector using the non-const iterators or has called * push_back(). * * This flavor of sort also eliminates repeated elements. */ template INLINE void ordered_vector:: sort_unique() { TAU_PROFILE("ordered_vector::sort_unique()", " ", TAU_USER); sort(begin(), end(), _compare); iterator new_end = unique(begin(), end(), EquivalentTest(_compare)); erase(new_end, end()); } /** * Ensures that the vector is properly sorted after a potentially damaging * operation. This should not normally need to be called, unless the user has * written to the vector using the non-const iterators or has called * push_back(). */ template INLINE void ordered_vector:: sort_nonunique() { TAU_PROFILE("ordered_vector::sort_nonunique()", " ", TAU_USER); std::stable_sort(begin(), end(), _compare); } /** * Adds the new element to the end of the vector without regard for proper * sorting. This is a bad idea to do except to populate the vector the first * time; be sure to call sort() after you have added all the elements. */ template INLINE void ordered_vector:: push_back(const value_type &key) { TAU_PROFILE("ordered_vector::push_back()", " ", TAU_USER); _vector.push_back(key); } /** * Adds the new element to the end of the vector without regard for proper * sorting. This is a bad idea to do except to populate the vector the first * time; be sure to call sort() after you have added all the elements. */ template INLINE void ordered_vector:: push_back(value_type &&key) { TAU_PROFILE("ordered_vector::push_back()", " ", TAU_USER); _vector.push_back(std::move(key)); } /** * Removes the last element at the end of the vector. */ template INLINE void ordered_vector:: pop_back() { TAU_PROFILE("ordered_vector::pop_back()", " ", TAU_USER); _vector.pop_back(); } /** * Resizes the vector to contain n elements. This should not be used except * to populate the vector for the first time. */ template INLINE void ordered_vector:: resize(SIZE_TYPE n) { TAU_PROFILE("ordered_vector::resize()", " ", TAU_USER); _vector.resize(n); } /** * Resizes the vector to contain n elements. This should not be used except * to populate the vector for the first time. */ template INLINE void ordered_vector:: resize(SIZE_TYPE n, const VALUE_TYPE &value) { TAU_PROFILE("ordered_vector::resize()", " ", TAU_USER); _vector.resize(n, value); } /** * I.e. "non-const iterator". This function is used to typecast a const * iterator to a non-const iterator for easy definition of const vs. non- * const flavors of some of these methods. */ template INLINE typename ordered_vector::ITERATOR ordered_vector:: nci(typename ordered_vector::CONST_ITERATOR i) { return begin() + (i - begin()); } /** * Searches for the appropriate place in the ordered vector to insert the * indicated key, and returns the corresponding iterator. */ template INLINE typename ordered_vector::ITERATOR ordered_vector:: find_insert_position(typename ordered_vector::ITERATOR first, typename ordered_vector::ITERATOR last, const typename ordered_vector::KEY_TYPE &key) { ITERATOR result = r_find_insert_position(first, last, key); return result; } /** * */ template INLINE ov_set:: ov_set(TypeHandle type_handle) : ordered_vector(type_handle) { } /** * */ template INLINE ov_set:: ov_set(const Compare &compare, TypeHandle type_handle) : ordered_vector(compare, type_handle) { } /** * Maps to insert_unique(). */ template typename ov_set::ITERATOR ov_set:: insert(typename ov_set::ITERATOR position, const typename ov_set::VALUE_TYPE &key) { return ordered_vector::insert_unique(position, key); } /** * Maps to insert_unique(). */ template INLINE std::pair::ITERATOR, bool> ov_set:: insert(const typename ov_set::VALUE_TYPE &key) { return ordered_vector::insert_unique(key); } /** * Maps to sort_unique(). */ template INLINE void ov_set:: sort() { ordered_vector::sort_unique(); } /** * Maps to verify_list_unique(). */ template INLINE bool ov_set:: verify_list() const { return ordered_vector::verify_list_unique(); } /** * */ template INLINE ov_multiset:: ov_multiset(TypeHandle type_handle) : ordered_vector(type_handle) { } /** * */ template INLINE ov_multiset:: ov_multiset(const Compare &compare, TypeHandle type_handle) : ordered_vector(compare, type_handle) { } /** * Maps to insert_nonunique(). */ template typename ov_multiset::ITERATOR ov_multiset:: insert(typename ov_multiset::ITERATOR position, const typename ov_multiset::VALUE_TYPE &key) { return ordered_vector::insert_nonunique(position, key); } /** * Maps to insert_nonunique(). */ template INLINE typename ov_multiset::ITERATOR ov_multiset:: insert(const typename ov_multiset::VALUE_TYPE &key) { return ordered_vector::insert_nonunique(key); } /** * Maps to sort_nonunique(). */ template INLINE void ov_multiset:: sort() { ordered_vector::sort_nonunique(); } /** * Maps to verify_list_nonunique(). */ template INLINE bool ov_multiset:: verify_list() const { return ordered_vector::verify_list_nonunique(); }