Home | History | Annotate | Download | only in common
      1 #ifndef _TCURANDOMVALUEITERATOR_HPP
      2 #define _TCURANDOMVALUEITERATOR_HPP
      3 /*-------------------------------------------------------------------------
      4  * drawElements Quality Program Tester Core
      5  * ----------------------------------------
      6  *
      7  * Copyright 2014 The Android Open Source Project
      8  *
      9  * Licensed under the Apache License, Version 2.0 (the "License");
     10  * you may not use this file except in compliance with the License.
     11  * You may obtain a copy of the License at
     12  *
     13  *      http://www.apache.org/licenses/LICENSE-2.0
     14  *
     15  * Unless required by applicable law or agreed to in writing, software
     16  * distributed under the License is distributed on an "AS IS" BASIS,
     17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     18  * See the License for the specific language governing permissions and
     19  * limitations under the License.
     20  *
     21  *//*!
     22  * \file
     23  * \brief Random value iterator.
     24  *//*--------------------------------------------------------------------*/
     25 
     26 #include "tcuDefs.hpp"
     27 #include "deRandom.hpp"
     28 
     29 namespace tcu
     30 {
     31 
     32 template <typename T>
     33 T getRandomValue (de::Random& rnd)
     34 {
     35 	// \note memcpy() is the only valid way to do cast from uint32 to float for instnance.
     36 	deUint8 data[sizeof(T) + sizeof(T)%4];
     37 	DE_STATIC_ASSERT(sizeof(data)%4 == 0);
     38 	for (int vecNdx = 0; vecNdx < DE_LENGTH_OF_ARRAY(data)/4; vecNdx++)
     39 	{
     40 		deUint32 rval = rnd.getUint32();
     41 		for (int compNdx = 0; compNdx < 4; compNdx++)
     42 			data[vecNdx*4+compNdx] = ((const deUint8*)&rval)[compNdx];
     43 	}
     44 	return *(const T*)&data[0];
     45 }
     46 
     47 // Faster implementations for int types.
     48 template <> inline deUint8	getRandomValue<deUint8>		(de::Random& rnd) { return (deUint8)rnd.getUint32();	}
     49 template <> inline deUint16	getRandomValue<deUint16>	(de::Random& rnd) { return (deUint16)rnd.getUint32();	}
     50 template <> inline deUint32	getRandomValue<deUint32>	(de::Random& rnd) { return rnd.getUint32();				}
     51 template <> inline deUint64	getRandomValue<deUint64>	(de::Random& rnd) { return rnd.getUint64();				}
     52 template <> inline deInt8	getRandomValue<deInt8>		(de::Random& rnd) { return (deInt8)rnd.getUint32();		}
     53 template <> inline deInt16	getRandomValue<deInt16>		(de::Random& rnd) { return (deInt16)rnd.getUint32();	}
     54 template <> inline deInt32	getRandomValue<deInt32>		(de::Random& rnd) { return (deInt32)rnd.getUint32();	}
     55 template <> inline deInt64	getRandomValue<deInt64>		(de::Random& rnd) { return (deInt64)rnd.getUint64();	}
     56 
     57 template <typename T>
     58 class RandomValueIterator : public std::iterator<std::forward_iterator_tag, T>
     59 {
     60 public:
     61 	static RandomValueIterator	begin					(deUint32 seed, int numValues)	{ return RandomValueIterator<T>(seed, numValues);	}
     62 	static RandomValueIterator	end						(void)							{ return RandomValueIterator<T>(0, 0);				}
     63 
     64 	RandomValueIterator&		operator++				(void);
     65 	RandomValueIterator			operator++				(int);
     66 
     67 	const T&					operator*				(void) const { return m_curVal; }
     68 
     69 	bool						operator==				(const RandomValueIterator<T>& other) const;
     70 	bool						operator!=				(const RandomValueIterator<T>& other) const;
     71 
     72 private:
     73 								RandomValueIterator		(deUint32 seed, int numLeft);
     74 
     75 	de::Random					m_rnd;
     76 	int							m_numLeft;
     77 	T							m_curVal;
     78 };
     79 
     80 template <typename T>
     81 RandomValueIterator<T>::RandomValueIterator (deUint32 seed, int numLeft)
     82 	: m_rnd		(seed)
     83 	, m_numLeft	(numLeft)
     84 	, m_curVal	(numLeft > 0 ? getRandomValue<T>(m_rnd) : T())
     85 {
     86 }
     87 
     88 template <typename T>
     89 RandomValueIterator<T>& RandomValueIterator<T>::operator++ (void)
     90 {
     91 	DE_ASSERT(m_numLeft > 0);
     92 
     93 	m_numLeft	-= 1;
     94 	m_curVal	 = getRandomValue<T>(m_rnd);
     95 
     96 	return *this;
     97 }
     98 
     99 template <typename T>
    100 RandomValueIterator<T> RandomValueIterator<T>::operator++ (int)
    101 {
    102 	RandomValueIterator copy(*this);
    103 	++(*this);
    104 	return copy;
    105 }
    106 
    107 template <typename T>
    108 bool RandomValueIterator<T>::operator== (const RandomValueIterator<T>& other) const
    109 {
    110 	return (m_numLeft == 0 && other.m_numLeft == 0) || (m_numLeft == other.m_numLeft && m_rnd == other.m_rnd);
    111 }
    112 
    113 template <typename T>
    114 bool RandomValueIterator<T>::operator!= (const RandomValueIterator<T>& other) const
    115 {
    116 	return !(m_numLeft == 0 && other.m_numLeft == 0) && (m_numLeft != other.m_numLeft || m_rnd != other.m_rnd);
    117 }
    118 
    119 } // tcu
    120 
    121 #endif // _TCURANDOMVALUEITERATOR_HPP
    122