Faker C++
Loading...
Searching...
No Matches
Helper.h
Go to the documentation of this file.
1#pragma once
2
3#include <initializer_list>
4#include <numeric>
5#include <span>
6#include <vector>
7
8#include "Number.h"
9
11{
26template <class T>
27T arrayElement(std::span<const T> data)
28{
29 if (data.empty())
30 {
31 throw std::invalid_argument{"Data is empty."};
32 }
33
34 const auto index = number::integer<size_t>(data.size() - 1);
35
36 return data[index];
37}
38
39template <typename T, std::size_t N>
40T arrayElement(const std::array<T, N>& data)
41{
42 if (data.empty())
43 {
44 throw std::invalid_argument{"Data is empty."};
45 }
46
47 const auto index = number::integer<size_t>(data.size() - 1);
48
49 return data[index];
50}
51
52template <typename It>
53auto arrayElement(It start, It end) -> decltype(*::std::declval<It>())
54{
55 auto size = static_cast<size_t>(end - start);
56
57 if (size == 0)
58 {
59 throw std::invalid_argument{"Range [start,end) is empty."};
60 }
61
62 const std::integral auto index = number::integer<size_t>(size - 1);
63
64 return start[index];
65}
66
80template <class T>
81T arrayElement(const std::vector<T>& data)
82{
83 if (data.empty())
84 {
85 throw std::invalid_argument{"Data is empty."};
86 }
87
88 const auto index = number::integer<size_t>(data.size() - 1);
89
90 return data[index];
91}
92
106template <class T>
107T arrayElement(const std::initializer_list<T>& data)
108{
109 if (data.size() == 0)
110 {
111 throw std::invalid_argument{"Data is empty."};
112 }
113
114 const auto index = number::integer<size_t>(data.size() - 1);
115
116 return *(data.begin() + index);
117}
118
134template <class T>
136{
137 unsigned weight;
139};
140
141template <class T>
142T weightedArrayElement(const std::vector<WeightedElement<T>>& data)
143{
144 if (data.empty())
145 {
146 throw std::invalid_argument{"Data is empty."};
147 }
148
149 const auto sumOfWeights =
150 std::accumulate(data.begin(), data.end(), 0u,
151 [](unsigned sum, const WeightedElement<T>& element) { return sum + element.weight; });
152
153 if (sumOfWeights == 0u)
154 {
155 throw std::invalid_argument{"Sum of weights is zero."};
156 }
157
158 const std::integral auto targetWeightValue = number::integer<unsigned>(1, sumOfWeights);
159
160 unsigned currentSum = 0;
161 for (const auto& elem : data)
162 {
163 currentSum += elem.weight;
164 if (currentSum >= targetWeightValue)
165 {
166 return elem.value;
167 }
168 }
169
170 return data.back().value;
171}
172
173}
Definition Helper.h:11
T arrayElement(std::span< const T > data)
Get a random element from an STL container.
Definition Helper.h:27
T weightedArrayElement(const std::vector< WeightedElement< T > > &data)
Definition Helper.h:142
Get a random element by weight from a vector.
Definition Helper.h:136
unsigned weight
Definition Helper.h:137
T value
Definition Helper.h:138