diff options
| author | Hannes Schulze <haschu0103@outlook.de> | 2025-02-06 19:54:38 +0100 |
|---|---|---|
| committer | Hannes Schulze <haschu0103@outlook.de> | 2025-02-06 19:54:38 +0100 |
| commit | 64ebfde8bcd6408e3b6925624e8680c314db6efc (patch) | |
| tree | b969314f909f7f16ef5acc63f90dca317a40850a /lib/nes/common | |
| parent | d060e3a50c987d10799ccc739bdbf9d7d7a13c10 (diff) | |
get rid of nasty stdlib
Diffstat (limited to 'lib/nes/common')
| -rw-r--r-- | lib/nes/common/CMakeLists.txt | 3 | ||||
| -rw-r--r-- | lib/nes/common/containers/CMakeLists.txt | 4 | ||||
| -rw-r--r-- | lib/nes/common/containers/box.hh | 8 | ||||
| -rw-r--r-- | lib/nes/common/containers/path-builder.cc | 12 | ||||
| -rw-r--r-- | lib/nes/common/containers/path-builder.hh | 11 | ||||
| -rw-r--r-- | lib/nes/common/containers/path-view.cc | 8 | ||||
| -rw-r--r-- | lib/nes/common/containers/path-view.hh | 10 | ||||
| -rw-r--r-- | lib/nes/common/containers/string-builder.cc | 18 | ||||
| -rw-r--r-- | lib/nes/common/containers/string-builder.hh | 23 | ||||
| -rw-r--r-- | lib/nes/common/containers/string-view.cc | 81 | ||||
| -rw-r--r-- | lib/nes/common/containers/string-view.hh | 40 | ||||
| -rw-r--r-- | lib/nes/common/fps-counter.cc | 7 | ||||
| -rw-r--r-- | lib/nes/common/fps-counter.hh | 3 | ||||
| -rw-r--r-- | lib/nes/common/utils.hh | 38 |
14 files changed, 215 insertions, 51 deletions
diff --git a/lib/nes/common/CMakeLists.txt b/lib/nes/common/CMakeLists.txt index 9a7cc6b..e227ca8 100644 --- a/lib/nes/common/CMakeLists.txt +++ b/lib/nes/common/CMakeLists.txt @@ -7,6 +7,7 @@ target_sources( display.hh status.hh fps-counter.hh - fps-counter.cc) + fps-counter.cc + utils.hh) add_subdirectory(containers)
\ No newline at end of file diff --git a/lib/nes/common/containers/CMakeLists.txt b/lib/nes/common/containers/CMakeLists.txt index 351772f..69b6dd9 100644 --- a/lib/nes/common/containers/CMakeLists.txt +++ b/lib/nes/common/containers/CMakeLists.txt @@ -9,4 +9,6 @@ target_sources( path-view.cc span.hh string-builder.hh - string-builder.cc)
\ No newline at end of file + string-builder.cc + string-view.hh + string-view.cc)
\ No newline at end of file diff --git a/lib/nes/common/containers/box.hh b/lib/nes/common/containers/box.hh index 7bf2848..82f6448 100644 --- a/lib/nes/common/containers/box.hh +++ b/lib/nes/common/containers/box.hh @@ -2,6 +2,8 @@ #include "nes/common/types.hh" #include "nes/common/debug.hh" +#include "nes/common/utils.hh" +#include <new> namespace nes { @@ -56,15 +58,15 @@ namespace nes operator bool() const { return has_value(); } auto has_value() const -> bool { return initialized_; } - auto get() -> T* { return has_value() ? std::launder(reinterpret_cast<T*>(buffer_)) : nullptr; } - auto get() const -> T const* { return has_value() ? std::launder(reinterpret_cast<T const *>(buffer_)) : nullptr; } + auto get() -> T* { return has_value() ? launder(reinterpret_cast<T*>(buffer_)) : nullptr; } + auto get() const -> T const* { return has_value() ? launder(reinterpret_cast<T const *>(buffer_)) : nullptr; } /// Construct a new value in-place, potentially replacing the old value. template<typename... Args> auto emplace(Args&&... args) -> void { clear(); - new (buffer_) T(std::forward<Args>(args)...); + new (buffer_) T(args...); initialized_ = true; } diff --git a/lib/nes/common/containers/path-builder.cc b/lib/nes/common/containers/path-builder.cc index 2e3ce07..f352b46 100644 --- a/lib/nes/common/containers/path-builder.cc +++ b/lib/nes/common/containers/path-builder.cc @@ -9,21 +9,21 @@ namespace nes if (buffer_.get_length() > 0) { buffer_[length_++] = '/'; } } - auto path_builder::push(std::string_view component) -> status + auto path_builder::push(string_view component) -> status { // Trim leading and trailing slashes - while (!component.empty() && component[0] == '/') { component = component.substr(1); } - while (!component.empty() && component[component.length() - 1] == '/') { component = component.substr(0, component.length() - 1); } - if (component.empty() || std::find(component.begin(), component.end(), '/') != component.end()) { return status::error_invalid_path; } + while (!component.is_empty() && component.get_first() == '/') { component = component.substring(1); } + while (!component.is_empty() && component.get_last() == '/') { component = component.substring(0, component.get_length() - 1); } + if (component.is_empty() || component.contains('/')) { return status::error_invalid_path; } // Check if there is enough remaining capacity for "/<component>" auto const add_leading_slash = length_ == 0 || buffer_[length_ - 1] != '/'; - auto const length = component.length() + (add_leading_slash ? 1 : 0); + auto const length = component.get_length() + (add_leading_slash ? 1 : 0); if (length_ + length > buffer_.get_length()) { return status::error_buffer_overflow; } // Append "/<component>" if (add_leading_slash) { buffer_[length_++] = '/'; } - for (auto i = u32{ 0 }; i < component.length(); ++i) { buffer_[length_++] = component[i]; } + for (auto i = u32{ 0 }; i < component.get_length(); ++i) { buffer_[length_++] = component[i]; } return status::success; } diff --git a/lib/nes/common/containers/path-builder.hh b/lib/nes/common/containers/path-builder.hh index 2991a83..3bddb87 100644 --- a/lib/nes/common/containers/path-builder.hh +++ b/lib/nes/common/containers/path-builder.hh @@ -1,10 +1,11 @@ #pragma once #include "nes/common/containers/span.hh" +#include "nes/common/containers/string-view.hh" #include "nes/common/containers/path-view.hh" #include "nes/common/types.hh" #include "nes/common/status.hh" -#include <string_view> +#include "nes/common/utils.hh" namespace nes { @@ -21,9 +22,9 @@ namespace nes explicit path_builder(span<char>); auto get_components() const -> path_view { return path_view{ get_path() }; } - auto get_path() const -> std::string_view { return std::string_view{ buffer_.get_data(), length_ }; } + auto get_path() const -> string_view { return string_view{ buffer_.get_data(), length_ }; } - auto push(std::string_view) -> status; + auto push(string_view) -> status; auto pop() -> status; }; @@ -42,13 +43,13 @@ namespace nes path_buffer(path_buffer const& other) : path_builder{ buffer_ } { - std::copy_n(other.buffer_, Capacity, buffer_); + copy(other.buffer_, buffer_, Capacity); length_ = other.length_; } auto operator=(path_buffer const& other) { - std::copy_n(other.buffer_, Capacity, buffer_); + copy(other.buffer_, buffer_, Capacity); length_ = other.length_; } }; diff --git a/lib/nes/common/containers/path-view.cc b/lib/nes/common/containers/path-view.cc index c81668b..33d82a8 100644 --- a/lib/nes/common/containers/path-view.cc +++ b/lib/nes/common/containers/path-view.cc @@ -3,10 +3,10 @@ namespace nes { - auto path_view::iterator::operator*() const -> std::string_view + auto path_view::iterator::operator*() const -> string_view { NES_ASSERT(current_ != nullptr && component_length_ > 0 && "invalid iterator"); - return std::string_view{ current_, component_length_ }; + return string_view{ current_, component_length_ }; } auto path_view::iterator::operator++() -> iterator& @@ -41,11 +41,11 @@ namespace nes auto path_view::begin() const -> iterator { - return ++iterator{ path_.data(), 0, static_cast<u32>(path_.size()) }; + return ++iterator{ path_.get_data(), 0, path_.get_length() }; } auto path_view::end() const -> iterator { - return iterator{ path_.data() + path_.size(), 0, 0 }; + return iterator{ path_.get_data() + path_.get_length(), 0, 0 }; } } // namespace nes
\ No newline at end of file diff --git a/lib/nes/common/containers/path-view.hh b/lib/nes/common/containers/path-view.hh index 7741060..1c25d26 100644 --- a/lib/nes/common/containers/path-view.hh +++ b/lib/nes/common/containers/path-view.hh @@ -1,14 +1,14 @@ #pragma once +#include "nes/common/containers/string-view.hh" #include "nes/common/types.hh" -#include <string_view> namespace nes { /// Non-owning copy of a path, useful for iterating over its components. class path_view { - std::string_view path_; + string_view path_; public: /// An iterator for the path components. @@ -24,7 +24,7 @@ namespace nes auto operator==(iterator const& other) -> bool { return current_ == other.current_; } auto operator!=(iterator const& other) -> bool { return current_ != other.current_; } - auto operator*() const -> std::string_view; + auto operator*() const -> string_view; auto operator++() -> iterator&; auto operator++(int) -> iterator; @@ -38,12 +38,12 @@ namespace nes }; explicit path_view() = default; - explicit path_view(std::string_view const path) + explicit path_view(string_view const path) : path_{ path } { } - auto get_path() const -> std::string_view { return path_; } + auto get_path() const -> string_view { return path_; } auto begin() const -> iterator; auto end() const -> iterator; diff --git a/lib/nes/common/containers/string-builder.cc b/lib/nes/common/containers/string-builder.cc index 74d9548..ad2f97f 100644 --- a/lib/nes/common/containers/string-builder.cc +++ b/lib/nes/common/containers/string-builder.cc @@ -16,7 +16,7 @@ namespace nes return status::success; } - auto string_builder::append_string(std::string_view const value) -> status + auto string_builder::append_string(string_view const value) -> status { auto copy = *this; for (auto const c : value) @@ -103,13 +103,13 @@ namespace nes return append_string(value ? "true" : "false"); } - auto string_builder::append_format(std::string_view const fmt, format_arg const* args, u32 const arg_count) -> status + auto string_builder::append_format(string_view const fmt, format_arg const* args, u32 const arg_count) -> status { auto copy = *this; // Go through the format string, inserting the arguments for the templates as necessary. auto current_arg = u32{ 0 }; - for (auto i = u32{ 0 }; i < fmt.length(); ++i) + for (auto i = u32{ 0 }; i < fmt.get_length(); ++i) { if (fmt[i] == '{') { @@ -122,10 +122,10 @@ namespace nes else { // start of template - auto const params = &fmt[i]; // remember start position + auto const params_start = i; // remember start position auto params_length = u32{ 0 }; // skip to the end of the template - while (fmt[i] && fmt[i] != '}') + while (i < fmt.get_length() && fmt[i] != '}') { params_length++; i++; @@ -137,7 +137,7 @@ namespace nes } // end of template - auto const p = std::string_view{ params, params_length }; + auto const p = fmt.substring(params_start, params_length); if (current_arg < arg_count) { if (auto const s = copy.append_format_arg(args[current_arg], p); s != status::success) { return s; } @@ -182,11 +182,11 @@ namespace nes return status::success; } - auto string_builder::append_format_arg(format_arg const arg, std::string_view const params) -> status + auto string_builder::append_format_arg(format_arg const arg, string_view const params) -> status { auto const parse_params = [&] { - if (!params.empty()) + if (!params.is_empty()) { return status::error_invalid_format_string; } @@ -196,7 +196,7 @@ namespace nes auto const parse_params_integer = [&](number_format& out_format) { - if (params.empty() || params == "d") + if (params.is_empty() || params == "d") { out_format = number_format::decimal; } diff --git a/lib/nes/common/containers/string-builder.hh b/lib/nes/common/containers/string-builder.hh index 0f8a64c..7dcbb34 100644 --- a/lib/nes/common/containers/string-builder.hh +++ b/lib/nes/common/containers/string-builder.hh @@ -1,9 +1,10 @@ #pragma once -#include "nes/common/types.hh" #include "nes/common/containers/span.hh" +#include "nes/common/containers/string-view.hh" +#include "nes/common/types.hh" #include "nes/common/status.hh" -#include <string_view> +#include "nes/common/utils.hh" namespace nes { @@ -38,7 +39,7 @@ namespace nes format_arg_type type; union { - std::string_view string; + string_view string; char character; i64 signed_integer; u64 unsigned_integer; @@ -48,7 +49,7 @@ namespace nes format_arg() = delete; explicit format_arg(char const* v) : type{ format_arg_type::string } { string = v; } - explicit format_arg(std::string_view const v) : type{ format_arg_type::string } { string = v; } + explicit format_arg(string_view const v) : type{ format_arg_type::string } { string = v; } explicit format_arg(char const v) : type{ format_arg_type::character } { character = v; } explicit format_arg(unsigned char const v) : format_arg{ static_cast<char>(v) } {} explicit format_arg(long long const v) : type{ format_arg_type::signed_integer } { signed_integer = v; } @@ -66,10 +67,10 @@ namespace nes explicit string_builder(span<char>); /// Get the resulting string. - auto get_result() const -> std::string_view { return std::string_view{ buffer_.get_data(), length_ }; } + auto get_result() const -> string_view { return string_view{ buffer_.get_data(), length_ }; } auto append_char(char) -> status; - auto append_string(std::string_view) -> status; + auto append_string(string_view) -> status; auto append_int(i64, number_format = number_format::decimal) -> status; auto append_int(u64, number_format = number_format::decimal) -> status; auto append_bool(bool) -> status; @@ -82,7 +83,7 @@ namespace nes /// /// Curly braces can be escaped by repeating them twice like {{this}}. template<typename... Args> - auto append_format(std::string_view const fmt, Args... args) -> status + auto append_format(string_view const fmt, Args... args) -> status { constexpr u32 arg_count = sizeof...(Args); // Add another argument at the end so we don't have an empty array expression. @@ -92,8 +93,8 @@ namespace nes } private: - auto append_format(std::string_view fmt, format_arg const* args, u32 arg_count) -> status; - auto append_format_arg(format_arg, std::string_view params) -> status; + auto append_format(string_view fmt, format_arg const* args, u32 arg_count) -> status; + auto append_format_arg(format_arg, string_view params) -> status; }; /// A string builder with a buffer embedded into it. @@ -111,13 +112,13 @@ namespace nes string_buffer(string_buffer const& other) : string_builder{ buffer_ } { - std::copy_n(other.buffer_, Capacity, buffer_); + copy(other.buffer_, buffer_, Capacity); length_ = other.length_; } auto operator=(string_buffer const& other) { - std::copy_n(other.buffer_, Capacity, buffer_); + copy(other.buffer_, buffer_, Capacity); length_ = other.length_; } }; diff --git a/lib/nes/common/containers/string-view.cc b/lib/nes/common/containers/string-view.cc new file mode 100644 index 0000000..8265d09 --- /dev/null +++ b/lib/nes/common/containers/string-view.cc @@ -0,0 +1,81 @@ +#include "nes/common/containers/string-view.hh" +#include "nes/common/debug.hh" + +namespace nes +{ + namespace + { + auto compute_length(char const* c_string) -> u32 + { + auto res = u32{ 0 }; + while (*c_string) + { + res += 1; + c_string++; + } + return res; + } + } // namespace + + string_view::string_view(span<char const> const data) + : data_{ data } + { + } + + string_view::string_view(char const* data, u32 length) + : data_{ data, length } + { + } + + string_view::string_view(char const* c_string) + : string_view{ c_string, compute_length(c_string) } + { + } + + auto string_view::get_first() const -> char + { + NES_ASSERT(!is_empty() && "unable to get character of empty string"); + return data_[0]; + } + + auto string_view::get_last() const -> char + { + NES_ASSERT(!is_empty() && "unable to get character of empty string"); + return data_[data_.get_length() - 1]; + } + + auto string_view::contains(char const needle) const -> bool + { + for (const auto c : *this) + { + if (c == needle) { return true; } + } + return false; + } + + auto string_view::substring(u32 const first) const -> string_view + { + return string_view{ data_.subspan(first) }; + } + + auto string_view::substring(u32 const first, u32 const length) const -> string_view + { + return string_view{ data_.subspan(first, length) }; + } + + auto operator==(string_view const lhs, string_view const rhs) -> bool + { + if (lhs.get_length() != rhs.get_length()) { return false; } + + for (auto i = u32{ 0 }; i < lhs.get_length(); ++i) + { + if (lhs[i] != rhs[i]) { return false; } + } + + return true; + } + auto operator!=(string_view const lhs, string_view const rhs) -> bool + { + return !(lhs == rhs); + } +} // namespace nes
\ No newline at end of file diff --git a/lib/nes/common/containers/string-view.hh b/lib/nes/common/containers/string-view.hh new file mode 100644 index 0000000..180a688 --- /dev/null +++ b/lib/nes/common/containers/string-view.hh @@ -0,0 +1,40 @@ +#pragma once + +#include "nes/common/containers/span.hh" +#include "nes/common/types.hh" + +namespace nes +{ + /// Non-owning view into a (not necessarily null-terminated) string. + class string_view + { + span<char const> data_; + + public: + explicit string_view() = default; + explicit string_view(span<char const>); + explicit string_view(char const* data, u32 length); + string_view(char const* c_string); + + using iterator = span<char const>::iterator; + + auto operator[](u32 const index) const -> char { return data_[index]; } + auto get_span() const -> span<char const> { return data_; } + auto get_data() const -> char const* { return data_.get_data(); } + auto get_length() const -> u32 { return data_.get_length(); } + auto is_empty() const -> bool { return get_length() == 0; } + auto begin() const -> iterator { return data_.begin(); } + auto end() const -> iterator { return data_.end(); } + + // String helpers + + auto get_first() const -> char; + auto get_last() const -> char; + auto contains(char) const -> bool; + auto substring(u32 first) const -> string_view; + auto substring(u32 first, u32 length) const -> string_view; + }; + + auto operator==(string_view, string_view) -> bool; + auto operator!=(string_view, string_view) -> bool; +} // namespace nes
\ No newline at end of file diff --git a/lib/nes/common/fps-counter.cc b/lib/nes/common/fps-counter.cc index ef6169b..8f19c7e 100644 --- a/lib/nes/common/fps-counter.cc +++ b/lib/nes/common/fps-counter.cc @@ -2,9 +2,9 @@ namespace nes { - auto fps_counter::frame(std::chrono::microseconds const elapsed_time) -> void + auto fps_counter::frame(u32 const elapsed_time_us) -> void { - if (elapsed_time.count() <= 0) { return; } + if (elapsed_time_us == 0) { return; } if (buffer_position_ == 0) { @@ -22,8 +22,7 @@ namespace nes } // Add the frame time to the buffer, replacing any existing content in the ring buffer. - auto const frame_time = static_cast<u32>(elapsed_time.count()); - frame_times_[buffer_position_] = frame_time; + frame_times_[buffer_position_] = elapsed_time_us; buffer_position_ = (buffer_position_ + 1) % buffer_size; } } // namespace nes
\ No newline at end of file diff --git a/lib/nes/common/fps-counter.hh b/lib/nes/common/fps-counter.hh index 96db98c..f921880 100644 --- a/lib/nes/common/fps-counter.hh +++ b/lib/nes/common/fps-counter.hh @@ -1,7 +1,6 @@ #pragma once #include "nes/common/types.hh" -#include <chrono> namespace nes { @@ -17,7 +16,7 @@ namespace nes public: explicit fps_counter() = default; - auto frame(std::chrono::microseconds elapsed_time) -> void; + auto frame(u32 elapsed_time_us) -> void; auto get_fps() const -> u32 { return buffered_fps_; } }; } // namespace nes
\ No newline at end of file diff --git a/lib/nes/common/utils.hh b/lib/nes/common/utils.hh new file mode 100644 index 0000000..460d0d5 --- /dev/null +++ b/lib/nes/common/utils.hh @@ -0,0 +1,38 @@ +#pragma once + +#include "nes/common/types.hh" + +namespace nes +{ + template<typename T> + auto launder(T* p) -> T* + { + return __builtin_launder(p); + } + + template<typename T> + auto copy(T const* src, T* dst, u32 const length) + { + for (auto i = u32{ 0 }; i < length; ++i) { dst[i] = src[i]; } + } + + template<typename T> + auto min(T const a, T const b) + { + return a < b ? a : b; + } + + template<typename T> + auto max(T const a, T const b) + { + return a > b ? a : b; + } + + template<typename T> + auto swap(T& a, T& b) -> void + { + auto const tmp = a; + a = b; + b = tmp; + } +} // namespace nes
\ No newline at end of file |
