32template <
class output_t,
class input_t, std::
size_t SIZE>
34 std::array<output_t, SIZE> result{};
35 for (std::size_t d = 0; d < SIZE; ++d) {
36 result[d] =
static_cast<output_t
>(a[d]);
53template <
class Container,
class Fun>
54void to_string(std::ostream &os,
const Container &container,
const std::string &delimiter,
55 const std::array<std::string, 2> &surround, Fun elemToString) {
56 auto it = std::cbegin(container);
57 const auto end = std::cend(container);
59 os << surround[0] << surround[1];
62 os << surround[0] << elemToString(*it);
63 for (++it; it != end; ++it) {
64 os << delimiter << elemToString(*it);
77template <
class Container>
78void to_string(std::ostream &os,
const Container &container,
const std::string &delimiter =
", ",
79 const std::array<std::string, 2> &surround = {
"[",
"]"}) {
80 to_string(os, container, delimiter, surround, [](
const auto &x) {
return x; });
95template <
class Container,
class Fun>
96[[nodiscard]] std::string
to_string(
const Container &container,
const std::string &delimiter,
97 const std::array<std::string, 2> &surround, Fun elemToString) {
98 std::ostringstream strStream;
99 strStream << std::boolalpha;
100 to_string(strStream, container, delimiter, surround, elemToString);
102 return strStream.str();
113template <
class Container>
114[[nodiscard]] std::string
to_string(
const Container &container,
const std::string &delimiter =
", ",
115 const std::array<std::string, 2> &surround = {
"[",
"]"}) {
116 return to_string(container, delimiter, surround, [](
const auto &elem) {
return elem; });
131template <ContainerType Container>
132std::ostream &
operator<<(std::ostream &os,
const Container &container) {
133 const std::string &delimiter =
", ";
134 const std::array<std::string, 2> &surround = {
"[",
"]"};
136 to_string(os, container, delimiter, surround);
150template <
class OuterContainerT>
153 vecvec, [](
auto &innerContainer) ->
auto & {
return innerContainer; });
168template <
class OuterContainerT,
class F>
170 using InnerContainerT =
typename OuterContainerT::value_type;
171 using ElemT =
typename std::remove_reference_t<
172 std::invoke_result_t<
decltype(innerContainerToVec), InnerContainerT &>>::value_type;
174 const auto vecvecSize = vecvec.size();
175 if (vecvecSize == 0) {
179 const size_t numElem = std::transform_reduce(vecvec.begin(), vecvec.end(), 0, std::plus<>(),
180 [&](
auto &vec) { return innerContainerToVec(vec).size(); });
181 const auto targetSize =
static_cast<long>(numElem / vecvecSize);
182 const auto remainder = numElem % vecvecSize;
184 std::vector<ElemT> tmpStorage;
186 size_t firstTooFew = 0;
188 for (
int pass = 0; pass == 0 or not tmpStorage.empty(); ++pass) {
190 for (
size_t i = firstTooFew; i < vecvecSize; ++i) {
191 auto &vec = innerContainerToVec(vecvec[i]);
192 const auto thisTargetSize = i < remainder ? targetSize + 1 : targetSize;
193 if (vec.size() > thisTargetSize) {
195 const auto startOfTooMuch = vec.begin() + thisTargetSize;
196 tmpStorage.insert(tmpStorage.end(), std::make_move_iterator(startOfTooMuch),
197 std::make_move_iterator(vec.end()));
198 vec.erase(startOfTooMuch, vec.end());
200 if (firstTooFew == i) {
203 }
else if (vec.size() < thisTargetSize) {
205 vec.reserve(thisTargetSize);
206 const long numMissing = thisTargetSize - vec.size();
207 const auto startOfInsertion =
208 tmpStorage.begin() + (std::max(0l,
static_cast<long>(tmpStorage.size()) - numMissing));
209 vec.insert(vec.end(), std::make_move_iterator(startOfInsertion), std::make_move_iterator(tmpStorage.end()));
210 tmpStorage.erase(startOfInsertion, tmpStorage.end());
212 }
else if (firstTooFew == i) {
217 if (pass > 0 and tmpStorage.empty()) {
In this namespace some helper functions for std::array can be found.
Definition: namespaces.h:54
void balanceVectors(OuterContainerT &vecvec)
Given a collection of vectors, redistributes the elements of the vectors so they all have the same (o...
Definition: ArrayUtils.h:151
std::ostream & operator<<(std::ostream &os, const Container &container)
Stream operator for containers (array and vector types).
Definition: ArrayUtils.h:132
constexpr std::array< output_t, SIZE > static_cast_copy_array(const std::array< input_t, SIZE > &a)
Creates a new array by performing an element-wise static_cast<>.
Definition: ArrayUtils.h:33
void to_string(std::ostream &os, const Container &container, const std::string &delimiter, const std::array< std::string, 2 > &surround, Fun elemToString)
Generates a string representation of a container which fulfills the Container requirement (provide cb...
Definition: ArrayUtils.h:54