guanaqo 1.0.0-alpha.25
Utilities for scientific software
Loading...
Searching...
No Matches
span.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file
4/// @ingroup linalg_views
5/// Conversions between Eigen vector views and `std::span`.
6
7#include <Eigen/Core>
8#include <span>
9#include <type_traits>
10
11namespace guanaqo {
12
13namespace detail {
14template <Eigen::Index R>
15constexpr auto to_std_extent =
16 R == Eigen::Dynamic ? std::dynamic_extent : static_cast<size_t>(R);
17template <size_t E>
18constexpr auto to_eigen_extent =
19 E == std::dynamic_extent ? Eigen::Dynamic : static_cast<Eigen::Index>(E);
20} // namespace detail
21
22/// @addtogroup linalg_views
23/// @{
24
25/// Convert an Eigen vector view to a `std::span`.
26template <class Derived>
27 requires(Derived::ColsAtCompileTime == 1 &&
28 Derived::InnerStrideAtCompileTime == 1)
29auto as_span(Eigen::DenseBase<Derived> &v) {
31 using T = std::remove_pointer_t<decltype(v.derived().data())>;
32 return std::span<T, E>{v.derived().data(), static_cast<size_t>(v.size())};
33}
34
35/// Convert an Eigen vector view to a `std::span`.
36template <class Derived>
37 requires(Derived::ColsAtCompileTime == 1 &&
38 Derived::InnerStrideAtCompileTime == 1)
39auto as_span(Eigen::DenseBase<Derived> &&v) {
40 using PlainObjectBase = Eigen::PlainObjectBase<std::decay_t<Derived>>;
41 static_assert(!std::is_base_of_v<PlainObjectBase, std::decay_t<Derived>>,
42 "Refusing to return a span to a temporary Eigen vector with "
43 "its own storage");
45 using T = std::remove_pointer_t<decltype(v.derived().data())>;
46 return std::span<T, E>{v.derived().data(), static_cast<size_t>(v.size())};
47}
48
49/// Convert an Eigen vector view to a `std::span`.
50template <class Derived>
51 requires(Derived::ColsAtCompileTime == 1 &&
52 Derived::InnerStrideAtCompileTime == 1)
53auto as_span(const Eigen::DenseBase<Derived> &v) {
55 using T = std::remove_pointer_t<decltype(v.derived().data())>;
56 return std::span<T, E>{v.derived().data(), static_cast<size_t>(v.size())};
57}
58
59/// Convert a `std::span` to an Eigen::Vector view.
60/// @todo Rename to as_eigen?
61template <class T, size_t E>
62auto as_eigen(std::span<T, E> s) {
63 constexpr auto R = detail::to_eigen_extent<E>;
64 using S = std::remove_const_t<T>;
65 using V = Eigen::Vector<S, R>;
66 using Map = Eigen::Map<std::conditional_t<std::is_const_v<T>, const V, V>>;
67 if constexpr (R == Eigen::Dynamic)
68 return Map{s.data(), static_cast<Eigen::Index>(s.size())};
69 else
70 return Map{s.data()};
71}
72
73template <class T, size_t E>
74[[deprecated("use as_eigen instead")]] auto as_vec(std::span<T, E> s) {
75 return as_eigen(s);
76}
77
78/// @}
79
80} // namespace guanaqo
auto as_span(Eigen::DenseBase< Derived > &v)
Convert an Eigen vector view to a std::span.
Definition span.hpp:29
auto as_vec(std::span< T, E > s)
Definition span.hpp:74
auto as_eigen(std::span< T, E > s)
Convert a std::span to an Eigen::Vector view.
Definition span.hpp:62
constexpr auto to_eigen_extent
Definition span.hpp:18
constexpr auto to_std_extent
Definition span.hpp:15