Skip to content

Commit ac3180a

Browse files
committed
more interoperability between c++ spans and arrays with dsga vectors and matrices
1 parent 9a1e88d commit ac3180a

File tree

3 files changed

+71
-18
lines changed

3 files changed

+71
-18
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
**dsga** is a single header-only **c++20 library** that implements the **vectors** and **matrices** from the OpenGL Shading Language 4.6 specification ([pdf](https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.60.pdf) | [html](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.html)). It is inspired by the spec, but does deviate in some small ways, mostly to make it work well in c++20. It is not intended to be used for rendering, just for sharing the fundamental data structures and associated functions. Our requirements in general are for things like 3D CAD/CAM applications and other geometric and algebraic things. See [motivation](docs/MOTIVATION.md) for more details. This library does not use SIMD instructions or types under the hood, beyond whatever the compiler provides through optimization.
44

55
## Current Version
6-
v1.0.6
6+
v1.0.7
77

88
## Contents
99
* [Some Quick Examples](#some-quick-examples)
@@ -288,7 +288,7 @@ Remember, this is a c++20 library, so that needs to be the minimum standard that
288288
289289
## Status
290290
291-
Current version: `v1.0.6`
291+
Current version: `v1.0.7`
292292
293293
* Everything major has some tests, but code coverage is not 100%.
294294
* [Released v1.0.0](https://github.com/davidbrowne/dsga/releases/tag/v1.0.0)

examples/span_convert.hxx

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ constexpr void copy_from_vector(std::span<U, E> lhs, const dsga::basic_vector<T,
7272

7373
// non-const T span from non-const vector
7474
template <dsga::dimensional_scalar T, std::size_t S>
75-
auto make_span(dsga::basic_vector<T, S> &v) noexcept
75+
[[nodiscard]] constexpr auto make_span(dsga::basic_vector<T, S> &v) noexcept
7676
{
7777
// return std::span<T, S>(v.begin(), v.end());
7878
// return std::span<T, S>(v.data(), v.size());
@@ -81,7 +81,7 @@ auto make_span(dsga::basic_vector<T, S> &v) noexcept
8181

8282
// const T span from const vector
8383
template <dsga::dimensional_scalar T, std::size_t S>
84-
auto make_span(const dsga::basic_vector<T, S> &v) noexcept
84+
[[nodiscard]] constexpr auto make_span(const dsga::basic_vector<T, S> &v) noexcept
8585
{
8686
// return std::span<const T, S>(v.begin(), v.end());
8787
// return std::span<const T, S>(v.data(), v.size());
@@ -98,7 +98,7 @@ auto make_span(const dsga::basic_vector<T, S> &&v) noexcept = delete;
9898

9999
// const T span from either const or non-const vector
100100
template <dsga::dimensional_scalar T, std::size_t S>
101-
auto make_const_span(const dsga::basic_vector<T, S> &v) noexcept
101+
[[nodiscard]] constexpr auto make_const_span(const dsga::basic_vector<T, S> &v) noexcept
102102
{
103103
// return std::span<const T, S>(v.begin(), v.end());
104104
// return std::span<const T, S>(v.data(), v.size());
@@ -119,7 +119,7 @@ auto make_const_span(const dsga::basic_vector<T, S> &&v) noexcept = delete;
119119

120120
// non-const dsga::basic_vector<T, C> span from non-const matrix
121121
template <dsga::floating_point_scalar T, std::size_t C, std::size_t R>
122-
auto make_span(dsga::basic_matrix<T, C, R> &m) noexcept
122+
[[nodiscard]] constexpr auto make_span(dsga::basic_matrix<T, C, R> &m) noexcept
123123
{
124124
// return std::span<dsga::basic_vector<T, R>, C>(m.begin(), m.end());
125125
// return std::span<dsga::basic_vector<T, R>, C>(m.data(), m.size());
@@ -128,7 +128,7 @@ auto make_span(dsga::basic_matrix<T, C, R> &m) noexcept
128128

129129
// const dsga::basic_vector<T, C> span from const matrix
130130
template <dsga::floating_point_scalar T, std::size_t C, std::size_t R>
131-
auto make_span(const dsga::basic_matrix<T, C, R> &m) noexcept
131+
[[nodiscard]] constexpr auto make_span(const dsga::basic_matrix<T, C, R> &m) noexcept
132132
{
133133
// return std::span<const dsga::basic_vector<T, R>, C>(m.begin(), m.end());
134134
// return std::span<const dsga::basic_vector<T, R>, C>(m.data(), m.size());
@@ -145,7 +145,7 @@ auto make_span(const dsga::basic_matrix<T, C, R> &&m) noexcept = delete;
145145

146146
// const dsga::basic_vector<T, C> span from either const or non-const matrix
147147
template <dsga::floating_point_scalar T, std::size_t C, std::size_t R>
148-
auto make_const_span(const dsga::basic_matrix<T, C, R> &m) noexcept
148+
[[nodiscard]] constexpr auto make_const_span(const dsga::basic_matrix<T, C, R> &m) noexcept
149149
{
150150
// return std::span<const dsga::basic_vector<T, R>, C>(m.begin(), m.end());
151151
// return std::span<const dsga::basic_vector<T, R>, C>(m.data(), m.size());
@@ -168,24 +168,28 @@ auto make_const_span(const dsga::basic_matrix<T, C, R> &&m) noexcept = delete;
168168
// use like: make_vector(vector_input_span, std::make_index_sequence<4>{})
169169
template <typename T, std::size_t E, std::size_t ...Is>
170170
requires (E != std::dynamic_extent) && dsga::dimensional_scalar<std::remove_cvref_t<T>> && dsga::dimensional_size<sizeof...(Is)> && dsga::detail::valid_range_indexes<E, Is...>
171-
auto make_vector(std::span<T, E> s, std::index_sequence<Is...> ) noexcept
171+
[[nodiscard]] constexpr auto make_vector(std::span<T, E> s, std::index_sequence<Is...> ) noexcept
172172
{
173173
return dsga::basic_vector<std::remove_cvref_t<T>, sizeof...(Is)>(s[Is]...);
174174
}
175175

176+
//
177+
// std::span to dsga::basic_matrix
178+
//
179+
176180
// create a basic_matrix from a span that holds at least the number of matrix elements.
177181
// use like: make_matrix<C, R>(matrix_input_span)
178182
template <std::size_t C, std::size_t R, typename T, std::size_t E>
179183
requires (E != std::dynamic_extent) && (((C >= 2u) && (C <= 4u)) && ((R >= 2u) && (R <= 4u))) && (C * R <= E) && dsga::floating_point_scalar<std::remove_cvref_t<T>>
180-
auto make_matrix(std::span<T, E> s) noexcept
184+
[[nodiscard]] constexpr auto make_matrix(std::span<T, E> s) noexcept
181185
{
182-
return[&]<std::size_t ...Js>(std::index_sequence <Js...>) noexcept
186+
return [&]<std::size_t ...Js>(std::index_sequence <Js...>) noexcept
183187
{
184188
return dsga::basic_matrix<std::remove_cvref_t<T>, C, R>(
185189
[&]<std::size_t ...Is>(std::index_sequence <Is...>) noexcept
186190
{
187191
constexpr auto cols = Js;
188-
return dsga::basic_vector<std::remove_cvref_t<T>, R>(s[cols*R + Is]...);
192+
return dsga::basic_vector<std::remove_cvref_t<T>, R>(s[cols * R + Is]...);
189193
}(std::make_index_sequence<R>{}) ...);
190194
}(std::make_index_sequence<C>{});
191195
}

include/dsga.hxx

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ inline void dsga_constexpr_assert_failed(Assert &&a) noexcept
6060

6161
constexpr inline int DSGA_MAJOR_VERSION = 1;
6262
constexpr inline int DSGA_MINOR_VERSION = 0;
63-
constexpr inline int DSGA_PATCH_VERSION = 6;
63+
constexpr inline int DSGA_PATCH_VERSION = 7;
6464

6565
namespace dsga
6666
{
@@ -6369,15 +6369,15 @@ namespace dsga
63696369
// converting from external vector type or data to internal vector type
63706370
//
63716371

6372-
template <dsga::dimensional_scalar T, std::size_t S>
6373-
requires dsga::dimensional_storage<T, S>
6372+
template <dimensional_scalar T, std::size_t S>
6373+
requires dimensional_storage<T, S>
63746374
[[nodiscard]] constexpr basic_vector<T, S> to_vector(const std::array<T, S> &arg) noexcept
63756375
{
63766376
return detail::passthru_execute(std::make_index_sequence<S>{}, arg);
63776377
}
63786378

6379-
template <dsga::dimensional_scalar T, std::size_t S>
6380-
requires dsga::dimensional_storage<T, S>
6379+
template <dimensional_scalar T, std::size_t S>
6380+
requires dimensional_storage<T, S>
63816381
[[nodiscard]] constexpr basic_vector<T, S> to_vector(const T(&arg)[S]) noexcept
63826382
{
63836383
return detail::passthru_execute(std::make_index_sequence<S>{}, arg);
@@ -6386,14 +6386,63 @@ namespace dsga
63866386
// converting from internal vector type to std::array
63876387

63886388
template <bool W, typename T, std::size_t C, typename D>
6389-
[[nodiscard]] constexpr std::array<T, C> to_array(const dsga::vector_base<W, T, C, D> &arg) noexcept
6389+
[[nodiscard]] constexpr std::array<T, C> to_array(const vector_base<W, T, C, D> &arg) noexcept
63906390
{
63916391
return[&]<std::size_t ...Is>(std::index_sequence<Is...>) noexcept -> std::array<T, C>
63926392
{
63936393
return {arg[Is]...};
63946394
}(std::make_index_sequence<C>{});
63956395
}
63966396

6397+
// converting from array to a basic_matrix
6398+
6399+
template <std::size_t C, std::size_t R, floating_point_scalar T, std::size_t S>
6400+
requires (((C >= 2u) && (C <= 4u)) && ((R >= 2u) && (R <= 4u))) && (C * R <= S)
6401+
[[nodiscard]] constexpr dsga::basic_matrix<T, C, R> to_matrix(const std::array<T, S> &arg) noexcept
6402+
{
6403+
return [&]<std::size_t ...Js>(std::index_sequence <Js...>) noexcept
6404+
{
6405+
return dsga::basic_matrix<T, C, R>(
6406+
[&]<std::size_t ...Is>(std::index_sequence <Is...>) noexcept
6407+
{
6408+
constexpr auto cols = Js;
6409+
return dsga::basic_vector<T, R>(arg[cols * R + Is]...);
6410+
}(std::make_index_sequence<R>{}) ...);
6411+
}(std::make_index_sequence<C>{});
6412+
}
6413+
6414+
template <std::size_t C, std::size_t R, floating_point_scalar T, std::size_t S>
6415+
requires (((C >= 2u) && (C <= 4u)) && ((R >= 2u) && (R <= 4u))) && (C * R <= S)
6416+
[[nodiscard]] constexpr dsga::basic_matrix<T, C, R> to_matrix(const T(&arg)[S]) noexcept
6417+
{
6418+
return [&]<std::size_t ...Js>(std::index_sequence <Js...>) noexcept
6419+
{
6420+
return dsga::basic_matrix<T, C, R>(
6421+
[&]<std::size_t ...Is>(std::index_sequence <Is...>) noexcept
6422+
{
6423+
constexpr auto cols = Js;
6424+
return dsga::basic_vector<T, R>(arg[cols * R + Is]...);
6425+
}(std::make_index_sequence<R>{}) ...);
6426+
}(std::make_index_sequence<C>{});
6427+
}
6428+
6429+
// converting from internal matrix type to std::array
6430+
6431+
template <floating_point_scalar T, std::size_t C, std::size_t R>
6432+
requires (((C >= 2u) && (C <= 4u)) && ((R >= 2u) && (R <= 4u)))
6433+
[[nodiscard]] constexpr std::array<T, C * R> to_array(const basic_matrix<T, C, R> &arg) noexcept
6434+
{
6435+
auto matrix_tuple = [&]<std::size_t ...Is>(std::index_sequence <Is...>) noexcept
6436+
{
6437+
return detail::flatten_args_to_tuple(arg[Is]...);
6438+
}(std::make_index_sequence<C>{});
6439+
6440+
return [&]<std::size_t ...Js>(std::index_sequence <Js...>) noexcept
6441+
{
6442+
return std::array<T, C * R>{std::get<Js>(matrix_tuple) ...};
6443+
}(std::make_index_sequence<C * R>{});
6444+
}
6445+
63976446
} // namespace dsga
63986447

63996448
//

0 commit comments

Comments
 (0)