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>
getRandomValue(de::Random & rnd)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.
getRandomValue(de::Random & rnd)48 template <> inline deUint8	getRandomValue<deUint8>		(de::Random& rnd) { return (deUint8)rnd.getUint32();	}
getRandomValue(de::Random & rnd)49 template <> inline deUint16	getRandomValue<deUint16>	(de::Random& rnd) { return (deUint16)rnd.getUint32();	}
getRandomValue(de::Random & rnd)50 template <> inline deUint32	getRandomValue<deUint32>	(de::Random& rnd) { return rnd.getUint32();				}
getRandomValue(de::Random & rnd)51 template <> inline deUint64	getRandomValue<deUint64>	(de::Random& rnd) { return rnd.getUint64();				}
getRandomValue(de::Random & rnd)52 template <> inline deInt8	getRandomValue<deInt8>		(de::Random& rnd) { return (deInt8)rnd.getUint32();		}
getRandomValue(de::Random & rnd)53 template <> inline deInt16	getRandomValue<deInt16>		(de::Random& rnd) { return (deInt16)rnd.getUint32();	}
getRandomValue(de::Random & rnd)54 template <> inline deInt32	getRandomValue<deInt32>		(de::Random& rnd) { return (deInt32)rnd.getUint32();	}
getRandomValue(de::Random & rnd)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:
begin(deUint32 seed,int numValues)61 	static RandomValueIterator	begin					(deUint32 seed, int numValues)	{ return RandomValueIterator<T>(seed, numValues);	}
end(void)62 	static RandomValueIterator	end						(void)							{ return RandomValueIterator<T>(0, 0);				}
63 
64 	RandomValueIterator&		operator++				(void);
65 	RandomValueIterator			operator++				(int);
66 
operator *(void) const67 	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>
RandomValueIterator(deUint32 seed,int numLeft)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>
operator ++(void)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>
operator ++(int)100 RandomValueIterator<T> RandomValueIterator<T>::operator++ (int)
101 {
102 	RandomValueIterator copy(*this);
103 	++(*this);
104 	return copy;
105 }
106 
107 template <typename T>
operator ==(const RandomValueIterator<T> & other) const108 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>
operator !=(const RandomValueIterator<T> & other) const114 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