ESPResSo
Extensible Simulation Package for Research on Soft Matter Systems
Loading...
Searching...
No Matches
Span.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2010-2022 The ESPResSo project
3 *
4 * This file is part of ESPResSo.
5 *
6 * ESPResSo is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * ESPResSo is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19#ifndef UTILS_SPAN_HPP
20#define UTILS_SPAN_HPP
21
22#include "device_qualifier.hpp"
23
24#include <cassert>
25#include <cstddef>
26#include <iterator>
27#include <stdexcept>
28#include <type_traits>
29
30namespace Utils {
31
32/**
33 * @brief A stripped-down version of std::span from C++17.
34 *
35 * Behaves like a std::span where implemented.
36 */
37
38template <class T> class Span {
39public:
40 using value_type = typename std::remove_cv<T>::type;
41 using pointer = T *;
42 using const_pointer = const T *;
43 using reference = T &;
44 using const_reference = const T &;
47 using reverse_iterator = std::reverse_iterator<iterator>;
48 using const_reverse_iterator = std::reverse_iterator<const_iterator>;
49 using size_type = std::size_t;
50 using difference_type = std::ptrdiff_t;
51
52private:
53 T *m_ptr;
54 std::size_t m_size{};
55
56 template <typename U>
57 using enable_if_const_t =
58 typename std::enable_if<std::is_const_v<T>, U>::type;
59 template <class U>
60 using enable_if_mutable_t =
61 typename std::enable_if<!std::is_const_v<T>, U>::type;
62 template <class U>
63 using enable_if_has_data_t = typename std::enable_if<
64 std::is_convertible_v<std::decay_t<decltype(std::declval<U>().data())> *,
65 T *const *>,
66 U>::type;
67
68public:
69 Span() = default;
70 Span(const Span &) = default;
71 Span &operator=(const Span &) = default;
72
74 constexpr Span(pointer array, size_type length)
75 : m_ptr(array), m_size(length) {}
76 template <std::size_t N>
77 DEVICE_QUALIFIER constexpr Span(T (&a)[N]) noexcept : Span(a, N) {}
78
79 template <typename C, typename = enable_if_mutable_t<C>,
80 typename = enable_if_has_data_t<C>>
81 DEVICE_QUALIFIER explicit Span(C &c) noexcept : Span(c.data(), c.size()) {}
82 template <typename C, typename = enable_if_const_t<C>,
83 typename = enable_if_has_data_t<C>>
84 DEVICE_QUALIFIER Span(const C &c) noexcept : Span(c.data(), c.size()) {}
85
86 DEVICE_QUALIFIER constexpr size_type size() const { return m_size; }
87 DEVICE_QUALIFIER constexpr bool empty() const { return size() == 0; }
88
89 DEVICE_QUALIFIER constexpr iterator begin() const { return m_ptr; }
90 DEVICE_QUALIFIER constexpr const_iterator cbegin() const { return m_ptr; }
91 DEVICE_QUALIFIER constexpr iterator end() const { return m_ptr + m_size; }
93 return m_ptr + m_size;
94 }
95 constexpr reverse_iterator rbegin() const { return reverse_iterator(end()); }
96 constexpr reverse_iterator rend() const { return reverse_iterator(begin()); }
97
99 return DEVICE_ASSERT(i < size()), m_ptr[i];
100 }
101
102 constexpr reference at(size_type i) const {
103 return (i < size()) ? m_ptr[i]
104 : throw std::out_of_range("span access out of bounds."),
105 m_ptr[i];
106 }
107
108 DEVICE_QUALIFIER constexpr pointer data() const { return m_ptr; }
109};
110
111template <typename T>
112DEVICE_QUALIFIER constexpr Span<T> make_span(T *p, std::size_t N) {
113 return Span<T>(p, N);
114}
115
116template <class C> DEVICE_QUALIFIER constexpr auto make_span(C &c) {
117 return make_span(c.data(), c.size());
118}
119
120template <typename T>
121DEVICE_QUALIFIER constexpr Span<std::add_const_t<T>>
122make_const_span(T *p, std::size_t N) {
123 return Span<std::add_const_t<T>>(p, N);
124}
125
126template <class C> DEVICE_QUALIFIER constexpr auto make_const_span(C &c) {
127 return make_const_span(c.data(), c.size());
128}
129
130} // namespace Utils
131
132#endif
float N[3]
A stripped-down version of std::span from C++17.
Definition Span.hpp:38
std::reverse_iterator< iterator > reverse_iterator
Definition Span.hpp:47
Span()=default
DEVICE_QUALIFIER Span(C &c) noexcept
Definition Span.hpp:81
DEVICE_QUALIFIER Span(const C &c) noexcept
Definition Span.hpp:84
constexpr reference at(size_type i) const
Definition Span.hpp:102
DEVICE_QUALIFIER constexpr Span(T(&a)[N]) noexcept
Definition Span.hpp:77
DEVICE_QUALIFIER constexpr reference operator[](size_type i) const
Definition Span.hpp:98
std::reverse_iterator< const_iterator > const_reverse_iterator
Definition Span.hpp:48
pointer iterator
Definition Span.hpp:45
const T & const_reference
Definition Span.hpp:44
DEVICE_QUALIFIER constexpr pointer data() const
Definition Span.hpp:108
DEVICE_QUALIFIER constexpr size_type size() const
Definition Span.hpp:86
T * pointer
Definition Span.hpp:41
std::size_t size_type
Definition Span.hpp:49
std::ptrdiff_t difference_type
Definition Span.hpp:50
const T * const_pointer
Definition Span.hpp:42
constexpr reverse_iterator rend() const
Definition Span.hpp:96
DEVICE_QUALIFIER constexpr const_iterator cend() const
Definition Span.hpp:92
DEVICE_QUALIFIER constexpr const_iterator cbegin() const
Definition Span.hpp:90
Span(const Span &)=default
T & reference
Definition Span.hpp:43
typename std::remove_cv< T >::type value_type
Definition Span.hpp:40
Span & operator=(const Span &)=default
DEVICE_QUALIFIER constexpr bool empty() const
Definition Span.hpp:87
DEVICE_QUALIFIER constexpr iterator end() const
Definition Span.hpp:91
const_pointer const_iterator
Definition Span.hpp:46
DEVICE_QUALIFIER constexpr Span(pointer array, size_type length)
Definition Span.hpp:74
constexpr reverse_iterator rbegin() const
Definition Span.hpp:95
DEVICE_QUALIFIER constexpr iterator begin() const
Definition Span.hpp:89
#define DEVICE_ASSERT(A)
#define DEVICE_QUALIFIER
DEVICE_QUALIFIER constexpr Span< T > make_span(T *p, std::size_t N)
Definition Span.hpp:112
DEVICE_QUALIFIER constexpr Span< std::add_const_t< T > > make_const_span(T *p, std::size_t N)
Definition Span.hpp:122