tinyopt 700
Tinyopt, a lightweight, header only optimization library
Loading...
Searching...
No Matches
params_pack.h
1// Copyright 2026 Julien Michot.
2// SPDX-License-Identifier: Apache-2.0
3
4#pragma once
5
6#include <tuple>
7#include <type_traits>
8#include <utility>
9
10#include <tinyopt/params_pack.h>
11#include <tinyopt/traits/parameter_traits.h>
12
13namespace tinyopt::traits {
14
15namespace detail {
16
17template <typename... Ts>
18struct PackDims;
19
20template <typename T>
21struct PackDims<T> : std::integral_constant<Index, params_trait<std::remove_cvref_t<T>>::Dims> {};
22
23template <typename T, typename U, typename... Ts>
24struct PackDims<T, U, Ts...> {
25 private:
26 static constexpr Index First = params_trait<std::remove_cvref_t<T>>::Dims;
27 static constexpr Index Rest = PackDims<U, Ts...>::value;
28
29 public:
30 static constexpr Index value = First == Dynamic || Rest == Dynamic ? Dynamic : First + Rest;
31};
32
33template <typename T, typename = void>
34struct IsJetScalar : std::false_type {};
35
36template <typename T>
37struct IsJetScalar<T, std::void_t<decltype(std::declval<T>().a), decltype(std::declval<T>().v)>>
38 : std::true_type {};
39
40template <typename T, typename Delta>
41void ApplyPackDelta(T &param, Index &offset, const Delta &delta) {
43 if constexpr (std::is_scalar_v<std::remove_cvref_t<T>> ||
45 Param::PlusEq(param, delta[offset]);
46 ++offset;
47 } else if constexpr (Param::Dims == Dynamic) {
48 const Index dims = Param::dims(param);
49 Param::PlusEq(param, delta.segment(offset, dims));
50 offset += dims;
51 } else {
52 Param::PlusEq(param, delta.template segment<Param::Dims>(offset));
53 offset += Param::Dims;
54 }
55}
56
57} // namespace detail
58
59template <typename... Ts>
61 using Scalar = std::common_type_t<typename params_trait<std::remove_cvref_t<Ts>>::Scalar...>;
62 static constexpr Index Dims = detail::PackDims<Ts...>::value;
63
64 static Index dims(const ::tinyopt::ParamsPack<Ts...> &pack) {
65 return std::apply(
66 [](const auto &...params) {
67 return (params_trait<std::remove_cvref_t<decltype(params)>>::dims(params) + ...);
68 },
69 pack.values);
70 }
71
72 template <typename T2>
73 static auto cast(const ::tinyopt::ParamsPack<Ts...> &pack) {
74 return std::apply(
75 [](const auto &...params) {
76 return ::tinyopt::ParamsPack<std::decay_t<decltype(
77 params_trait<std::remove_cvref_t<decltype(params)>>::template cast<T2>(params))>...>(
78 params_trait<std::remove_cvref_t<decltype(params)>>::template cast<T2>(params)...);
79 },
80 pack.values);
81 }
82
83 static void PlusEq(::tinyopt::ParamsPack<Ts...> &pack, const auto &delta) {
84 Index offset = 0;
85 std::apply([&](auto &...params) { (detail::ApplyPackDelta(params, offset, delta), ...); },
86 pack.values);
87 }
88};
89
90} // namespace tinyopt::traits
Definition params_pack.h:12
Definition params_pack.h:34
Definition params_pack.h:18
Definition parameter_traits.h:15