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