KaMPIng 0.1.1
Flexible and (near) zero-overhead C++ bindings for MPI
Loading...
Searching...
No Matches
span.hpp
1// This file is part of KaMPIng.
2//
3// Copyright 2022-2024 The KaMPIng Authors
4//
5// KaMPIng is free software : you can redistribute it and/or modify it under the terms of the GNU Lesser General Public
6// License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
7// version. KaMPIng is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
8// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
9// for more details.
10//
11// You should have received a copy of the GNU Lesser General Public License along with KaMPIng. If not, see
12// <https://www.gnu.org/licenses/>.
13
14#pragma once
15
16#include <cstddef>
17#include <iterator>
18#include <type_traits>
19
20namespace kamping::internal {
21///
22/// @brief Obtain the address represented by \c p. Modelled after C++20's \c std::to_address.
23/// See https://en.cppreference.com/w/cpp/memory/to_address for details.
24/// @param p a raw pointer
25/// @tparam the underlying type
26template <typename T>
27constexpr T* to_address(T* p) noexcept {
28 static_assert(!std::is_function_v<T>);
29 return p;
30}
31
32/// @brief Obtain the address represented by \c p. Modelled after C++20's \c std::to_address.
33/// See https://en.cppreference.com/w/cpp/memory/to_address for details.
34/// @param p a smart pointer
35/// @tparam the pointer type
36template <typename T>
37constexpr auto to_address(T const& p) noexcept {
38 // specialization to make this work with smart pointers
39 // the standard mandates the pointer to be obtained in this way
40 return to_address(p.operator->());
41}
42} // namespace kamping::internal
43
44namespace kamping {
45
46/// @brief A span modeled after C++20's \c std::span.
47///
48/// Since KaMPIng needs to be C++17 compatible and \c std::span is part of C++20, we need our own implementation of
49/// the above-described functionality.
50/// @tparam T type for which the span is defined.
51template <typename T>
52class Span {
53public:
54 using element_type = T; ///< Element type; i.e. \c T.
55 using value_type = std::remove_cv_t<T>; ///< Value type; i.e. \c T with volatile and const qualifiers removed.
56 using size_type = size_t; ///< The type used for the size of the span.
57 using difference_type = std::ptrdiff_t; ///< The type used for the difference between two elements in the span.
58 using pointer = T*; ///< The type of a pointer to a single elements in the span.
59 using const_pointer = T const*; ///< The type of a const pointer to a single elements in the span.
60 using reference = T&; ///< The type of a reference to a single elements in the span.
61 using const_reference = T const&; ///< The type of a const reference to a single elements in the span.
62 using iterator = pointer; ///< The type of an iterator to a single elements in the span.
64 std::reverse_iterator<iterator>; ///< The type of a reverse iterator to a single elements in the span.
65
66 /// @brief Default constructor for an empty span. The pointer is set to \c nullptr and the size to 0.
67 constexpr Span() noexcept : _ptr(nullptr), _size(0) {}
68
69 /// @brief Constructor for a span from an iterator of type \p It and a \p size.
70 ///
71 /// @param first Iterator pointing to the first element of the span.
72 /// @param size The number of elements in the span.
73 /// @tparam It The iterator type.
74 template <typename It>
75 constexpr Span(It first, size_type size) : _ptr(internal::to_address(first)),
76 _size(size) {}
77
78 /// @brief Constructs a span that is a view over the range <code>[first, last)</code>; the resulting span has
79 /// <code>data() == kamping::internal::to_address(first)</code> and <code>size() == last-first</code>.
80 ///
81 /// If <code>[first, last)</code> is not a valid range, or if \c It does not model a C++20 contiguous iterator, the
82 /// behavior is undefined. This is analogous to the behavior of \c std::span.
83 /// @param first begin iterator of the range
84 /// @param last end iterator of the range
85 /// @tparam It the iterator type.
86 template <typename It>
87 constexpr Span(It first, It last)
88 : _ptr(internal::to_address(first)),
90
91 /// @brief Constructs a span that is a view over the range \c range. The resulting span has
92 /// <code>data() == std::data(range)</code> and <code>size() == std::size()</code>.
93 ///
94 /// If <code>range</code> does not model a C++20 contiguous range, the
95 /// behavior is undefined. This is analogous to the behavior of \c std::span.
96 /// @param range The range.
97 /// @tparam Range The range type.
98 template <typename Range>
99 constexpr Span(Range&& range) : _ptr(std::data(range)),
100 _size(std::size(range)) {}
101
102 /// @brief Get access to the underlying memory.
103 ///
104 /// @return Pointer to the underlying memory.
106 return _ptr;
107 }
108
109 /// @brief Get iterator pointing to the first element of the span.
110 ///
111 /// @return Iterator pointing to the first element of the span.
113 return _ptr;
114 }
115
116 /// @brief Get iterator pointing past the last element of the span.
117 ///
118 /// @return Iterator pointing past the last element of the span.
120 return _ptr + size();
121 }
122
123 /// @brief Get a reverse iterator pointing to the first element of the reversed span.
125 return std::reverse_iterator{_ptr + _size};
126 }
127
128 /// @brief Get a reverse iterator pointing to the last element of the reversed span.
130 return std::reverse_iterator{_ptr};
131 }
132
133 /// @brief Access the first element of the span.
135 return *_ptr;
136 }
137
138 /// @brief Access the last element of the span.
140 return *(_ptr + _size - 1);
141 }
142
143 /// @brief Access the element at index \p idx.
144 constexpr reference operator[](size_type idx) const noexcept {
145 return _ptr[idx];
146 }
147
148 /// @brief Returns the number of elements in the Span.
149 ///
150 /// @return Number of elements in the span.
152 return _size;
153 }
154
155 /// @brief Return the number of bytes occupied by the elements in the Span.
156 ///
157 /// @return The number of elements in the span times the number of bytes per element.
159 return _size * sizeof(value_type);
160 }
161
162 /// @brief Check if the Span is empty.
163 ///
164 /// @return \c true if the Span is empty, \c false otherwise.
165 [[nodiscard]] constexpr bool empty() const noexcept {
166 return _size == 0;
167 }
168
169 /// @brief Obtain a span that is a view over the first \p count elements of the span.
170 constexpr Span first(size_type count) const {
171 return Span{_ptr, count};
172 }
173
174 /// @brief Obtain a span that is a view over the last \p count elements of the span.
175 constexpr Span last(size_type count) const {
176 return Span{_ptr + _size - count, count};
177 }
178
179 /// @brief Obtain a span that is a view over the span elements in the range <code>[offset, offset + count)</code>.
180 /// @param offset The offset of the first element of the span.
181 /// @param count The number of elements in the span.
182 constexpr Span subspan(size_type offset, size_type count) const {
183 return Span{_ptr + offset, count};
184 }
185
186protected:
187 pointer _ptr; ///< Pointer to the data referred to by Span.
188 size_type _size; ///< Number of elements of type T referred to by Span.
189};
190
191// Deduction guides
192
193template <typename Range>
195
196template <typename It>
198
199template <typename It>
201} // namespace kamping
STL-compatible allocator for requesting memory using the builtin MPI allocator.
Definition allocator.hpp:32
A span modeled after C++20's std::span.
Definition span.hpp:52
constexpr reverse_iterator rbegin() const noexcept
Get a reverse iterator pointing to the first element of the reversed span.
Definition span.hpp:124
std::reverse_iterator< iterator > reverse_iterator
The type of a reverse iterator to a single elements in the span.
Definition span.hpp:63
constexpr Span() noexcept
Default constructor for an empty span. The pointer is set to nullptr and the size to 0.
Definition span.hpp:67
constexpr Span(Range &&range)
Constructs a span that is a view over the range range. The resulting span has data() == std::data(ran...
Definition span.hpp:99
T * pointer
The type of a pointer to a single elements in the span.
Definition span.hpp:58
constexpr reference front() const noexcept
Access the first element of the span.
Definition span.hpp:134
constexpr iterator end() const noexcept
Get iterator pointing past the last element of the span.
Definition span.hpp:119
constexpr reverse_iterator rend() const noexcept
Get a reverse iterator pointing to the last element of the reversed span.
Definition span.hpp:129
pointer _ptr
Pointer to the data referred to by Span.
Definition span.hpp:187
std::remove_cv_t< T > value_type
Value type; i.e. T with volatile and const qualifiers removed.
Definition span.hpp:55
constexpr pointer data() const noexcept
Get access to the underlying memory.
Definition span.hpp:105
size_type _size
Number of elements of type T referred to by Span.
Definition span.hpp:188
constexpr size_type size_bytes() const noexcept
Return the number of bytes occupied by the elements in the Span.
Definition span.hpp:158
constexpr bool empty() const noexcept
Check if the Span is empty.
Definition span.hpp:165
constexpr iterator begin() const noexcept
Get iterator pointing to the first element of the span.
Definition span.hpp:112
constexpr Span(It first, size_type size)
Constructor for a span from an iterator of type It and a size.
Definition span.hpp:75
constexpr size_type size() const noexcept
Returns the number of elements in the Span.
Definition span.hpp:151
constexpr Span last(size_type count) const
Obtain a span that is a view over the last count elements of the span.
Definition span.hpp:175
constexpr reference back() const noexcept
Access the last element of the span.
Definition span.hpp:139
T element_type
Element type; i.e. T.
Definition span.hpp:54
constexpr Span(It first, It last)
Constructs a span that is a view over the range [first, last); the resulting span has data() == kampi...
Definition span.hpp:87
constexpr Span first(size_type count) const
Obtain a span that is a view over the first count elements of the span.
Definition span.hpp:170
constexpr Span subspan(size_type offset, size_type count) const
Obtain a span that is a view over the span elements in the range [offset, offset + count).
Definition span.hpp:182
constexpr reference operator[](size_type idx) const noexcept
Access the element at index idx.
Definition span.hpp:144
pointer iterator
The type of an iterator to a single elements in the span.
Definition span.hpp:62
std::ptrdiff_t difference_type
The type used for the difference between two elements in the span.
Definition span.hpp:57
T & reference
The type of a reference to a single elements in the span.
Definition span.hpp:60
Internal namespace marking the code that is not user-facing.
Definition collectives_helpers.hpp:20
constexpr T * to_address(T *p) noexcept
Obtain the address represented by p. Modelled after C++20's std::to_address. See https://en....
Definition span.hpp:27
STL namespace.