16 [[nodiscard]]
auto getIn(T &&item)
18 return std::forward<T>(item);
21 template<
class ImmerT,
class K,
class ...Keys>
22 [[nodiscard]]
auto getIn(ImmerT &&container, K &&key, Keys &&...keys)
24 return getIn(std::forward<ImmerT>(container)[std::forward<K>(key)], std::forward<Keys>(keys)...);
28 [[nodiscard]]
auto setIn(T, T newVal)
33 template<
class ImmerT,
class K>
34 [[nodiscard]]
auto setIn(ImmerT container, std::decay_t<
decltype(
getIn(std::declval<ImmerT>(), std::declval<K>()))> newVal, K &&key) -> std::decay_t<ImmerT>
36 return std::move(container).set(std::forward<K>(key), std::move(newVal));
39 template<
class ImmerT,
class K,
class ...Keys>
40 [[nodiscard]]
auto setIn(ImmerT container, std::decay_t<
decltype(
getIn(std::declval<ImmerT>(), std::declval<K>(), std::declval<Keys>()...))> newVal, K &&key, Keys &&...keys) -> std::decay_t<ImmerT>
42 auto oldItem =
getIn(container, key);
43 return std::move(container).set(
45 setIn(oldItem, std::move(newVal), std::forward<Keys>(keys)...)
49 template<
class T,
class Func>
50 [[nodiscard]]
auto updateIn(T oldVal, Func func) -> T
52 return std::move(func)(oldVal);
55 template<
class ImmerT,
class Func,
class ...Keys>
56 [[nodiscard]]
auto updateIn(ImmerT container, Func func, Keys &&...keys) -> ImmerT
58 auto oldVal =
getIn(container, keys...);
59 auto newVal = std::move(func)(std::move(oldVal));
60 return setIn(std::move(container), std::move(newVal), std::forward<Keys>(keys)...);
72 template<
class ImmerT,
class Func,
class ValueT =
typename ImmerT::value_type>
73 auto withBox(ImmerT &box, Func &&func) -> std::decay_t<std::invoke_result_t<Func &&, ValueT &>>
75 using ResT = std::decay_t<std::invoke_result_t<Func &&, ValueT &>>;
76 if constexpr (std::is_same_v<ResT, void>) {
78 .update([f=std::forward<Func>(func)](ValueT v)
mutable {
79 std::forward<Func>(f)(v);
83 std::optional<ResT> res;
85 .update([f=std::forward<Func>(func), &res](ValueT v)
mutable {
86 res = std::forward<Func>(f)(v);
89 return std::move(res).value();
97 class BoxT =
typename ImmerT::mapped_type,
98 class ValueT =
typename BoxT::value_type
100 auto withMapBox(ImmerT &map, Key &&k, Func &&func) -> std::decay_t<std::invoke_result_t<Func &&, ValueT &>>
102 using ResT = std::decay_t<std::invoke_result_t<Func &&, ValueT &>>;
103 if constexpr (std::is_same_v<ResT, void>) {
105 .update(std::forward<Key>(k), [f=std::forward<Func>(func)](BoxT v)
mutable {
106 withBox(v, std::forward<Func>(f));
110 std::optional<ResT> res;
112 .update(std::forward<Key>(k), [f=std::forward<Func>(func), &res](BoxT v)
mutable {
113 res =
withBox(v, std::forward<Func>(f));
116 return std::move(res).value();
Definition location.hpp:10
auto setIn(T, T newVal)
Definition immer-utils.hpp:28
auto withMapBox(ImmerT &map, Key &&k, Func &&func) -> std::decay_t< std::invoke_result_t< Func &&, ValueT & > >
Definition immer-utils.hpp:100
auto updateIn(T oldVal, Func func) -> T
Definition immer-utils.hpp:50
auto getIn(T &&item)
Definition immer-utils.hpp:16
auto withBox(ImmerT &box, Func &&func) -> std::decay_t< std::invoke_result_t< Func &&, ValueT & > >
Do something with the box, updating its value, then return the return value of the function.
Definition immer-utils.hpp:73