Skip to content

Commit 87eee9b

Browse files
committed
refactoring and comments and minor utility function (unrelated to vectors/matrices)
1 parent a136c61 commit 87eee9b

File tree

6 files changed

+85
-42
lines changed

6 files changed

+85
-42
lines changed

README.md

Lines changed: 16 additions & 16 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.3.10
6+
v1.3.11
77

88
## Contents
99
* [Some Quick Examples](#some-quick-examples)
@@ -278,7 +278,7 @@ This is a c++20 library, so that needs to be the minimum standard that you tell
278278
279279
## Status
280280
281-
Current version: `v1.3.10`
281+
Current version: `v1.3.11`
282282
283283
* Everything major has some tests, but code coverage is not 100%.
284284
* [Last Released: v1.3.0](https://github.com/davidbrowne/dsga/releases/tag/v1.3.0)
@@ -312,8 +312,8 @@ The tests have been most recently run on:
312312
[doctest] doctest version is "2.4.11"
313313
[doctest] run with "--help" for options
314314
===============================================================================
315-
[doctest] test cases: 108 | 108 passed | 0 failed | 0 skipped
316-
[doctest] assertions: 2133 | 2133 passed | 0 failed |
315+
[doctest] test cases: 109 | 109 passed | 0 failed | 0 skipped
316+
[doctest] assertions: 2135 | 2135 passed | 0 failed |
317317
[doctest] Status: SUCCESS!
318318
```
319319
@@ -323,8 +323,8 @@ The tests have been most recently run on:
323323
[doctest] doctest version is "2.4.11"
324324
[doctest] run with "--help" for options
325325
===============================================================================
326-
[doctest] test cases: 108 | 108 passed | 0 failed | 0 skipped
327-
[doctest] assertions: 2133 | 2133 passed | 0 failed |
326+
[doctest] test cases: 109 | 109 passed | 0 failed | 0 skipped
327+
[doctest] assertions: 2135 | 2135 passed | 0 failed |
328328
[doctest] Status: SUCCESS!
329329
```
330330
@@ -336,8 +336,8 @@ Performs all the unit tests except where there is lack of support for ```std::is
336336
[doctest] doctest version is "2.4.11"
337337
[doctest] run with "--help" for options
338338
===============================================================================
339-
[doctest] test cases: 108 | 108 passed | 0 failed | 0 skipped
340-
[doctest] assertions: 2117 | 2117 passed | 0 failed |
339+
[doctest] test cases: 109 | 109 passed | 0 failed | 0 skipped
340+
[doctest] assertions: 2119 | 2119 passed | 0 failed |
341341
[doctest] Status: SUCCESS!
342342
```
343343
@@ -349,8 +349,8 @@ Performs all the unit tests except where there is lack of support for ```std::is
349349
[doctest] doctest version is "2.4.11"
350350
[doctest] run with "--help" for options
351351
===============================================================================
352-
[doctest] test cases: 108 | 108 passed | 0 failed | 0 skipped
353-
[doctest] assertions: 2133 | 2133 passed | 0 failed |
352+
[doctest] test cases: 109 | 109 passed | 0 failed | 0 skipped
353+
[doctest] assertions: 2135 | 2135 passed | 0 failed |
354354
[doctest] Status: SUCCESS!
355355
```
356356
@@ -362,8 +362,8 @@ Performs all the unit tests except where there is lack of support for ```std::is
362362
[doctest] doctest version is "2.4.11"
363363
[doctest] run with "--help" for options
364364
===============================================================================
365-
[doctest] test cases: 108 | 108 passed | 0 failed | 0 skipped
366-
[doctest] assertions: 2117 | 2117 passed | 0 failed |
365+
[doctest] test cases: 109 | 109 passed | 0 failed | 0 skipped
366+
[doctest] assertions: 2119 | 2119 passed | 0 failed |
367367
[doctest] Status: SUCCESS!
368368
```
369369
@@ -375,8 +375,8 @@ Performs all the unit tests except where there is lack of support for ```std::is
375375
[doctest] doctest version is "2.4.11"
376376
[doctest] run with "--help" for options
377377
===============================================================================
378-
[doctest] test cases: 108 | 108 passed | 0 failed | 0 skipped
379-
[doctest] assertions: 2133 | 2133 passed | 0 failed |
378+
[doctest] test cases: 109 | 109 passed | 0 failed | 0 skipped
379+
[doctest] assertions: 2135 | 2135 passed | 0 failed |
380380
[doctest] Status: SUCCESS!
381381
```
382382
@@ -388,8 +388,8 @@ Performs all the unit tests except where there is lack of support for ```std::is
388388
[doctest] doctest version is "2.4.11"
389389
[doctest] run with "--help" for options
390390
===============================================================================
391-
[doctest] test cases: 108 | 108 passed | 0 failed | 0 skipped
392-
[doctest] assertions: 2117 | 2117 passed | 0 failed |
391+
[doctest] test cases: 109 | 109 passed | 0 failed | 0 skipped
392+
[doctest] assertions: 2119 | 2119 passed | 0 failed |
393393
[doctest] Status: SUCCESS!
394394
```
395395

docs/API.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ Convenience using directive for creating a ```indexed_vector``` for ```Count ==
240240
* [```make_sequence_array```](#make_sequence_array)
241241
* [```make_reverse_sequence```](#make_reverse_sequence)
242242
* [```is_constexpr```](#is_constexpr)
243+
* [```to_underlying```](#to_underlying)
243244

244245
#### ```make_sequence_array```
245246
```c++
@@ -262,6 +263,14 @@ consteval auto is_constexpr(C) noexcept;
262263
```
263264
Is a default-constructible callable constexpr? If not, then compile error due to trying to evaluate something that is not constexpr at compile time.
264265

266+
##### ```to_underlying```
267+
```c++
268+
template <typename E>
269+
requires std::is_enum_v<E>
270+
[[nodiscard]] constexpr std::underlying_type_t<E> to_underlying(E e) noexcept;
271+
```
272+
Not a vector or matrix function. Not in GLSL. This functionality was added to ```c++23```, but since this is a ```c++20``` library, we have to provide the underlying implementation ourselves. It is not really a good fit for dsga, but it is handy to have around anyway.
273+
265274
### Class Templates
266275

267276
* [```basic_vector```](#basic_vector)
@@ -2198,8 +2207,8 @@ template <bool W1, floating_point_scalar T, std::size_t C, typename D1, bool W2,
21982207

21992208
##### ```byteswap```
22002209
```c++
2201-
template <bool W, non_bool_scalar T, std::size_t C, typename D>
2202-
[[nodiscard]] inline auto byteswap(const vector_base<W, T, C, D> &arg) noexcept;
2210+
template <bool W, numeric_integral_scalar T, std::size_t C, typename D>
2211+
[[nodiscard]] constexpr auto byteswap(const vector_base<W, T, C, D> &arg) noexcept;
22032212
```
22042213
Not in GLSL. This functionality was added to ```c++23```, but since this is a ```c++20``` library, we have to provide the underlying implementation ourselves.
22052214

docs/DOCUMENTATION.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,7 @@ There are scalar versions of these vector functions where it makes sense, i.e.,
433433
* ```ldexp()```
434434
* ```byteswap()``` - not in GLSL - doesn't use ```std::byteswap()``` since that is in c++23
435435
* ```swizzle()``` - not in GLSL - runtime swizzle() function
436+
* ```to_underlying``` - not in GLSL - not for vectors or matrices, but is a c++23 function that might come in handy
436437
437438
#### Geometric Functions
438439
The geometric functions treat a vector as an entity instead of as a collection of components.

examples/stl.cxx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,11 @@ bool read_binary_stl_float(std::ifstream &some_file, float &float_val)
125125
return false;
126126

127127
if constexpr (std::endian::native == std::endian::big)
128-
float_val = dsga::byteswap(float_val);
128+
{
129+
auto integral_float = std::bit_cast<unsigned int>(float_val);
130+
integral_float = dsga::byteswap(integral_float);
131+
float_val = std::bit_cast<float>(integral_float);
132+
}
129133

130134
return true;
131135
}

include/dsga.hxx

Lines changed: 36 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ inline void cxcm_constexpr_assert_failed(Assert &&a) noexcept
9696

9797
constexpr inline int DSGA_MAJOR_VERSION = 1;
9898
constexpr inline int DSGA_MINOR_VERSION = 3;
99-
constexpr inline int DSGA_PATCH_VERSION = 10;
99+
constexpr inline int DSGA_PATCH_VERSION = 11;
100100

101101
namespace dsga
102102
{
@@ -1937,7 +1937,7 @@ namespace dsga
19371937
return copy;
19381938
}
19391939

1940-
// min value in vector
1940+
// min value in vector - been through nanobench testing for current best implemention
19411941
[[nodiscard]] constexpr T min() const noexcept requires non_bool_scalar<T>
19421942
{
19431943
T smallest = (*this)[0];
@@ -1950,7 +1950,7 @@ namespace dsga
19501950
return smallest;
19511951
}
19521952

1953-
// max value in vector
1953+
// max value in vector - been through nanobench testing for current best implemention
19541954
[[nodiscard]] constexpr T max() const noexcept requires non_bool_scalar<T>
19551955
{
19561956
T largest = (*this)[0];
@@ -1963,7 +1963,7 @@ namespace dsga
19631963
return largest;
19641964
}
19651965

1966-
// sum of values in vector
1966+
// sum of values in vector - been through nanobench testing for current best implemention
19671967
[[nodiscard]] constexpr T sum() const noexcept requires non_bool_scalar<T>
19681968
{
19691969
return [&]<std::size_t ...Is>(std::index_sequence<Is...>) noexcept
@@ -3823,6 +3823,7 @@ namespace dsga
38233823

38243824
// binary
38253825

3826+
// been through nanobench testing for current best implemention
38263827
template <bool W1, dimensional_scalar T1, std::size_t C, typename D1, bool W2, dimensional_scalar T2, typename D2, typename BinOp>
38273828
constexpr auto apply_unitype_make(const vector_base<W1, T1, C, D1> &lhs,
38283829
const vector_base<W2, T2, C, D2> &rhs,
@@ -5651,23 +5652,35 @@ namespace dsga
56515652
//
56525653

56535654
// since dsga is designed for c++20, we can't use std::byteswap() from c++23
5654-
inline auto byte_swap_op = []<non_bool_scalar T>(T x) noexcept -> T
5655+
constexpr auto byteswap_op = []<numeric_integral_scalar T>(T x) noexcept -> T
56555656
{
5656-
auto bytes = reinterpret_cast<std::byte *>(&x);
5657-
std::reverse(bytes, bytes + sizeof(T));
5658-
return *reinterpret_cast<T *>(bytes);
5657+
auto value_representation = std::bit_cast<std::array<std::byte, sizeof(T)>>(x);
5658+
std::ranges::reverse(value_representation);
5659+
return std::bit_cast<T>(value_representation);
56595660
};
56605661

5661-
template <bool W, non_bool_scalar T, std::size_t C, typename D>
5662-
[[nodiscard]] inline auto byteswap(const vector_base<W, T, C, D> &arg) noexcept
5662+
template <bool W, numeric_integral_scalar T, std::size_t C, typename D>
5663+
[[nodiscard]] constexpr auto byteswap(const vector_base<W, T, C, D> &arg) noexcept
56635664
{
5664-
return machinery::apply_make(arg, byte_swap_op);
5665+
return machinery::apply_make(arg, byteswap_op);
56655666
}
56665667

5667-
template <non_bool_scalar T>
5668-
[[nodiscard]] inline auto byteswap(T arg) noexcept
5668+
template <numeric_integral_scalar T>
5669+
[[nodiscard]] constexpr auto byteswap(T arg) noexcept
56695670
{
5670-
return byte_swap_op(arg);
5671+
return byteswap_op(arg);
5672+
}
5673+
5674+
//
5675+
// to_underlying() for underlying enum value - not really a good fit for dsga, but a helpful function anyway
5676+
//
5677+
5678+
// since dsga is designed for c++20, we can't use std::to_underlying() from c++23
5679+
template <typename E>
5680+
requires std::is_enum_v<E>
5681+
[[nodiscard]] constexpr std::underlying_type_t<E> to_underlying(E e) noexcept
5682+
{
5683+
return static_cast<std::underlying_type_t<E>>(e);
56715684
}
56725685

56735686
//
@@ -6330,21 +6343,21 @@ namespace dsga
63306343
}(std::make_index_sequence<C2>{});
63316344
}
63326345

6333-
// transpose a matrix
6346+
// transpose a matrix - been through nanobench testing for current best implemention
63346347
template <floating_point_scalar T, std::size_t C, std::size_t R>
63356348
[[nodiscard]] constexpr basic_matrix<T, R, C> transpose(const basic_matrix<T, C, R> &arg) noexcept
63366349
{
6337-
auto trans = basic_matrix<T, R, C>();
6350+
auto val = basic_matrix<T, R, C>();
63386351

63396352
[&] <std::size_t ...Is>(std::index_sequence <Is...>) noexcept
63406353
{
63416354
(([&] <std::size_t ...Js>(std::index_sequence <Js...>, std::size_t row) noexcept
63426355
{
6343-
((trans[row][Js] = arg[Js][row]), ...);
6356+
((val[row][Js] = arg[Js][row]), ...);
63446357
}(std::make_index_sequence<C>{}, Is)), ...);
63456358
}(std::make_index_sequence<R>{});
63466359

6347-
return trans;
6360+
return val;
63486361
}
63496362

63506363
// determinant() - only on square matrices
@@ -6714,7 +6727,7 @@ namespace dsga
67146727
}
67156728

67166729
//
6717-
// linear-algebriac binary ops
6730+
// linear-algebriac binary ops - been through nanobench testing for current best implemention
67186731
//
67196732

67206733
// matrix * (column) vector => (column) vector
@@ -6750,12 +6763,12 @@ namespace dsga
67506763
{
67516764
auto val = basic_matrix<T, C2, R1>();
67526765

6753-
for (std::size_t i = 0; i < R1; ++i)
6766+
for (std::size_t j = 0; j < R1; ++j)
67546767
{
6755-
auto row = lhs.row(i);
6756-
for (std::size_t j = 0; j < C2; ++j)
6768+
auto row = lhs.row(j);
6769+
for (std::size_t i = 0; i < C2; ++i)
67576770
{
6758-
val[j][i] = functions::dot(rhs[j], row);
6771+
val[i][j] = functions::dot(row, rhs[i]);
67596772
}
67606773
}
67616774

tests/function_test.cxx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,22 @@ TEST_SUITE("test functions")
617617
CHECK_EQ(runtime_swizzle2, basic_vector(3.0));
618618
}
619619

620+
TEST_CASE("general utility functions")
621+
{
622+
// to_underlying()
623+
enum class bool_flag : bool {};
624+
enum class int_flag : int {};
625+
626+
auto bool_arg = bool_flag{true};
627+
auto int_arg = int_flag{42};
628+
629+
auto bool_value = dsga::to_underlying(bool_arg);
630+
auto int_value = dsga::to_underlying(int_arg);
631+
632+
CHECK_EQ(bool_value, true);
633+
CHECK_EQ(int_value, 42);
634+
}
635+
620636
TEST_CASE("matrix functions")
621637
{
622638
// matrixCompMult() - equivalent to a component-wise "matrix/matrix binary operator *" if there was one

0 commit comments

Comments
 (0)