diff options
-rw-r--r-- | include/jau/math/util/sstack.hpp | 115 | ||||
-rw-r--r-- | test/test_math_vec.cpp | 19 |
2 files changed, 134 insertions, 0 deletions
diff --git a/include/jau/math/util/sstack.hpp b/include/jau/math/util/sstack.hpp new file mode 100644 index 0000000..a36df49 --- /dev/null +++ b/include/jau/math/util/sstack.hpp @@ -0,0 +1,115 @@ +/* + * Author: Sven Gothel <[email protected]> + * Copyright (c) 2014-2024 Gothel Software e.K. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +#ifndef JAU_SSTACK_HPP_ +#define JAU_SSTACK_HPP_ + +#include <cmath> +#include <cstdarg> +#include <cstdint> +#include <cassert> +#include <limits> +#include <vector> +#include <type_traits> +#include <algorithm> + +#include <jau/cpp_lang_util.hpp> + +namespace jau::math::util { + + /** \addtogroup Math + * + * @{ + */ + + /** + * A simple stack of compounds, each consisting of `element_size` * `T` + * @tparam T type of one element used in each compound + * @tparam element_size number of T elements making up one compound + */ + template<typename Value_type, size_t Element_size, + std::enable_if_t<std::is_floating_point_v<Value_type> || + std::is_integral_v<Value_type>, + bool> = true> + class SimpleStack { + public: + typedef Value_type value_type; + constexpr static const size_t element_size = Element_size; + + private: + int growSize; + std::vector<Value_type> buffer; + + public: + /** + * Start w/ zero size and growSize is 16, half GL-min size (32) + */ + constexpr_cxx20 SimpleStack() noexcept + : growSize(16*element_size), buffer(0) {} + + /** + * @param initialSize initial size + * @param growSize grow size if {@link #position()} is reached, maybe <code>0</code> + */ + constexpr_cxx20 SimpleStack(int initialSize, int growSize_) noexcept + : growSize(growSize_), buffer(initialSize) {} + + constexpr_cxx20 size_t growIfNecessary(int length) noexcept { + const size_t p = buffer.size(); + const size_t nsz = buffer.size() + length; + if( nsz > buffer.capacity() ) { + buffer.reserve(buffer.size() + std::max(length, growSize)); + } + buffer.resize(nsz); + return p; + } + + constexpr_cxx20 void push(const Value_type* src) noexcept { + size_t p = growIfNecessary(element_size); + for(size_t i=0; i<element_size; ++i) { + buffer[p+i] = src[i]; + } + } + + constexpr_cxx20 void pop(Value_type* dest) noexcept { + const size_t sz = buffer.size(); + assert( sz >= element_size ); + const size_t p = sz - element_size; + for(size_t i=0; i<element_size; ++i) { + dest[i] = buffer[p+i]; + } + buffer.resize(p); + } + }; + + /** + * 4x4 float matrix stack + */ + typedef SimpleStack<float, 16 /* Element_size */> Stack16f; + + + /**@}*/ + +} // namespace jau::math + +#endif // JAU_SSTACK_HPP_ diff --git a/test/test_math_vec.cpp b/test/test_math_vec.cpp index 641cae6..f884932 100644 --- a/test/test_math_vec.cpp +++ b/test/test_math_vec.cpp @@ -186,5 +186,24 @@ TEST_CASE( "Math Vec Angle Test 02", "[vec][linear_algebra][math]" ) { std::cout << "a0(v0, v1) = " << a0_v0_v1 << " rad, " << jau::rad_to_adeg(a0_v0_v1) << " deg, via dot, acos" << std::endl; REQUIRE(true == jau::equals((float)M_PI, a0_v0_v1)); } +} +TEST_CASE( "Math Float16Stack Test 80", "[stack][math]" ) { + Stack16f s1; + Mat4f m1( { 1.0f, 2.0f, 3.0f, 4.0f, // column 0 + 5.0f, 6.0f, 7.0f, 8.0f, // column 1 + 9.0f, 10.0f, 11.0f, 12.0f, // column 2 + 13.0f, 14.0f, 15.0f, 16.0f // column 3 + } ); + Mat4f m2 = m1 * 2.0f; + std::cout << "mat4 m1 " << m1 << std::endl; + std::cout << "mat4 m2 " << m2 << std::endl; + s1.push(m1.cbegin()); + s1.push(m2.cbegin()); + Mat4f m20, m10; + s1.pop(m20.begin()); + s1.pop(m10.begin()); + REQUIRE( m2 == m20 ); + REQUIRE( m1 == m10 ); } + |