3#include <clingo/util/algorithm.hh>
4#include <clingo/util/immutable_array.hh>
10namespace CppClingo::Util {
14template <
class T,
class F>
using transform_result = std::optional<std::remove_cv_t<std::invoke_result_t<F, T>>>;
16template <
class T,
class F>
17using and_then_result = std::remove_cv_t<std::remove_reference_t<std::invoke_result_t<F, T>>>;
19template <
class T,
class F>
20using transform_vec_result = std::optional<std::vector<typename transform_result<T, F>::value_type>>;
28template <
class T,
class F>
constexpr auto transform(std::optional<T> &x, F &&f) -> Detail::transform_result<T &, F> {
30 return std::invoke(std::forward<F>(f), *x);
36template <
class T,
class F>
37constexpr auto transform(std::optional<T>
const &x, F &&f) -> Detail::transform_result<T const &, F> {
39 return std::invoke(std::forward<F>(f), *x);
46template <
class T,
class F>
constexpr auto transform(std::optional<T> &&x, F &&f) -> Detail::transform_result<T, F> {
48 return std::invoke(std::forward<F>(f), *std::move(x));
54template <
class T,
class F>
55constexpr auto transform(std::optional<T>
const &&x, F &&f) -> Detail::transform_result<T const, F> {
57 return std::invoke(std::forward<F>(f), *std::move(x));
63template <
class T,
class F>
constexpr auto and_then(std::optional<T> &x, F &&f) -> Detail::and_then_result<T &, F> {
65 return std::invoke(std::forward<F>(f), *x);
67 return std::remove_cv_t<std::remove_reference_t<std::invoke_result_t<F, T &>>>{};
71template <
class T,
class F>
72constexpr auto and_then(std::optional<T>
const &x, F &&f) -> Detail::and_then_result<T const &, F> {
74 return std::invoke(std::forward<F>(f), *x);
76 return std::remove_cv_t<std::remove_reference_t<std::invoke_result_t<F, T const &>>>{};
80template <
class T,
class F>
constexpr auto and_then(std::optional<T> &&x, F &&f) -> Detail::and_then_result<T, F> {
82 return std::invoke(std::forward<F>(f), *std::move(x));
84 return std::remove_cv_t<std::remove_reference_t<std::invoke_result_t<F, T>>>{};
88template <
class T,
class F>
89constexpr auto and_then(std::optional<T>
const &&x, F &&f) -> Detail::and_then_result<T const, F> {
91 return std::invoke(std::forward<F>(f), *std::move(x));
93 return std::remove_cv_t<std::remove_reference_t<std::invoke_result_t<F, T const>>>{};
97template <
class T,
class F>
99 -> Detail::transform_vec_result<T const &, F const &> {
100 return transform(vec, [&f](
auto const &vec) {
101 typename Detail::transform_vec_result<T const &, F const &>::value_type ret;
102 ret.reserve(vec.size());
103 for (
auto const &elem : vec) {
104 ret.emplace_back(std::invoke(f, elem));
111template <
class T,
class F>
113auto transform_vec(std::optional<std::vector<T>> &&vec, F
const &f) -> Detail::transform_vec_result<T, F const &> {
115 typename Detail::transform_vec_result<T, F const &>::value_type ret;
116 ret.reserve(vec.size());
117 for (
auto &elem : vec) {
118 ret.emplace_back(std::invoke(f, std::move(elem)));
142 std::optional<E>
value = std::nullopt;
149template <
class T,
bool UseSpan = true>
class ResultVec {
154 using Span = std::span<ValueType const>;
160 using Source = std::conditional_t<UseSpan, Span, Array const &>;
162 using Iterator = std::conditional_t<UseSpan, typename Span::iterator, typename Array::const_iterator>;
164 using Result = std::conditional_t<UseSpan, Vector, Array>;
175 result_->emplace_back(*current_);
182 result_->insert(result_->end(), current_, source_.end());
184 current_ = source_.end();
189 result_ =
Util::copy_n(source_, std::distance(source_.begin(), current_));
194 template <
class... Args>
void replace(Args &&...args) {
196 result_ =
Util::copy_n(source_, std::distance(source_.begin(), current_));
198 result_->emplace_back(std::forward<Args>(args)...);
203 if (!
value.has_value()) {
210 template <
class... Args>
void append(Args &&...args) {
212 result_ =
Util::copy_n(source_, std::distance(source_.begin(), current_));
214 result_->emplace_back(std::forward<Args>(args)...);
217 template <
class It>
void extend(It begin, It end) {
219 result_ =
Util::copy_n(source_, std::distance(source_.begin(), current_));
221 result_->insert(result_->end(), begin, end);
235 return *std::move(result_);
237 if constexpr (UseSpan) {
238 return {source_.begin(), source_.end()};
244 [[nodiscard]]
auto has_value() const ->
bool {
return result_.has_value(); }
246 [[nodiscard]]
auto as_optional() & -> std::optional<Vector> & {
return result_; }
248 [[nodiscard]]
auto as_optional() && -> std::optional<Vector> {
return std::move(result_); }
259 [[nodiscard]]
auto complete()
const {
return current_ == source_.end(); }
263 std::optional<Vector> result_;
Helper to update a vector of elements.
Definition optional.hh:149
void keep()
Keep the current element.
Definition optional.hh:173
void remove()
Remove the current element.
Definition optional.hh:187
std::conditional_t< UseSpan, typename Span::iterator, typename Array::const_iterator > Iterator
A constant iterator to the source values.
Definition optional.hh:162
std::conditional_t< UseSpan, Vector, Array > Result
The result values.
Definition optional.hh:164
auto current() const -> ValueType const &
Get current element.
Definition optional.hh:170
auto complete() const
Check if all elements have been processed.
Definition optional.hh:259
void keep_all()
Keep all elements.
Definition optional.hh:180
std::span< ValueType const > Span
A span of values.
Definition optional.hh:154
auto value() &&-> Result
Move out the new vector or return a copy of the old one.
Definition optional.hh:233
auto value() const &-> Span
Get a const reference to the current vector.
Definition optional.hh:226
T ValueType
The value type.
Definition optional.hh:152
std::conditional_t< UseSpan, Span, Array const & > Source
The (reference to the) source values.
Definition optional.hh:160
void append(Args &&...args)
Append fresh elements.
Definition optional.hh:210
auto operator*() const &-> Span
Get a const reference to the current vector.
Definition optional.hh:253
auto has_value() const -> bool
Check if the old vector has been updated.
Definition optional.hh:244
ResultVec(Source source)
Construct a result vec to track changes to the given source.
Definition optional.hh:167
void update(std::optional< ValueType > value)
Update the current alement given the optional value.
Definition optional.hh:202
auto as_optional() &-> std::optional< Vector > &
Return a reference to the updated vector if there was a change.
Definition optional.hh:246
auto as_optional() &&-> std::optional< Vector >
Move out the updated vector.
Definition optional.hh:248
std::vector< ValueType > Vector
A vector of values.
Definition optional.hh:158
void extend(It begin, It end)
Append fresh elements.
Definition optional.hh:217
void replace(Args &&...args)
Replace the current element.
Definition optional.hh:194
auto operator*() &&-> Result
Move out the new vector or return a copy of the old one.
Definition optional.hh:255
An immutable array with efficient copying.
Definition immutable_array.hh:18
auto copy_n(Rng const &rng, size_t n) -> std::vector< typename Rng::value_type >
Return a vector with the first n elements from the given one.
Definition algorithm.hh:14
constexpr auto and_then(std::optional< T > &x, F &&f) -> Detail::and_then_result< T &, F >
Implemenatation of std::optional<T>::and_then.
Definition optional.hh:63
auto transform_vec(std::optional< std::vector< T > > const &vec, F const &f) -> Detail::transform_vec_result< T const &, F const & >
Map the given predicate over an optional vector.
Definition optional.hh:98
constexpr auto transform(std::optional< T > &x, F &&f) -> Detail::transform_result< T &, F >
Implemenatation of std::optional<T>::transform.
Definition optional.hh:28
The result of a simplification.
Definition optional.hh:128
ResultState(S state=S{}, std::optional< E > value=std::nullopt)
Construct from state and value.
Definition optional.hh:130
std::optional< E > value
An optional rewritten expression.
Definition optional.hh:142
ResultState(ResultState< F, S > const &res)
Construct from compatible result state.
Definition optional.hh:133
S state
A truth value or state.
Definition optional.hh:140
ResultState(ResultState< F, S > &&res)
Construct from compatible result state.
Definition optional.hh:137