/*!
@author d金魚
@since 2004/2/4
@note
このヘッダだけでも使えるようにしたい！！
*/
#ifndef DKUTIL_MATH_INTERFACE_HPP
#define DKUTIL_MATH_INTERFACE_HPP

#include <dkutil/macro.hpp>
#include <math.h>
#include <time.h>

namespace dkutil{
template<typename SEED_T,typename RESULT_T=int>
class ansi_rand_functor{
public:
	RESULT_T operator()(SEED_T *seed)
	{
			(*seed) = (*seed) * 1103515245L + 12345;
			return (unsigned)((*seed) / 65536L) % 32768U;
	}
};
	
/**
http://members.tripod.co.jp/cprogram/various1.html
より。
Min_<= x <=Max_まで返す
*/
template<typename RESULT_T,typename ARG_T,class BASE>
struct random_domain_functor{
	inline RESULT_T operator()(ARG_T Min_,ARG_T Max_,BASE &x)
	{
		double fNum, fDenom;

		fNum   = (double)x.rand() * ( (double)Max_ - (double)Min_ + 1.0f );
		fDenom = (double)x.getRandMax() + 1.0f;

		//return (RESULT_T)(Min_ + (int)( fNum / fDenom ));
		return (RESULT_T)(Min_ + (ARG_T)( fNum / fDenom ));
	}
};

template<typename RESULT_T,typename ARG_T,class BASE>
struct random_functor{
	inline RESULT_T operator()(ARG_T Max_,BASE &x)
	{
		return x.rand() * (1+Max_) / x.getRandMax();
	}
};


///random number generater interface
template<class POLICY_T>
class rng_interface{
protected:
	POLICY_T mPolicy;
public:
	typedef typename POLICY_T policy_type;
	typedef typename POLICY_T::result_type result_type;
	typedef typename POLICY_T::seed_type seed_type;
	typedef typename POLICY_T::state_type state_type;
	policy_type &getPolicy(){
		return mPolicy;
	}
	result_type getRandMax()const{
		return mPolicy.getRandMax();
	}
	state_type &getState()const{
		return mPolicy.getState();
	}
	state_type &getState(){
		return mPolicy.getState();
	}
	void setSeed(seed_type seed){
		mPolicy.seed(seed);
	}
	void setState(const state_type &x){
		mPolicy.setState(x);
	}
	result_type rand(){
		return mPolicy.rand();
	}
	result_type random(result_type Max_){
		return mPolicy.random(Max_);
	}
	result_type random(result_type Min_,result_type Max_)
	{
		return mPolicy.random(Min_,Max_);
	}
};

}//end of dkutil namespace







#endif



