Skip to content

Commit 714f6df

Browse files
committed
v2.0.0 - see changelog for info -- breaking change with how we evaluate operations/functions of length 1 vectors
1 parent f5cb428 commit 714f6df

File tree

11 files changed

+776
-435
lines changed

11 files changed

+776
-435
lines changed

README.md

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
# dsga : Data Structures for Geometric Algorithms
22

3-
**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.
3+
**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 intended to be used for [array programming](https://en.wikipedia.org/wiki/Array_programming) other than rendering. 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
## Home
66
[https://github.com/davidbrowne/dsga](https://github.com/davidbrowne/dsga)
77

88
## Current Version
9-
v1.5.0
9+
v2.0.0
10+
11+
## [Latest Major Changes](docs/CHANGELOG.md)
12+
13+
* v2.0.0
14+
* Large __Breaking Change__ - minimized how vectors of length == 1 behave as vectors. Most dsga operations and functions treat length == 1 vectors as scalars, returning scalar results (mostly through refactoring the underlying execution machinery). Use of the non-GLSL types iscal, uscal, bscal, scal, fscal, dscal, etc., is generally discouraged.
15+
* Small __Breaking Change__ - reverted/removed ```std::initializer_list``` constructors added in v1.5.0.
16+
* Added ```within_tolerance()``` comparison functions, that fit well with ```within_distance()``` and ```within_box()```.
17+
18+
* v1.5.0
19+
* Small __Breaking Change__ - added ```std::initializer_list``` constructors to ```basic_vector``` and ```basic_matrix``` - if not enough components, then fill rest with zeros - if too many components, just use the components necessary to fill the vector or matrix.
20+
* Fixed ```indexed_vector``` iterator classes to use signed types for indexing into storage (fixes iterator subtraction and ```reverse_iterator``` usage, as the iterators are random-access).
1021

1122
## Minimum Version of Tested Compilers
1223
* Microsoft Visual Studio 2022 v17.x
@@ -193,7 +204,7 @@ template <dsga::floating_point_scalar T1, dsga::floating_point_scalar T2>
193204
```
194205
## Relevant GLSL Overview
195206

196-
Our programming environment is ```c++20```, not a GLSL shader program, so the entire GLSL Shading language specification is a super-set of what we are trying to achieve. We really just want the vector and matrix data structures (and their corresponding functions and behavior) to be usable in a ```c++20``` environment.
207+
Our programming environment is ```C++20```, not a GLSL shader program, so the entire GLSL Shading language specification is a super-set of what we are trying to achieve. We really just want the vector and matrix data structures (and their corresponding functions and behavior) to be usable in a ```C++20``` environment. Another term for this type of programming is [array programming](https://en.wikipedia.org/wiki/Array_programming).
197208

198209
The following links to the shading specification should help with understanding what we are trying to implement with this header-only library.
199210

@@ -311,10 +322,11 @@ This is a c++20 library, so that needs to be the minimum standard that you tell
311322
312323
## Status
313324
314-
Current version: `v1.5.0`
325+
Current version: `v2.0.0`
315326
316327
* Everything major has some tests, but code coverage is not 100%.
317-
* [Last Released: v1.5.0](https://github.com/davidbrowne/dsga/releases/tag/v1.5.0)
328+
* [Last Released: v2.0.0](https://github.com/davidbrowne/dsga/releases/tag/v2.0.0)
329+
* [Change Log](docs/CHANGELOG.md)
318330
319331
### The next steps
320332
* Refining API documentation.
@@ -361,7 +373,7 @@ The tests have been most recently run on:
361373
[doctest] Status: SUCCESS!
362374
```
363375
364-
* **clang 18.1.3** on Windows, [official binaries](https://github.com/llvm/llvm-project/releases/tag/llvmorg-18.1.3), with MSVC and/or gcc 13.2.0 installed:
376+
* **clang 18.1.5** on Windows, [official binaries](https://github.com/llvm/llvm-project/releases/tag/llvmorg-18.1.5), with MSVC and/or gcc 13.2.0 installed:
365377
366378
Performs all the unit tests except where there is lack of support for ```std::is_corresponding_member<>```, and this is protected with a feature test macro.
367379
@@ -374,7 +386,7 @@ Performs all the unit tests except where there is lack of support for ```std::is
374386
[doctest] Status: SUCCESS!
375387
```
376388
377-
### Ubuntu Noble Numbat preview running in WSL2 for Windows 11
389+
### Ubuntu 24.04 LTS running in WSL2 for Windows 11
378390
379391
* **gcc 14.0.1**
380392
@@ -387,7 +399,7 @@ Performs all the unit tests except where there is lack of support for ```std::is
387399
[doctest] Status: SUCCESS!
388400
```
389401
390-
* **clang 18.1.0rc2**
402+
* **clang 18.1.3**
391403
392404
Performs all the unit tests except where there is lack of support for ```std::is_corresponding_member<>```, and this is protected with a feature test macro.
393405

VS2022/dsga.vcxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@
185185
</ItemGroup>
186186
<ItemGroup>
187187
<None Include="..\docs\API.md" />
188+
<None Include="..\docs\CHANGELOG.md" />
188189
<None Include="..\docs\DETAILS.md" />
189190
<None Include="..\docs\DOCUMENTATION.md" />
190191
<None Include="..\docs\dsga.puml" />

VS2022/dsga.vcxproj.filters

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
<Filter>Resource Files</Filter>
6565
</None>
6666
<None Include="..\docs\API.md" />
67+
<None Include="..\docs\CHANGELOG.md" />
6768
</ItemGroup>
6869
<ItemGroup>
6970
<Text Include="..\LICENSE_1_0.txt" />

docs/API.md

Lines changed: 64 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ template <typename UnOp>
581581
requires (std::same_as<T, std::invoke_result_t<UnOp, T>> || std::same_as<T, std::invoke_result_t<UnOp, const T &>>)
582582
[[nodiscard]] constexpr basic_vector<T, Count> apply(UnOp op) const noexcept;
583583
```
584-
Applies a lambda/function/function object/callable to every element of a vector, in an unspecified order. The callable must take either a ```T``` or ```const T &```, and it must return a ```T```. Returns a vector of the results.
584+
Applies a lambda/function/function object/callable to every element of a vector, in element order (order only matters if callable is side-effecting and/or has state). The callable must take either a ```T``` or ```const T &```, and it must return a ```T```. Returns a vector of the results.
585585

586586
##### ```vector_base::shift```
587587
```c++
@@ -1822,6 +1822,7 @@ Most of the functions perform their operation component-wise. There are some fun
18221822
* [```none```](#none)
18231823
* [```logicalNot```](#logicalnot)
18241824
* Tolerance Checking Functions
1825+
* [```within_tolerance```](#within_tolerance)
18251826
* [```within_distance```](#within_distance)
18261827
* [```within_box```](#within_box)
18271828
* Other Vector Functions
@@ -1976,15 +1977,15 @@ Not in GLSL. May or may not actually be faster that ```rsqrt()```, for which thi
19761977

19771978
##### ```abs```
19781979
```c++
1979-
template <bool W, dimensional_scalar T, std::size_t C, typename D>
1980-
requires (!unsigned_scalar<T>) && non_bool_scalar<T>
1980+
template <bool W, non_bool_scalar T, std::size_t C, typename D>
1981+
requires (!unsigned_scalar<T>)
19811982
[[nodiscard]] constexpr auto abs(const vector_base<W, T, C, D> &arg) noexcept;
19821983
```
19831984

19841985
##### ```sign```
19851986
```c++
1986-
template <bool W, dimensional_scalar T, std::size_t C, typename D>
1987-
requires (!unsigned_scalar<T>) && non_bool_scalar<T>
1987+
template <bool W, non_bool_scalar T, std::size_t C, typename D>
1988+
requires (!unsigned_scalar<T>)
19881989
[[nodiscard]] constexpr auto sign(const vector_base<W, T, C, D> &arg) noexcept;
19891990
```
19901991

@@ -2257,17 +2258,23 @@ template <bool W1, floating_point_scalar T1, std::size_t C, typename D1, bool W2
22572258
template <bool W1, floating_point_scalar T1, typename D1, bool W2, floating_point_scalar T2, typename D2>
22582259
[[nodiscard]] constexpr auto cross(const vector_base<W1, T1, 3, D1> &a,
22592260
const vector_base<W2, T2, 3, D2> &b) noexcept;
2261+
2262+
template <floating_point_scalar T1, floating_point_scalar T2>
2263+
[[nodiscard]] constexpr auto cross(const basic_vector<T1, 3> &a,
2264+
const basic_vector<T2, 3> &b) noexcept;
22602265
```
22612266

22622267
##### ```normalize```
22632268
```c++
22642269
template <bool W, floating_point_scalar T, std::size_t C, typename D>
2270+
requires (C > 1)
22652271
[[nodiscard]] constexpr auto normalize(const vector_base<W, T, C, D> &x) noexcept;
22662272
```
22672273

22682274
##### ```faceforward```
22692275
```c++
22702276
template <bool W1, floating_point_scalar T, std::size_t C, typename D1, bool W2, typename D2, bool W3, typename D3>
2277+
requires (C > 1)
22712278
[[nodiscard]] constexpr auto faceforward(const vector_base<W1, T, C, D1> &n,
22722279
const vector_base<W2, T, C, D2> &i,
22732280
const vector_base<W3, T, C, D3> &nref) noexcept;
@@ -2276,13 +2283,15 @@ template <bool W1, floating_point_scalar T, std::size_t C, typename D1, bool W2,
22762283
##### ```reflect```
22772284
```c++
22782285
template <bool W1, floating_point_scalar T, std::size_t C, typename D1, bool W2, typename D2>
2286+
requires (C > 1)
22792287
[[nodiscard]] constexpr auto reflect(const vector_base<W1, T, C, D1> &i,
22802288
const vector_base<W2, T, C, D2> &n) noexcept;
22812289
```
22822290

22832291
##### ```refract```
22842292
```c++
22852293
template <bool W1, floating_point_scalar T, std::size_t C, typename D1, bool W2, typename D2>
2294+
requires (C > 1)
22862295
[[nodiscard]] constexpr auto refract(const vector_base<W1, T, C, D1> &i,
22872296
const vector_base<W2, T, C, D2> &n,
22882297
T eta) noexcept;
@@ -2373,44 +2382,80 @@ This function takes the place of GLSL function ```not```. We can't define a func
23732382

23742383
#### Tolerance Checking Functions
23752384

2385+
##### ```within_tolerance```
2386+
```c++
2387+
template <non_bool_scalar T, non_bool_scalar U>
2388+
requires implicitly_convertible_to<U, T>
2389+
[[nodiscard]] constexpr bool within_tolerance(T x,
2390+
U tolerance) noexcept;
2391+
2392+
template <bool W, non_bool_scalar T, std::size_t C, typename D, non_bool_scalar U>
2393+
requires implicitly_convertible_to<U, T>
2394+
[[nodiscard]] constexpr bool within_tolerance(const vector_base<W, T, C, D> &x,
2395+
U tolerance) noexcept;
2396+
2397+
template <bool W1, non_bool_scalar T, std::size_t C1, typename D1, bool W2, non_bool_scalar U, std::size_t C2, typename D2>
2398+
requires ((C1 == C2) || (C2 == 1)) && implicitly_convertible_to<U, T>
2399+
[[nodiscard]] constexpr bool within_tolerance(const vector_base<W1, T, C1, D1> &x,
2400+
const vector_base<W2, U, C2, D2> &tolerance) noexcept;
2401+
```
2402+
Not in GLSL. Is a vector of values (or a single value) the same as 0 within a tolerance (or vector of tolerances). The tolerance is a less-than-or-equal comparison. Tolerances need to be non-negative, or the function will assert.
2403+
23762404
##### ```within_distance```
23772405
```c++
2378-
template <bool W1, non_bool_scalar T, std::size_t C, typename D1, bool W2, typename D2>
2406+
template <non_bool_scalar T, non_bool_scalar U>
2407+
requires implicitly_convertible_to<U, T>
2408+
[[nodiscard]] constexpr bool within_distance(T x,
2409+
T y,
2410+
U tolerance) noexcept;
2411+
2412+
template <bool W1, non_bool_scalar T, std::size_t C, typename D1, bool W2, typename D2, non_bool_scalar U>
2413+
requires implicitly_convertible_to<U, T>
23792414
[[nodiscard]] constexpr bool within_distance(const vector_base<W1, T, C, D1> &x,
23802415
const vector_base<W2, T, C, D2> &y,
2381-
T tolerance) noexcept;
2416+
U tolerance) noexcept;
23822417

2383-
template <bool W1, non_bool_scalar T, std::size_t C, typename D1, bool W2, typename D2, bool W3, typename D3>
2418+
template <bool W1, non_bool_scalar T, std::size_t C, typename D1, bool W2, typename D2, bool W3, non_bool_scalar U, typename D3>
2419+
requires implicitly_convertible_to<U, T>
23842420
[[nodiscard]] constexpr bool within_distance(const vector_base<W1, T, C, D1> &x,
23852421
const vector_base<W2, T, C, D2> &y,
2386-
const vector_base<W3, T, 1, D3> &tolerance) noexcept;
2387-
2422+
const vector_base<W3, U, 1, D3> &tolerance) noexcept;
23882423
```
2389-
Not in GLSL. It compares the Euclidean distance between two vectors to see if they are within the tolerance. The tolerance is a strictly less-than comparison. Tolerances need to be non-negative.
2424+
Not in GLSL. It compares the Euclidean distance between two vectors to see if the distance is 0 within the tolerance. The tolerance is a less-than-or-equal comparison. Tolerances need to be non-negative, or the function will assert.
23902425

23912426
##### ```within_box```
23922427
```c++
2393-
template <bool W1, non_bool_scalar T, std::size_t C, typename D1, bool W2, typename D2>
2394-
requires non_bool_scalar<T>
2428+
template <non_bool_scalar T, non_bool_scalar U>
2429+
requires implicitly_convertible_to<U, T>
2430+
[[nodiscard]] constexpr bool within_box(T x,
2431+
T y,
2432+
U tolerance) noexcept;
2433+
2434+
template <bool W1, non_bool_scalar T, std::size_t C, typename D1, bool W2, typename D2, non_bool_scalar U>
2435+
requires implicitly_convertible_to<U, T>
23952436
[[nodiscard]] constexpr bool within_box(const vector_base<W1, T, C, D1> &x,
23962437
const vector_base<W2, T, C, D2> &y,
2397-
T tolerance) noexcept;
2438+
U tolerance) noexcept;
23982439

2399-
template <bool W1, non_bool_scalar T, std::size_t C1, typename D1, bool W2, typename D2, bool W3, std::size_t C2, typename D3>
2400-
requires ((C1 == C2) || (C2 == 1))
2440+
template <bool W1, non_bool_scalar T, std::size_t C1, typename D1, bool W2, typename D2, bool W3, non_bool_scalar U, std::size_t C2, typename D3>
2441+
requires ((C1 == C2) || (C2 == 1)) && implicitly_convertible_to<U, T>
24012442
[[nodiscard]] constexpr bool within_box(const vector_base<W1, T, C1, D1> &x,
24022443
const vector_base<W2, T, C1, D2> &y,
2403-
const vector_base<W3, T, C2, D3> &tolerance) noexcept;
2444+
const vector_base<W3, U, C2, D3> &tolerance) noexcept;
24042445
```
2405-
Not in GLSL. This represents a bounding-box tolerance check, which aggregates the component-wise tolerance checks. These functions can take a single tolerance or a vector of tolerances. All the vector elements must be within tolerance or the whole answer is false. The tolerance is a strictly less-than comparison. All tolerances need to be non-negative.
2446+
Not in GLSL. This represents a bounding-box tolerance check, which aggregates the component-wise tolerance checks. These functions can take a single tolerance or a vector of tolerances and check if the differences of the value(s) are 0 within the tolerance(s). All the vector elements must be within tolerance or the whole answer is false. The tolerance is a less-than-or-equal comparison. All tolerances need to be non-negative, or the function will assert.
24062447

24072448
##### ```swizzle```
24082449
```c++
2450+
template <bool W, dimensional_scalar T, std::size_t C, typename D, typename Arg>
2451+
requires std::convertible_to<Arg, std::size_t>
2452+
inline auto swizzle(const vector_base<W, T, C, D> &v, const Arg &index);
2453+
24092454
template <bool W, dimensional_scalar T, std::size_t C, typename D, typename ...Args>
24102455
requires (std::convertible_to<Args, std::size_t> && ...) && (sizeof...(Args) > 0) && (sizeof...(Args) <= 4)
24112456
inline basic_vector<T, sizeof...(Args)> swizzle(const vector_base<W, T, C, D> &v, const Args &...Is);
24122457
```
2413-
Not in GLSL. Runtime function for swizzling. Returns a stand-alone ```dsga::basic_vector``` version of a swizzle, instead of a ```dsga::indexed_vector``` data member. If the index arguments are invalid (out of bounds), this function will throw a ```std::out_of_range()``` exception. Inspired by the [Odin Programming Language](https://odin-lang.org/docs/overview/#swizzle-operations).
2458+
Not in GLSL. Runtime function for swizzling. Returns a stand-alone ```dsga::basic_vector``` version of a swizzle, instead of a ```dsga::indexed_vector``` data member. Will return a scalar value if only one index argument. If the index arguments are invalid (out of bounds), this function will throw a ```std::out_of_range()``` exception. Inspired by the [Odin Programming Language](https://odin-lang.org/docs/overview/#swizzle-operations).
24142459

24152460
### Scalar Functions
24162461
Scalar versions of most of the vector free functions exist. It is not recommended to use them if there is a function in the C++ Standard Library that does the same thing.

docs/CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Change Log
2+
3+
### v2.0.0
4+
* Large __Breaking Change__ - minimized how vectors of length == 1 behave as vectors. Most dsga operations and functions treat length == 1 vectors as scalars, returning scalar results (mostly through refactoring the underlying execution machinery). Use of the non-GLSL types iscal, uscal, bscal, scal, fscal, dscal, etc., is generally discouraged.
5+
* Small __Breaking Change__ - reverted/removed ```std::initializer_list``` constructors added in v1.5.0.
6+
* Moved vector relational functions above the other vector functions (for use in assertions).
7+
* Added ```within_tolerance()``` comparison functions, that fit well with ```within_distance()``` and ```within_box()```.
8+
* Upgraded to cxcm v1.1.2.
9+
* Minor type constraint (concepts) refactoring.
10+
* Other minor refactoring.
11+
* Added changelog.
12+
13+
### v1.5.0
14+
* Small __Breaking Change__ - added ```std::initializer_list``` constructors to ```basic_vector``` and ```basic_matrix``` - if not enough components, then fill rest with zeros - if too many components, just use the components necessary to fill the vector or matrix.
15+
* Fixed ```indexed_vector``` iterator classes to use signed types for indexing into storage (fixes iterator subtraction and ```reverse_iterator``` usage, as the iterators are random-access).
16+
17+
### v1.4.1
18+
* Minor refactoring.
19+
* Comment removal and/or updating.
20+
* Removed Microsoft VS2019 support (latest version of VS2019 does not compile dsga).
21+
22+
### v1.4.0
23+
* Minor type constraint (concepts) refactoring.
24+
* Updating copyright dates.

0 commit comments

Comments
 (0)