1 /*
2 ===========================================================================
3 Copyright (C) 2000 - 2013, Raven Software, Inc.
4 Copyright (C) 2001 - 2013, Activision, Inc.
5 Copyright (C) 2013 - 2015, OpenJK contributors
6 
7 This file is part of the OpenJK source code.
8 
9 OpenJK is free software; you can redistribute it and/or modify it
10 under the terms of the GNU General Public License version 2 as
11 published by the Free Software Foundation.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 ===========================================================================
21 */
22 
23 ////////////////////////////////////////////////////////////////////////////////////////
24 // RAVEN STANDARD TEMPLATE LIBRARY
25 //  (c) 2002 Activision
26 //
27 //
28 // Vector
29 // ------
30 // The vector class is a simple addition to the array.  It supports some useful additions
31 // like sort and binary search, as well as keeping track of the number of objects
32 // contained within.
33 //
34 //
35 //
36 //
37 //
38 // NOTES:
39 //
40 //
41 ////////////////////////////////////////////////////////////////////////////////////////
42 #if !defined(RATL_VECTOR_VS_INC)
43 #define RATL_VECTOR_VS_INC
44 
45 
46 ////////////////////////////////////////////////////////////////////////////////////////
47 // Includes
48 ////////////////////////////////////////////////////////////////////////////////////////
49 #if !defined(RATL_COMMON_INC)
50 	#include "ratl_common.h"
51 #endif
52 namespace ratl
53 {
54 
55 
56 ////////////////////////////////////////////////////////////////////////////////////////
57 // The Vector Class
58 ////////////////////////////////////////////////////////////////////////////////////////
59 template<class T>
60 class vector_base : public ratl_base
61 {
62 public:
63     typedef T TStorageTraits;
64 	typedef typename T::TValue TTValue;
65     ////////////////////////////////////////////////////////////////////////////////////
66 	// Capacity Enum
67     ////////////////////////////////////////////////////////////////////////////////////
68 	static const int CAPACITY		= T::CAPACITY;
69 private:
70 	array_base<TStorageTraits>		mArray;			// The Memory
71 	int								mSize;
72 public:
73 
74 	////////////////////////////////////////////////////////////////////////////////////
75 	// Constructor
76     ////////////////////////////////////////////////////////////////////////////////////
vector_base()77 	vector_base()
78 	{
79 		mSize = 0;
80 	}
81 
82 	////////////////////////////////////////////////////////////////////////////////////
83 	// Copy Constructor
84 	////////////////////////////////////////////////////////////////////////////////////
vector_base(const vector_base & B)85 	vector_base(const vector_base &B)
86 	{
87 		for (int i=0; i<B.size(); i++)
88 		{
89 			mArray[i] = B.mArray[i];
90 		}
91 		mSize = B.mSize;
92 	}
93 
94     ////////////////////////////////////////////////////////////////////////////////////
95 	// How Many Objects Can Be Added?
96     ////////////////////////////////////////////////////////////////////////////////////
capacity()97 	int				capacity() const
98 	{
99 		assert(mSize>=0&&mSize<=CAPACITY);
100 		return (CAPACITY);
101 	}
102 
103     ////////////////////////////////////////////////////////////////////////////////////
104 	// How Many Objects Have Been Added To This Vector?
105     ////////////////////////////////////////////////////////////////////////////////////
size()106 	int				size() const
107 	{
108 		assert(mSize>=0&&mSize<=CAPACITY);
109 		return (mSize);
110 	}
111 
112     ////////////////////////////////////////////////////////////////////////////////////
113 	// Have Any Objects Have Been Added To This Vector?
114     ////////////////////////////////////////////////////////////////////////////////////
empty()115 	bool			empty() const
116 	{
117 		assert(mSize>=0&&mSize<=CAPACITY);
118 		return (!mSize);
119 	}
120 
121     ////////////////////////////////////////////////////////////////////////////////////
122 	// Have Any Objects Have Been Added To This Vector?
123     ////////////////////////////////////////////////////////////////////////////////////
full()124 	bool			full() const
125 	{
126 		assert(mSize>=0&&mSize<=CAPACITY);
127 		return (mSize==CAPACITY);
128 	}
129 
130 	////////////////////////////////////////////////////////////////////////////////////
131 	// Clear Out Entire Array
132 	////////////////////////////////////////////////////////////////////////////////////
clear()133 	void			clear()
134 	{
135 		mArray.clear();
136 		mSize = 0;
137 	}
138 	// Constant Access Operator
139 	////////////////////////////////////////////////////////////////////////////////////
140 	const TTValue&		operator[](int index) const
141 	{
142 		assert(index>=0&&index<mSize);
143 		return mArray[index];
144 	}
145 
146 	////////////////////////////////////////////////////////////////////////////////////
147 	// Access Operator
148 	////////////////////////////////////////////////////////////////////////////////////
149 	TTValue&				operator[](int index)
150 	{
151 		assert(index>=0&&index<mSize);
152 		return mArray[index];
153 	}
154 
155 	////////////////////////////////////////////////////////////////////////////////////
156 	// Access To The Raw Array Pointer
157 	////////////////////////////////////////////////////////////////////////////////////
raw_array()158 	TTValue *				raw_array()
159 	{
160 		  // this (intentionally) won't compile for anything except value semantics
161 			// could be done with object semantics, but I would want to assert that all objects are contructed
162 		  return T::raw_array(mArray);
163 	}
164 
165 	////////////////////////////////////////////////////////////////////////////////////
166 	// Access To The Raw Array Pointer
167 	////////////////////////////////////////////////////////////////////////////////////
raw_array()168 	const TTValue*				raw_array() const
169 	{
170 		  // this (intentionally) won't compile for anything except value semantics
171 			// could be done with object semantics, but I would want to assert that all objects are contructed
172 		  return T::raw_array(mArray);
173 	}
174 
175 
176 	////////////////////////////////////////////////////////////////////////////////////
177 	// Assignment Operator
178 	////////////////////////////////////////////////////////////////////////////////////
179 	vector_base&		operator=(const vector_base& val)
180 	{
181 		for (int i=0; i<val.size(); i++)
182 		{
183 			mArray[i] = val.mArray[i];
184 		}
185 		mSize = val.mSize;
186 		return *this;
187 	}
188 
189 	////////////////////////////////////////////////////////////////////////////////////
190 	// Add
191 	////////////////////////////////////////////////////////////////////////////////////
push_back()192 	TTValue &				push_back()
193 	{
194 		assert(mSize>=0&&mSize<CAPACITY);
195 		mArray.construct(mSize);
196 		mSize++;
197 		return (mArray[mSize-1]);
198 	}
199 
200 	////////////////////////////////////////////////////////////////////////////////////
201 	// Add (And Set)
202 	////////////////////////////////////////////////////////////////////////////////////
push_back(const TTValue & value)203 	void			push_back(const TTValue& value)
204 	{
205 		assert(mSize>=0&&mSize<CAPACITY);
206 		mArray.construct(mSize,value);
207 		mSize++;
208 	}
209 
210 	////////////////////////////////////////////////////////////////////////////////////
211 	// Add raw
212 	////////////////////////////////////////////////////////////////////////////////////
push_back_raw()213 	TRatlNew *			push_back_raw()
214 	{
215 		assert(mSize>=0&&mSize<CAPACITY);
216 		mSize++;
217 		return mArray.alloc_raw(mSize-1);
218 	}
219 
220 	////////////////////////////////////////////////////////////////////////////////////
221 	// Remove
222 	////////////////////////////////////////////////////////////////////////////////////
pop_back()223 	void			pop_back()
224 	{
225 		assert(mSize>0);
226 		mSize--;
227 		mArray.destruct(mSize);
228 	}
229 
230 	////////////////////////////////////////////////////////////////////////////////////
231 	// Resizes The Array.  If New Elements Are Needed, It Uses The (value) Param
232 	////////////////////////////////////////////////////////////////////////////////////
resize(int nSize,const TTValue & value)233 	void			resize(int nSize, const TTValue& value)
234 	{
235 		int i;
236 		for (i=(mSize-1); i>=nSize; i--)
237 		{
238 			mArray.destruct(i);
239 			mSize--;
240 		}
241 		for (i=mSize; i<nSize; i++)
242 		{
243 			mArray.construct(i,value);
244 		}
245 		mSize = nSize;
246 	}
247 
248 	////////////////////////////////////////////////////////////////////////////////////
249 	// Resizes The Array.  If New Elements Are Needed, It Uses The (value) Param
250 	////////////////////////////////////////////////////////////////////////////////////
resize(int nSize)251 	void			resize(int nSize)
252 	{
253 		int i;
254 		for (i=mSize-1; i>=nSize; i--)
255 		{
256 			mArray.destruct(i);
257 			mSize--;
258 		}
259 		for (i=mSize; i<nSize; i++)
260 		{
261 			mArray.construct(i);
262 		}
263 		mSize = nSize;
264 	}
265 
266 	////////////////////////////////////////////////////////////////////////////////////
267 	// Swap the values at two locations
268 	////////////////////////////////////////////////////////////////////////////////////
swap(int i,int j)269 	void swap(int i,int j)
270 	{
271 		assert(i<mSize && j<mSize);
272 		mArray.swap(i, j);
273 	}
274 
275 
276 
277 	////////////////////////////////////////////////////////////////////////////////////
278 	// Erase An Iterator Location... NOTE: THIS DOES NOT PRESERVE ORDER IN THE VECTOR!!
279 	////////////////////////////////////////////////////////////////////////////////////
erase_swap(int Index)280 	void erase_swap(int Index)
281 	{
282 		assert(Index>=0 && Index<mSize);
283 		if (Index != mSize - 1)
284 		{
285 			mArray.swap(Index, mSize - 1);
286 		}
287 		pop_back();
288 	}
289 
290 
291 	////////////////////////////////////////////////////////////////////////////////////
292 	// Binary Search
293 	////////////////////////////////////////////////////////////////////////////////////
find_index(const TTValue & value)294 	int				find_index(const TTValue& value) const
295 	{
296 		int base = 0;
297 		int head = mSize-1;
298 
299 		while (1)
300 		{
301 			int searchAt = (base+head)/2;
302 
303 			if (base == head && searchAt == head)
304 			{
305 				break;
306 			}
307 
308 			if (value < mArray[searchAt])
309 			{
310 				head = searchAt-1;
311 			}
312 			else if (mArray[searchAt] < value)
313 			{
314 				base = searchAt;
315 			}
316 			else
317 			{
318 				return searchAt;
319 			}
320 			if (head < base)
321 			{
322 				break;
323 			}
324 		}
325 
326 		return mSize; //not found!
327 	}
328 
329 
330 	////////////////////////////////////////////////////////////////////////////////////
331 	// Heap Sort
332 	//
333 	// This sort algorithm has all the advantages of merge sort in terms of guarenteeing
334 	// O(n log n) worst case, as well as all the advantages of quick sort in that it is
335 	// "in place" and requires no additional storage.
336 	//
337 	////////////////////////////////////////////////////////////////////////////////////
sort()338 	void			sort()
339 	{
340 		// Temporary Data
341 		//----------------
342 		int	HeapSize;	// How Large The Heap Is (Grows In PHASE 1, Shrinks In PHASE 2)
343 		int	Pos;		// The Location We Are AT During "re-heapify" Loops
344 		int	Compare;	// The Location We Are Comparing AGAINST During "re-heapify" Loops
345 
346 
347 
348 
349 		// PHASE 1, CONSTRUCT THE HEAP										  O(n log n)
350 		//===============================================================================
351 		for (HeapSize=1; HeapSize<mSize; HeapSize++)
352 		{
353 			// We Now Have An Element At Heap Size Which Is Not In It's Correct Place
354 			//------------------------------------------------------------------------
355 			Pos		= HeapSize;
356 			Compare	= parent(Pos);
357 			while (mArray[Compare]<mArray[Pos])
358 			{
359 				// Swap The Compare Element With The Pos Element
360 				//-----------------------------------------------
361 				mArray.swap(Compare, Pos);
362 
363 				// Move Pos To The Current Compare, And Recalc Compare
364 				//------------------------------------------------------
365 				Pos		= Compare;
366 				Compare = parent(Pos);
367 			}
368 		}
369 
370 
371 
372 
373 		// PHASE 2, POP OFF THE TOP OF THE HEAP ONE AT A TIME (AND FIX)       O(n log n)
374 		//===============================================================================
375 		for (HeapSize=(mSize-1); HeapSize>0; HeapSize--)
376 		{
377 			// Swap The End And Front Of The "Heap" Half Of The Array
378 			//--------------------------------------------------------
379 			mArray.swap(0, HeapSize);
380 
381 			// We Now Have A Bogus Element At The Root, So Fix The Heap
382 			//----------------------------------------------------------
383 			Pos		= 0;
384 			Compare = largest_child(Pos, HeapSize);
385 			while (mArray[Pos]<mArray[Compare])
386 			{
387 				// Swap The Compare Element With The Pos Element
388 				//-----------------------------------------------
389 				mArray.swap(Compare, Pos);
390 
391 				// Move Pos To The Current Compare, And Recalc Compare
392 				//------------------------------------------------------
393 				Pos		= Compare;
394 				Compare	= largest_child(Pos, HeapSize);
395 			}
396 		}
397 	}
398 
399 
400 	////////////////////////////////////////////////////////////////////////////////////
401 	// THIS IS A QUICK VALIDATION OF A SORTED LIST
402 	////////////////////////////////////////////////////////////////////////////////////
403 #ifdef _DEBUG
sort_validate()404 	void			sort_validate() const
405 	{
406 		for (int a=0; a<(mSize-1); a++)
407 		{
408 			assert(mArray[a] < mArray[a+1]);
409 		}
410 	}
411 #endif
412 
413 private:
414 	////////////////////////////////////////////////////////////////////////////////////
415 	// For Heap Sort
416 	// Returns The Location Of Node (i)'s Parent Node (The Parent Node Of Zero Is Zero)
417 	////////////////////////////////////////////////////////////////////////////////////
parent(int i)418 	static int			parent(int i)
419 	{
420 		return ((i-1)/2);
421 	}
422 
423 	////////////////////////////////////////////////////////////////////////////////////
424 	// For Heap Sort
425 	// Returns The Location Of Node (i)'s Left Child (The Child Of A Leaf Is The Leaf)
426 	////////////////////////////////////////////////////////////////////////////////////
left(int i)427 	static int			left(int i)
428 	{
429 		return ((2*i)+1);
430 	}
431 
432 	////////////////////////////////////////////////////////////////////////////////////
433 	// For Heap Sort
434 	// Returns The Location Of Node (i)'s Right Child (The Child Of A Leaf Is The Leaf)
435 	////////////////////////////////////////////////////////////////////////////////////
right(int i)436 	static int			right(int i)
437 	{
438 		return ((2*i)+2);
439 	}
440 
441 	////////////////////////////////////////////////////////////////////////////////////
442 	// For Heap Sort
443 	// Returns The Location Of Largest Child Of Node (i)
444 	////////////////////////////////////////////////////////////////////////////////////
largest_child(int i,int Size)445 	int			largest_child(int i, int Size) const
446 	{
447 		if (left(i)<Size)
448 		{
449 			if (right(i)<Size)
450 			{
451 				return ( (mArray[right(i)] < mArray[left(i)]) ? (left(i)) : (right(i)) );
452 			}
453 			return left(i);	// Node i only has a left child, so by default it is the biggest
454 		}
455 		return i;		// Node i is a leaf, so just return it
456 	}
457 
458 public:
459     ////////////////////////////////////////////////////////////////////////////////////
460 	// Iterator
461     ////////////////////////////////////////////////////////////////////////////////////
462 	class const_iterator;
463 	class iterator
464 	{
465 		friend class vector_base<T>;
466 		friend class const_iterator;
467 		// Data
468 		//------
469 		int						mLoc;
470 		vector_base<T>*			mOwner;
471 
472 	public:
473 		// Constructors
474 		//--------------
iterator()475 		iterator()						: mOwner(0), mLoc(0)
476 		{}
iterator(vector_base<T> * p,int t)477 		iterator(vector_base<T>* p, int t)	: mOwner(p), mLoc(t)
478 		{}
479 
iterator(const iterator & t)480 		iterator(const iterator &t)		: mOwner(t.mOwner), mLoc(t.mLoc)
481 		{}
482 
483 		// Assignment Operator
484 		//---------------------
485 		void		operator= (const iterator &t)
486 		{
487 			mOwner	= t.mOwner;
488 			mLoc	= t.mLoc;
489 		}
490 
491 
492 		// Equality Operators
493 		//--------------------
494 		bool		operator!=(const iterator &t)	const
495 		{
496 			return (mLoc!=t.mLoc  || mOwner!=t.mOwner);
497 		}
498 		bool		operator==(const iterator &t)	const
499 		{
500 			return (mLoc==t.mLoc && mOwner==t.mOwner);
501 		}
502 
503 		// DeReference Operator
504 		//----------------------
505 		TTValue&			operator* ()	const
506 		{
507 			assert(mLoc>=0 && mLoc<mOwner->mSize);
508 			return (mOwner->mArray[mLoc]);
509 		}
510 		// DeReference Operator
511 		//----------------------
value()512 		TTValue&			value()	const
513 		{
514 			assert(mLoc>=0 && mLoc<mOwner->mSize);
515 			return (mOwner->mArray[mLoc]);
516 		}
517 
518 		// DeReference Operator
519 		//----------------------
520 		TTValue*			operator-> ()	const
521 		{
522 			assert(mLoc>=0 && mLoc<mOwner->mSize);
523 			return (&mOwner->mArray[mLoc]);
524 		}
525 
526 		// Inc Operator
527 		//--------------
528 		iterator	operator++(int) //postfix
529 		{
530 			assert(mLoc>=0 && mLoc<mOwner->mSize);
531 			iterator old(*this);
532 			mLoc ++;
533 			return old;
534 		}
535 
536 		// Inc Operator
537 		//--------------
538 		iterator	operator++()
539 		{
540 			assert(mLoc>=0 && mLoc<mOwner->mSize);
541 			mLoc ++;
542 			return *this;
543 		}
544 
545 	};
546 
547     ////////////////////////////////////////////////////////////////////////////////////
548 	// Constant Iterator
549     ////////////////////////////////////////////////////////////////////////////////////
550 	class const_iterator
551 	{
552 		friend class vector_base<T>;
553 
554 		int							mLoc;
555 		const vector_base<T>*		mOwner;
556 
557 	public:
558 		// Constructors
559 		//--------------
const_iterator()560 		const_iterator()							: mOwner(0), mLoc(0)
561 		{}
const_iterator(const vector_base<T> * p,int t)562 		const_iterator(const vector_base<T>* p, int t)	: mOwner(p), mLoc(t)
563 		{}
const_iterator(const const_iterator & t)564 		const_iterator(const const_iterator &t)		: mOwner(t.mOwner), mLoc(t.mLoc)
565 		{}
const_iterator(const iterator & t)566 		const_iterator(const iterator &t)			: mOwner(t.mOwner), mLoc(t.mLoc)
567 		{}
568 
569 		// Assignment Operator
570 		//---------------------
571 		void		operator= (const const_iterator &t)
572 		{
573 			mOwner	= t.mOwner;
574 			mLoc	= t.mLoc;
575 		}
576 		// Assignment Operator
577 		//---------------------
578 		void		operator= (const iterator &t)
579 		{
580 			mOwner	= t.mOwner;
581 			mLoc	= t.mLoc;
582 		}
583 
584 
585 
586 		// Equality Operators
587 		//--------------------
588 		bool		operator!=(const iterator &t)		const
589 		{
590 			return (mLoc!=t.mLoc  || mOwner!=t.mOwner);
591 		}
592 		bool		operator==(const iterator &t)		const
593 		{
594 			return (mLoc==t.mLoc && mOwner==t.mOwner);
595 		}
596 
597 		// Equality Operators
598 		//--------------------
599 		bool		operator!=(const const_iterator &t)		const
600 		{
601 			return (mLoc!=t.mLoc || mOwner!=t.mOwner);
602 		}
603 		bool		operator==(const const_iterator &t)		const
604 		{
605 			return (mLoc==t.mLoc  && mOwner==t.mOwner);
606 		}
607 
608 		// DeReference Operator
609 		//----------------------
610 		const TTValue&			operator* ()		const
611 		{
612 			assert(mLoc>=0 && mLoc<mOwner->mSize);
613 			return (mOwner->mArray[mLoc]);
614 		}
615 
616 		// DeReference Operator
617 		//----------------------
value()618 		const TTValue&			value()		const
619 		{
620 			assert(mLoc>=0 && mLoc<mOwner->mSize);
621 			return (mOwner->mArray[mLoc]);
622 		}
623 
624 		// DeReference Operator
625 		//----------------------
626 		const TTValue*			operator-> ()		const
627 		{
628 			assert(mLoc>=0 && mLoc<mOwner->mSize);
629 			return (&mOwner->mArray[mLoc]);
630 		}
631 
632 		// Inc Operator
633 		//--------------
634 		const_iterator operator++(int)
635 		{
636 			assert(mLoc>=0 && mLoc<mOwner->mSize);
637 			const_iterator old(*this);
638 			mLoc ++;
639 			return old;
640 		}
641 
642 		// Inc Operator
643 		//--------------
644 		const_iterator operator++()
645 		{
646 			assert(mLoc>=0 && mLoc<mOwner->mSize);
647 			mLoc ++;
648 			return *this;
649 		}
650 
651 
652 	};
653 	friend class				iterator;
654 	friend class				const_iterator;
655 
656 
657     ////////////////////////////////////////////////////////////////////////////////////
658 	// Iterator Begin (Starts At Address 0)
659     ////////////////////////////////////////////////////////////////////////////////////
begin()660 	iterator	begin()
661 	{
662 		return iterator(this, 0);
663 	}
664 
665     ////////////////////////////////////////////////////////////////////////////////////
666 	// Iterator End (Set To Address mSize)
667     ////////////////////////////////////////////////////////////////////////////////////
end()668 	iterator	end()
669 	{
670 		return iterator(this, mSize);
671 	}
672 
673     ////////////////////////////////////////////////////////////////////////////////////
674 	// Iterator Begin (Starts At Address 0)
675     ////////////////////////////////////////////////////////////////////////////////////
begin()676 	const_iterator	begin() const
677 	{
678 		return const_iterator(this, 0);
679 	}
680 
681     ////////////////////////////////////////////////////////////////////////////////////
682 	// Iterator End (Set To Address mSize)
683     ////////////////////////////////////////////////////////////////////////////////////
end()684 	const_iterator	end() const
685 	{
686 		return const_iterator(this, mSize);
687 	}
688 
689 	////////////////////////////////////////////////////////////////////////////////////
690 	// Iterator Find (If Fails To Find, Returns iterator end()
691 	////////////////////////////////////////////////////////////////////////////////////
find(const TTValue & value)692 	iterator	find(const TTValue& value)
693 	{
694 		int		index = find_index(value);		// Call Find By Index
695 		if (index<mSize)
696 		{
697 			return iterator(this, index);		// Found It, Return An Iterator To Index
698 		}
699 		return end();							// Return "end" Iterator If Not Found
700 	}
701 
702 	////////////////////////////////////////////////////////////////////////////////////
703 	// Iterator Find (If Fails To Find, Returns iterator end()
704 	////////////////////////////////////////////////////////////////////////////////////
find(const TTValue & value)705 	const_iterator	find(const TTValue& value) const
706 	{
707 		int		index = find_index(value);		// Call Find By Index
708 		if (index<mSize)
709 		{
710 			return const_iterator(this, index);		// Found It, Return An Iterator To Index
711 		}
712 		return end();							// Return "end" Iterator If Not Found
713 	}
714 
715 	////////////////////////////////////////////////////////////////////////////////////
716 	// Erase An Iterator Location... NOTE: THIS DOES NOT PRESERVE ORDER IN THE VECTOR!!
717 	////////////////////////////////////////////////////////////////////////////////////
erase_swap(const iterator & it)718 	iterator erase_swap(const iterator &it)
719 	{
720 		assert(it.mLoc>=0 && it.mLoc<it.mOwner->mSize);
721 		if (it.mLoc != mSize - 1)
722 		{
723 			mArray.swap(it.mLoc, mSize - 1);
724 		}
725 		pop_back();
726 		return it;
727 	}
728 	template<class CAST_TO>
verify_alloc(CAST_TO * p)729 	CAST_TO *verify_alloc(CAST_TO *p) const
730 	{
731 		return mArray.verify_alloc(p);
732 	}
733 };
734 
735 template<class T, int ARG_CAPACITY>
736 class vector_vs : public vector_base<storage::value_semantics<T,ARG_CAPACITY> >
737 {
738 public:
739 	typedef typename storage::value_semantics<T,ARG_CAPACITY> TStorageTraits;
740 	typedef typename TStorageTraits::TValue TTValue;
741 	static const int CAPACITY		= ARG_CAPACITY;
vector_vs()742 	vector_vs() {}
743 };
744 
745 template<class T, int ARG_CAPACITY>
746 class vector_os : public vector_base<storage::object_semantics<T,ARG_CAPACITY> >
747 {
748 public:
749 	typedef typename storage::object_semantics<T,ARG_CAPACITY> TStorageTraits;
750 	typedef typename TStorageTraits::TValue TTValue;
751 	static const int CAPACITY		= ARG_CAPACITY;
vector_os()752 	vector_os() {}
753 };
754 
755 template<class T, int ARG_CAPACITY, int ARG_MAX_CLASS_SIZE>
756 class vector_is : public vector_base<storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> >
757 {
758 public:
759 	typedef typename storage::virtual_semantics<T,ARG_CAPACITY,ARG_MAX_CLASS_SIZE> TStorageTraits;
760 	typedef typename TStorageTraits::TValue TTValue;
761 	static const int CAPACITY		= ARG_CAPACITY;
762 	static const int MAX_CLASS_SIZE	= ARG_MAX_CLASS_SIZE;
vector_is()763 	vector_is() {}
764 };
765 
766 }
767 #endif
768