#pragma once
#include "nstd_prefix.h"

namespace nstd {


/////////////////////////////////////////////////////////////////////////////////
template< class T > T Median( T t1, T t2, T t3 ) {
  if( t1<t2 ) 
	  return t2<t3 ? t2 : t1<t3 ? t3 : t1;
  return t1<t3 ? t1 : t2<t3 ? t3 : t2;
}
	
/////////////////////////////////////////////////////////////////////////////////
template < typename T, int Size > struct LoopedQueue {
	enum { SizeMask = Size-1 };			
	int mBeginIdx;
	T mBuffer[ Size ];
	typedef int size_type;
	size_type mSize;
	
	LoopedQueue() : mBeginIdx( 0 ), mSize( 0 ) {}

	bool empty() const { return !mSize; }
	size_type size() const { return mSize; }

	T& front() { assert( mSize>0 ); return mBuffer[ mBeginIdx ];  }
	T& back() { assert( mSize>0 ); return mBuffer[ (mBeginIdx+mSize-1)&SizeMask ]; }
	T& operator[]( int theIdx ) { 
		ASSERT( theIdx >= 0 && theIdx < mSize );
		return mBuffer[ ( mBeginIdx + theIdx )&SizeMask ]; 
	}
	void push_front( T const& val ) { 
		mBeginIdx = ( mBeginIdx - 1 )&SizeMask;
		mBuffer[ mBeginIdx ] = val; 
		mSize = ( mSize + 1 )&SizeMask;
	}
	void push_back( T const& val ) { 
		mBuffer[ ( mBeginIdx + mSize )&SizeMask ] = val; 
		if( ++mSize>Size ) { mSize = Size; mBeginIdx = ( mBeginIdx + 1 )&SizeMask; }
	}
	void pop_front() { assert( mSize>0 ); --mSize; mBeginIdx=(mBeginIdx+1)&SizeMask; }
	void pop_back() { assert( mSize>0 ); --mSize; }
};

}