[tint][utils] Abstract absl dependency
Move the use of absl::from_chars() in the WGSL parser into utils, behind a new abstraction. If we decide one day to drop the absl dependency, we can reimplement this function. It also consolodates tint source_set dependencies on absl to the common utils module. No new tests as this is a thin wrapper around an existing implementation, and the single use is already heavily tested for parsing. Change-Id: I1ce5d68857e81299d1c97322b0ec28f0a83a31b7 Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/134581 Kokoro: Kokoro <noreply+kokoro@google.com> Commit-Queue: Ben Clayton <bclayton@google.com> Reviewed-by: Dan Sinclair <dsinclair@chromium.org>
This commit is contained in:
parent
8ba1ff7789
commit
f75e5c07b0
|
@ -251,6 +251,8 @@ libtint_source_set("libtint_utils_src") {
|
|||
"utils/hashset.h",
|
||||
"utils/map.h",
|
||||
"utils/math.h",
|
||||
"utils/parse_num.cc",
|
||||
"utils/parse_num.h",
|
||||
"utils/predicates.h",
|
||||
"utils/scoped_assignment.h",
|
||||
"utils/slice.h",
|
||||
|
@ -273,6 +275,8 @@ libtint_source_set("libtint_utils_src") {
|
|||
} else {
|
||||
sources += [ "diagnostic/printer_other.cc" ]
|
||||
}
|
||||
|
||||
deps = [ ":abseil" ]
|
||||
}
|
||||
|
||||
libtint_source_set("libtint_clone_context_hdrs") {
|
||||
|
@ -1064,7 +1068,6 @@ libtint_source_set("libtint_wgsl_reader_src") {
|
|||
]
|
||||
|
||||
deps = [
|
||||
":abseil",
|
||||
":libtint_ast_src",
|
||||
":libtint_builtins_src",
|
||||
":libtint_program_src",
|
||||
|
|
|
@ -536,6 +536,8 @@ list(APPEND TINT_LIB_SRCS
|
|||
utils/hashset.h
|
||||
utils/map.h
|
||||
utils/math.h
|
||||
utils/parse_num.cc
|
||||
utils/parse_num.h
|
||||
utils/predicates.h
|
||||
utils/scoped_assignment.h
|
||||
utils/slice.h
|
||||
|
|
|
@ -25,9 +25,9 @@
|
|||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/strings/charconv.h"
|
||||
#include "src/tint/debug.h"
|
||||
#include "src/tint/number.h"
|
||||
#include "src/tint/utils/parse_num.h"
|
||||
#include "src/tint/utils/unicode.h"
|
||||
|
||||
namespace tint::reader::wgsl {
|
||||
|
@ -414,12 +414,13 @@ std::optional<Token> Lexer::try_float() {
|
|||
end_ptr = &at(length() - 1) + 1;
|
||||
}
|
||||
|
||||
double value = 0;
|
||||
auto ret = absl::from_chars(&at(start), end_ptr, value);
|
||||
bool overflow = ret.ec != std::errc();
|
||||
auto ret = utils::ParseDouble(std::string_view(&at(start), end - start));
|
||||
double value = ret ? ret.Get() : 0.0;
|
||||
bool overflow = !ret && ret.Failure() == utils::ParseNumberError::kResultOutOfRange;
|
||||
|
||||
// Value didn't fit in a double, check for underflow as that is 0.0 in WGSL and not an error.
|
||||
if (ret.ec == std::errc::result_out_of_range) {
|
||||
// If the value didn't fit in a double, check for underflow as that is 0.0 in WGSL and not an
|
||||
// error.
|
||||
if (overflow) {
|
||||
// The exponent is negative, so treat as underflow
|
||||
if (negative_exponent) {
|
||||
overflow = false;
|
||||
|
@ -446,7 +447,6 @@ std::optional<Token> Lexer::try_float() {
|
|||
}
|
||||
}
|
||||
|
||||
TINT_ASSERT(Reader, end_ptr == ret.ptr);
|
||||
advance(end - start);
|
||||
|
||||
if (has_f_suffix) {
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
// Copyright 2023 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "src/tint/utils/parse_num.h"
|
||||
|
||||
#include <charconv>
|
||||
|
||||
#include "absl/strings/charconv.h"
|
||||
|
||||
namespace tint::utils {
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
Result<T, ParseNumberError> Parse(std::string_view number) {
|
||||
T val = 0;
|
||||
if constexpr (std::is_floating_point_v<T>) {
|
||||
auto result = absl::from_chars(number.data(), number.data() + number.size(), val);
|
||||
if (result.ec == std::errc::result_out_of_range) {
|
||||
return ParseNumberError::kResultOutOfRange;
|
||||
}
|
||||
if (result.ec != std::errc() || result.ptr != number.data() + number.size()) {
|
||||
return ParseNumberError::kUnparsable;
|
||||
}
|
||||
} else {
|
||||
auto result = std::from_chars(number.data(), number.data() + number.size(), val);
|
||||
if (result.ec == std::errc::result_out_of_range) {
|
||||
return ParseNumberError::kResultOutOfRange;
|
||||
}
|
||||
if (result.ec != std::errc() || result.ptr != number.data() + number.size()) {
|
||||
return ParseNumberError::kUnparsable;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
Result<float, ParseNumberError> ParseFloat(std::string_view str) {
|
||||
return Parse<float>(str);
|
||||
}
|
||||
|
||||
Result<double, ParseNumberError> ParseDouble(std::string_view str) {
|
||||
return Parse<double>(str);
|
||||
}
|
||||
|
||||
Result<int, ParseNumberError> ParseInt(std::string_view str) {
|
||||
return Parse<int>(str);
|
||||
}
|
||||
|
||||
Result<unsigned int, ParseNumberError> ParseUint(std::string_view str) {
|
||||
return Parse<unsigned int>(str);
|
||||
}
|
||||
|
||||
Result<int64_t, ParseNumberError> ParseInt64(std::string_view str) {
|
||||
return Parse<int64_t>(str);
|
||||
}
|
||||
|
||||
Result<uint64_t, ParseNumberError> ParseUint64(std::string_view str) {
|
||||
return Parse<uint64_t>(str);
|
||||
}
|
||||
|
||||
Result<int32_t, ParseNumberError> ParseInt32(std::string_view str) {
|
||||
return Parse<int32_t>(str);
|
||||
}
|
||||
|
||||
Result<uint32_t, ParseNumberError> ParseUint32(std::string_view str) {
|
||||
return Parse<uint32_t>(str);
|
||||
}
|
||||
|
||||
Result<int16_t, ParseNumberError> ParseInt16(std::string_view str) {
|
||||
return Parse<int16_t>(str);
|
||||
}
|
||||
|
||||
Result<uint16_t, ParseNumberError> ParseUint16(std::string_view str) {
|
||||
return Parse<uint16_t>(str);
|
||||
}
|
||||
|
||||
Result<int8_t, ParseNumberError> ParseInt8(std::string_view str) {
|
||||
return Parse<int8_t>(str);
|
||||
}
|
||||
|
||||
Result<uint8_t, ParseNumberError> ParseUint8(std::string_view str) {
|
||||
return Parse<uint8_t>(str);
|
||||
}
|
||||
|
||||
} // namespace tint::utils
|
|
@ -0,0 +1,126 @@
|
|||
// Copyright 2023 The Tint Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef SRC_TINT_UTILS_PARSE_NUM_H_
|
||||
#define SRC_TINT_UTILS_PARSE_NUM_H_
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "src/tint/utils/result.h"
|
||||
|
||||
namespace tint::utils {
|
||||
|
||||
/// Error returned by the number parsing functions
|
||||
enum class ParseNumberError {
|
||||
/// The number was unparsable
|
||||
kUnparsable,
|
||||
/// The parsed number is not representable by the target datatype
|
||||
kResultOutOfRange,
|
||||
};
|
||||
|
||||
/// @param str the string
|
||||
/// @returns the string @p str parsed as a float
|
||||
Result<float, ParseNumberError> ParseFloat(std::string_view str);
|
||||
|
||||
/// @param str the string
|
||||
/// @returns the string @p str parsed as a double
|
||||
Result<double, ParseNumberError> ParseDouble(std::string_view str);
|
||||
|
||||
/// @param str the string
|
||||
/// @returns the string @p str parsed as a int
|
||||
Result<int, ParseNumberError> ParseInt(std::string_view str);
|
||||
|
||||
/// @param str the string
|
||||
/// @returns the string @p str parsed as a unsigned int
|
||||
Result<unsigned int, ParseNumberError> ParseUint(std::string_view str);
|
||||
|
||||
/// @param str the string
|
||||
/// @returns the string @p str parsed as a int64_t
|
||||
Result<int64_t, ParseNumberError> ParseInt64(std::string_view str);
|
||||
|
||||
/// @param str the string
|
||||
/// @returns the string @p str parsed as a uint64_t
|
||||
Result<uint64_t, ParseNumberError> ParseUint64(std::string_view str);
|
||||
|
||||
/// @param str the string
|
||||
/// @returns the string @p str parsed as a int32_t
|
||||
Result<int32_t, ParseNumberError> ParseInt32(std::string_view str);
|
||||
|
||||
/// @param str the string
|
||||
/// @returns the string @p str parsed as a uint32_t
|
||||
Result<uint32_t, ParseNumberError> ParseUint32(std::string_view str);
|
||||
|
||||
/// @param str the string
|
||||
/// @returns the string @p str parsed as a int16_t
|
||||
Result<int16_t, ParseNumberError> ParseInt16(std::string_view str);
|
||||
|
||||
/// @param str the string
|
||||
/// @returns the string @p str parsed as a uint16_t
|
||||
Result<uint16_t, ParseNumberError> ParseUint16(std::string_view str);
|
||||
|
||||
/// @param str the string
|
||||
/// @returns the string @p str parsed as a int8_t
|
||||
Result<int8_t, ParseNumberError> ParseInt8(std::string_view str);
|
||||
|
||||
/// @param str the string
|
||||
/// @returns the string @p str parsed as a uint8_t
|
||||
Result<uint8_t, ParseNumberError> ParseUint8(std::string_view str);
|
||||
|
||||
/// @param str the string
|
||||
/// @returns the string @p str parsed as a the number @p T
|
||||
template <typename T>
|
||||
inline Result<T, ParseNumberError> ParseNumber(std::string_view str) {
|
||||
if constexpr (std::is_same_v<T, float>) {
|
||||
return ParseFloat(str);
|
||||
}
|
||||
if constexpr (std::is_same_v<T, double>) {
|
||||
return ParseDouble(str);
|
||||
}
|
||||
if constexpr (std::is_same_v<T, int>) {
|
||||
return ParseInt(str);
|
||||
}
|
||||
if constexpr (std::is_same_v<T, unsigned int>) {
|
||||
return ParseUint(str);
|
||||
}
|
||||
if constexpr (std::is_same_v<T, int64_t>) {
|
||||
return ParseInt64(str);
|
||||
}
|
||||
if constexpr (std::is_same_v<T, uint64_t>) {
|
||||
return ParseUint64(str);
|
||||
}
|
||||
if constexpr (std::is_same_v<T, int32_t>) {
|
||||
return ParseInt32(str);
|
||||
}
|
||||
if constexpr (std::is_same_v<T, uint32_t>) {
|
||||
return ParseUint32(str);
|
||||
}
|
||||
if constexpr (std::is_same_v<T, int16_t>) {
|
||||
return ParseInt16(str);
|
||||
}
|
||||
if constexpr (std::is_same_v<T, uint16_t>) {
|
||||
return ParseUint16(str);
|
||||
}
|
||||
if constexpr (std::is_same_v<T, int8_t>) {
|
||||
return ParseInt8(str);
|
||||
}
|
||||
if constexpr (std::is_same_v<T, uint8_t>) {
|
||||
return ParseUint8(str);
|
||||
}
|
||||
return ParseNumberError::kUnparsable;
|
||||
}
|
||||
|
||||
} // namespace tint::utils
|
||||
|
||||
#endif // SRC_TINT_UTILS_PARSE_NUM_H_
|
Loading…
Reference in New Issue