#pragma once #include #include #include #include #include #include #include namespace Aftr { //Common helpful string functions. Convert floats, doubles, ints to strings and vice versa. And //do it *fast*. Also parse or split strings. /// converts an integer to a string, i.e. 1 -> "1", 346 -> "346" ... std::string toString( std::int16_t x ); std::string toString( std::int32_t x ); std::string toString( std::int64_t x ); std::string toString( std::uint16_t x ); std::string toString( std::uint32_t x ); std::string toString( std::uint64_t x ); std::string toString( float x ); std::string toString( double x ); std::string toString( long double x ); // Converts a string_view into a the corresponding numeric value. If the string // does not contain a valid numeric value, the returned optional is std::nullopt; // otherwise the optional will contain the requested type with the corresponding // value. std::optional toByte( std::string_view v ) noexcept; std::optional toUByte( std::string_view v ) noexcept; std::optional toShort( std::string_view v ) noexcept; std::optional toUShort( std::string_view v ) noexcept; std::optional toInt( std::string_view v ) noexcept; std::optional toUInt( std::string_view v ) noexcept; std::optional toInt64( std::string_view v ) noexcept; std::optional toUInt64( std::string_view v ) noexcept; std::optional toFloat( std::string_view v ) noexcept; std::optional toDouble( std::string_view v ) noexcept; std::optional toLongDouble( std::string_view v ) noexcept; std::optional toUnsignedInt( std::string_view v ) noexcept; // "" -> false // "0" -> false; // "false ", " FALSE ", " fAlSe", etc (case insensitive, ignore whitespace) -> false // " false true " -> false because false was found first. // everything else returns true std::optional toBool( std::string_view v ) noexcept; ///< Returns false if x is "0" or "false" (case insenstive); true, otherwise /// Hashing functions that are common across all AftrBurner uses (std::hash varies between compilers). /// These hash functions are based on the FNV1a hash algorithm (it is in boost) /// http://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-1 /// https://www.boost.org/doc/libs/1_81_0/libs/unordered/examples/fnv1.hpp /// /// However, Nykl implemented them again here to make them CONSTEXPR (compile time) so strings can /// be hashed to integers at compile time. This is useful for things like NetMsgs that /// can be registered earlier. As of C++23 ish, this is easier to consteval a const char* than a string consteval unsigned int hash_str_fnv1a_consteval_32_bit( std::string_view str ) { // For 32 bit machines: const std::uint64_t fnv_prime = 16777619u; const std::uint64_t fnv_offset_basis = 2166136261u; // For 64 bit machines: // const std::size_t fnv_prime = 1099511628211u; // const std::size_t fnv_offset_basis = 14695981039346656037u; // For 128 bit machines: // const std::size_t fnv_prime = 309485009821345068724781401u; // const std::size_t fnv_offset_basis = // 275519064689413815358837431229664493455u; // For 256 bit machines: // const std::size_t fnv_prime = // 374144419156711147060143317175368453031918731002211u; // const std::size_t fnv_offset_basis = // 100029257958052580907070968620625704837092796014241193945225284501741471925557u; std::uint64_t hash = fnv_offset_basis; for( auto c : str ) { hash ^= c; hash *= fnv_prime; } uint32_t h = static_cast(hash); //convert the 64 bit operations back to 32 bit, truncating anything in the upper 32-bits return h; } /// This constexpr function will return the name of the class, as a string_view, which invoked this. /// function. constexpr std::string toString_ClassType( std::source_location const& loc ) { using namespace std::string_view_literals; auto func_name = std::string_view{ loc.function_name() }; auto groups = std::views::split( func_name, "::"sv ); //Output will be something like ClassName::getClassName() auto const numGroups = std::ranges::distance( groups ); if( numGroups < 2 ) return std::string{ std::string_view{ *groups.begin() } }; // class_name::mem_fn auto subrange = func_name | std::views::split( "::"sv ) | std::views::drop( numGroups - 2 ) | std::views::take( 1 ) //| std::ranges::to() ; //auto s = subrange; //if std::ranges::to() worked, we could just return subrange, C++26, maybe? auto name_len = std::ranges::distance( subrange.front() ); std::string s( name_len, '\0' ); std::ranges::copy( subrange.front(), s.begin() ); //fmt::print( "ERROR: {:s}: Must call from a class, see WO.h/.cpp WO::getClassName(...) for example...\n", AFTR_FILE_LINE_STR ); return s; } } //namespace Aftr