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 29namespace tcu 30{ 31 32template <typename T> 33T 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. 48template <> inline deUint8 getRandomValue<deUint8> (de::Random& rnd) { return (deUint8)rnd.getUint32(); } 49template <> inline deUint16 getRandomValue<deUint16> (de::Random& rnd) { return (deUint16)rnd.getUint32(); } 50template <> inline deUint32 getRandomValue<deUint32> (de::Random& rnd) { return rnd.getUint32(); } 51template <> inline deUint64 getRandomValue<deUint64> (de::Random& rnd) { return rnd.getUint64(); } 52template <> inline deInt8 getRandomValue<deInt8> (de::Random& rnd) { return (deInt8)rnd.getUint32(); } 53template <> inline deInt16 getRandomValue<deInt16> (de::Random& rnd) { return (deInt16)rnd.getUint32(); } 54template <> inline deInt32 getRandomValue<deInt32> (de::Random& rnd) { return (deInt32)rnd.getUint32(); } 55template <> inline deInt64 getRandomValue<deInt64> (de::Random& rnd) { return (deInt64)rnd.getUint64(); } 56 57template <typename T> 58class RandomValueIterator : public std::iterator<std::forward_iterator_tag, T> 59{ 60public: 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 72private: 73 RandomValueIterator (deUint32 seed, int numLeft); 74 75 de::Random m_rnd; 76 int m_numLeft; 77 T m_curVal; 78}; 79 80template <typename T> 81RandomValueIterator<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 88template <typename T> 89RandomValueIterator<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 99template <typename T> 100RandomValueIterator<T> RandomValueIterator<T>::operator++ (int) 101{ 102 RandomValueIterator copy(*this); 103 ++(*this); 104 return copy; 105} 106 107template <typename T> 108bool 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 113template <typename T> 114bool 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