62 if(algo_spec.empty()) {
63 throw Invalid_Argument(
"Expected algorithm name, got empty string");
69 if(algo_spec.find_first_of(
"(),/") == std::string_view::npos) {
70 m_alg_name = std::string(algo_spec);
74 std::vector<std::pair<size_t, std::string>> name;
76 std::pair<size_t, std::string> accum = std::make_pair(level,
"");
78 bool expect_token =
true;
80 for(
const char c : algo_spec) {
81 if(c ==
'/' || c ==
',' || c ==
'(' || c ==
')') {
86 throw Invalid_Algorithm_Name(m_orig_algo_spec);
91 if(c ==
'/' && level > 0) {
92 accum.second.push_back(c);
96 throw Invalid_Algorithm_Name(m_orig_algo_spec);
98 if(!accum.second.empty()) {
99 name.push_back(accum);
101 accum = std::make_pair(level,
"");
102 expect_token = (c !=
')');
105 accum.second.push_back(c);
106 expect_token = false;
110 if(!accum.second.empty()) {
111 name.push_back(accum);
115 throw Invalid_Algorithm_Name(m_orig_algo_spec);
120 throw Invalid_Algorithm_Name(m_orig_algo_spec);
124 throw Invalid_Algorithm_Name(m_orig_algo_spec);
127 m_alg_name = name[0].second;
129 bool in_modes =
false;
131 for(
size_t i = 1; i != name.size(); ++i) {
132 if(name[i].first == 0) {
133 m_mode_info.push_back(make_arg(name, i));
135 }
else if(name[i].first == 1 && !in_modes) {
136 m_args.push_back(make_arg(name, i));