122 lines
4.1 KiB
C++
122 lines
4.1 KiB
C++
#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
|