diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/bit_field.h | 19 | ||||
| -rw-r--r-- | src/common/string_util.cpp | 57 | ||||
| -rw-r--r-- | src/common/string_util.h | 33 |
3 files changed, 12 insertions, 97 deletions
diff --git a/src/common/bit_field.h b/src/common/bit_field.h index bf803da8d..21e07925d 100644 --- a/src/common/bit_field.h +++ b/src/common/bit_field.h | |||
| @@ -117,21 +117,21 @@ private: | |||
| 117 | // We don't delete it because we want BitField to be trivially copyable. | 117 | // We don't delete it because we want BitField to be trivially copyable. |
| 118 | constexpr BitField& operator=(const BitField&) = default; | 118 | constexpr BitField& operator=(const BitField&) = default; |
| 119 | 119 | ||
| 120 | // StorageType is T for non-enum types and the underlying type of T if | 120 | // UnderlyingType is T for non-enum types and the underlying type of T if |
| 121 | // T is an enumeration. Note that T is wrapped within an enable_if in the | 121 | // T is an enumeration. Note that T is wrapped within an enable_if in the |
| 122 | // former case to workaround compile errors which arise when using | 122 | // former case to workaround compile errors which arise when using |
| 123 | // std::underlying_type<T>::type directly. | 123 | // std::underlying_type<T>::type directly. |
| 124 | using StorageType = typename std::conditional_t<std::is_enum<T>::value, std::underlying_type<T>, | 124 | using UnderlyingType = typename std::conditional_t<std::is_enum_v<T>, std::underlying_type<T>, |
| 125 | std::enable_if<true, T>>::type; | 125 | std::enable_if<true, T>>::type; |
| 126 | 126 | ||
| 127 | // Unsigned version of StorageType | 127 | // We store the value as the unsigned type to avoid undefined behaviour on value shifting |
| 128 | using StorageTypeU = std::make_unsigned_t<StorageType>; | 128 | using StorageType = std::make_unsigned_t<UnderlyingType>; |
| 129 | 129 | ||
| 130 | public: | 130 | public: |
| 131 | /// Constants to allow limited introspection of fields if needed | 131 | /// Constants to allow limited introspection of fields if needed |
| 132 | static constexpr std::size_t position = Position; | 132 | static constexpr std::size_t position = Position; |
| 133 | static constexpr std::size_t bits = Bits; | 133 | static constexpr std::size_t bits = Bits; |
| 134 | static constexpr StorageType mask = (((StorageTypeU)~0) >> (8 * sizeof(T) - bits)) << position; | 134 | static constexpr StorageType mask = (((StorageType)~0) >> (8 * sizeof(T) - bits)) << position; |
| 135 | 135 | ||
| 136 | /** | 136 | /** |
| 137 | * Formats a value by masking and shifting it according to the field parameters. A value | 137 | * Formats a value by masking and shifting it according to the field parameters. A value |
| @@ -148,11 +148,12 @@ public: | |||
| 148 | * union in a constexpr context. | 148 | * union in a constexpr context. |
| 149 | */ | 149 | */ |
| 150 | static constexpr FORCE_INLINE T ExtractValue(const StorageType& storage) { | 150 | static constexpr FORCE_INLINE T ExtractValue(const StorageType& storage) { |
| 151 | if (std::numeric_limits<T>::is_signed) { | 151 | if constexpr (std::numeric_limits<UnderlyingType>::is_signed) { |
| 152 | std::size_t shift = 8 * sizeof(T) - bits; | 152 | std::size_t shift = 8 * sizeof(T) - bits; |
| 153 | return (T)((storage << (shift - position)) >> shift); | 153 | return static_cast<T>(static_cast<UnderlyingType>(storage << (shift - position)) >> |
| 154 | shift); | ||
| 154 | } else { | 155 | } else { |
| 155 | return (T)((storage & mask) >> position); | 156 | return static_cast<T>((storage & mask) >> position); |
| 156 | } | 157 | } |
| 157 | } | 158 | } |
| 158 | 159 | ||
diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index 731d1db34..14f7037d8 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp | |||
| @@ -4,11 +4,10 @@ | |||
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <cctype> | 6 | #include <cctype> |
| 7 | #include <cerrno> | ||
| 8 | #include <codecvt> | 7 | #include <codecvt> |
| 9 | #include <cstdio> | ||
| 10 | #include <cstdlib> | 8 | #include <cstdlib> |
| 11 | #include <cstring> | 9 | #include <locale> |
| 10 | #include <sstream> | ||
| 12 | #include "common/common_paths.h" | 11 | #include "common/common_paths.h" |
| 13 | #include "common/logging/log.h" | 12 | #include "common/logging/log.h" |
| 14 | #include "common/string_util.h" | 13 | #include "common/string_util.h" |
| @@ -33,24 +32,6 @@ std::string ToUpper(std::string str) { | |||
| 33 | return str; | 32 | return str; |
| 34 | } | 33 | } |
| 35 | 34 | ||
| 36 | // For Debugging. Read out an u8 array. | ||
| 37 | std::string ArrayToString(const u8* data, std::size_t size, int line_len, bool spaces) { | ||
| 38 | std::ostringstream oss; | ||
| 39 | oss << std::setfill('0') << std::hex; | ||
| 40 | |||
| 41 | for (int line = 0; size; ++data, --size) { | ||
| 42 | oss << std::setw(2) << (int)*data; | ||
| 43 | |||
| 44 | if (line_len == ++line) { | ||
| 45 | oss << '\n'; | ||
| 46 | line = 0; | ||
| 47 | } else if (spaces) | ||
| 48 | oss << ' '; | ||
| 49 | } | ||
| 50 | |||
| 51 | return oss.str(); | ||
| 52 | } | ||
| 53 | |||
| 54 | std::string StringFromBuffer(const std::vector<u8>& data) { | 35 | std::string StringFromBuffer(const std::vector<u8>& data) { |
| 55 | return std::string(data.begin(), std::find(data.begin(), data.end(), '\0')); | 36 | return std::string(data.begin(), std::find(data.begin(), data.end(), '\0')); |
| 56 | } | 37 | } |
| @@ -75,40 +56,6 @@ std::string StripQuotes(const std::string& s) { | |||
| 75 | return s; | 56 | return s; |
| 76 | } | 57 | } |
| 77 | 58 | ||
| 78 | bool TryParse(const std::string& str, u32* const output) { | ||
| 79 | char* endptr = nullptr; | ||
| 80 | |||
| 81 | // Reset errno to a value other than ERANGE | ||
| 82 | errno = 0; | ||
| 83 | |||
| 84 | unsigned long value = strtoul(str.c_str(), &endptr, 0); | ||
| 85 | |||
| 86 | if (!endptr || *endptr) | ||
| 87 | return false; | ||
| 88 | |||
| 89 | if (errno == ERANGE) | ||
| 90 | return false; | ||
| 91 | |||
| 92 | #if ULONG_MAX > UINT_MAX | ||
| 93 | if (value >= 0x100000000ull && value <= 0xFFFFFFFF00000000ull) | ||
| 94 | return false; | ||
| 95 | #endif | ||
| 96 | |||
| 97 | *output = static_cast<u32>(value); | ||
| 98 | return true; | ||
| 99 | } | ||
| 100 | |||
| 101 | bool TryParse(const std::string& str, bool* const output) { | ||
| 102 | if ("1" == str || "true" == ToLower(str)) | ||
| 103 | *output = true; | ||
| 104 | else if ("0" == str || "false" == ToLower(str)) | ||
| 105 | *output = false; | ||
| 106 | else | ||
| 107 | return false; | ||
| 108 | |||
| 109 | return true; | ||
| 110 | } | ||
| 111 | |||
| 112 | std::string StringFromBool(bool value) { | 59 | std::string StringFromBool(bool value) { |
| 113 | return value ? "True" : "False"; | 60 | return value ? "True" : "False"; |
| 114 | } | 61 | } |
diff --git a/src/common/string_util.h b/src/common/string_util.h index 32bf6a19c..08f96533b 100644 --- a/src/common/string_util.h +++ b/src/common/string_util.h | |||
| @@ -5,8 +5,6 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <cstddef> | 7 | #include <cstddef> |
| 8 | #include <iomanip> | ||
| 9 | #include <sstream> | ||
| 10 | #include <string> | 8 | #include <string> |
| 11 | #include <vector> | 9 | #include <vector> |
| 12 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| @@ -19,44 +17,13 @@ std::string ToLower(std::string str); | |||
| 19 | /// Make a string uppercase | 17 | /// Make a string uppercase |
| 20 | std::string ToUpper(std::string str); | 18 | std::string ToUpper(std::string str); |
| 21 | 19 | ||
| 22 | std::string ArrayToString(const u8* data, std::size_t size, int line_len = 20, bool spaces = true); | ||
| 23 | |||
| 24 | std::string StringFromBuffer(const std::vector<u8>& data); | 20 | std::string StringFromBuffer(const std::vector<u8>& data); |
| 25 | 21 | ||
| 26 | std::string StripSpaces(const std::string& s); | 22 | std::string StripSpaces(const std::string& s); |
| 27 | std::string StripQuotes(const std::string& s); | 23 | std::string StripQuotes(const std::string& s); |
| 28 | 24 | ||
| 29 | // Thousand separator. Turns 12345678 into 12,345,678 | ||
| 30 | template <typename I> | ||
| 31 | std::string ThousandSeparate(I value, int spaces = 0) { | ||
| 32 | std::ostringstream oss; | ||
| 33 | |||
| 34 | // std::locale("") seems to be broken on many platforms | ||
| 35 | #if defined _WIN32 || (defined __linux__ && !defined __clang__) | ||
| 36 | oss.imbue(std::locale("")); | ||
| 37 | #endif | ||
| 38 | oss << std::setw(spaces) << value; | ||
| 39 | |||
| 40 | return oss.str(); | ||
| 41 | } | ||
| 42 | |||
| 43 | std::string StringFromBool(bool value); | 25 | std::string StringFromBool(bool value); |
| 44 | 26 | ||
| 45 | bool TryParse(const std::string& str, bool* output); | ||
| 46 | bool TryParse(const std::string& str, u32* output); | ||
| 47 | |||
| 48 | template <typename N> | ||
| 49 | static bool TryParse(const std::string& str, N* const output) { | ||
| 50 | std::istringstream iss(str); | ||
| 51 | |||
| 52 | N tmp = 0; | ||
| 53 | if (iss >> tmp) { | ||
| 54 | *output = tmp; | ||
| 55 | return true; | ||
| 56 | } else | ||
| 57 | return false; | ||
| 58 | } | ||
| 59 | |||
| 60 | std::string TabsToSpaces(int tab_size, std::string in); | 27 | std::string TabsToSpaces(int tab_size, std::string in); |
| 61 | 28 | ||
| 62 | void SplitString(const std::string& str, char delim, std::vector<std::string>& output); | 29 | void SplitString(const std::string& str, char delim, std::vector<std::string>& output); |