29 #ifndef PIRANHA_DETAIL_KM_COMMONS_HPP 30 #define PIRANHA_DETAIL_KM_COMMONS_HPP 38 #include <piranha/config.hpp> 40 #include <piranha/symbol_utils.hpp> 50 template <
typename VType,
typename KaType,
typename T>
51 inline VType km_unpack(
const symbol_fset &args,
const T &value)
53 if (unlikely(args.size() > VType::max_size)) {
54 piranha_throw(std::invalid_argument,
"the size of the input arguments set (" + std::to_string(args.size())
55 +
") is larger than the maximum allowed size (" 56 + std::to_string(VType::max_size) +
")");
58 VType retval(static_cast<typename VType::size_type>(args.size()), 0);
59 piranha_assert(args.size() == retval.size());
60 KaType::decode(retval, value);
64 template <
typename VType,
typename KaType,
typename T>
65 inline T km_merge_symbols(
const symbol_idx_fmap<symbol_fset> &ins_map,
const symbol_fset &args,
const T &value)
67 if (unlikely(!ins_map.size())) {
71 "invalid argument(s) for symbol set merging: the insertion map cannot be empty");
73 if (unlikely(ins_map.rbegin()->first > args.size())) {
77 "invalid argument(s) for symbol set merging: the last index of the insertion map (" 78 + std::to_string(ins_map.rbegin()->first) +
") must not be greater than the key's size (" 79 + std::to_string(args.size()) +
")");
81 const auto old_vector = km_unpack<VType, KaType>(args, value);
83 auto map_it = ins_map.begin();
84 const auto map_end = ins_map.end();
85 for (decltype(old_vector.size()) i = 0; i < old_vector.size(); ++i) {
86 if (map_it != map_end && map_it->first == i) {
89 std::fill_n(std::back_inserter(new_vector), map_it->second.size(), T(0));
92 new_vector.push_back(old_vector[i]);
95 if (map_it != map_end) {
96 std::fill_n(std::back_inserter(new_vector), map_it->second.size(), T(0));
97 piranha_assert(map_it + 1 == map_end);
100 return KaType::encode(new_vector);
103 template <
typename VType,
typename KaType,
typename T>
104 inline void km_trim_identify(std::vector<char> &candidates,
const symbol_fset &args,
const T &value)
106 if (unlikely(candidates.size() != args.size())) {
107 piranha_throw(std::invalid_argument,
"invalid mask for trim_identify(): the size of the mask (" 108 + std::to_string(candidates.size())
109 +
") differs from the size of the reference symbol set (" 110 + std::to_string(args.size()) +
")");
112 const VType tmp = km_unpack<VType, KaType>(args, value);
113 for (decltype(tmp.size()) i = 0; i < tmp.size(); ++i) {
114 if (tmp[i] != T(0)) {
115 candidates[
static_cast<decltype(candidates.size())
>(i)] = 0;
120 template <
typename VType,
typename KaType,
typename T>
121 inline T km_trim(
const std::vector<char> &trim_idx,
const symbol_fset &args,
const T &value)
123 if (unlikely(trim_idx.size() != args.size())) {
124 piranha_throw(std::invalid_argument,
"invalid mask for trim(): the size of the mask (" 125 + std::to_string(trim_idx.size())
126 +
") differs from the size of the reference symbol set (" 127 + std::to_string(args.size()) +
")");
129 const VType tmp = km_unpack<VType, KaType>(args, value);
131 for (decltype(tmp.size()) i = 0; i < tmp.size(); ++i) {
132 if (!trim_idx[
static_cast<decltype(trim_idx.size())
>(i)]) {
133 new_vector.push_back(tmp[i]);
136 return KaType::encode(new_vector);
#define piranha_throw(exception_type,...)
Exception-throwing macro.
boost::container::flat_set< std::string > symbol_fset
Flat set of symbols.