1 #ifndef INTERPOLATE_H_INCLUDED_ 2 #define INTERPOLATE_H_INCLUDED_ 4 #include "containers.h" 8 #include <yaml-cpp/yaml.h> 10 #include "cppcoro/generator.hpp" 12 #include <experimental/coroutine> 17 #include <unordered_map> 27 template <uint64_t V,
typename...>
31 template <uint64_t V,
typename T,
typename... Ts>
33 : std::conditional_t<(V <= sizeof(T)), tag<T>, min_unsigned<V, Ts...>> {};
36 using min_unsigned_t = typename details::min_unsigned<V, uint8_t, uint16_t,
37 uint32_t, uint64_t>::type;
40 template <std::size_t N>
42 static_assert(N > 0, "str_prefix of size zero is disallowed");
47 constexpr
str_prefix(std::string_view s) : str{} {
48 kblib::copy_n(s.begin(), std::min(s.size(), N), &str[0]);
51 constexpr str_prefix reverse()
const {
53 for (std::size_t i = 0; i < N; ++i) {
54 reversed.str[N - i - 1] = str[i];
61 template <std::size_t shift = std::numeric_limits<unsigned char>::digits*(N -
63 constexpr
auto to_uint()
const {
64 using To = details::min_unsigned_t<N + shift / CHAR_BIT>;
65 static_assert(N <=
sizeof(To));
66 if constexpr (N >= 2) {
67 return static_cast<To
>(str[N - 1]) << shift |
72 std::numeric_limits<unsigned char>::digits>());
74 return static_cast<To
>(str[0]) << shift;
79 auto to_uint_fast()
const {
80 using To = details::min_unsigned_t<N>;
81 static_assert(N <=
sizeof(To));
83 if constexpr (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) {
84 std::memcpy(&x, &str[0], N);
87 std::memcpy(&x, &r.str[0], N);
92 constexpr
char& operator[](std::size_t n) {
return str[n]; }
93 constexpr
const char& operator[](std::size_t n)
const {
return str[n]; }
95 constexpr
friend bool operator==(str_prefix lhs, str_prefix rhs) {
96 return kblib::equal(&lhs[0], &lhs[N - 1], &rhs[0]);
98 constexpr
friend bool operator!=(str_prefix lhs, str_prefix rhs) {
101 constexpr
friend bool operator<(str_prefix lesser, str_prefix greater) {
102 return kblib::lexicographical_compare(&lesser[0], &lesser[N - 1],
103 &greater[0], &greater[N - 1]);
105 constexpr
friend bool operator>(str_prefix greater, str_prefix lesser) {
106 return lesser < greater;
108 constexpr
friend bool operator<=(str_prefix lesser, str_prefix greater) {
109 return !(greater < lesser);
111 constexpr
friend bool operator>=(str_prefix greater, str_prefix lesser) {
112 return !(greater < lesser);
120 using channelID = uint64_t;
122 constexpr
inline channelID ch(std::string_view s) {
123 return (static_cast<uint64_t>(
str_prefix<4>(s).to_uint_fast()) << 32u |
124 kblib::FNVa<std::uint32_t>(s));
127 constexpr channelID
operator""_ch(
const char* s, std::size_t len) {
128 return (static_cast<uint64_t>(
str_prefix<4>({s, len}).to_uint()) << 32u |
129 kblib::FNVa<std::uint32_t>(std::string_view{s, len}));
134 std::vector<path_t> children;
137 using word_data_t = vmap<channelID, std::string, 8>;
144 std::string& val() {
return data[
"val"_ch]; }
145 const std::string& val()
const {
return data.at(
"val"_ch); }
148 inline auto word_from_val(std::string v) -> word_data_t {
150 ret.emplace(
"val"_ch, std::move(v));
154 std::string format(
const word_data_t& data, std::string_view fmt,
155 const path_t* path =
nullptr);
157 inline std::string format(
Word word, std::string_view fmt) {
159 word.data.insert_or_assign(
"freq"_ch, kblib::toStr(word.freq));
160 return format(word.data, fmt, &word.path);
163 using string_transformer = std::function<word_data_t(Word, channelID)>;
165 using replace_sequence = std::vector<string_transformer>;
168 using Alternative = vmap<channelID, bytecodes>;
169 std::vector<std::variant<double, bytecodes>> freqs;
170 std::vector<bytecodes> vals;
171 std::vector<Alternative> other_channels;
172 unsigned short declared_argc;
178 vmap<channelID, replace_sequence> actions;
184 using flist_t = std::vector<double>;
185 using ilist_t = std::vector<std::pair<std::size_t, std::optional<double>>>;
189 const std::vector<std::string>& args,
190 const std::variant<std::monostate, flist_t, ilist_t>& freq_override);
192 cppcoro::generator<Word>
194 std::vector<std::string> args,
195 std::variant<std::monostate, flist_t, ilist_t> freq_override,
200 datafile(YAML::Node data, RandomGenerator&);
202 Word transform(
Word,
bool keephist, std::string_view hist_sep)
const;
206 const std::vector<std::string>& args,
207 const std::variant<std::monostate, flist_t, ilist_t>& freq_override,
208 bool keephist, std::string_view sep) {
210 chooseFrom(*
this, rng, c, node, args, std::move(freq_override)),
212 bm.variables.clear();
220 static std::tuple<std::string, int, bool> parse_nodename(std::string_view);
222 static std::unordered_map<channelID, std::string>& ch_db();
224 word_data_t channelNames;
225 vmap<channelID, std::shared_ptr<datafile>> externFiles;
226 small_vector<ReplaceStage, 1> replace;
227 std::optional<std::string> startNode;
229 vmap<std::string, std::vector<node>, 1> nodes;
231 template <
typename Datafile>
232 static auto find_node_impl(Datafile& This, std::string_view name);
233 template <
typename Map>
234 static auto find_node_impl(Map& nodes, std::string_view name,
int argc)
235 -> kblib::copy_const_t<Map, node>* {
236 auto nlist = nodes.find(name);
238 if (nlist == nodes.end()) {
241 for (
auto&& n : nlist->second) {
242 if (n.declared_argc == argc ||
243 (n.variadic && n.declared_argc <= argc)) {
250 node* find_node(std::string_view name);
251 const node* find_node(std::string_view name)
const;
252 node* find_node(std::string_view name,
int argc) {
253 return find_node_impl(nodes, name, argc);
255 const node* find_node(std::string_view name,
int argc)
const {
256 return find_node_impl(nodes, name, argc);
259 datafile* lookup_domain(std::string_view name) {
264 if (
auto check = kblib::get_check(externFiles, ch(name))) {
265 return check->second.get();
275 const datafile* lookup_domain(std::string_view name)
const {
279 if (
auto check = kblib::get_check(externFiles, ch(name))) {
280 return check->second.get();
292 std::optional<const datafile*> source;
294 std::vector<std::string> args;
295 std::variant<std::monostate, flist_t, ilist_t> freq_override;
299 [[nodiscard]] cppcoro::generator<
300 std::variant<std::string, noderef, wordgen_error>>
301 fparse(
const datafile&,
const std::string& s);
304 const std::vector<std::string>& args,
308 std::string pre_text;
309 std::optional<std::string> id;
313 cppcoro::generator<basic_parse_token> basic_parser(std::string_view input);
315 #endif // INTERPOLATE_H_INCLUDED_ Definition: interpolate.h:167
Definition: interpolate.h:41
Definition: interpolate.h:28
Definition: interpolate.h:198
Definition: interpolate.h:20
Definition: interpolate.h:177
Definition: interpolate.h:139
Definition: interpolate.h:307
Definition: interpolate.h:22
Definition: interpolate.h:132
Definition: tstrings.h:175
Definition: tstrings.h:196
Definition: interpolate.h:291