xref: /haiku/headers/private/kernel/util/Vector.h (revision 4f00613311d0bd6b70fa82ce19931c41f071ea4e)
1 // Vector.h
2 //
3 // Copyright (c) 2003, Ingo Weinhold (bonefish@cs.tu-berlin.de)
4 //
5 // Permission is hereby granted, free of charge, to any person obtaining a
6 // copy of this software and associated documentation files (the "Software"),
7 // to deal in the Software without restriction, including without limitation
8 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 // and/or sell copies of the Software, and to permit persons to whom the
10 // Software is furnished to do so, subject to the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 // DEALINGS IN THE SOFTWARE.
22 //
23 // Except as contained in this notice, the name of a copyright holder shall
24 // not be used in advertising or otherwise to promote the sale, use or other
25 // dealings in this Software without prior written authorization of the
26 // copyright holder.
27 
28 #ifndef _VECTOR_H
29 #define _VECTOR_H
30 
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include <SupportDefs.h>
35 #include <util/kernel_cpp.h>
36 
37 template<typename Value> class VectorIterator;
38 
39 // for convenience
40 #define _VECTOR_TEMPLATE_LIST template<typename Value>
41 #define _VECTOR_CLASS_NAME Vector<Value>
42 #define _VECTOR_CLASS_TYPE typename Vector<Value>
43 
44 /*!
45 	\class Vector
46 	\brief A generic vector implementation.
47 */
48 template<typename Value>
49 class Vector {
50 public:
51 	typedef VectorIterator<Value>		Iterator;
52 	typedef VectorIterator<const Value>	ConstIterator;
53 
54 private:
55 	static const size_t				kDefaultChunkSize = 10;
56 	static const size_t				kMaximalChunkSize = 1024 * 1024;
57 
58 public:
59 	Vector(size_t chunkSize = kDefaultChunkSize);
60 	~Vector();
61 
62 	status_t PushFront(const Value &value);
63 	status_t PushBack(const Value &value);
64 
65 	void PopFront();
66 	void PopBack();
67 
68 	status_t Insert(const Value &value, int32 index);
69 	status_t Insert(const Value &value, const Iterator &iterator);
70 
71 	int32 Remove(const Value &value);
72 	Iterator Erase(int32 index);
73 	Iterator Erase(const Iterator &iterator);
74 
75 	inline int32 Count() const;
76 	inline bool IsEmpty() const;
77 	void MakeEmpty();
78 
79 	inline Iterator Begin();
80 	inline ConstIterator Begin() const;
81 	inline Iterator End();
82 	inline ConstIterator End() const;
83 	inline Iterator Null();
84 	inline ConstIterator Null() const;
85 	inline Iterator IteratorForIndex(int32 index);
86 	inline ConstIterator IteratorForIndex(int32 index) const;
87 
88 	inline const Value &ElementAt(int32 index) const;
89 	inline Value &ElementAt(int32 index);
90 
91 	int32 IndexOf(const Value &value, int32 start = 0) const;
92 	Iterator Find(const Value &value);
93 	Iterator Find(const Value &value, const Iterator &start);
94 	ConstIterator Find(const Value &value) const;
95 	ConstIterator Find(const Value &value, const ConstIterator &start) const;
96 
97 	inline Value &operator[](int32 index);
98 	inline const Value &operator[](int32 index) const;
99 
100 	// debugging
101 	int32 GetCapacity() const	{ return fCapacity; }
102 
103 private:
104 	inline static void _MoveItems(Value *values, int32 offset, int32 count);
105 	bool _Resize(size_t count);
106 	inline int32 _IteratorIndex(const Iterator &iterator) const;
107 	inline int32 _IteratorIndex(const ConstIterator &iterator) const;
108 
109 private:
110 	size_t	fCapacity;
111 	size_t	fChunkSize;
112 	int32	fItemCount;
113 	Value	*fItems;
114 };
115 
116 
117 // VectorIterator
118 template<typename Value>
119 class VectorIterator {
120 private:
121 	typedef VectorIterator<Value>	Iterator;
122 
123 public:
124 	inline VectorIterator<Value>()
125 		: fElement(NULL)
126 	{
127 	}
128 
129 	inline VectorIterator<Value>(const Iterator &other)
130 		: fElement(other.fElement)
131 	{
132 	}
133 
134 	inline Iterator &operator++()
135 	{
136 		if (fElement)
137 			++fElement;
138 		return *this;
139 	}
140 
141 	inline Iterator operator++(int)
142 	{
143 		Iterator it(*this);
144 		++*this;
145 		return it;
146 	}
147 
148 	inline Iterator &operator--()
149 	{
150 		if (fElement)
151 			--fElement;
152 		return *this;
153 	}
154 
155 	inline Iterator operator--(int)
156 	{
157 		Iterator it(*this);
158 		--*this;
159 		return it;
160 	}
161 
162 	inline Iterator &operator=(const Iterator &other)
163 	{
164 		fElement = other.fElement;
165 		return *this;
166 	}
167 
168 
169 	inline bool operator==(const Iterator &other) const
170 	{
171 		return (fElement == other.fElement);
172 	}
173 
174 	inline bool operator!=(const Iterator &other) const
175 	{
176 		return !(*this == other);
177 	}
178 
179 	inline Value &operator*() const
180 	{
181 		return *fElement;
182 	}
183 
184 	inline Value *operator->() const
185 	{
186 		return fElement;
187 	}
188 
189 	inline operator bool() const
190 	{
191 		return fElement;
192 	}
193 
194 // private
195 public:
196 	inline VectorIterator<Value>(Value *element)
197 		: fElement(element)
198 	{
199 	}
200 
201 	inline Value *Element() const
202 	{
203 		return fElement;
204 	}
205 
206 protected:
207 	Value	*fElement;
208 };
209 
210 
211 // Vector
212 
213 // constructor
214 /*!	\brief Creates an empty vector.
215 	\param chunkSize The granularity for the vector's capacity, i.e. the
216 		   minimal number of elements the capacity grows or shrinks when
217 		   necessary.
218 */
219 _VECTOR_TEMPLATE_LIST
220 _VECTOR_CLASS_NAME::Vector(size_t chunkSize)
221 	: fCapacity(0),
222 	  fChunkSize(chunkSize),
223 	  fItemCount(0),
224 	  fItems(NULL)
225 {
226 	if (fChunkSize == 0 || fChunkSize > kMaximalChunkSize)
227 		fChunkSize = kDefaultChunkSize;
228 	_Resize(0);
229 }
230 
231 // destructor
232 /*!	\brief Frees all resources associated with the object.
233 
234 	The contained elements are destroyed. Note, that, if the element
235 	type is a pointer type, only the pointer is destroyed, not the object
236 	it points to.
237 */
238 _VECTOR_TEMPLATE_LIST
239 _VECTOR_CLASS_NAME::~Vector()
240 {
241 	MakeEmpty();
242 	free(fItems);
243 }
244 
245 // PushFront
246 /*!	\brief Inserts a copy of the supplied value at the beginning of the
247 		   vector.
248 	\param value The element to be inserted.
249 	\return
250 	- \c B_OK: Everything went fine.
251 	- \c B_NO_MEMORY: Insufficient memory for this operation.
252 */
253 _VECTOR_TEMPLATE_LIST
254 status_t
255 _VECTOR_CLASS_NAME::PushFront(const Value &value)
256 {
257 	return Insert(value, 0);
258 }
259 
260 // PushBack
261 /*!	\brief Inserts a copy of the supplied value at the end of the vector.
262 	\param value The element to be inserted.
263 	\return
264 	- \c B_OK: Everything went fine.
265 	- \c B_NO_MEMORY: Insufficient memory for this operation.
266 */
267 _VECTOR_TEMPLATE_LIST
268 status_t
269 _VECTOR_CLASS_NAME::PushBack(const Value &value)
270 {
271 	return Insert(value, fItemCount);
272 }
273 
274 // PopFront
275 /*!	\brief Removes the first element of the vector.
276 
277 	Invocation on an empty vector is harmless.
278 */
279 _VECTOR_TEMPLATE_LIST
280 void
281 _VECTOR_CLASS_NAME::PopFront()
282 {
283 	if (fItemCount > 0)
284 		Erase(0);
285 }
286 
287 // PopBack
288 /*!	\brief Removes the last element of the vector.
289 
290 	Invocation on an empty vector is harmless.
291 */
292 _VECTOR_TEMPLATE_LIST
293 void
294 _VECTOR_CLASS_NAME::PopBack()
295 {
296 	if (fItemCount > 0)
297 		Erase(fItemCount - 1);
298 }
299 
300 // _MoveItems
301 /*!	\brief Moves elements within an array.
302 	\param items The elements to be moved.
303 	\param offset The index to which the elements shall be moved. May be
304 		   negative.
305 	\param count The number of elements to be moved.
306 */
307 _VECTOR_TEMPLATE_LIST
308 inline
309 void
310 _VECTOR_CLASS_NAME::_MoveItems(Value* items, int32 offset, int32 count)
311 {
312 	if (count > 0 && offset != 0)
313 		memmove(items + offset, items, count * sizeof(Value));
314 }
315 
316 // Insert
317 /*!	\brief Inserts a copy of the the supplied value at the given index.
318 	\param value The value to be inserted.
319 	\param index The index at which to insert the new element. It must
320 		   hold: 0 <= \a index <= Count().
321 	\return
322 	- \c B_OK: Everything went fine.
323 	- \c B_BAD_VALUE: \a index is out of range.
324 	- \c B_NO_MEMORY: Insufficient memory for this operation.
325 */
326 _VECTOR_TEMPLATE_LIST
327 status_t
328 _VECTOR_CLASS_NAME::Insert(const Value &value, int32 index)
329 {
330 	if (index < 0 || index > fItemCount)
331 		return B_BAD_VALUE;
332 	if (!_Resize(fItemCount + 1))
333 		return B_NO_MEMORY;
334 	_MoveItems(fItems + index, 1, fItemCount - index - 1);
335 	new(fItems + index) Value(value);
336 	return B_OK;
337 }
338 
339 // Insert
340 /*!	\brief Inserts a copy of the the supplied value at the given position.
341 	\param value The value to be inserted.
342 	\param iterator An iterator specifying the position at which to insert
343 		   the new element.
344 	\return
345 	- \c B_OK: Everything went fine.
346 	- \c B_BAD_VALUE: \a iterator is is invalid.
347 	- \c B_NO_MEMORY: Insufficient memory for this operation.
348 */
349 _VECTOR_TEMPLATE_LIST
350 status_t
351 _VECTOR_CLASS_NAME::Insert(const Value &value, const Iterator &iterator)
352 {
353 	int32 index = _IteratorIndex(iterator);
354 	if (index >= 0)
355 		return Insert(value, index);
356 	return B_BAD_VALUE;
357 }
358 
359 // Remove
360 /*!	\brief Removes all elements of the supplied value.
361 	\param value The value of the elements to be removed.
362 	\return The number of removed occurrences.
363 */
364 _VECTOR_TEMPLATE_LIST
365 int32
366 _VECTOR_CLASS_NAME::Remove(const Value &value)
367 {
368 	int32 count = 0;
369 	for (int32 i = fItemCount - 1; i >= 0; i--) {
370 		if (ElementAt(i) == value) {
371 			Erase(i);
372 			count++;
373 		}
374 	}
375 	return count;
376 }
377 
378 // Erase
379 /*!	\brief Removes the element at the given index.
380 	\param index The position of the element to be removed.
381 	\return An iterator referring to the element now being located at index
382 			\a index (End(), if it was the last element that has been
383 			removed), or Null(), if \a index was out of range.
384 */
385 _VECTOR_TEMPLATE_LIST
386 _VECTOR_CLASS_TYPE::Iterator
387 _VECTOR_CLASS_NAME::Erase(int32 index)
388 {
389 	if (index >= 0 && index < fItemCount) {
390 		fItems[index].~Value();
391 		_MoveItems(fItems + index + 1, -1, fItemCount - index - 1);
392 		_Resize(fItemCount - 1);
393 		return Iterator(fItems + index);
394 	}
395 	return Null();
396 }
397 
398 // Erase
399 /*!	\brief Removes the element at the given position.
400 	\param iterator An iterator referring to the element to be removed.
401 	\return An iterator referring to the element succeeding the removed
402 			one (End(), if it was the last element that has been
403 			removed), or Null(), if \a iterator was an invalid iterator
404 			(in this case including End()).
405 */
406 _VECTOR_TEMPLATE_LIST
407 _VECTOR_CLASS_TYPE::Iterator
408 _VECTOR_CLASS_NAME::Erase(const Iterator &iterator)
409 {
410 	int32 index = _IteratorIndex(iterator);
411 	if (index >= 0 && index < fItemCount)
412 		return Erase(index);
413 	return Null();
414 }
415 
416 // Count
417 /*!	\brief Returns the number of elements the vector contains.
418 	\return The number of elements the vector contains.
419 */
420 _VECTOR_TEMPLATE_LIST
421 inline
422 int32
423 _VECTOR_CLASS_NAME::Count() const
424 {
425 	return fItemCount;
426 }
427 
428 // IsEmpty
429 /*!	\brief Returns whether the vector is empty.
430 	\return \c true, if the vector is empty, \c false otherwise.
431 */
432 _VECTOR_TEMPLATE_LIST
433 inline
434 bool
435 _VECTOR_CLASS_NAME::IsEmpty() const
436 {
437 	return (fItemCount == 0);
438 }
439 
440 // MakeEmpty
441 /*!	\brief Removes all elements from the vector.
442 */
443 _VECTOR_TEMPLATE_LIST
444 void
445 _VECTOR_CLASS_NAME::MakeEmpty()
446 {
447 	for (int32 i = 0; i < fItemCount; i++)
448 		fItems[i].~Value();
449 	_Resize(0);
450 }
451 
452 // Begin
453 /*!	\brief Returns an iterator referring to the beginning of the vector.
454 
455 	If the vector is not empty, Begin() refers to its first element,
456 	otherwise it is equal to End() and must not be dereferenced!
457 
458 	\return An iterator referring to the beginning of the vector.
459 */
460 _VECTOR_TEMPLATE_LIST
461 inline
462 _VECTOR_CLASS_TYPE::Iterator
463 _VECTOR_CLASS_NAME::Begin()
464 {
465 	return Iterator(fItems);
466 }
467 
468 // Begin
469 /*!	\brief Returns an iterator referring to the beginning of the vector.
470 
471 	If the vector is not empty, Begin() refers to its first element,
472 	otherwise it is equal to End() and must not be dereferenced!
473 
474 	\return An iterator referring to the beginning of the vector.
475 */
476 _VECTOR_TEMPLATE_LIST
477 inline
478 _VECTOR_CLASS_TYPE::ConstIterator
479 _VECTOR_CLASS_NAME::Begin() const
480 {
481 	return ConstIterator(fItems);
482 }
483 
484 // End
485 /*!	\brief Returns an iterator referring to the end of the vector.
486 
487 	The position identified by End() is the one succeeding the last
488 	element, i.e. it must not be dereferenced!
489 
490 	\return An iterator referring to the end of the vector.
491 */
492 _VECTOR_TEMPLATE_LIST
493 inline
494 _VECTOR_CLASS_TYPE::Iterator
495 _VECTOR_CLASS_NAME::End()
496 {
497 	return Iterator(fItems + fItemCount);
498 }
499 
500 // End
501 /*!	\brief Returns an iterator referring to the end of the vector.
502 
503 	The position identified by End() is the one succeeding the last
504 	element, i.e. it must not be dereferenced!
505 
506 	\return An iterator referring to the end of the vector.
507 */
508 _VECTOR_TEMPLATE_LIST
509 inline
510 _VECTOR_CLASS_TYPE::ConstIterator
511 _VECTOR_CLASS_NAME::End() const
512 {
513 	return ConstIterator(fItems + fItemCount);
514 }
515 
516 // Null
517 /*!	\brief Returns an invalid iterator.
518 
519 	Null() is used as a return value, if something went wrong. It must
520 	neither be incremented or decremented nor dereferenced!
521 
522 	\return An invalid iterator.
523 */
524 _VECTOR_TEMPLATE_LIST
525 inline
526 _VECTOR_CLASS_TYPE::Iterator
527 _VECTOR_CLASS_NAME::Null()
528 {
529 	return Iterator(NULL);
530 }
531 
532 // Null
533 /*!	\brief Returns an invalid iterator.
534 
535 	Null() is used as a return value, if something went wrong. It must
536 	neither be incremented or decremented nor dereferenced!
537 
538 	\return An invalid iterator.
539 */
540 _VECTOR_TEMPLATE_LIST
541 inline
542 _VECTOR_CLASS_TYPE::ConstIterator
543 _VECTOR_CLASS_NAME::Null() const
544 {
545 	return ConstIterator(NULL);
546 }
547 
548 // IteratorForIndex
549 /*!	\brief Returns an iterator for a given index.
550 	\return An iterator referring to the same element as \a index, or
551 			End(), if \a index is out of range.
552 */
553 _VECTOR_TEMPLATE_LIST
554 inline
555 _VECTOR_CLASS_TYPE::Iterator
556 _VECTOR_CLASS_NAME::IteratorForIndex(int32 index)
557 {
558 	if (index >= 0 && index <= fItemCount)
559 		return Iterator(fItems + index);
560 	return End();
561 }
562 
563 // IteratorForIndex
564 /*!	\brief Returns an iterator for a given index.
565 	\return An iterator referring to the same element as \a index, or
566 			End(), if \a index is out of range.
567 */
568 _VECTOR_TEMPLATE_LIST
569 inline
570 _VECTOR_CLASS_TYPE::ConstIterator
571 _VECTOR_CLASS_NAME::IteratorForIndex(int32 index) const
572 {
573 	if (index >= 0 && index <= fItemCount)
574 		return ConstIterator(fItems + index);
575 	return End();
576 }
577 
578 // ElementAt
579 /*!	\brief Returns the element at a given index.
580 	\param index The index identifying the element to be returned.
581 	\return The element identified by the given index.
582 */
583 _VECTOR_TEMPLATE_LIST
584 inline
585 const Value &
586 _VECTOR_CLASS_NAME::ElementAt(int32 index) const
587 {
588 	if (index >= 0 && index < fItemCount)
589 		return fItems[index];
590 	// Return the 0th element by default. Unless the allocation failed, there
591 	// is always a 0th element -- uninitialized perhaps.
592 	return fItems[0];
593 }
594 
595 // ElementAt
596 /*!	\brief Returns the element at a given index.
597 	\param index The index identifying the element to be returned.
598 	\return The element identified by the given index.
599 */
600 _VECTOR_TEMPLATE_LIST
601 inline
602 Value &
603 _VECTOR_CLASS_NAME::ElementAt(int32 index)
604 {
605 	if (index >= 0 && index < fItemCount)
606 		return fItems[index];
607 	// Return the 0th element by default. Unless the allocation failed, there
608 	// is always a 0th element -- uninitialized perhaps.
609 	return fItems[0];
610 }
611 
612 // IndexOf
613 /*!	\brief Returns the index of the next element with the specified value.
614 	\param value The value of the element to be found.
615 	\param start The index at which to be started to search for the element.
616 	\return The index of the found element, or \c -1, if no further element
617 			with the given value could be found or \a index is out of range.
618 */
619 _VECTOR_TEMPLATE_LIST
620 int32
621 _VECTOR_CLASS_NAME::IndexOf(const Value &value, int32 start) const
622 {
623 	if (start >= 0) {
624 		for (int32 i = start; i < fItemCount; i++) {
625 			if (fItems[i] == value)
626 				return i;
627 		}
628 	}
629 	return -1;
630 }
631 
632 // Find
633 /*!	\brief Returns an iterator referring to the next element with the
634 		   specified value.
635 	\param value The value of the element to be found.
636 	\return An iterator referring to the found element, or End(), if no
637 			further with the given value could be found.
638 */
639 _VECTOR_TEMPLATE_LIST
640 inline
641 _VECTOR_CLASS_TYPE::Iterator
642 _VECTOR_CLASS_NAME::Find(const Value &value)
643 {
644 	return Find(value, Begin());
645 }
646 
647 // Find
648 /*!	\brief Returns an iterator referring to the next element with the
649 		   specified value.
650 	\param value The value of the element to be found.
651 	\param start And iterator specifying where to start searching for the
652 		   element.
653 	\return An iterator referring to the found element, or End(), if no
654 			further with the given value could be found or \a start was
655 			invalid.
656 */
657 _VECTOR_TEMPLATE_LIST
658 _VECTOR_CLASS_TYPE::Iterator
659 _VECTOR_CLASS_NAME::Find(const Value &value, const Iterator &start)
660 {
661 	int32 index = IndexOf(value, _IteratorIndex(start));
662 	if (index >= 0)
663 		return Iterator(fItems + index);
664 	return End();
665 }
666 
667 // Find
668 /*!	\brief Returns an iterator referring to the of the next element with the
669 		   specified value.
670 	\param value The value of the element to be found.
671 	\return An iterator referring to the found element, or End(), if no
672 			further with the given value could be found.
673 */
674 _VECTOR_TEMPLATE_LIST
675 inline
676 _VECTOR_CLASS_TYPE::ConstIterator
677 _VECTOR_CLASS_NAME::Find(const Value &value) const
678 {
679 	return Find(value, Begin());
680 }
681 
682 // Find
683 /*!	\brief Returns an iterator referring to the of the next element with the
684 		   specified value.
685 	\param value The value of the element to be found.
686 	\param start And iterator specifying where to start searching for the
687 		   element.
688 	\return An iterator referring to the found element, or End(), if no
689 			further with the given value could be found or \a start was
690 			invalid.
691 */
692 _VECTOR_TEMPLATE_LIST
693 _VECTOR_CLASS_TYPE::ConstIterator
694 _VECTOR_CLASS_NAME::Find(const Value &value, const ConstIterator &start) const
695 {
696 	int32 index = IndexOf(value, _IteratorIndex(start));
697 	if (index >= 0)
698 		return ConstIterator(fItems + index);
699 	return End();
700 }
701 
702 // []
703 /*!	\brief Semantically equivalent to ElementAt().
704 */
705 _VECTOR_TEMPLATE_LIST
706 inline
707 Value &
708 _VECTOR_CLASS_NAME::operator[](int32 index)
709 {
710 	return ElementAt(index);
711 }
712 
713 // []
714 /*!	\brief Semantically equivalent to ElementAt().
715 */
716 _VECTOR_TEMPLATE_LIST
717 inline
718 const Value &
719 _VECTOR_CLASS_NAME::operator[](int32 index) const
720 {
721 	return ElementAt(index);
722 }
723 
724 // _Resize
725 /*!	\brief Resizes the vector.
726 
727 	The internal element array will be grown or shrunk to the next multiple
728 	of \a fChunkSize >= \a count, but no less than \a fChunkSize.
729 
730 	Also adjusts \a fItemCount according to the supplied \a count, but does
731 	not invoke a destructor or constructor on any element.
732 
733 	\param count The number of element.
734 	\return \c true, if everything went fine, \c false, if the memory
735 			allocation failed.
736 */
737 _VECTOR_TEMPLATE_LIST
738 bool
739 _VECTOR_CLASS_NAME::_Resize(size_t count)
740 {
741 	bool result = true;
742 	// calculate the new capacity
743 	int32 newSize = count;
744 	if (newSize <= 0)
745 		newSize = 1;
746 	newSize = ((newSize - 1) / fChunkSize + 1) * fChunkSize;
747 	// resize if necessary
748 	if ((size_t)newSize != fCapacity) {
749 		Value* newItems = (Value*)realloc(fItems, newSize * sizeof(Value));
750 		if (newItems) {
751 			fItems = newItems;
752 			fCapacity = newSize;
753 		} else
754 			result = false;
755 	}
756 	if (result)
757 		fItemCount = count;
758 	return result;
759 }
760 
761 // _IteratorIndex
762 /*!	\brief Returns index of the element the supplied iterator refers to.
763 	\return The index of the element the supplied iterator refers to, or
764 			\c -1, if the iterator is invalid (End() is considered valid
765 			here, and Count() is returned).
766 */
767 _VECTOR_TEMPLATE_LIST
768 inline
769 int32
770 _VECTOR_CLASS_NAME::_IteratorIndex(const Iterator &iterator) const
771 {
772 	if (iterator.Element()) {
773 		int32 index = iterator.Element() - fItems;
774 		if (index >= 0 && index <= fItemCount)
775 			return index;
776 	}
777 	return -1;
778 }
779 
780 // _IteratorIndex
781 /*!	\brief Returns index of the element the supplied iterator refers to.
782 	\return The index of the element the supplied iterator refers to, or
783 			\c -1, if the iterator is invalid (End() is considered valid
784 			here, and Count() is returned).
785 */
786 _VECTOR_TEMPLATE_LIST
787 inline
788 int32
789 _VECTOR_CLASS_NAME::_IteratorIndex(const ConstIterator &iterator) const
790 {
791 	if (iterator.Element()) {
792 		int32 index = iterator.Element() - fItems;
793 		if (index >= 0 && index <= fItemCount)
794 			return index;
795 	}
796 	return -1;
797 }
798 
799 #endif	// _VECTOR_H
800