diff --git a/upstream_utils/sleipnir_patches/0001-Remove-using-enum-declarations.patch b/upstream_utils/sleipnir_patches/0001-Remove-using-enum-declarations.patch index 29c083bcca..45ea997600 100644 --- a/upstream_utils/sleipnir_patches/0001-Remove-using-enum-declarations.patch +++ b/upstream_utils/sleipnir_patches/0001-Remove-using-enum-declarations.patch @@ -1,7 +1,7 @@ From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Tyler Veness Date: Wed, 24 Apr 2024 15:56:06 -0700 -Subject: [PATCH] Remove "using enum" declarations +Subject: [PATCH 1/2] Remove "using enum" declarations --- include/sleipnir/autodiff/Expression.hpp | 161 +++++++----------- @@ -9,7 +9,7 @@ Subject: [PATCH] Remove "using enum" declarations 2 files changed, 73 insertions(+), 110 deletions(-) diff --git a/include/sleipnir/autodiff/Expression.hpp b/include/sleipnir/autodiff/Expression.hpp -index ff904cec61315b244e3302ccc8ba68e2a6f6a3a3..460be3791c084cf30c979fe8ca53d27c72ac71ee 100644 +index b60226ccffef9ac161727483ebca3d53df09dec2..fc503c10a209b4779e204e598d3bae45d27916cb 100644 --- a/include/sleipnir/autodiff/Expression.hpp +++ b/include/sleipnir/autodiff/Expression.hpp @@ -192,8 +192,6 @@ struct SLEIPNIR_DLLEXPORT Expression { diff --git a/upstream_utils/sleipnir_patches/0002-Add-implicit-typename.patch b/upstream_utils/sleipnir_patches/0002-Add-implicit-typename.patch new file mode 100644 index 0000000000..534c6c19bd --- /dev/null +++ b/upstream_utils/sleipnir_patches/0002-Add-implicit-typename.patch @@ -0,0 +1,24 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Tyler Veness +Date: Mon, 29 Apr 2024 19:17:18 -0700 +Subject: [PATCH 2/2] Add implicit typename + +--- + include/sleipnir/util/SmallVector.hpp | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/sleipnir/util/SmallVector.hpp b/include/sleipnir/util/SmallVector.hpp +index a4fd51931bb86b2b689805b2c4c5e0125cc560fc..e301b973f1dcd1f662bd9c9f8fd567053e5ee578 100644 +--- a/include/sleipnir/util/SmallVector.hpp ++++ b/include/sleipnir/util/SmallVector.hpp +@@ -152,8 +152,8 @@ class small_vector + }; + + template +-constexpr small_vector::size_type erase_if(small_vector& c, +- Pred pred) { ++constexpr typename small_vector::size_type erase_if(small_vector& c, ++ Pred pred) { + auto it = std::remove_if(c.begin(), c.end(), pred); + auto r = c.end() - it; + c.erase(it, c.end()); diff --git a/upstream_utils/update_sleipnir.py b/upstream_utils/update_sleipnir.py index e9407990c5..3d58250abe 100755 --- a/upstream_utils/update_sleipnir.py +++ b/upstream_utils/update_sleipnir.py @@ -15,8 +15,8 @@ from upstream_utils import ( def main(): upstream_root = clone_repo( "https://github.com/SleipnirGroup/Sleipnir", - # main on 2024-04-25 - "fd2df40330df1f39b04f831f41fbcc22bab07a70", + # main on 2024-04-29 + "9bac50e0f6c1b9ae20e1f611fb7db2cc305ca4fc", shallow=False, ) wpilib_root = get_repo_root() @@ -26,6 +26,7 @@ def main(): os.chdir(upstream_root) for f in [ "0001-Remove-using-enum-declarations.patch", + "0002-Add-implicit-typename.patch", ]: git_am(os.path.join(wpilib_root, "upstream_utils/sleipnir_patches", f)) diff --git a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/Expression.hpp b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/Expression.hpp index 460be3791c..fc503c10a2 100644 --- a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/Expression.hpp +++ b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/Expression.hpp @@ -10,11 +10,11 @@ #include #include #include -#include #include "sleipnir/autodiff/ExpressionType.hpp" #include "sleipnir/util/IntrusiveSharedPtr.hpp" #include "sleipnir/util/Pool.hpp" +#include "sleipnir/util/SmallVector.hpp" #include "sleipnir/util/SymbolExports.hpp" namespace sleipnir::detail { @@ -425,7 +425,7 @@ inline void IntrusiveSharedPtrDecRefCount(Expression* expr) { // Expression destructor when expr's refcount reaches zero can cause a stack // overflow. Instead, we iterate over its children to decrement their // refcounts and deallocate them. - std::vector stack; + small_vector stack; stack.emplace_back(expr); while (!stack.empty()) { diff --git a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/ExpressionGraph.hpp b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/ExpressionGraph.hpp index 337fc378f3..d338cfe3ab 100644 --- a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/ExpressionGraph.hpp +++ b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/ExpressionGraph.hpp @@ -3,10 +3,10 @@ #pragma once #include -#include #include "sleipnir/autodiff/Expression.hpp" #include "sleipnir/util/FunctionRef.hpp" +#include "sleipnir/util/SmallVector.hpp" #include "sleipnir/util/SymbolExports.hpp" namespace sleipnir::detail { @@ -36,7 +36,7 @@ class SLEIPNIR_DLLEXPORT ExpressionGraph { // https://en.wikipedia.org/wiki/Breadth-first_search // BFS list sorted from parent to child. - std::vector stack; + small_vector stack; stack.emplace_back(root.Get()); @@ -119,7 +119,7 @@ class SLEIPNIR_DLLEXPORT ExpressionGraph { * * @param wrt Variables with respect to which to compute the gradient. */ - std::vector GenerateGradientTree( + small_vector GenerateGradientTree( std::span wrt) const { // Read docs/algorithms.md#Reverse_accumulation_automatic_differentiation // for background on reverse accumulation automatic differentiation. @@ -128,7 +128,7 @@ class SLEIPNIR_DLLEXPORT ExpressionGraph { wrt[row]->row = row; } - std::vector grad; + small_vector grad; grad.reserve(wrt.size()); for (size_t row = 0; row < wrt.size(); ++row) { grad.emplace_back(MakeExpressionPtr()); @@ -231,13 +231,13 @@ class SLEIPNIR_DLLEXPORT ExpressionGraph { private: // List that maps nodes to their respective row. - std::vector m_rowList; + small_vector m_rowList; // List for updating adjoints - std::vector m_adjointList; + small_vector m_adjointList; // List for updating values - std::vector m_valueList; + small_vector m_valueList; }; } // namespace sleipnir::detail diff --git a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/Hessian.hpp b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/Hessian.hpp index 8fb671c106..b964737d60 100644 --- a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/Hessian.hpp +++ b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/Hessian.hpp @@ -3,7 +3,6 @@ #pragma once #include -#include #include #include @@ -13,6 +12,7 @@ #include "sleipnir/autodiff/Profiler.hpp" #include "sleipnir/autodiff/Variable.hpp" #include "sleipnir/autodiff/VariableMatrix.hpp" +#include "sleipnir/util/SmallVector.hpp" #include "sleipnir/util/SymbolExports.hpp" namespace sleipnir { @@ -36,7 +36,7 @@ class SLEIPNIR_DLLEXPORT Hessian { Hessian(Variable variable, const VariableMatrix& wrt) noexcept : m_jacobian{ [&] { - std::vector wrtVec; + small_vector wrtVec; wrtVec.reserve(wrt.size()); for (auto& elem : wrt) { wrtVec.emplace_back(elem.expr); diff --git a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/Jacobian.hpp b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/Jacobian.hpp index b415da0dd8..4d85c2f407 100644 --- a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/Jacobian.hpp +++ b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/autodiff/Jacobian.hpp @@ -3,7 +3,6 @@ #pragma once #include -#include #include @@ -11,6 +10,7 @@ #include "sleipnir/autodiff/Profiler.hpp" #include "sleipnir/autodiff/Variable.hpp" #include "sleipnir/autodiff/VariableMatrix.hpp" +#include "sleipnir/util/SmallVector.hpp" #include "sleipnir/util/SymbolExports.hpp" namespace sleipnir { @@ -81,7 +81,7 @@ class SLEIPNIR_DLLEXPORT Jacobian { VariableMatrix Get() const { VariableMatrix result{m_variables.Rows(), m_wrt.Rows()}; - std::vector wrtVec; + small_vector wrtVec; wrtVec.reserve(m_wrt.size()); for (auto& elem : m_wrt) { wrtVec.emplace_back(elem.expr); @@ -145,16 +145,16 @@ class SLEIPNIR_DLLEXPORT Jacobian { VariableMatrix m_variables; VariableMatrix m_wrt; - std::vector m_graphs; + small_vector m_graphs; Eigen::SparseMatrix m_J{m_variables.Rows(), m_wrt.Rows()}; // Cached triplets for gradients of linear rows - std::vector> m_cachedTriplets; + small_vector> m_cachedTriplets; // List of row indices for nonlinear rows whose graients will be computed in // Value() - std::vector m_nonlinearRows; + small_vector m_nonlinearRows; Profiler m_profiler; }; diff --git a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/optimization/Constraints.hpp b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/optimization/Constraints.hpp index 820430bd3b..61ed70b483 100644 --- a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/optimization/Constraints.hpp +++ b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/optimization/Constraints.hpp @@ -4,11 +4,11 @@ #include #include -#include #include "sleipnir/autodiff/Variable.hpp" #include "sleipnir/util/Assert.hpp" #include "sleipnir/util/Concepts.hpp" +#include "sleipnir/util/SmallVector.hpp" #include "sleipnir/util/SymbolExports.hpp" namespace sleipnir { @@ -28,8 +28,8 @@ template requires(ScalarLike || MatrixLike) && (ScalarLike || MatrixLike) && (!std::same_as || !std::same_as) -std::vector MakeConstraints(const LHS& lhs, const RHS& rhs) { - std::vector constraints; +small_vector MakeConstraints(const LHS& lhs, const RHS& rhs) { + small_vector constraints; if constexpr (ScalarLike && ScalarLike) { constraints.emplace_back(lhs - rhs); @@ -113,7 +113,7 @@ std::vector MakeConstraints(const LHS& lhs, const RHS& rhs) { */ struct SLEIPNIR_DLLEXPORT EqualityConstraints { /// A vector of scalar equality constraints. - std::vector constraints; + small_vector constraints; /** * Constructs an equality constraint from a left and right side. @@ -146,7 +146,7 @@ struct SLEIPNIR_DLLEXPORT EqualityConstraints { */ struct SLEIPNIR_DLLEXPORT InequalityConstraints { /// A vector of scalar inequality constraints. - std::vector constraints; + small_vector constraints; /** * Constructs an inequality constraint from a left and right side. diff --git a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/optimization/Multistart.hpp b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/optimization/Multistart.hpp index e25ad1ea74..a873062fc9 100644 --- a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/optimization/Multistart.hpp +++ b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/optimization/Multistart.hpp @@ -5,10 +5,10 @@ #include #include #include -#include #include "sleipnir/optimization/SolverStatus.hpp" #include "sleipnir/util/FunctionRef.hpp" +#include "sleipnir/util/SmallVector.hpp" namespace sleipnir { @@ -43,12 +43,16 @@ MultistartResult Multistart( function_ref(const DecisionVariables&)> solve, std::span initialGuesses) { - std::vector>> futures; + small_vector>> futures; + futures.reserve(initialGuesses.size()); + for (const auto& initialGuess : initialGuesses) { futures.emplace_back(std::async(std::launch::async, solve, initialGuess)); } - std::vector> results; + small_vector> results; + results.reserve(futures.size()); + for (auto& future : futures) { results.emplace_back(future.get()); } diff --git a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/optimization/OptimizationProblem.hpp b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/optimization/OptimizationProblem.hpp index 224618720d..237266ac6d 100644 --- a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/optimization/OptimizationProblem.hpp +++ b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/optimization/OptimizationProblem.hpp @@ -10,7 +10,6 @@ #include #include #include -#include #include @@ -23,6 +22,7 @@ #include "sleipnir/optimization/SolverStatus.hpp" #include "sleipnir/optimization/solver/InteriorPoint.hpp" #include "sleipnir/util/Print.hpp" +#include "sleipnir/util/SmallVector.hpp" #include "sleipnir/util/SymbolExports.hpp" namespace sleipnir { @@ -531,16 +531,16 @@ class SLEIPNIR_DLLEXPORT OptimizationProblem { private: // The list of decision variables, which are the root of the problem's // expression tree - std::vector m_decisionVariables; + small_vector m_decisionVariables; // The cost function: f(x) std::optional m_f; // The list of equality constraints: cₑ(x) = 0 - std::vector m_equalityConstraints; + small_vector m_equalityConstraints; // The list of inequality constraints: cᵢ(x) ≥ 0 - std::vector m_inequalityConstraints; + small_vector m_inequalityConstraints; // The user callback std::function m_callback = diff --git a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/util/Pool.hpp b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/util/Pool.hpp index 23b80d03c0..87d093cec9 100644 --- a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/util/Pool.hpp +++ b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/util/Pool.hpp @@ -4,8 +4,8 @@ #include #include -#include +#include "sleipnir/util/SmallVector.hpp" #include "sleipnir/util/SymbolExports.hpp" namespace sleipnir { @@ -76,8 +76,8 @@ class SLEIPNIR_DLLEXPORT PoolResource { } private: - std::vector> m_buffer; - std::vector m_freeList; + small_vector> m_buffer; + small_vector m_freeList; size_t blocksPerChunk; /** diff --git a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/util/SmallVector.hpp b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/util/SmallVector.hpp new file mode 100644 index 0000000000..dcf02c02b7 --- /dev/null +++ b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/util/SmallVector.hpp @@ -0,0 +1,163 @@ +// Copyright (c) Sleipnir contributors + +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace sleipnir { + +template +struct small_buffer_vector_allocator { + alignas(alignof(T)) std::byte m_smallBuffer[MaxSize * sizeof(T)]; + std::allocator m_alloc; + bool m_smallBufferUsed = false; + + using value_type = T; + // we have to set this three values, as they are responsible for the correct + // handling of the move assignment operator + using propagate_on_container_move_assignment = std::false_type; + using propagate_on_container_swap = std::false_type; + using is_always_equal = std::false_type; + + constexpr small_buffer_vector_allocator() noexcept = default; + + template + constexpr small_buffer_vector_allocator( // NOLINT + const small_buffer_vector_allocator&) noexcept {} + + template + struct rebind { + using other = small_buffer_vector_allocator; + }; + + // don't copy the small buffer for the copy/move constructors, as the copying + // is done through the vector + constexpr small_buffer_vector_allocator( + const small_buffer_vector_allocator& other) noexcept + : m_smallBufferUsed(other.m_smallBufferUsed) {} + + constexpr small_buffer_vector_allocator& operator=( + const small_buffer_vector_allocator& other) noexcept { + if (this == &other) { + return *this; + } + + m_smallBufferUsed = other.m_smallBufferUsed; + return *this; + } + + constexpr small_buffer_vector_allocator( + small_buffer_vector_allocator&&) noexcept {} + + constexpr small_buffer_vector_allocator& operator=( + const small_buffer_vector_allocator&&) noexcept { + return *this; + } + + [[nodiscard]] + constexpr T* allocate(const size_t n) { + // when the allocator was rebound we don't want to use the small buffer + if constexpr (std::is_same_v) { + if (n <= MaxSize) { + m_smallBufferUsed = true; + // as long as we use less memory than the small buffer, we return a + // pointer to it + return reinterpret_cast(&m_smallBuffer); + } + } + m_smallBufferUsed = false; + // otherwise use the default allocator + return m_alloc.allocate(n); + } + + constexpr void deallocate(void* p, const size_t n) { + // we don't deallocate anything if the memory was allocated in small buffer + if (&m_smallBuffer != p) { + m_alloc.deallocate(static_cast(p), n); + } + m_smallBufferUsed = false; + } + + // according to the C++ standard when propagate_on_container_move_assignment + // is set to false, the comparision operators are used to check if two + // allocators are equal. When they are not, an element wise move is done + // instead of just taking over the memory. For our implementation this means + // the comparision has to return false, when the small buffer is active + friend constexpr bool operator==(const small_buffer_vector_allocator& lhs, + const small_buffer_vector_allocator& rhs) { + return !lhs.m_smallBufferUsed && !rhs.m_smallBufferUsed; + } + + friend constexpr bool operator!=(const small_buffer_vector_allocator& lhs, + const small_buffer_vector_allocator& rhs) { + return !(lhs == rhs); + } +}; + +template +class small_vector + : public std::vector> { + public: + using vectorT = std::vector>; + + // default initialize with the small buffer size + constexpr small_vector() noexcept { vectorT::reserve(N); } + + small_vector(const small_vector&) = default; + small_vector& operator=(const small_vector&) = default; + + small_vector(small_vector&& other) noexcept( + std::is_nothrow_move_constructible_v) { + if (other.size() <= N) { + vectorT::reserve(N); + } + vectorT::operator=(std::move(other)); + } + + small_vector& operator=(small_vector&& other) noexcept( + std::is_nothrow_move_constructible_v) { + if (other.size() <= N) { + vectorT::reserve(N); + } + vectorT::operator=(std::move(other)); + return *this; + } + + // use the default constructor first to reserve then construct the values + explicit small_vector(size_t count) : small_vector() { + vectorT::resize(count); + } + + small_vector(size_t count, const T& value) : small_vector() { + vectorT::assign(count, value); + } + + template + small_vector(InputIt first, InputIt last) : small_vector() { + vectorT::insert(vectorT::begin(), first, last); + } + + small_vector(std::initializer_list init) : small_vector() { // NOLINT + vectorT::insert(vectorT::begin(), init); + } + + friend void swap(small_vector& a, small_vector& b) noexcept { + std::swap(static_cast(a), static_cast(b)); + } +}; + +template +constexpr typename small_vector::size_type erase_if(small_vector& c, + Pred pred) { + auto it = std::remove_if(c.begin(), c.end(), pred); + auto r = c.end() - it; + c.erase(it, c.end()); + return r; +} + +} // namespace sleipnir diff --git a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/util/Spy.hpp b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/util/Spy.hpp index d7276db65a..67b0b0736c 100644 --- a/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/util/Spy.hpp +++ b/wpimath/src/main/native/thirdparty/sleipnir/include/sleipnir/util/Spy.hpp @@ -5,10 +5,10 @@ #include #include #include -#include #include +#include "sleipnir/util/SmallVector.hpp" #include "sleipnir/util/SymbolExports.hpp" namespace sleipnir { @@ -32,7 +32,7 @@ SLEIPNIR_DLLEXPORT inline void Spy(std::ostream& file, const int cells_width = mat.cols() + 1; const int cells_height = mat.rows(); - std::vector cells; + small_vector cells; // Allocate space for matrix of characters plus trailing newlines cells.reserve(cells_width * cells_height); diff --git a/wpimath/src/main/native/thirdparty/sleipnir/src/optimization/solver/util/FeasibilityRestoration.hpp b/wpimath/src/main/native/thirdparty/sleipnir/src/optimization/solver/util/FeasibilityRestoration.hpp index 15f0088112..776bf8a2a9 100644 --- a/wpimath/src/main/native/thirdparty/sleipnir/src/optimization/solver/util/FeasibilityRestoration.hpp +++ b/wpimath/src/main/native/thirdparty/sleipnir/src/optimization/solver/util/FeasibilityRestoration.hpp @@ -6,7 +6,6 @@ #include #include #include -#include #include @@ -17,6 +16,7 @@ #include "sleipnir/optimization/SolverStatus.hpp" #include "sleipnir/optimization/solver/InteriorPoint.hpp" #include "sleipnir/util/FunctionRef.hpp" +#include "sleipnir/util/SmallVector.hpp" namespace sleipnir { @@ -66,7 +66,7 @@ inline void FeasibilityRestoration( constexpr double ρ = 1000.0; - std::vector fr_decisionVariables; + small_vector fr_decisionVariables; fr_decisionVariables.reserve(decisionVariables.size() + 2 * equalityConstraints.size() + 2 * inequalityConstraints.size()); @@ -158,7 +158,7 @@ inline void FeasibilityRestoration( } // cₑ(x) - pₑ + nₑ = 0 - std::vector fr_equalityConstraints; + small_vector fr_equalityConstraints; fr_equalityConstraints.assign(equalityConstraints.begin(), equalityConstraints.end()); for (size_t row = 0; row < fr_equalityConstraints.size(); ++row) { @@ -167,7 +167,7 @@ inline void FeasibilityRestoration( } // cᵢ(x) - s - pᵢ + nᵢ = 0 - std::vector fr_inequalityConstraints; + small_vector fr_inequalityConstraints; fr_inequalityConstraints.assign(inequalityConstraints.begin(), inequalityConstraints.end()); for (size_t row = 0; row < fr_inequalityConstraints.size(); ++row) { diff --git a/wpimath/src/main/native/thirdparty/sleipnir/src/optimization/solver/util/Filter.hpp b/wpimath/src/main/native/thirdparty/sleipnir/src/optimization/solver/util/Filter.hpp index 01d43dbee6..ee5c7c3f57 100644 --- a/wpimath/src/main/native/thirdparty/sleipnir/src/optimization/solver/util/Filter.hpp +++ b/wpimath/src/main/native/thirdparty/sleipnir/src/optimization/solver/util/Filter.hpp @@ -6,11 +6,11 @@ #include #include #include -#include #include #include "sleipnir/autodiff/Variable.hpp" +#include "sleipnir/util/SmallVector.hpp" namespace sleipnir { @@ -108,7 +108,7 @@ class Filter { */ void Add(const FilterEntry& entry) { // Remove dominated entries - std::erase_if(m_filter, [&](const auto& elem) { + erase_if(m_filter, [&](const auto& elem) { return entry.cost <= elem.cost && entry.constraintViolation <= elem.constraintViolation; }); @@ -123,7 +123,7 @@ class Filter { */ void Add(FilterEntry&& entry) { // Remove dominated entries - std::erase_if(m_filter, [&](const auto& elem) { + erase_if(m_filter, [&](const auto& elem) { return entry.cost <= elem.cost && entry.constraintViolation <= elem.constraintViolation; }); @@ -182,7 +182,7 @@ class Filter { private: Variable* m_f = nullptr; double m_μ = 0.0; - std::vector m_filter; + small_vector m_filter; }; } // namespace sleipnir