Commit 26043940 authored by Dominik Charousset's avatar Dominik Charousset

Reduce indirections and stack usage

Reduce stack usage by (1) making sure temporary `error` objects go
out-of-scope before recursing deeper into inspector arguments and (2)
calling `apply `directly whenever possible instead of dispatching over
`apply_derived` (removed entirely) and `operator()`.
parent 398a1f67
...@@ -242,7 +242,7 @@ public: ...@@ -242,7 +242,7 @@ public:
for (auto& x : xs) { for (auto& x : xs) {
using value_type = typename std::remove_reference<decltype(x)>::type; using value_type = typename std::remove_reference<decltype(x)>::type;
using mutable_type = typename std::remove_const<value_type>::type; using mutable_type = typename std::remove_const<value_type>::type;
if (auto err = apply_derived(const_cast<mutable_type&>(x))) if (auto err = dref().apply(const_cast<mutable_type&>(x)))
return err; return err;
} }
return none; return none;
...@@ -252,7 +252,7 @@ public: ...@@ -252,7 +252,7 @@ public:
template <class U, class T> template <class U, class T>
error consume_range_c(T& xs) { error consume_range_c(T& xs) {
for (U x : xs) { for (U x : xs) {
if (auto err = apply_derived(x)) if (auto err = dref().apply(x))
return err; return err;
} }
return none; return none;
...@@ -264,7 +264,7 @@ public: ...@@ -264,7 +264,7 @@ public:
auto insert_iter = std::inserter(xs, xs.end()); auto insert_iter = std::inserter(xs, xs.end());
for (size_t i = 0; i < num_elements; ++i) { for (size_t i = 0; i < num_elements; ++i) {
typename std::remove_const<typename T::value_type>::type x; typename std::remove_const<typename T::value_type>::type x;
if (auto err = apply_derived(x)) if (auto err = dref().apply(x))
return err; return err;
*insert_iter++ = std::move(x); *insert_iter++ = std::move(x);
} }
...@@ -278,7 +278,7 @@ public: ...@@ -278,7 +278,7 @@ public:
auto insert_iter = std::inserter(xs, xs.end()); auto insert_iter = std::inserter(xs, xs.end());
for (size_t i = 0; i < num_elements; ++i) { for (size_t i = 0; i < num_elements; ++i) {
U x; U x;
if (auto err = apply_derived(x)) if (auto err = dref().apply(x))
return err; return err;
*insert_iter++ = std::move(x); *insert_iter++ = std::move(x);
} }
...@@ -375,8 +375,9 @@ public: ...@@ -375,8 +375,9 @@ public:
using t0 = typename std::remove_const<F>::type; using t0 = typename std::remove_const<F>::type;
// This cast allows the data processor to cope with // This cast allows the data processor to cope with
// `pair<const K, V>` value types used by `std::map`. // `pair<const K, V>` value types used by `std::map`.
return error::eval([&] { return apply_derived(const_cast<t0&>(xs.first)); }, if (auto err = dref().apply(const_cast<t0&>(xs.first)))
[&] { return apply_derived(xs.second); }); return err;
return dref().apply(xs.second);
} }
template <class... Ts> template <class... Ts>
...@@ -470,29 +471,31 @@ public: ...@@ -470,29 +471,31 @@ public:
// -- operator() ------------------------------------------------------------- // -- operator() -------------------------------------------------------------
inline error operator()() { error operator()() {
return none; return none;
} }
template <class F, class... Ts> template <class F, class... Ts>
error operator()(meta::save_callback_t<F> x, Ts&&... xs) { error operator()(meta::save_callback_t<F> x, Ts&&... xs) {
error e; // TODO: use `if constexpr` when switching to C++17.
if (Derived::reads_state) if (Derived::reads_state)
e = x.fun(); if (auto err = x.fun())
return e ? e : (*this)(std::forward<Ts>(xs)...); return err;
return dref()(std::forward<Ts>(xs)...);
} }
template <class F, class... Ts> template <class F, class... Ts>
error operator()(meta::load_callback_t<F> x, Ts&&... xs) { error operator()(meta::load_callback_t<F> x, Ts&&... xs) {
error e; // TODO: use `if constexpr` when switching to C++17.
if (Derived::writes_state) if (Derived::writes_state)
e = x.fun(); if (auto err = x.fun())
return e ? e : (*this)(std::forward<Ts>(xs)...); return err;
return dref()(std::forward<Ts>(xs)...);
} }
template <class... Ts> template <class... Ts>
error operator()(const meta::annotation&, Ts&&... xs) { error operator()(const meta::annotation&, Ts&&... xs) {
return (*this)(std::forward<Ts>(xs)...); return dref()(std::forward<Ts>(xs)...);
} }
template <class T, class... Ts> template <class T, class... Ts>
...@@ -501,7 +504,7 @@ public: ...@@ -501,7 +504,7 @@ public:
error error
>::type >::type
operator()(const T&, Ts&&... xs) { operator()(const T&, Ts&&... xs) {
return (*this)(std::forward<Ts>(xs)...); return dref()(std::forward<Ts>(xs)...);
} }
template <class T, class... Ts> template <class T, class... Ts>
...@@ -519,7 +522,7 @@ public: ...@@ -519,7 +522,7 @@ public:
"a loading inspector requires mutable lvalue references"); "a loading inspector requires mutable lvalue references");
if (auto err = apply(deconst(x))) if (auto err = apply(deconst(x)))
return err; return err;
return apply_derived(std::forward<Ts>(xs)...); return dref()(std::forward<Ts>(xs)...);
} }
protected: protected:
...@@ -578,12 +581,6 @@ private: ...@@ -578,12 +581,6 @@ private:
return *static_cast<Derived*>(this); return *static_cast<Derived*>(this);
} }
// Applies `xs...` to `dref()`.
template <class... Ts>
error apply_derived(Ts&&... xs) {
return dref()(std::forward<Ts>(xs)...);
}
execution_unit* context_; execution_unit* context_;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment