TRIQS/itertools 1.3.0
C++ range library
Loading...
Searching...
No Matches
utils.hpp
Go to the documentation of this file.
1// Copyright (c) 2024 Simons Foundation
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0.txt
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14//
15// Authors: Thomas Hahn, Olivier Parcollet, Nils Wentzell, chuffa
16
22#ifndef _ITERTOOLS_UTILS_HPP
23#define _ITERTOOLS_UTILS_HPP
24
25#include <cstddef>
26#include <iterator>
27#include <type_traits>
28#include <utility>
29#include <vector>
30
31namespace itertools {
32
50 template <typename Iter1, typename Iter2>
51 [[nodiscard]] inline typename std::iterator_traits<Iter1>::difference_type distance(Iter1 first, Iter2 last) {
52 // O(1) for random access iterators
53 if constexpr (std::is_same_v<typename std::iterator_traits<Iter1>::iterator_category, std::random_access_iterator_tag>) {
54 return last - first;
55 } else { // O(n) for other iterators
56 typename std::iterator_traits<Iter1>::difference_type r(0);
57 for (; first != last; ++first) ++r;
58 return r;
59 }
60 }
61
69 template <typename R> [[nodiscard]] auto make_vector_from_range(R const &rg) {
70 std::vector<std::decay_t<decltype(*(std::begin(rg)))>> vec{};
71 // do we really want to reserve memory here? maybe only for random access ranges?
72 if constexpr (std::is_same_v<decltype(std::cbegin(rg)), decltype(std::cend(rg))>) {
73 auto total_size = distance(std::cbegin(rg), std::cend(rg));
74 vec.reserve(total_size);
75 }
76 for (auto const &x : rg) vec.emplace_back(x);
77 return vec;
78 }
79
92 [[nodiscard]] inline std::pair<std::ptrdiff_t, std::ptrdiff_t> chunk_range(std::ptrdiff_t first, std::ptrdiff_t last, long n_chunks, long rank) {
93 auto total_size = last - first;
94 auto chunk_size = total_size / n_chunks;
95 auto n_large_nodes = total_size - n_chunks * chunk_size;
96 if (rank < n_large_nodes)
97 return {first + rank * (chunk_size + 1), first + (rank + 1) * (chunk_size + 1)};
98 else
99 return {first + n_large_nodes + rank * chunk_size, first + n_large_nodes + (rank + 1) * chunk_size};
100 }
101
104} // namespace itertools
105
106#endif // _ITERTOOLS_UTILS_HPP
std::pair< std::ptrdiff_t, std::ptrdiff_t > chunk_range(std::ptrdiff_t first, std::ptrdiff_t last, long n_chunks, long rank)
Given an integer range [first, last), divide it as equally as possible into N chunks.
Definition utils.hpp:92
std::iterator_traits< Iter1 >::difference_type distance(Iter1 first, Iter2 last)
Calculate the distance between two iterators.
Definition utils.hpp:51
auto make_vector_from_range(R const &rg)
Create a vector from a range.
Definition utils.hpp:69