Merge pull request #729 from jpcima/misc-opcode-things
Move the value reading helpers out of Opcode
This commit is contained in:
commit
b24d09e7d2
2 changed files with 102 additions and 32 deletions
|
|
@ -147,21 +147,20 @@ absl::optional<T> readInt_(OpcodeSpec<T> spec, absl::string_view v)
|
||||||
{
|
{
|
||||||
using Limits = std::numeric_limits<T>;
|
using Limits = std::numeric_limits<T>;
|
||||||
|
|
||||||
size_t numberEnd = 0;
|
|
||||||
|
|
||||||
if (numberEnd < v.size() && (v[numberEnd] == '+' || v[numberEnd] == '-'))
|
|
||||||
++numberEnd;
|
|
||||||
|
|
||||||
while (numberEnd < v.size() && absl::ascii_isdigit(v[numberEnd]))
|
|
||||||
++numberEnd;
|
|
||||||
|
|
||||||
if (numberEnd == 0 && (spec.flags & kCanBeNote))
|
|
||||||
return readNoteValue(v);
|
|
||||||
|
|
||||||
v = v.substr(0, numberEnd);
|
|
||||||
|
|
||||||
int64_t returnedValue;
|
int64_t returnedValue;
|
||||||
if (!absl::SimpleAtoi(v, &returnedValue))
|
bool readValueSuccess = false;
|
||||||
|
|
||||||
|
if (readLeadingInt(v, &returnedValue))
|
||||||
|
readValueSuccess = true;
|
||||||
|
|
||||||
|
if (!readValueSuccess && (spec.flags & kCanBeNote)) {
|
||||||
|
if (absl::optional<uint8_t> noteValue = readNoteValue(v)) {
|
||||||
|
returnedValue = *noteValue;
|
||||||
|
readValueSuccess = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!readValueSuccess)
|
||||||
return absl::nullopt;
|
return absl::nullopt;
|
||||||
|
|
||||||
if (returnedValue > static_cast<int64_t>(spec.bounds.getEnd())) {
|
if (returnedValue > static_cast<int64_t>(spec.bounds.getEnd())) {
|
||||||
|
|
@ -201,23 +200,8 @@ INSTANTIATE_FOR_INTEGRAL(int64_t)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
absl::optional<T> readFloat_(OpcodeSpec<T> spec, absl::string_view v)
|
absl::optional<T> readFloat_(OpcodeSpec<T> spec, absl::string_view v)
|
||||||
{
|
{
|
||||||
size_t numberEnd = 0;
|
T returnedValue;
|
||||||
|
if (!readLeadingFloat(v, &returnedValue))
|
||||||
if (numberEnd < v.size() && (v[numberEnd] == '+' || v[numberEnd] == '-'))
|
|
||||||
++numberEnd;
|
|
||||||
while (numberEnd < v.size() && absl::ascii_isdigit(v[numberEnd]))
|
|
||||||
++numberEnd;
|
|
||||||
|
|
||||||
if (numberEnd < v.size() && v[numberEnd] == '.') {
|
|
||||||
++numberEnd;
|
|
||||||
while (numberEnd < v.size() && absl::ascii_isdigit(v[numberEnd]))
|
|
||||||
++numberEnd;
|
|
||||||
}
|
|
||||||
|
|
||||||
v = v.substr(0, numberEnd);
|
|
||||||
|
|
||||||
float returnedValue;
|
|
||||||
if (!absl::SimpleAtof(v, &returnedValue))
|
|
||||||
return absl::nullopt;
|
return absl::nullopt;
|
||||||
|
|
||||||
if (spec.flags & kWrapPhase)
|
if (spec.flags & kWrapPhase)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,9 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "absl/strings/string_view.h"
|
#include <absl/strings/ascii.h>
|
||||||
|
#include <absl/strings/numbers.h>
|
||||||
|
#include <absl/strings/string_view.h>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -101,3 +103,87 @@ uint64_t hashNumber(Int i, uint64_t h = Fnv1aBasis)
|
||||||
"The hashed object must be of arithmetic type");
|
"The hashed object must be of arithmetic type");
|
||||||
return hash(absl::string_view(reinterpret_cast<const char*>(&i), sizeof(i)), h);
|
return hash(absl::string_view(reinterpret_cast<const char*>(&i), sizeof(i)), h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read a floating-point number from a string non-permissively
|
||||||
|
*
|
||||||
|
* @param[in] input a string to read from
|
||||||
|
* @param[out] result address of the value where the result is stored
|
||||||
|
* @return whether the conversion is successful
|
||||||
|
*/
|
||||||
|
template <class F>
|
||||||
|
bool readFloat(absl::string_view input, F* result);
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline bool readFloat<float>(absl::string_view input, float* result)
|
||||||
|
{
|
||||||
|
return absl::SimpleAtof(input, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
inline bool readFloat<double>(absl::string_view input, double* result)
|
||||||
|
{
|
||||||
|
return absl::SimpleAtod(input, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read an integer from a string, permitting extra trailing characters.
|
||||||
|
*
|
||||||
|
* @param[in] input a string to read from
|
||||||
|
* @param[out] result address of the value where the result is stored
|
||||||
|
* @param[out] rest optional address which receives the unprocessed tail of the input
|
||||||
|
* @return whether the conversion is successful
|
||||||
|
*/
|
||||||
|
template <class I>
|
||||||
|
bool readLeadingInt(absl::string_view input, I* result, absl::string_view* rest = nullptr)
|
||||||
|
{
|
||||||
|
size_t numberEnd = 0;
|
||||||
|
|
||||||
|
if (numberEnd < input.size() && (input[numberEnd] == '+' || input[numberEnd] == '-'))
|
||||||
|
++numberEnd;
|
||||||
|
|
||||||
|
while (numberEnd < input.size() && absl::ascii_isdigit(input[numberEnd]))
|
||||||
|
++numberEnd;
|
||||||
|
|
||||||
|
if (!absl::SimpleAtoi(input.substr(0, numberEnd), result))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (rest)
|
||||||
|
*rest = input.substr(numberEnd);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Read a floating-point number from a string, permitting extra
|
||||||
|
* trailing characters.
|
||||||
|
*
|
||||||
|
* @param[in] input a string to read from
|
||||||
|
* @param[out] result address of the value where the result is stored
|
||||||
|
* @param[out] rest optional address which receives the unprocessed tail of the input
|
||||||
|
* @return whether the conversion is successful
|
||||||
|
*/
|
||||||
|
template <class F>
|
||||||
|
bool readLeadingFloat(absl::string_view input, F* result, absl::string_view* rest = nullptr)
|
||||||
|
{
|
||||||
|
size_t numberEnd = 0;
|
||||||
|
|
||||||
|
if (numberEnd < input.size() && (input[numberEnd] == '+' || input[numberEnd] == '-'))
|
||||||
|
++numberEnd;
|
||||||
|
while (numberEnd < input.size() && absl::ascii_isdigit(input[numberEnd]))
|
||||||
|
++numberEnd;
|
||||||
|
|
||||||
|
if (numberEnd < input.size() && input[numberEnd] == '.') {
|
||||||
|
++numberEnd;
|
||||||
|
while (numberEnd < input.size() && absl::ascii_isdigit(input[numberEnd]))
|
||||||
|
++numberEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!readFloat(input.substr(0, numberEnd), result))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (rest)
|
||||||
|
*rest = input.substr(numberEnd);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue