xref: /aosp_15_r20/external/deqp/framework/common/tcuRandomValueIterator.hpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
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 
29 namespace tcu
30 {
31 
32 template <typename T>
getRandomValue(de::Random & rnd)33 T getRandomValue(de::Random &rnd)
34 {
35     // \note memcpy() is the only valid way to do cast from uint32 to float for instnance.
36     uint8_t 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         uint32_t rval = rnd.getUint32();
41         for (int compNdx = 0; compNdx < 4; compNdx++)
42             data[vecNdx * 4 + compNdx] = ((const uint8_t *)&rval)[compNdx];
43     }
44     return *(const T *)&data[0];
45 }
46 
47 // Faster implementations for int types.
48 template <>
getRandomValue(de::Random & rnd)49 inline uint8_t getRandomValue<uint8_t>(de::Random &rnd)
50 {
51     return (uint8_t)rnd.getUint32();
52 }
53 template <>
getRandomValue(de::Random & rnd)54 inline uint16_t getRandomValue<uint16_t>(de::Random &rnd)
55 {
56     return (uint16_t)rnd.getUint32();
57 }
58 template <>
getRandomValue(de::Random & rnd)59 inline uint32_t getRandomValue<uint32_t>(de::Random &rnd)
60 {
61     return rnd.getUint32();
62 }
63 template <>
getRandomValue(de::Random & rnd)64 inline uint64_t getRandomValue<uint64_t>(de::Random &rnd)
65 {
66     return rnd.getUint64();
67 }
68 template <>
getRandomValue(de::Random & rnd)69 inline int8_t getRandomValue<int8_t>(de::Random &rnd)
70 {
71     return (int8_t)rnd.getUint32();
72 }
73 template <>
getRandomValue(de::Random & rnd)74 inline int16_t getRandomValue<int16_t>(de::Random &rnd)
75 {
76     return (int16_t)rnd.getUint32();
77 }
78 template <>
getRandomValue(de::Random & rnd)79 inline int32_t getRandomValue<int32_t>(de::Random &rnd)
80 {
81     return (int32_t)rnd.getUint32();
82 }
83 template <>
getRandomValue(de::Random & rnd)84 inline int64_t getRandomValue<int64_t>(de::Random &rnd)
85 {
86     return (int64_t)rnd.getUint64();
87 }
88 
89 template <typename T>
90 class RandomValueIterator
91 {
92 public:
93     using iterator_category = std::forward_iterator_tag;
94     using value_type        = T;
95     using difference_type   = std::ptrdiff_t;
96     using pointer           = T *;
97     using reference         = T &;
98 
begin(uint32_t seed,int numValues)99     static RandomValueIterator begin(uint32_t seed, int numValues)
100     {
101         return RandomValueIterator<T>(seed, numValues);
102     }
end(void)103     static RandomValueIterator end(void)
104     {
105         return RandomValueIterator<T>(0, 0);
106     }
107 
108     RandomValueIterator &operator++(void);
109     RandomValueIterator operator++(int);
110 
operator *(void) const111     const T &operator*(void) const
112     {
113         return m_curVal;
114     }
115 
116     bool operator==(const RandomValueIterator<T> &other) const;
117     bool operator!=(const RandomValueIterator<T> &other) const;
118 
119 private:
120     RandomValueIterator(uint32_t seed, int numLeft);
121 
122     de::Random m_rnd;
123     int m_numLeft;
124     T m_curVal;
125 };
126 
127 template <typename T>
RandomValueIterator(uint32_t seed,int numLeft)128 RandomValueIterator<T>::RandomValueIterator(uint32_t seed, int numLeft)
129     : m_rnd(seed)
130     , m_numLeft(numLeft)
131     , m_curVal(numLeft > 0 ? getRandomValue<T>(m_rnd) : T())
132 {
133 }
134 
135 template <typename T>
operator ++(void)136 RandomValueIterator<T> &RandomValueIterator<T>::operator++(void)
137 {
138     DE_ASSERT(m_numLeft > 0);
139 
140     m_numLeft -= 1;
141     m_curVal = getRandomValue<T>(m_rnd);
142 
143     return *this;
144 }
145 
146 template <typename T>
operator ++(int)147 RandomValueIterator<T> RandomValueIterator<T>::operator++(int)
148 {
149     RandomValueIterator copy(*this);
150     ++(*this);
151     return copy;
152 }
153 
154 template <typename T>
operator ==(const RandomValueIterator<T> & other) const155 bool RandomValueIterator<T>::operator==(const RandomValueIterator<T> &other) const
156 {
157     return (m_numLeft == 0 && other.m_numLeft == 0) || (m_numLeft == other.m_numLeft && m_rnd == other.m_rnd);
158 }
159 
160 template <typename T>
operator !=(const RandomValueIterator<T> & other) const161 bool RandomValueIterator<T>::operator!=(const RandomValueIterator<T> &other) const
162 {
163     return !(m_numLeft == 0 && other.m_numLeft == 0) && (m_numLeft != other.m_numLeft || m_rnd != other.m_rnd);
164 }
165 
166 } // namespace tcu
167 
168 #endif // _TCURANDOMVALUEITERATOR_HPP
169