#ifndef _TCURANDOMVALUEITERATOR_HPP #define _TCURANDOMVALUEITERATOR_HPP /*------------------------------------------------------------------------- * drawElements Quality Program Tester Core * ---------------------------------------- * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Random value iterator. *//*--------------------------------------------------------------------*/ #include "tcuDefs.hpp" #include "deRandom.hpp" namespace tcu { template <typename T> T getRandomValue (de::Random& rnd) { // \note memcpy() is the only valid way to do cast from uint32 to float for instnance. deUint8 data[sizeof(T) + sizeof(T)%4]; DE_STATIC_ASSERT(sizeof(data)%4 == 0); for (int vecNdx = 0; vecNdx < DE_LENGTH_OF_ARRAY(data)/4; vecNdx++) { deUint32 rval = rnd.getUint32(); for (int compNdx = 0; compNdx < 4; compNdx++) data[vecNdx*4+compNdx] = ((const deUint8*)&rval)[compNdx]; } return *(const T*)&data[0]; } // Faster implementations for int types. template <> inline deUint8 getRandomValue<deUint8> (de::Random& rnd) { return (deUint8)rnd.getUint32(); } template <> inline deUint16 getRandomValue<deUint16> (de::Random& rnd) { return (deUint16)rnd.getUint32(); } template <> inline deUint32 getRandomValue<deUint32> (de::Random& rnd) { return rnd.getUint32(); } template <> inline deUint64 getRandomValue<deUint64> (de::Random& rnd) { return rnd.getUint64(); } template <> inline deInt8 getRandomValue<deInt8> (de::Random& rnd) { return (deInt8)rnd.getUint32(); } template <> inline deInt16 getRandomValue<deInt16> (de::Random& rnd) { return (deInt16)rnd.getUint32(); } template <> inline deInt32 getRandomValue<deInt32> (de::Random& rnd) { return (deInt32)rnd.getUint32(); } template <> inline deInt64 getRandomValue<deInt64> (de::Random& rnd) { return (deInt64)rnd.getUint64(); } template <typename T> class RandomValueIterator : public std::iterator<std::forward_iterator_tag, T> { public: static RandomValueIterator begin (deUint32 seed, int numValues) { return RandomValueIterator<T>(seed, numValues); } static RandomValueIterator end (void) { return RandomValueIterator<T>(0, 0); } RandomValueIterator& operator++ (void); RandomValueIterator operator++ (int); const T& operator* (void) const { return m_curVal; } bool operator== (const RandomValueIterator<T>& other) const; bool operator!= (const RandomValueIterator<T>& other) const; private: RandomValueIterator (deUint32 seed, int numLeft); de::Random m_rnd; int m_numLeft; T m_curVal; }; template <typename T> RandomValueIterator<T>::RandomValueIterator (deUint32 seed, int numLeft) : m_rnd (seed) , m_numLeft (numLeft) , m_curVal (numLeft > 0 ? getRandomValue<T>(m_rnd) : T()) { } template <typename T> RandomValueIterator<T>& RandomValueIterator<T>::operator++ (void) { DE_ASSERT(m_numLeft > 0); m_numLeft -= 1; m_curVal = getRandomValue<T>(m_rnd); return *this; } template <typename T> RandomValueIterator<T> RandomValueIterator<T>::operator++ (int) { RandomValueIterator copy(*this); ++(*this); return copy; } template <typename T> bool RandomValueIterator<T>::operator== (const RandomValueIterator<T>& other) const { return (m_numLeft == 0 && other.m_numLeft == 0) || (m_numLeft == other.m_numLeft && m_rnd == other.m_rnd); } template <typename T> bool RandomValueIterator<T>::operator!= (const RandomValueIterator<T>& other) const { return !(m_numLeft == 0 && other.m_numLeft == 0) && (m_numLeft != other.m_numLeft || m_rnd != other.m_rnd); } } // tcu #endif // _TCURANDOMVALUEITERATOR_HPP