1 #ifndef _VKTPIPELINECOMBINATIONSITERATOR_HPP
2 #define _VKTPIPELINECOMBINATIONSITERATOR_HPP
3 /*------------------------------------------------------------------------
4 * Vulkan Conformance Tests
5 * ------------------------
7 * Copyright (c) 2015 The Khronos Group Inc.
8 * Copyright (c) 2015 Imagination Technologies Ltd.
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * Unless required by applicable law or agreed to in writing, software
17 * distributed under the License is distributed on an "AS IS" BASIS,
18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19 * See the License for the specific language governing permissions and
20 * limitations under the License.
24 * \brief Iterator over combinations of items without repetition
25 *//*--------------------------------------------------------------------*/
27 #include "tcuDefs.hpp"
28 #include "deRandom.hpp"
38 class CombinationsIterator
41 CombinationsIterator (deUint32 numItems, deUint32 combinationSize);
42 virtual ~CombinationsIterator (void) {}
43 bool hasNext (void) const;
48 virtual T getCombinationValue (const std::vector<deUint32>& combination) = 0;
51 static deUint32 factorial (deUint32 x);
54 deUint32 m_combinationIndex;
55 deUint32 m_combinationSize;
56 deUint32 m_combinationCount;
58 std::vector<deUint32> m_combination;
61 static deUint32 seriesProduct (deUint32 first, deUint32 last)
65 for (deUint32 i = first; i <= last; i++)
72 CombinationsIterator<T>::CombinationsIterator (deUint32 numItems, deUint32 combinationSize)
73 : m_numItems (numItems)
74 , m_combinationSize (combinationSize)
76 DE_ASSERT(m_combinationSize > 0);
77 DE_ASSERT(m_combinationSize <= m_numItems);
79 m_combinationCount = seriesProduct(numItems - combinationSize + 1, numItems) / seriesProduct(1, combinationSize);
81 m_combination.resize(m_combinationSize);
86 bool CombinationsIterator<T>::hasNext (void) const
88 return m_combinationIndex < m_combinationCount;
92 T CombinationsIterator<T>::next (void)
94 DE_ASSERT(m_combinationIndex < m_combinationCount);
96 if (m_combinationIndex > 0)
98 for (int combinationItemNdx = (int)m_combinationSize - 1; combinationItemNdx >= 0; combinationItemNdx--)
100 if ((m_combination[combinationItemNdx] + 1 < m_numItems) && ((combinationItemNdx == (int)m_combinationSize - 1) || (m_combination[combinationItemNdx + 1] > m_combination[combinationItemNdx] + 1)))
102 m_combination[combinationItemNdx]++;
104 for (deUint32 resetNdx = combinationItemNdx + 1; resetNdx < m_combinationSize; resetNdx++)
105 m_combination[resetNdx] = m_combination[resetNdx - 1] + 1;
112 m_combinationIndex++;
114 return getCombinationValue(m_combination);
117 template <typename T>
118 void CombinationsIterator<T>::reset (void)
120 // Set up first combination
121 for (deUint32 itemNdx = 0; itemNdx < m_combinationSize; itemNdx++)
122 m_combination[itemNdx] = itemNdx;
124 m_combinationIndex = 0;
127 template <typename T>
128 deUint32 CombinationsIterator<T>::factorial (deUint32 x)
132 for (deUint32 value = x; value > 1; value--)
141 #endif // _VKTPIPELINECOMBINATIONSITERATOR_HPP