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