| #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 |