// Copyright (c) 2016 Google Inc. // // 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 SOURCE_UTIL_PARSE_NUMBER_H_ #define SOURCE_UTIL_PARSE_NUMBER_H_ #include <functional> #include <string> #include <tuple> #include "source/util/hex_float.h" #include "spirv-tools/libspirv.h" namespace spvtools { namespace utils { // A struct to hold the expected type information for the number in text to be // parsed. struct NumberType { … }; // Returns true if the type is a scalar integer type. inline bool IsIntegral(const NumberType& type) { … } // Returns true if the type is a scalar floating point type. inline bool IsFloating(const NumberType& type) { … } // Returns true if the type is a signed value. inline bool IsSigned(const NumberType& type) { … } // Returns true if the type is unknown. inline bool IsUnknown(const NumberType& type) { … } // Returns the number of bits in the type. This is only valid for integer and // floating types. inline int AssumedBitWidth(const NumberType& type) { … } // A templated class with a static member function Clamp, where Clamp sets a // referenced value of type T to 0 if T is an unsigned integer type, and // returns true if it modified the referenced value. template <typename T, typename = void> class ClampToZeroIfUnsignedType { … }; // The specialization of ClampToZeroIfUnsignedType for unsigned integer types. ClampToZeroIfUnsignedType<T, typename std::enable_if<std::is_unsigned<T>::value>::type>; // Returns true if the given value fits within the target scalar integral type. // The target type may have an unusual bit width. If the value was originally // specified as a hexadecimal number, then the overflow bits should be zero. // If it was hex and the target type is signed, then return the sign-extended // value through the updated_value_for_hex pointer argument. On failure, // returns false. template <typename T> bool CheckRangeAndIfHexThenSignExtend(T value, const NumberType& type, bool is_hex, T* updated_value_for_hex) { … } // Parses a numeric value of a given type from the given text. The number // should take up the entire string, and should be within bounds for the target // type. On success, returns true and populates the object referenced by // value_pointer. On failure, returns false. template <typename T> bool ParseNumber(const char* text, T* value_pointer) { … } // Enum to indicate the parsing and encoding status. enum class EncodeNumberStatus { … }; // Parses an integer value of a given |type| from the given |text| and encodes // the number by the given |emit| function. On success, returns // EncodeNumberStatus::kSuccess and the parsed number will be consumed by the // given |emit| function word by word (least significant word first). On // failure, this function returns the error code of the encoding status and // |emit| function will not be called. If the string pointer |error_msg| is not // a nullptr, it will be overwritten with error messages in case of failure. In // case of success, |error_msg| will not be touched. Integers up to 64 bits are // supported. EncodeNumberStatus ParseAndEncodeIntegerNumber( const char* text, const NumberType& type, std::function<void(uint32_t)> emit, std::string* error_msg); // Parses a floating point value of a given |type| from the given |text| and // encodes the number by the given |emit| function. On success, returns // EncodeNumberStatus::kSuccess and the parsed number will be consumed by the // given |emit| function word by word (least significant word first). On // failure, this function returns the error code of the encoding status and // |emit| function will not be called. If the string pointer |error_msg| is not // a nullptr, it will be overwritten with error messages in case of failure. In // case of success, |error_msg| will not be touched. Only 16, 32 and 64 bit // floating point numbers are supported. EncodeNumberStatus ParseAndEncodeFloatingPointNumber( const char* text, const NumberType& type, std::function<void(uint32_t)> emit, std::string* error_msg); // Parses an integer or floating point number of a given |type| from the given // |text| and encodes the number by the given |emit| function. On success, // returns EncodeNumberStatus::kSuccess and the parsed number will be consumed // by the given |emit| function word by word (least significant word first). On // failure, this function returns the error code of the encoding status and // |emit| function will not be called. If the string pointer |error_msg| is not // a nullptr, it will be overwritten with error messages in case of failure. In // case of success, |error_msg| will not be touched. Integers up to 64 bits // and 16/32/64 bit floating point values are supported. EncodeNumberStatus ParseAndEncodeNumber(const char* text, const NumberType& type, std::function<void(uint32_t)> emit, std::string* error_msg); } // namespace utils } // namespace spvtools #endif // SOURCE_UTIL_PARSE_NUMBER_H_