xref: /haiku/headers/private/kernel/util/VectorMap.h (revision 51978af14a173e7fae0563b562be5603bc652aeb)
1 // VectorMap.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_MAP_H
29 #define _VECTOR_MAP_H
30 
31 #include <new>
32 #include <stdlib.h>
33 #include <string.h>
34 
35 #include <SupportDefs.h>
36 
37 #include <KernelUtilsOrder.h>
38 #include <Vector.h>
39 
40 namespace VectorMapEntryStrategy {
41 	// Pair
42 	template<typename Key, typename Value,
43 			 typename KeyOrder = KernelUtilsOrder::Ascending<Key> > class Pair;
44 	// ImplicitKey
45 	template<typename Key, typename Value, typename GetKey,
46 			 typename KeyOrder = KernelUtilsOrder::Ascending<Key> >
47 			 class ImplicitKey;
48 }
49 
50 template<typename Entry, typename Parent, typename EntryIterator>
51 	class VectorMapIterator;
52 template<typename _Key, typename _Value, typename Entry, typename Parent>
53 	class VectorMapEntry;
54 
55 // for convenience
56 #define _VECTOR_MAP_TEMPLATE_LIST template<typename Key, typename Value, \
57 										   typename EntryStrategy>
58 #define _VECTOR_MAP_CLASS_NAME VectorMap<Key, Value, EntryStrategy>
59 
60 /*!
61 	\class VectorMap
62 	\brief A generic vector-based map implementation.
63 
64 	The map entries are ordered according to the supplied
65 	compare function object. Default is ascending order.
66 
67 	Note that VectorMap::Entry is not the same class as EntryStrategy::Entry.
68 	It is light-weight class, an object of which is returned when a iterator
69 	is dereferenced. It features a Key() and a Value() method returning
70 	references to the entry's key/value. This allows EntryStrategy::Entry
71 	to be an arbitrary class, not needing to implement a certain interface.
72 */
73 template<typename Key, typename Value,
74 		 typename EntryStrategy = VectorMapEntryStrategy::Pair<Key, Value> >
75 class VectorMap {
76 private:
77 	typedef _VECTOR_MAP_CLASS_NAME							Class;
78 	typedef typename EntryStrategy::Entry					_Entry;
79 	typedef typename EntryStrategy::KeyReference			KeyReference;
80 	typedef Vector<_Entry>									ElementVector;
81 
82 public:
83 	typedef VectorMapEntry<KeyReference, Value, _Entry, Class>
84 															Entry;
85 	typedef VectorMapEntry<KeyReference, const Value, const _Entry,
86 						   const Class>						ConstEntry;
87 	typedef VectorMapIterator<Entry, Class, ElementVector::Iterator>
88 															Iterator;
89 	typedef VectorMapIterator<ConstEntry, const Class,
90 							  ElementVector::ConstIterator>	ConstIterator;
91 
92 private:
93 	static const size_t				kDefaultChunkSize = 10;
94 	static const size_t				kMaximalChunkSize = 1024 * 1024;
95 
96 public:
97 	VectorMap(size_t chunkSize = kDefaultChunkSize);
98 // TODO: Copy constructor, assignment operator.
99 	~VectorMap();
100 
101 	status_t Insert(const Key &key, const Value &value);
102 	status_t Put(const Key &key, const Value &value);
103 	Value &Get(const Key &key);
104 	const Value &Get(const Key &key) const;
105 
106 	int32 Remove(const Key &key);
107 	Iterator Erase(const Iterator &iterator);
108 
109 	inline int32 Count() const;
110 	inline bool IsEmpty() const;
111 	void MakeEmpty();
112 
113 	inline Iterator Begin();
114 	inline ConstIterator Begin() const;
115 	inline Iterator End();
116 	inline ConstIterator End() const;
117 	inline Iterator Null();
118 	inline ConstIterator Null() const;
119 
120 	Iterator Find(const Key &key);
121 	ConstIterator Find(const Key &key) const;
122 	Iterator FindClose(const Key &key, bool less);
123 	ConstIterator FindClose(const Key &key, bool less) const;
124 
125 private:
126 	int32 _FindInsertionIndex(const Key &key, bool &exists) const;
127 
128 private:
129 	friend class Entry;
130 	friend class ConstEntry;
131 
132 	ElementVector	fElements;
133 	EntryStrategy	fEntryStrategy;
134 };
135 
136 
137 // VectorMapEntry
138 template<typename KeyReference, typename _Value, typename Entry,
139 		 typename Parent>
140 class VectorMapEntry {
141 private:
142 	typedef VectorMapEntry<KeyReference, _Value, Entry, Parent>	Class;
143 
144 public:
145 	VectorMapEntry()
146 		: fParent(NULL), fEntry(NULL) {}
147 
148 	inline KeyReference Key() const
149 	{
150 		return fParent->fEntryStrategy.GetKey(*fEntry);
151 	}
152 
153 	inline _Value &Value() const
154 	{
155 		return fParent->fEntryStrategy.GetValue(*fEntry);
156 	}
157 
158 	inline const Class *operator->() const
159 	{
160 		return this;
161 	}
162 
163 // private
164 public:
165 	VectorMapEntry(Parent *parent, Entry *entry)
166 		: fParent(parent), fEntry(entry) {}
167 
168 private:
169 	const Parent	*fParent;
170 	Entry			*fEntry;
171 };
172 
173 
174 // VectorMapIterator
175 template<typename Entry, typename Parent, typename EntryIterator>
176 class VectorMapIterator {
177 private:
178 	typedef VectorMapIterator<Entry, Parent, EntryIterator>	Iterator;
179 
180 public:
181 	inline VectorMapIterator()
182 		: fParent(NULL),
183 		  fIterator()
184 	{
185 	}
186 
187 	inline VectorMapIterator(
188 		const Iterator &other)
189 		: fParent(other.fParent),
190 		  fIterator(other.fIterator)
191 	{
192 	}
193 
194 	inline Iterator &operator++()
195 	{
196 		++fIterator;
197 		return *this;
198 	}
199 
200 	inline Iterator operator++(int)
201 	{
202 		Iterator it(*this);
203 		++*this;
204 		return it;
205 	}
206 
207 	inline Iterator &operator--()
208 	{
209 		--fIterator;
210 		return *this;
211 	}
212 
213 	inline Iterator operator--(int)
214 	{
215 		Iterator it(*this);
216 		--*this;
217 		return it;
218 	}
219 
220 	inline Iterator &operator=(const Iterator &other)
221 	{
222 		fParent = other.fParent;
223 		fIterator = other.fIterator;
224 		return *this;
225 	}
226 
227 	inline bool operator==(const Iterator &other) const
228 	{
229 		return (fParent == other.fParent && fIterator == other.fIterator);
230 	}
231 
232 	inline bool operator!=(const Iterator &other) const
233 	{
234 		return !(*this == other);
235 	}
236 
237 	inline Entry operator*() const
238 	{
239 		return Entry(fParent, &*fIterator);
240 	}
241 
242 	inline Entry operator->() const
243 	{
244 		return Entry(fParent, &*fIterator);
245 	}
246 
247 	inline operator bool() const
248 	{
249 		return fIterator;
250 	}
251 
252 // private
253 public:
254 	inline VectorMapIterator(Parent *parent, const EntryIterator &iterator)
255 		: fParent(parent),
256 		  fIterator(iterator)
257 	{
258 	}
259 
260 	inline EntryIterator &GetIterator()
261 	{
262 		return fIterator;
263 	}
264 
265 	inline const EntryIterator &GetIterator() const
266 	{
267 		return fIterator;
268 	}
269 
270 protected:
271 	Parent			*fParent;
272 	EntryIterator	fIterator;
273 };
274 
275 
276 // VectorMap
277 
278 // constructor
279 /*!	\brief Creates an empty map.
280 	\param chunkSize The granularity for the underlying vector's capacity,
281 		   i.e. the minimal number of elements the capacity grows or shrinks
282 		   when necessary.
283 */
284 _VECTOR_MAP_TEMPLATE_LIST
285 _VECTOR_MAP_CLASS_NAME::VectorMap(size_t chunkSize)
286 	: fElements(chunkSize)
287 {
288 }
289 
290 // destructor
291 /*!	\brief Frees all resources associated with the object.
292 
293 	The contained keys and values are destroyed. Note, that for pointer
294 	types only the pointer is destroyed, not the object it points to.
295 */
296 _VECTOR_MAP_TEMPLATE_LIST
297 _VECTOR_MAP_CLASS_NAME::~VectorMap()
298 {
299 }
300 
301 // Insert
302 /*!	\brief Associates a key with a value.
303 
304 	If there is already a value associated with the key, the old entry
305 	is replaced.
306 
307 	\param key The key to which a value shall be associated.
308 	\param value The value to be associated with the key.
309 	\return
310 	- \c B_OK: Everything went fine.
311 	- \c B_NO_MEMORY: Insufficient memory for this operation.
312 	- \c B_BAD_VALUE: The map's EntryStrategy requires some special
313 	  relationship between key and value, that \a key and \a value haven't
314 	  (doesn't apply to the default strategy).
315 */
316 _VECTOR_MAP_TEMPLATE_LIST
317 status_t
318 _VECTOR_MAP_CLASS_NAME::Insert(const Key &key, const Value &value)
319 {
320 	if (!fEntryStrategy.AreCompatible(key, value))
321 		return B_BAD_VALUE;
322 	bool exists = false;
323 	int32 index = _FindInsertionIndex(key, exists);
324 	if (exists) {
325 		fElements[index] = fEntryStrategy.MakeEntry(key, value);
326 		return B_OK;
327 	}
328 	return fElements.Insert(fEntryStrategy.MakeEntry(key, value), index);
329 }
330 
331 // Put
332 /*!	\brief Equivalent to Insert().
333 */
334 _VECTOR_MAP_TEMPLATE_LIST
335 inline
336 status_t
337 _VECTOR_MAP_CLASS_NAME::Put(const Key &key, const Value &value)
338 {
339 	return Insert(key, value);
340 }
341 
342 // Get
343 /*!	\brief Returns the value associated with a given key.
344 
345 	\note Invoking this method for a key not know to the map is dangerous!
346 		  The behavior is unspecified. It may even crash.
347 
348 	\param key The key to be looked up.
349 	\return The value associated with \a key.
350 */
351 _VECTOR_MAP_TEMPLATE_LIST
352 Value &
353 _VECTOR_MAP_CLASS_NAME::Get(const Key &key)
354 {
355 	bool exists = false;
356 	int32 index = _FindInsertionIndex(key, exists);
357 	if (!exists)
358 		return fEntryStrategy.GetValue(fElements[0]);
359 	return fEntryStrategy.GetValue(fElements[index]);
360 }
361 
362 // Get
363 /*!	\brief Returns the value associated with a given key.
364 
365 	\note Invoking this method for a key not know to the map is dangerous!
366 		  The behavior is unspecified. It may even crash.
367 
368 	\param key The key to be looked up.
369 	\return The value associated with \a key.
370 */
371 _VECTOR_MAP_TEMPLATE_LIST
372 const Value &
373 _VECTOR_MAP_CLASS_NAME::Get(const Key &key) const
374 {
375 	bool exists = false;
376 	int32 index = _FindInsertionIndex(key, exists);
377 	if (!exists)
378 		return fEntryStrategy.GetValue(fElements[0]);
379 	return fEntryStrategy.GetValue(fElements[index]);
380 }
381 
382 // Remove
383 /*!	\brief Removes the entry with the supplied key.
384 	\param key The key to be removed.
385 	\return The number of removed occurrences, i.e. \c 1, if the map
386 			contained an entry with that key, \c 0 otherwise.
387 */
388 _VECTOR_MAP_TEMPLATE_LIST
389 int32
390 _VECTOR_MAP_CLASS_NAME::Remove(const Key &key)
391 {
392 	bool exists = false;
393 	int32 index = _FindInsertionIndex(key, exists);
394 	if (!exists)
395 		return 0;
396 	fElements.Erase(index);
397 	return 1;
398 }
399 
400 // Erase
401 /*!	\brief Removes the entry at the given position.
402 	\param iterator An iterator referring to the entry to be removed.
403 	\return An iterator referring to the entry succeeding the removed
404 			one (End(), if it was the last element that has been
405 			removed), or Null(), if \a iterator was an invalid iterator
406 			(in this case including End()).
407 */
408 _VECTOR_MAP_TEMPLATE_LIST
409 _VECTOR_MAP_CLASS_NAME::Iterator
410 _VECTOR_MAP_CLASS_NAME::Erase(const Iterator &iterator)
411 {
412 	return Iterator(this, fElements.Erase(iterator.GetIterator()));
413 }
414 
415 // Count
416 /*!	\brief Returns the number of entry the map contains.
417 	\return The number of entries the map contains.
418 */
419 _VECTOR_MAP_TEMPLATE_LIST
420 inline
421 int32
422 _VECTOR_MAP_CLASS_NAME::Count() const
423 {
424 	return fElements.Count();
425 }
426 
427 // IsEmpty
428 /*!	\brief Returns whether the map is empty.
429 	\return \c true, if the map is empty, \c false otherwise.
430 */
431 _VECTOR_MAP_TEMPLATE_LIST
432 inline
433 bool
434 _VECTOR_MAP_CLASS_NAME::IsEmpty() const
435 {
436 	return fElements.IsEmpty();
437 }
438 
439 // MakeEmpty
440 /*!	\brief Removes all entries from the map.
441 */
442 _VECTOR_MAP_TEMPLATE_LIST
443 void
444 _VECTOR_MAP_CLASS_NAME::MakeEmpty()
445 {
446 	fElements.MakeEmpty();
447 }
448 
449 // Begin
450 /*!	\brief Returns an iterator referring to the beginning of the map.
451 
452 	If the map is not empty, Begin() refers to its first entry,
453 	otherwise it is equal to End() and must not be dereferenced!
454 
455 	\return An iterator referring to the beginning of the map.
456 */
457 _VECTOR_MAP_TEMPLATE_LIST
458 inline
459 _VECTOR_MAP_CLASS_NAME::Iterator
460 _VECTOR_MAP_CLASS_NAME::Begin()
461 {
462 	return Iterator(this, fElements.Begin());
463 }
464 
465 // Begin
466 /*!	\brief Returns an iterator referring to the beginning of the map.
467 
468 	If the map is not empty, Begin() refers to its first entry,
469 	otherwise it is equal to End() and must not be dereferenced!
470 
471 	\return An iterator referring to the beginning of the map.
472 */
473 _VECTOR_MAP_TEMPLATE_LIST
474 inline
475 _VECTOR_MAP_CLASS_NAME::ConstIterator
476 _VECTOR_MAP_CLASS_NAME::Begin() const
477 {
478 	return ConstIterator(this, fElements.Begin());
479 }
480 
481 // End
482 /*!	\brief Returns an iterator referring to the end of the map.
483 
484 	The position identified by End() is the one succeeding the last
485 	entry, i.e. it must not be dereferenced!
486 
487 	\return An iterator referring to the end of the map.
488 */
489 _VECTOR_MAP_TEMPLATE_LIST
490 inline
491 _VECTOR_MAP_CLASS_NAME::Iterator
492 _VECTOR_MAP_CLASS_NAME::End()
493 {
494 	return Iterator(this, fElements.End());
495 }
496 
497 // End
498 /*!	\brief Returns an iterator referring to the end of the map.
499 
500 	The position identified by End() is the one succeeding the last
501 	entry, i.e. it must not be dereferenced!
502 
503 	\return An iterator referring to the end of the map.
504 */
505 _VECTOR_MAP_TEMPLATE_LIST
506 inline
507 _VECTOR_MAP_CLASS_NAME::ConstIterator
508 _VECTOR_MAP_CLASS_NAME::End() const
509 {
510 	return ConstIterator(this, fElements.End());
511 }
512 
513 // Null
514 /*!	\brief Returns an invalid iterator.
515 
516 	Null() is used as a return value, if something went wrong. It must
517 	neither be incremented or decremented nor dereferenced!
518 
519 	\return An invalid iterator.
520 */
521 _VECTOR_MAP_TEMPLATE_LIST
522 inline
523 _VECTOR_MAP_CLASS_NAME::Iterator
524 _VECTOR_MAP_CLASS_NAME::Null()
525 {
526 	return Iterator(this, fElements.Null());
527 }
528 
529 // Null
530 /*!	\brief Returns an invalid iterator.
531 
532 	Null() is used as a return value, if something went wrong. It must
533 	neither be incremented or decremented nor dereferenced!
534 
535 	\return An invalid iterator.
536 */
537 _VECTOR_MAP_TEMPLATE_LIST
538 inline
539 _VECTOR_MAP_CLASS_NAME::ConstIterator
540 _VECTOR_MAP_CLASS_NAME::Null() const
541 {
542 	return ConstIterator(this, fElements.Null());
543 }
544 
545 // Find
546 /*!	\brief Returns an iterator referring to the entry with the
547 		   specified key.
548 	\param key The key of the entry to be found.
549 	\return An iterator referring to the found entry, or End(), if the
550 			map doesn't contain any entry with the given value.
551 */
552 _VECTOR_MAP_TEMPLATE_LIST
553 _VECTOR_MAP_CLASS_NAME::Iterator
554 _VECTOR_MAP_CLASS_NAME::Find(const Key &key)
555 {
556 	bool exists = false;
557 	int32 index = _FindInsertionIndex(key, exists);
558 	if (!exists)
559 		return End();
560 	return Iterator(this, fElements.IteratorForIndex(index));
561 }
562 
563 // Find
564 /*!	\brief Returns an iterator referring to the entry with the
565 		   specified key.
566 	\param key The key of the entry to be found.
567 	\return An iterator referring to the found entry, or End(), if the
568 			map doesn't contain any entry with the given value.
569 */
570 _VECTOR_MAP_TEMPLATE_LIST
571 _VECTOR_MAP_CLASS_NAME::ConstIterator
572 _VECTOR_MAP_CLASS_NAME::Find(const Key &key) const
573 {
574 	bool exists = false;
575 	int32 index = _FindInsertionIndex(key, exists);
576 	if (!exists)
577 		return End();
578 	return ConstIterator(this, fElements.IteratorForIndex(index));
579 }
580 
581 // FindClose
582 /*!	\brief Returns an iterator referring to the entry with a key closest
583 		   to the specified one.
584 
585 	If the map contains an entry with the specified key, an iterator
586 	to it is returned. Otherwise \a less indicates whether an iterator to
587 	the entry with an directly smaller or greater key shall be returned.
588 
589 	If \a less is \c true and the first entry in the map has a greater
590 	key than the specified one, End() is returned. Similarly, when \a less
591 	is \c false and the last entry's key is smaller. Find() invoked on an
592 	empty map always returns End().
593 
594 	Note, that the key order used for the set is specified as template
595 	argument to the class. Default is ascending order. Descending order
596 	inverts the meaning of \a less, i.e. if \c true, greater values will
597 	be returned, since they are smaller ones according to the order.
598 
599 	\param value The key of the entry to be found.
600 	\return An iterator referring to the found entry, or End(), if the
601 			map doesn't contain any entry with the given key or a close
602 			one according to \a less.
603 */
604 _VECTOR_MAP_TEMPLATE_LIST
605 _VECTOR_MAP_CLASS_NAME::Iterator
606 _VECTOR_MAP_CLASS_NAME::FindClose(const Key &key, bool less)
607 {
608 	bool exists = false;
609 	int32 index = _FindInsertionIndex(key, exists);
610 	// If not found, the index _FindInsertionIndex() returns will point to
611 	// an element with a greater value or to End(). So, no special handling
612 	// is needed for !less.
613 	if (exists || !less)
614 		return Iterator(this, fElements.IteratorForIndex(index));
615 	// An element with a smaller value is desired. The previous one (if any)
616 	// will do.
617 	if (index > 0)
618 		return Iterator(this, fElements.IteratorForIndex(index - 1));
619 	return End();
620 }
621 
622 // FindClose
623 /*!	\brief Returns an iterator referring to the entry with a key closest
624 		   to the specified one.
625 
626 	If the map contains an entry with the specified key, an iterator
627 	to it is returned. Otherwise \a less indicates whether an iterator to
628 	the entry with an directly smaller or greater key shall be returned.
629 
630 	If \a less is \c true and the first entry in the map has a greater
631 	key than the specified one, End() is returned. Similarly, when \a less
632 	is \c false and the last entry's key is smaller. Find() invoked on an
633 	empty map always returns End().
634 
635 	Note, that the key order used for the set is specified as template
636 	argument to the class. Default is ascending order. Descending order
637 	inverts the meaning of \a less, i.e. if \c true, greater values will
638 	be returned, since they are smaller ones according to the order.
639 
640 	\param value The key of the entry to be found.
641 	\return An iterator referring to the found entry, or End(), if the
642 			map doesn't contain any entry with the given key or a close
643 			one according to \a less.
644 */
645 _VECTOR_MAP_TEMPLATE_LIST
646 _VECTOR_MAP_CLASS_NAME::ConstIterator
647 _VECTOR_MAP_CLASS_NAME::FindClose(const Key &key, bool less) const
648 {
649 	bool exists = false;
650 	int32 index = _FindInsertionIndex(key, exists);
651 	// If not found, the index _FindInsertionIndex() returns will point to
652 	// an element with a greater value or to End(). So, no special handling
653 	// is needed for !less.
654 	if (exists || !less)
655 		return ConstIterator(this, fElements.IteratorForIndex(index));
656 	// An element with a smaller value is desired. The previous one (if any)
657 	// will do.
658 	if (index > 0)
659 		return ConstIterator(this, fElements.IteratorForIndex(index - 1));
660 	return End();
661 }
662 
663 // _FindInsertionIndex
664 /*!	\brief Finds the index at which the entry with the supplied key is
665 		   located or at which it would need to be inserted.
666 	\param key The key.
667 	\param exists Is set to \c true, if the map does already contain an
668 		   entry with that key, to \c false otherwise.
669 	\return The index at which the entry with the supplied key is
670 			located or at which it would need to be inserted.
671 */
672 _VECTOR_MAP_TEMPLATE_LIST
673 int32
674 _VECTOR_MAP_CLASS_NAME::_FindInsertionIndex(const Key &key,
675 											bool &exists) const
676 {
677 	// binary search
678 	int32 lower = 0;
679 	int32 upper = Count();
680 	while (lower < upper) {
681 		int32 mid = (lower + upper) / 2;
682 		int cmp = fEntryStrategy.Compare(fEntryStrategy.GetKey(fElements[mid]),
683 															   key);
684 		if (cmp < 0)
685 			lower = mid + 1;
686 		else
687 			upper = mid;
688 	}
689 	exists = (lower < Count() && fEntryStrategy.Compare(key,
690 		fEntryStrategy.GetKey(fElements[lower])) == 0);
691 	return lower;
692 }
693 
694 
695 // entry strategies
696 
697 namespace VectorMapEntryStrategy {
698 
699 // Pair
700 template<typename Key, typename Value, typename KeyOrder>
701 class Pair {
702 public:
703 	typedef const Key	&KeyReference;
704 
705 	class Entry {
706 	public:
707 		Entry(const Key &key, const Value &value)
708 			: key(key), value(value) {}
709 
710 		Key		key;
711 		Value	value;
712 	};
713 
714 	inline KeyReference GetKey(const Entry &entry) const
715 	{
716 		return entry.key;
717 	}
718 
719 	inline const Value &GetValue(const Entry &entry) const
720 	{
721 		return entry.value;
722 	}
723 
724 	inline Value &GetValue(Entry &entry) const
725 	{
726 		return entry.value;
727 	}
728 
729 	inline Entry MakeEntry(const Key &key, const Value &value) const
730 	{
731 		return Entry(key, value);
732 	}
733 
734 	inline bool AreCompatible(const Key &, const Value &) const
735 	{
736 		return true;
737 	}
738 
739 	inline int Compare(const Key &a, const Key &b) const
740 	{
741 		return fCompare(a, b);
742 	}
743 
744 private:
745 	KeyOrder	fCompare;
746 };
747 
748 // ImplicitKey
749 template<typename Key, typename Value, typename _GetKey, typename KeyOrder>
750 class ImplicitKey {
751 public:
752 	typedef Key			KeyReference;
753 	typedef Value		Entry;
754 
755 	inline KeyReference GetKey(const Entry &entry) const
756 	{
757 		return fGetKey(entry);
758 	}
759 
760 	inline const Value &GetValue(const Entry &entry) const
761 	{
762 		return entry;
763 	}
764 
765 	inline Value &GetValue(Entry &entry) const
766 	{
767 		return entry;
768 	}
769 
770 	inline Entry MakeEntry(const Key &, const Value &value) const
771 	{
772 		return value;
773 	}
774 
775 	inline bool AreCompatible(const Key &key, const Value &value) const
776 	{
777 		return (fGetKey(value) == key);
778 	}
779 
780 	inline int Compare(const Key &a, const Key &b) const
781 	{
782 		return fCompare(a, b);
783 	}
784 
785 private:
786 	KeyOrder	fCompare;
787 	_GetKey		fGetKey;
788 };
789 
790 }	// VectorMapEntryStrategy
791 
792 #endif	// _VECTOR_MAP_H
793