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 59{ 60public: 61 using iterator_category = std::forward_iterator_tag; 62 using value_type = T; 63 using difference_type = std::ptrdiff_t; 64 using pointer = T*; 65 using reference = T&; 66 67 static RandomValueIterator begin (deUint32 seed, int numValues) { return RandomValueIterator<T>(seed, numValues); } 68 static RandomValueIterator end (void) { return RandomValueIterator<T>(0, 0); } 69 70 RandomValueIterator& operator++ (void); 71 RandomValueIterator operator++ (int); 72 73 const T& operator* (void) const { return m_curVal; } 74 75 bool operator== (const RandomValueIterator<T>& other) const; 76 bool operator!= (const RandomValueIterator<T>& other) const; 77 78private: 79 RandomValueIterator (deUint32 seed, int numLeft); 80 81 de::Random m_rnd; 82 int m_numLeft; 83 T m_curVal; 84}; 85 86template <typename T> 87RandomValueIterator<T>::RandomValueIterator (deUint32 seed, int numLeft) 88 : m_rnd (seed) 89 , m_numLeft (numLeft) 90 , m_curVal (numLeft > 0 ? getRandomValue<T>(m_rnd) : T()) 91{ 92} 93 94template <typename T> 95RandomValueIterator<T>& RandomValueIterator<T>::operator++ (void) 96{ 97 DE_ASSERT(m_numLeft > 0); 98 99 m_numLeft -= 1; 100 m_curVal = getRandomValue<T>(m_rnd); 101 102 return *this; 103} 104 105template <typename T> 106RandomValueIterator<T> RandomValueIterator<T>::operator++ (int) 107{ 108 RandomValueIterator copy(*this); 109 ++(*this); 110 return copy; 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 119template <typename T> 120bool RandomValueIterator<T>::operator!= (const RandomValueIterator<T>& other) const 121{ 122 return !(m_numLeft == 0 && other.m_numLeft == 0) && (m_numLeft != other.m_numLeft || m_rnd != other.m_rnd); 123} 124 125} // tcu 126 127#endif // _TCURANDOMVALUEITERATOR_HPP 128