aboutsummaryrefslogtreecommitdiff
path: root/source/util
diff options
context:
space:
mode:
Diffstat (limited to 'source/util')
-rw-r--r--source/util/bit_vector.h2
-rw-r--r--source/util/hex_float.h18
-rw-r--r--source/util/ilist.h2
-rw-r--r--source/util/parse_number.h2
-rw-r--r--source/util/small_vector.h7
-rw-r--r--source/util/string_utils.h63
-rw-r--r--source/util/timer.h6
7 files changed, 78 insertions, 22 deletions
diff --git a/source/util/bit_vector.h b/source/util/bit_vector.h
index 3e189cb1..826d62f0 100644
--- a/source/util/bit_vector.h
+++ b/source/util/bit_vector.h
@@ -32,7 +32,7 @@ class BitVector {
enum { kInitialNumBits = 1024 };
public:
- // Creates a bit vector contianing 0s.
+ // Creates a bit vector containing 0s.
BitVector(uint32_t reserved_size = kInitialNumBits)
: bits_((reserved_size - 1) / kBitContainerSize + 1, 0) {}
diff --git a/source/util/hex_float.h b/source/util/hex_float.h
index cfc40fa6..903b6288 100644
--- a/source/util/hex_float.h
+++ b/source/util/hex_float.h
@@ -199,7 +199,7 @@ bool operator==(const FloatProxy<T>& first, const FloatProxy<T>& second) {
// Reads a FloatProxy value as a normal float from a stream.
template <typename T>
std::istream& operator>>(std::istream& is, FloatProxy<T>& value) {
- T float_val;
+ T float_val = static_cast<T>(0.0);
is >> float_val;
value = FloatProxy<T>(float_val);
return is;
@@ -1005,6 +1005,9 @@ std::istream& operator>>(std::istream& is, HexFloat<T, Traits>& value) {
is.get();
next_char = is.peek();
}
+
+ // Finished reading the part preceding any '.' or 'p'.
+
bits_written = false;
while (seen_dot && !seen_p) {
// Handle only fractional parts now.
@@ -1037,11 +1040,16 @@ std::istream& operator>>(std::istream& is, HexFloat<T, Traits>& value) {
next_char = is.peek();
}
+ // Finished reading the part preceding 'p'.
+ // In hex floats syntax, the binary exponent is required.
+
bool seen_sign = false;
int8_t exponent_sign = 1;
+ bool seen_written_exponent_digits = false;
int_type written_exponent = 0;
while (true) {
- if ((next_char == '-' || next_char == '+')) {
+ if (!seen_written_exponent_digits &&
+ (next_char == '-' || next_char == '+')) {
if (seen_sign) {
is.setstate(std::ios::failbit);
return is;
@@ -1049,6 +1057,7 @@ std::istream& operator>>(std::istream& is, HexFloat<T, Traits>& value) {
seen_sign = true;
exponent_sign = (next_char == '-') ? -1 : 1;
} else if (::isdigit(next_char)) {
+ seen_written_exponent_digits = true;
// Hex-floats express their exponent as decimal.
written_exponent = static_cast<int_type>(written_exponent * 10);
written_exponent =
@@ -1059,6 +1068,11 @@ std::istream& operator>>(std::istream& is, HexFloat<T, Traits>& value) {
is.get();
next_char = is.peek();
}
+ if (!seen_written_exponent_digits) {
+ // Binary exponent had no digits.
+ is.setstate(std::ios::failbit);
+ return is;
+ }
written_exponent = static_cast<int_type>(written_exponent * exponent_sign);
exponent = static_cast<int_type>(exponent + written_exponent);
diff --git a/source/util/ilist.h b/source/util/ilist.h
index 9837b09b..b7ecf01e 100644
--- a/source/util/ilist.h
+++ b/source/util/ilist.h
@@ -59,7 +59,7 @@ class IntrusiveList {
// Moves the contents of the given list to the list being constructed.
IntrusiveList(IntrusiveList&&);
- // Destorys the list. Note that the elements of the list will not be deleted,
+ // Destroys the list. Note that the elements of the list will not be deleted,
// but they will be removed from the list.
virtual ~IntrusiveList();
diff --git a/source/util/parse_number.h b/source/util/parse_number.h
index 729aac54..d0f2a09a 100644
--- a/source/util/parse_number.h
+++ b/source/util/parse_number.h
@@ -220,7 +220,7 @@ EncodeNumberStatus ParseAndEncodeIntegerNumber(
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| funciton. On success, returns
+// 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
diff --git a/source/util/small_vector.h b/source/util/small_vector.h
index f2c1147b..f1762a9f 100644
--- a/source/util/small_vector.h
+++ b/source/util/small_vector.h
@@ -175,9 +175,12 @@ class SmallVector {
return true;
}
+// Avoid infinite recursion from rewritten operators in C++20
+#if __cplusplus <= 201703L
friend bool operator==(const std::vector<T>& lhs, const SmallVector& rhs) {
return rhs == lhs;
}
+#endif
friend bool operator!=(const SmallVector& lhs, const std::vector<T>& rhs) {
return !(lhs == rhs);
@@ -363,7 +366,7 @@ class SmallVector {
}
}
- // Upate the size.
+ // Update the size.
size_ += num_of_new_elements;
return pos;
}
@@ -449,7 +452,7 @@ class SmallVector {
T* small_data_;
// The actual data used to store the array elements. It must never be used
- // directly, but must only be accesed through |small_data_|.
+ // directly, but must only be accessed through |small_data_|.
typename std::aligned_storage<sizeof(T), std::alignment_of<T>::value>::type
buffer[small_size];
diff --git a/source/util/string_utils.h b/source/util/string_utils.h
index 4282aa94..03e20b3d 100644
--- a/source/util/string_utils.h
+++ b/source/util/string_utils.h
@@ -16,6 +16,8 @@
#define SOURCE_UTIL_STRING_UTILS_H_
#include <assert.h>
+
+#include <cstring>
#include <sstream>
#include <string>
#include <vector>
@@ -44,9 +46,10 @@ std::string CardinalToOrdinal(size_t cardinal);
// string will be empty.
std::pair<std::string, std::string> SplitFlagArgs(const std::string& flag);
-// Encodes a string as a sequence of words, using the SPIR-V encoding.
-inline std::vector<uint32_t> MakeVector(std::string input) {
- std::vector<uint32_t> result;
+// Encodes a string as a sequence of words, using the SPIR-V encoding, appending
+// to an existing vector.
+inline void AppendToVector(const std::string& input,
+ std::vector<uint32_t>* result) {
uint32_t word = 0;
size_t num_bytes = input.size();
// SPIR-V strings are null-terminated. The byte_index == num_bytes
@@ -56,24 +59,36 @@ inline std::vector<uint32_t> MakeVector(std::string input) {
(byte_index < num_bytes ? uint8_t(input[byte_index]) : uint8_t(0));
word |= (new_byte << (8 * (byte_index % sizeof(uint32_t))));
if (3 == (byte_index % sizeof(uint32_t))) {
- result.push_back(word);
+ result->push_back(word);
word = 0;
}
}
// Emit a trailing partial word.
if ((num_bytes + 1) % sizeof(uint32_t)) {
- result.push_back(word);
+ result->push_back(word);
}
+}
+
+// Encodes a string as a sequence of words, using the SPIR-V encoding.
+inline std::vector<uint32_t> MakeVector(const std::string& input) {
+ std::vector<uint32_t> result;
+ AppendToVector(input, &result);
return result;
}
-// Decode a string from a sequence of words, using the SPIR-V encoding.
-template <class VectorType>
-inline std::string MakeString(const VectorType& words) {
+// Decode a string from a sequence of words between first and last, using the
+// SPIR-V encoding. Assert that a terminating 0-byte was found (unless
+// assert_found_terminating_null is passed as false).
+template <class InputIt>
+inline std::string MakeString(InputIt first, InputIt last,
+ bool assert_found_terminating_null = true) {
std::string result;
+ constexpr size_t kCharsPerWord = sizeof(*first);
+ static_assert(kCharsPerWord == 4, "expect 4-byte word");
- for (uint32_t word : words) {
- for (int byte_index = 0; byte_index < 4; byte_index++) {
+ for (InputIt pos = first; pos != last; ++pos) {
+ uint32_t word = *pos;
+ for (size_t byte_index = 0; byte_index < kCharsPerWord; byte_index++) {
uint32_t extracted_word = (word >> (8 * byte_index)) & 0xFF;
char c = static_cast<char>(extracted_word);
if (c == 0) {
@@ -82,9 +97,33 @@ inline std::string MakeString(const VectorType& words) {
result += c;
}
}
- assert(false && "Did not find terminating null for the string.");
+ assert(!assert_found_terminating_null &&
+ "Did not find terminating null for the string.");
+ (void)assert_found_terminating_null; /* No unused parameters in release
+ builds. */
return result;
-} // namespace utils
+}
+
+// Decode a string from a sequence of words in a vector, using the SPIR-V
+// encoding.
+template <class VectorType>
+inline std::string MakeString(const VectorType& words,
+ bool assert_found_terminating_null = true) {
+ return MakeString(words.cbegin(), words.cend(),
+ assert_found_terminating_null);
+}
+
+// Decode a string from array words, consuming up to count words, using the
+// SPIR-V encoding.
+inline std::string MakeString(const uint32_t* words, size_t num_words,
+ bool assert_found_terminating_null = true) {
+ return MakeString(words, words + num_words, assert_found_terminating_null);
+}
+
+// Check if str starts with prefix (only included since C++20)
+inline bool starts_with(const std::string& str, const char* prefix) {
+ return 0 == str.compare(0, std::strlen(prefix), prefix);
+}
} // namespace utils
} // namespace spvtools
diff --git a/source/util/timer.h b/source/util/timer.h
index fc4b747b..08083119 100644
--- a/source/util/timer.h
+++ b/source/util/timer.h
@@ -206,16 +206,16 @@ class Timer {
// Variable to save the result of clock_gettime(CLOCK_PROCESS_CPUTIME_ID) when
// Timer::Stop() is called. It is used as the last status of CPU time. The
- // resouce usage is measured by subtracting |cpu_before_| from it.
+ // resource usage is measured by subtracting |cpu_before_| from it.
timespec cpu_after_;
// Variable to save the result of clock_gettime(CLOCK_MONOTONIC) when
// Timer::Stop() is called. It is used as the last status of WALL time. The
- // resouce usage is measured by subtracting |wall_before_| from it.
+ // resource usage is measured by subtracting |wall_before_| from it.
timespec wall_after_;
// Variable to save the result of getrusage() when Timer::Stop() is called. It
- // is used as the last status of USR time, SYS time, and RSS. Those resouce
+ // is used as the last status of USR time, SYS time, and RSS. Those resource
// usages are measured by subtracting |usage_before_| from it.
rusage usage_after_;