29 #ifndef PIRANHA_SUBSTITUTABLE_SERIES_HPP 30 #define PIRANHA_SUBSTITUTABLE_SERIES_HPP 33 #include <type_traits> 37 #include <piranha/math.hpp> 38 #include <piranha/series.hpp> 39 #include <piranha/symbol_utils.hpp> 49 struct substitutable_series_tag {
75 template <
typename Series,
typename Derived>
80 template <
typename Term,
typename T>
82 = std::integral_constant<unsigned,
86 template <
typename T,
typename Term>
89 template <
typename T,
typename Term>
90 using ret_type_1 = decltype(std::declval<
const cf_subs_type<T, Term> &>() * std::declval<Derived const &>());
91 template <typename T, typename Term, enable_if_t<subs_term_score<Term, T>::value == 1u,
int> = 0>
98 tmp.set_symbol_set(s_set);
99 tmp.insert(Term(
typename Term::cf_type(1), t.m_key));
101 return math::subs(t.m_cf, dict) * std::move(tmp);
104 template <
typename T,
typename Term>
105 using k_subs_type =
typename decltype(std::declval<const typename Term::key_type &>().
subs(
106 std::declval<
const symbol_idx_fmap<T> &>(), std::declval<const symbol_fset &>()))::value_type::first_type;
107 template <
typename T,
typename Term>
108 using ret_type_2_ = decltype(std::declval<Derived const &>() * std::declval<
const k_subs_type<T, Term> &>());
109 template <
typename T,
typename Term>
110 using ret_type_2 = enable_if_t<conjunction<is_addable_in_place<ret_type_2_<T, Term>>,
111 std::is_constructible<ret_type_2_<T, Term>,
const int &>>::value,
112 ret_type_2_<T, Term>>;
113 template <typename T, typename Term, enable_if_t<subs_term_score<Term, T>::value == 2u,
int> = 0>
117 ret_type_2<T, Term> retval(0);
118 auto ksubs = t.m_key.subs(idx, s_set);
119 for (
auto &p : ksubs) {
121 tmp.set_symbol_set(s_set);
122 tmp.insert(Term{t.m_cf, std::move(p.second)});
124 retval += std::move(tmp) * std::move(p.first);
130 template <
typename T,
typename Term>
132 = decltype(std::declval<
const cf_subs_type<T, Term> &>() * std::declval<
const ret_type_2<T, Term> &>());
133 template <typename T, typename Term, enable_if_t<subs_term_score<Term, T>::value == 3u,
int> = 0>
138 ret_type_2<T, Term> acc(0);
139 auto ksubs = t.m_key.subs(idx, s_set);
141 for (
auto &p : ksubs) {
143 tmp.set_symbol_set(s_set);
144 tmp.insert(Term(
typename Term::cf_type(1), std::move(p.second)));
146 acc += std::move(tmp) * std::move(p.first);
148 return std::move(cf_subs) * std::move(acc);
151 template <
typename T>
152 using subs_type_ = decltype(
153 subs_term_impl(std::declval<typename Series::term_type const &>(), std::declval<
const symbol_fmap<T> &>(),
159 template <
typename T>
217 template <
typename T>
221 subs_type<T> retval(0);
222 for (
const auto &t : this->m_container) {
223 retval += subs_term_impl(t, dict, idx, this->m_symbol_set);
233 template <
typename Series,
typename T>
234 using subs_impl_subs_series_enabler = enable_if_t<conjunction<
235 std::is_base_of<substitutable_series_tag, Series>,
236 is_returnable<decltype(std::declval<const Series &>().subs(std::declval<
const symbol_fmap<T> &>()))>>::value>;
247 template <
typename Series,
typename T>
248 struct subs_impl<Series, T, detail::subs_impl_subs_series_enabler<Series, T>> {
substitutable_series()=default
Defaulted default constructor.
boost::container::flat_map< std::string, T > symbol_fmap
Flat map of symbols.
In-place addable type trait.
Type trait to detect the presence of the piranha::math::subs function.
#define PIRANHA_FORWARDING_CTOR(Derived, Base)
Constructor-forwarding macro.
~substitutable_series()
Trivial destructor.
boost::container::flat_set< std::string > symbol_fset
Flat set of symbols.
symbol_idx_fmap< T > sm_intersect_idx(const symbol_fset &s, const symbol_fmap< T > &m)
Find the indices of the intersection of a symbol_fset and a symbol_fmap.
Type trait to detect the presence of the substitution method in keys.
Detect if type can be returned from a function.
Toolbox for substitutable series.
boost::container::flat_map< symbol_idx, T > symbol_idx_fmap
Flat map of symbol indices.
subs_type< T > subs(const symbol_fmap< T > &dict) const
Substitution.
#define PIRANHA_TT_CHECK(tt,...)
Macro for static type trait checks.
Default functor for the implementation of piranha::math::subs().
Type trait to detect series types.
detail::math_subs_type< T, U > subs(const T &x, const symbol_fmap< U > &dict)
Substitution.
#define PIRANHA_FORWARDING_ASSIGNMENT(Derived, Base)
Assignment-forwarding macro.
auto operator()(const Series &s, const symbol_fmap< T > &dict) const -> decltype(s.subs(dict))
Call operator.
substitutable_series & operator=(const substitutable_series &other)=default
Copy assignment operator.