1#ifndef _BBM_STRING_CONVERT_H_
2#define _BBM_STRING_CONVERT_H_
68 if( std::string(std::decay_t<T>::name) != key )
throw std::invalid_argument(std::string(
"BBM: mismatched object name ") + key +
", expected: " + std::string(std::decay_t<T>::name));
71 if constexpr (bbm::detail::has_constructor_args_t<T>)
73 auto args = bbm::fromString<typename std::decay_t<T>::constructor_args_t>(
value);
93 return linear_search_named(str, bbm::reflection::enum_v<T>, []<
size_t IDX,
typename ENUM>(
const std::string&
value, ENUM&& enum_v) -> T
95 if constexpr (IDX == std::decay_t<ENUM>::size)
96 throw std::invalid_argument(std::string(
"BBM: name '") +
value +
"' not found in enumeration: " + std::string(
typestring<std::decay_t<T>>));
97 else return std::get<IDX>(enum_v);
128 if(obj == std::get<IDX>(bbm::reflection::enum_v<T>))
129 result += std::string( bbm::reflection::enum_v<T>.
template name<IDX> );
144 static inline float fromString(
const std::string& str) {
return std::stof(str); }
145 static inline std::string
toString(
float v) { std::stringstream ss; ss << v;
return ss.str(); }
150 static inline double fromString(
const std::string& str) {
return std::stod(str); }
151 static inline std::string
toString(
double v) { std::stringstream ss; ss << v;
return ss.str(); }
156 static inline long double fromString(
const std::string& str) {
return std::stold(str); }
157 static inline std::string
toString(
long double v) { std::stringstream ss; ss << v;
return ss.str(); }
162 static inline int fromString(
const std::string& str) {
return std::stoi(str); }
163 static inline std::string
toString(
int v) {
return std::to_string(v); }
168 static inline long fromString(
const std::string& str) {
return std::stol(str); }
169 static inline std::string
toString(
long v) {
return std::to_string(v); }
174 static inline long long fromString(
const std::string& str) {
return std::stoll(str); }
175 static inline std::string
toString(
long long v) {
return std::to_string(v); }
180 static inline unsigned int fromString(
const std::string& str) {
return std::stoul(str); }
181 static inline std::string
toString(
unsigned int v) {
return std::to_string(v); }
186 static inline unsigned long fromString(
const std::string& str) {
return std::stoul(str); }
187 static inline std::string
toString(
unsigned long v) {
return std::to_string(v); }
192 static inline unsigned long long fromString(
const std::string& str) {
return std::stoull(str); }
193 static inline std::string
toString(
unsigned long long v) {
return std::to_string(v); }
206 std::string newStr(str);
207 std::transform(str.begin(), str.end(), newStr.begin(), [](
unsigned char c) { return std::tolower(c); });
210 bool True = (newStr ==
"true") || (newStr ==
"1");
211 bool False = (newStr ==
"false") || (newStr ==
"0");
214 if(!True && !False)
throw std::invalid_argument(std::string(
"BBM: cannot convert to bool from: ") + str);
222 if(b)
return std::string(
"True");
223 else return std::string(
"False");
236 const char* quotes =
"\"' \r\n\t\v";
237 size_t s = str.find_first_not_of(quotes);
238 size_t e = str.find_last_not_of(quotes);
241 if(s > e)
throw std::invalid_argument(std::string(
"BBM: connect convert to string; unbalanced quotes in: ") + str);
244 return str.substr(s, e-s+1);
247 static inline std::string
toString(
const std::string& str)
249 return std::string(
"\"") + str + std::string(
"\"");
261 return std::string(str);
269 struct string_converter<T>
274 if(str.size() != 3 || str[0] !=
'\'' || str[2] !=
'\'')
throw std::invalid_argument(std::string(
"BBM: cannot convert to " + std::string(typestring<T>) +
" from: " + str));
282 return std::string(
"'") + c + std::string(
"'");
295 std::vector<T> result;
302 for(
auto& a :
args) result.push_back( bbm::fromString<T>(a) );
304 throw std::invalid_argument(std::string(
"BBM: cannot convert to vector<") + std::string(typestring<T>) +
"> from: " + str);
313 std::string result(
"(");
314 for(
auto itr=vec.begin(); itr != vec.end(); ++itr)
316 if(itr != vec.begin()) result +=
", ";
332 template<
typename T,
size_t N>
335 static inline std::array<T,N>
fromString(
const std::string& str)
337 std::array<T, N> arr;
342 vec = bbm::fromString<bbm::vector<T>>(str);
347 vec.push_back( bbm::fromString<T>(str) );
351 throw std::invalid_argument(std::string(
"BBM: cannot convert to std::array<") + std::string(typestring<T>) +
", " + std::to_string(N) +
"> from: " + str);
355 if(vec.size() == N) std::copy(vec.begin(), vec.end(), arr.begin());
356 else if(vec.size() == 1) std::fill(arr.begin(), arr.end(), vec[0]);
357 else throw std::invalid_argument(std::string(
"BBM: too few arguments to convert to std::array<") + std::string(typestring<T>) +
", " + std::to_string(N) +
">. Found " + std::to_string(vec.size()) +
" argument in: " + str);
363 static inline std::string
toString(
const std::array<T,N>& arr)
365 std::string result(
"[");
366 for(
auto itr=arr.begin(); itr != arr.end(); ++itr)
368 if(itr != arr.begin()) result +=
", ";
379 template<
typename... Ts>
382 static inline std::tuple<Ts...>
fromString(
const std::string& str)
387 if(
args.
size() !=
sizeof...(Ts))
throw std::invalid_argument(
"BBM: too few arguments to convert to " + std::string(
typestring<std::tuple<Ts...>>) +
", expected " + std::to_string(
sizeof...(Ts)) +
" but found " + std::to_string(
args.
size()) +
" in: " + str);
390 auto args_to_tup = [&]<
size_t... IDX>(std::index_sequence<IDX...>)
392 return std::make_tuple(
bbm::fromString<std::tuple_element_t<IDX, std::tuple<Ts...>>>(
args[IDX])... );
397 return args_to_tup(std::make_index_sequence<
sizeof...(Ts)>{});
399 throw std::invalid_argument(
"BBM: cannot convert to " + std::string(
typestring<std::tuple<Ts...>>) +
" from: " + str);
405 static inline std::string
toString(
const std::tuple<Ts...>& tup)
407 std::string result(
"(");
410 if constexpr (idx != 0) result +=
", ";
421 template<
typename TUP, string_literal... NAMES>
425 static constexpr size_t size =
sizeof...(NAMES);
432 if(
args.
size() !=
size)
throw std::invalid_argument(
"BBM: too few arguments to convert to " + std::string(typestring<type>) +
", expected " + std::to_string(
size) +
" but found " + std::to_string(
args.
size()) +
" in: " + str);
435 std::array<std::string, size> names;
436 CONSTFOR(idx,
size, { names[idx] = type::template name<idx>; });
439 std::array<std::pair<std::string, std::string>,
size> keyval;
440 for(
size_t idx=0; idx !=
size; ++idx)
444 auto get_permutation = [&](
size_t idx)
446 auto key = keyval[idx].first;
449 if(key.empty())
return idx;
452 auto match = std::find(std::begin(names), std::end(names), key);
455 if(match == std::end(names))
throw std::invalid_argument(
"BBM: cannot convert to " + std::string(typestring<type>) +
": invalid name: " + key +
" in " + str);
457 return size_t(std::distance(std::begin(names), match));
461 std::array<size_t, size> perm;
462 std::array<bool, size> used; std::fill(std::begin(used), std::end(used),
false);
464 for(
size_t idx=0; idx <
size; ++idx)
466 size_t match = get_permutation(idx);
472 for(
size_t idx=0; idx <
size; ++idx)
473 if(!used[idx])
throw std::invalid_argument(
"BBM: cannot convert to " + std::string(typestring<type>) +
": " + std::to_string(idx) +
" element (" + names[idx] +
") not assigned.");
476 auto create_named = [&]<
size_t... IDX>(std::index_sequence<IDX...>)
478 return make_named<NAMES...>( bbm::fromString<std::tuple_element_t<IDX, type>>(keyval[perm[IDX]].second)... );
482 return create_named( std::make_index_sequence<size>{} );
487 std::string result(
"(");
490 if constexpr (idx != 0) result +=
", ";
492 result += std::string(std::decay_t<
decltype(obj)>::template name<idx>);
504 template<
typename ARGS>
requires is_args_v<ARGS>
517 if(
args.
size() > ARGS::size)
throw std::invalid_argument(std::string(
"BBM: expected at most ") + std::to_string(ARGS::size) +
" arguments, found " + std::to_string(
args.
size()) +
" in: " + str);
520 std::set<std::string> arg_names;
523 arg_names.insert( std::string(ARGS::template name<idx>) );
527 std::map<std::string, size_t> name_map;
528 std::vector<bool> named_arg;
529 std::vector<std::string> values;
531 for(
size_t idx=0; idx !=
args.
size(); ++idx)
538 named_arg.push_back(
true);
539 if(arg_names.contains(key)) name_map[key] = idx;
540 else throw std::invalid_argument(std::string(
"BBM: invalid argument name: ") + key +
"(" +
value +
") in: " + str);
542 else named_arg.push_back(
false);
545 values.push_back(
value);
549 auto retrieve_arg = [&]<
size_t IDX>(void)
551 using arg_t = std::decay_t<typename ARGS::template type<IDX>>;
552 using type = std::decay_t<typename arg_t::type>;
555 auto name_itr = name_map.find(std::string(arg_t::name));
556 if(name_itr != name_map.end())
return arg_t( bbm::fromString<type>(values[name_itr->second]) );
559 if(IDX < values.size() && !named_arg[IDX])
return arg_t( bbm::fromString<type>(values[IDX]) );
562 if constexpr (std::is_constructible_v<arg_t>)
return arg_t();
565 else throw std::invalid_argument(std::string(
"BBM: unable to find argument ") + std::string(arg_t::name) +
" in: " + str);
569 auto create_args = [&]<
size_t... IDX>(std::index_sequence<IDX...>)
571 return ARGS( retrieve_arg.template
operator()<IDX>()... );
575 return create_args(std::make_index_sequence<ARGS::size>{});
583 template<
typename T>
requires concepts::from_stringconvert<T>
593 template<
typename T>
requires concepts::to_stringconvert<T>
Provides a more flexible argument passing to function and methods.
Definition: vector_util.h:27
Concept to check if type has a fromString member.
Definition: stringconvert.h:57
Concept to check if type has a toString member.
Definition: stringconvert.h:48
A named class is a class that contains a static constexpr string_literal name.
Definition: named.h:19
attribute reflection allows to enumerate and direct access to the attributes of a class....
Definition: reflection.h:34
concept to check if a enum supports reflection
Definition: reflection.h:65
true if type is the same as any of the listed types
Definition: util.h:31
Concept wrapper around a type trait: check if T meets the type TRAIT<T,ARGS...>
Definition: util.h:19
#define CONSTFOR(IDX, NUMITR,...)
HELPER MACRO.
Definition: constfor.h:63
Predefined exceptions for common errors.
concept to check if a type has a valid string_converter.
constexpr decltype(auto) attributes(T &&t)
Definition: reflection.h:200
std::pair< std::string, std::string > split_eq(const std::string &str)
split a string of the form "key = val" in key and value. If no '=', then return an empty key.
Definition: string_util.h:77
std::pair< std::string, std::string > get_keyword(const std::string &str)
Return the keyword substring appearing an open bracket, and the arguments appearing in the brackets: ...
Definition: string_util.h:65
std::string remove_brackets(const std::string &str)
remove surrounding backets
Definition: string_util.h:37
std::vector< std::string > split_args(const std::string &str)
Split a string based on comma's if not surrounded by brackets.
Definition: string_util.h:94
Definition: aggregatebsdf.h:29
constexpr named< anonymize_t< T >, NAMES... > make_named(T &&t)
Make a named of a gettable type (with size == #NAMES); renames if the type is a named container.
Definition: named.h:293
static constexpr std::string_view typestring
Definition: typestring.h:51
detail::is_args_impl< std::decay_t< T > > is_args
Definition: args.h:221
auto linear_search_named(const std::string &str, NAMED &&named, PROCESS &&process, Ts &&... context)
linear search for unsorted named tuples
Definition: named_util.h:380
T fromString(const std::string &)
fromString alias
Definition: stringconvert.h:584
size_t size(T &&t)
Definition: iterator_util.h:22
decltype(value_copy_named(std::declval< T >())) value_copy_named_t
type of value copying a named typle
Definition: named_util.h:27
std::string toString(const T &)
toString alias
Definition: stringconvert.h:594
decltype(auto) value(T &&t)
return the value of an attribute, or if not an attribute the object
Definition: attribute_value.h:20
Helper method for processing strings.
Forward declaration.
Definition: args.h:248
static constexpr size_t size
Definition: args.h:282
constexpr auto values(void) const
Returns a tuple of all arguments' values.
Definition: args.h:291
named container
Definition: named.h:131
static std::string toString(const ARGS &args)
Definition: stringconvert.h:507
static ARGS fromString(const std::string &str)
Definition: stringconvert.h:512
static std::string toString(const T &c)
Definition: stringconvert.h:280
static T fromString(const std::string &str)
Definition: stringconvert.h:271
static std::string toString(const bbm::vector< T > &vec)
Definition: stringconvert.h:311
static bbm::vector< T > fromString(const std::string &str)
Definition: stringconvert.h:293
static std::string toString(bool b)
Definition: stringconvert.h:220
static bool fromString(const std::string &str)
Definition: stringconvert.h:203
static double fromString(const std::string &str)
Definition: stringconvert.h:150
static std::string toString(double v)
Definition: stringconvert.h:151
static std::string toString(float v)
Definition: stringconvert.h:145
static float fromString(const std::string &str)
Definition: stringconvert.h:144
static std::string toString(int v)
Definition: stringconvert.h:163
static int fromString(const std::string &str)
Definition: stringconvert.h:162
static long fromString(const std::string &str)
Definition: stringconvert.h:168
static std::string toString(long v)
Definition: stringconvert.h:169
static std::string toString(long double v)
Definition: stringconvert.h:157
static long double fromString(const std::string &str)
Definition: stringconvert.h:156
static long long fromString(const std::string &str)
Definition: stringconvert.h:174
static std::string toString(long long v)
Definition: stringconvert.h:175
static std::string toString(const named< TUP, NAMES... > &obj)
Definition: stringconvert.h:485
static type fromString(const std::string &str)
Definition: stringconvert.h:427
static std::string toString(const std::array< T, N > &arr)
Definition: stringconvert.h:363
static std::array< T, N > fromString(const std::string &str)
Definition: stringconvert.h:335
static std::string fromString(const std::string &str)
Definition: stringconvert.h:233
static std::string toString(const std::string &str)
Definition: stringconvert.h:247
static std::string toString(const std::tuple< Ts... > &tup)
Definition: stringconvert.h:405
static std::tuple< Ts... > fromString(const std::string &str)
Definition: stringconvert.h:382
static std::string toString(const string_literal< N > &str)
Definition: stringconvert.h:259
static std::string toString(unsigned int v)
Definition: stringconvert.h:181
static unsigned int fromString(const std::string &str)
Definition: stringconvert.h:180
static std::string toString(unsigned long v)
Definition: stringconvert.h:187
static unsigned long fromString(const std::string &str)
Definition: stringconvert.h:186
static std::string toString(unsigned long long v)
Definition: stringconvert.h:193
static unsigned long long fromString(const std::string &str)
Definition: stringconvert.h:192
forward decalaration
Definition: stringconvert.h:47
static T fromString(const std::string &str)
convert a string to a type T
Definition: stringconvert.h:61
static std::string toString(const T &obj)
convert an object to a type T
Definition: stringconvert.h:112
Definition: string_literal.h:16
Extensions for the STL tuple class.
produce stringview of type name of a type. Avoids using typeid for GCC, MSVC, and CLANG....
Compile-time reflection of:
Extensions for the STL vector class.