Compare commits

..

No commits in common. "227f3cd9f584039cfddad75f1fe1275ad6cac000" and "4061b8314ef612491105dd4f4e9ae5103a26f216" have entirely different histories.

11 changed files with 118 additions and 115 deletions

View File

@ -124,7 +124,6 @@ install(
stringliteral.hpp
stringview.hpp
strongint.hpp
strconv.hpp
strops.hpp
trace.hpp
typeinfo.hpp

View File

@ -112,4 +112,38 @@ constexpr int lastIndexOf(const auto &str, int character, std::size_t maxLen = 0
return retval;
}
template<typename Integer, typename T>
constexpr T itoa(Integer v, T str) noexcept {
if (v) {
ox::ResizedInt_t<Integer, 64> mod = 1000000000000000000;
ox::ResizedInt_t<Integer, 64> val = v;
constexpr auto base = 10;
auto it = 0;
if (val < 0) {
str[static_cast<std::size_t>(it)] = '-';
it++;
}
while (mod) {
auto digit = val / mod;
val %= mod;
mod /= base;
if (it || digit) {
ox::ResizedInt_t<Integer, 64> start = '0';
if (digit >= 10) {
start = 'a';
digit -= 10;
}
str[static_cast<std::size_t>(it)] = static_cast<typename ox::remove_reference<decltype(str[0])>::type>(start + digit);
it++;
}
}
str[static_cast<std::size_t>(it)] = 0;
} else {
// 0 is a special case
str[0] = '0';
str[1] = 0;
}
return str;
}
}

View File

@ -75,17 +75,14 @@ constexpr StringView toStringView(const auto&) noexcept requires(force) {
class FmtArg {
private:
static constexpr auto DataSz = 23;
char dataStr[DataSz] = {};
char dataStr[10] = {};
template<typename T>
constexpr StringView sv(const T &v, char *dataStr) noexcept {
if constexpr(is_bool_v<T>) {
return v ? "true" : "false";
} else if constexpr(is_integer_v<T>) {
ox::CharBuffWriter w(dataStr, DataSz);
std::ignore = ox::writeItoa(v, w);
return dataStr;
return ox::itoa(v, dataStr);
} else {
return toStringView(v);
}
@ -200,13 +197,13 @@ constexpr StringType sfmt(StringView fmt, Args&&... args) noexcept {
for (size_t i = 0; i < fmtSegments.size - 1; ++i) {
std::ignore = out.append(elements[i].out);
const auto &s = fmtSegments.segments[i + 1];
std::ignore = out.append(s.str, s.length);
std::ignore = out.append(s.str);
}
return out;
}
template<typename T = String>
constexpr Result<T> join(auto const&d, auto const&list) {
constexpr Result<T> join(auto d, const auto &list) {
if (!list.size()) {
return T("");
}

View File

@ -9,15 +9,10 @@
#pragma once
#include "array.hpp"
#include "concepts.hpp"
#include "cstrops.hpp"
#include "memops.hpp"
#include "error.hpp"
#include "buffer.hpp"
#include "ignore.hpp"
#include "ox/std/error.hpp"
#include "stringview.hpp"
#include "typetraits.hpp"
#include "strconv.hpp"
namespace ox {
@ -25,8 +20,8 @@ namespace ox {
template<std::size_t StrCap>
class IString {
private:
size_t m_size{};
ox::Array<char, StrCap + 1> m_buff;
size_t m_size{};
public:
constexpr IString() noexcept;
@ -39,6 +34,8 @@ class IString {
constexpr IString &operator=(const char *str) noexcept;
constexpr IString &operator=(char *str) noexcept;
constexpr IString &operator=(Integer_c auto i) noexcept;
@ -104,11 +101,9 @@ constexpr IString<size>::IString(const char *str) noexcept: m_buff{{0}} {
template<std::size_t size>
constexpr IString<size> &IString<size>::operator=(Integer_c auto i) noexcept {
ox::Array<char, 22> s;
ox::CharBuffWriter w(s);
std::ignore = ox::writeItoa(i, w);
this->operator=({s.data(), w.tellp()});
return *this;
ox::Array<char, 65> str{};
ox::itoa(i, str.data());
return this->operator=(str.data());
}
template<std::size_t size>
@ -137,6 +132,11 @@ constexpr IString<size> &IString<size>::operator=(const char *str) noexcept {
return *this;
}
template<std::size_t size>
constexpr IString<size> &IString<size>::operator=(char *str) noexcept {
return *this = static_cast<const char*>(str);
}
template<std::size_t StrCap>
constexpr bool IString<StrCap>::operator==(const char *other) const noexcept {
return ox::StringView(*this) == other;
@ -239,12 +239,9 @@ constexpr std::size_t IString<StrCap>::bytes() const noexcept {
template<std::size_t StrCap>
constexpr ox::Error IString<StrCap>::resize(size_t sz) noexcept {
if (sz > StrCap) [[unlikely]] {
if (sz > StrCap) {
return OxError(1, "Trying to extend IString beyond its cap");
}
for (auto i = m_size; i < sz; ++i) {
m_buff[i] = 0;
}
m_size = sz;
return {};
}
@ -259,30 +256,4 @@ struct MaybeView<ox::IString<sz>> {
using type = ox::StringView;
};
template<Integer_c Integer>
[[nodiscard]]
constexpr auto itoa(Integer v) noexcept {
constexpr auto Cap = [] {
auto out = 0;
switch (sizeof(Integer)) {
case 1:
out = 3;
case 2:
out = 5;
case 4:
out = 10;
case 8:
out = 21;
}
return out + ox::is_signed_v<Integer>;
}();
ox::IString<Cap> out;
std::ignore = out.resize(out.cap());
ox::CharBuffWriter w(out.data(), out.cap());
std::ignore = writeItoa(v, w);
std::ignore = out.resize(w.tellp());
return out;
}
}

View File

@ -1,44 +0,0 @@
#pragma once
#include "error.hpp"
#include "types.hpp"
#include "writer.hpp"
namespace ox {
template<Integer_c Integer>
constexpr ox::Error writeItoa(Integer v, ox::Writer_c auto &writer) noexcept {
if (v) {
ox::ResizedInt_t<Integer, 64> mod = 1000000000000000000;
ox::ResizedInt_t<Integer, 64> val = v;
constexpr auto base = 10;
auto it = 0;
if (val < 0) {
oxReturnError(writer.put('-'));
++it;
}
while (mod) {
auto digit = val / mod;
val %= mod;
mod /= base;
if (it || digit) {
ox::ResizedInt_t<Integer, 64> start = '0';
if (digit >= 10) {
start = 'a';
digit -= 10;
}
oxReturnError(writer.put(static_cast<char>(start + digit)));
++it;
}
}
} else {
// 0 is a special case
oxReturnError(writer.put('0'));
}
return {};
}
}
#include "istring.hpp"

View File

@ -16,7 +16,6 @@
#include "ignore.hpp"
#include "memops.hpp"
#include "serialize.hpp"
#include "strconv.hpp"
#include "stringliteral.hpp"
#include "stringview.hpp"
#include "strops.hpp"
@ -24,9 +23,6 @@
namespace ox {
template<typename Integer>
constexpr ox::IString<21> itoa(Integer v) noexcept;
template<std::size_t SmallStringSize_v>
class BasicString {
private:
@ -331,13 +327,17 @@ constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operat
template<std::size_t SmallStringSize_v>
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(int64_t i) noexcept {
set(ox::itoa(i));
ox::Array<char, 65> str{};
ox::itoa(i, str.data());
set(str.data());
return *this;
}
template<std::size_t SmallStringSize_v>
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator=(uint64_t i) noexcept {
set(ox::itoa(i));
ox::Array<char, 65> str{};
ox::itoa(i, str.data());
set(str.data());
return *this;
}
@ -383,8 +383,9 @@ constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operat
template<std::size_t SmallStringSize_v>
constexpr BasicString<SmallStringSize_v> &BasicString<SmallStringSize_v>::operator+=(Integer_c auto i) noexcept {
auto const str = ox::itoa(i);
return this->operator+=(str.c_str());
char str[65] = {};
ox::itoa(i, str);
return this->operator+=(str);
}
template<std::size_t SmallStringSize_v>
@ -426,7 +427,8 @@ constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::operato
template<std::size_t SmallStringSize_v>
constexpr BasicString<SmallStringSize_v> BasicString<SmallStringSize_v>::operator+(Integer_c auto i) const noexcept {
auto const str = ox::itoa(i);
char str[65] = {};
ox::itoa(i, str);
return *this + str;
}

View File

@ -33,6 +33,38 @@ constexpr ox::StringView substr(ox::StringView const&str, std::size_t start, std
return {};
}
template<typename Integer>
constexpr ox::Error writeItoa(Integer v, ox::Writer_c auto &writer) noexcept {
if (v) {
ox::ResizedInt_t<Integer, 64> mod = 1000000000000000000;
ox::ResizedInt_t<Integer, 64> val = v;
constexpr auto base = 10;
auto it = 0;
if (val < 0) {
oxReturnError(writer.put('-'));
++it;
}
while (mod) {
auto digit = val / mod;
val %= mod;
mod /= base;
if (it || digit) {
ox::ResizedInt_t<Integer, 64> start = '0';
if (digit >= 10) {
start = 'a';
digit -= 10;
}
oxReturnError(writer.put(static_cast<char>(start + digit)));
++it;
}
}
} else {
// 0 is a special case
oxReturnError(writer.put('0'));
}
return {};
}
[[nodiscard]]
constexpr bool beginsWith(CRStringView base, CRStringView beginning) noexcept {
const auto beginningLen = ox::min(beginning.len(), base.len());

View File

@ -30,6 +30,7 @@ struct VectorAllocator {
static_assert(alignof(AllocAlias<T>) == alignof(T));
private:
ox::Array<AllocAlias<T>, Size> m_data = {};
Allocator m_allocator;
protected:
constexpr VectorAllocator() noexcept = default;
constexpr VectorAllocator(const VectorAllocator&) noexcept = default;
@ -38,7 +39,7 @@ struct VectorAllocator {
constexpr void allocate(T **items, std::size_t cap) noexcept {
// small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr
if (std::is_constant_evaluated() || cap > Size) {
*items = Allocator{}.allocate(cap);
*items = m_allocator.allocate(cap);
} else {
*items = reinterpret_cast<T*>(m_data.data());
}
@ -86,7 +87,7 @@ struct VectorAllocator {
// small vector optimization cannot be done it constexpr, but it doesn't really matter in constexpr
if (std::is_constant_evaluated()) {
if (items && static_cast<void*>(items) != static_cast<void*>(m_data.data())) {
Allocator{}.deallocate(items, cap);
m_allocator.deallocate(items, cap);
}
}
}
@ -95,13 +96,15 @@ struct VectorAllocator {
template<typename T, typename Allocator>
struct VectorAllocator<T, Allocator, 0> {
private:
Allocator m_allocator;
protected:
constexpr VectorAllocator() noexcept = default;
constexpr VectorAllocator(const VectorAllocator&) noexcept = default;
constexpr VectorAllocator(VectorAllocator&&) noexcept = default;
constexpr void allocate(T **items, std::size_t cap) noexcept {
*items = Allocator{}.allocate(cap);
*items = m_allocator.allocate(cap);
}
[[maybe_unused]]
@ -118,7 +121,7 @@ struct VectorAllocator<T, Allocator, 0> {
constexpr void deallocate(T *items, std::size_t cap) noexcept {
if (items) {
Allocator{}.deallocate(items, cap);
m_allocator.deallocate(items, cap);
}
}

View File

@ -68,6 +68,12 @@ void PaletteEditorImGui::drawColumn(ox::CStringView txt) noexcept {
ImGui::Text("%s", txt.c_str());
}
void PaletteEditorImGui::drawColumn(uint64_t i) noexcept {
ox::Array<char, 10> numStr;
ox::itoa(i, numStr.data());
drawColumn(numStr.data());
}
void PaletteEditorImGui::drawColorsEditor() noexcept {
constexpr auto tableFlags = ImGuiTableFlags_RowBg;
auto const colorsSz = ImGui::GetContentRegionAvail();

View File

@ -33,9 +33,7 @@ class PaletteEditorImGui: public studio::Editor {
private:
static void drawColumn(ox::CStringView txt) noexcept;
static void drawColumn(ox::Integer_c auto i) noexcept {
drawColumn(ox::itoa(i));
}
static void drawColumn(uint64_t i) noexcept;
void drawColorsEditor() noexcept;

View File

@ -8,6 +8,8 @@
#include <ox/std/point.hpp>
#include <keel/media.hpp>
#include "ox/std/buffer.hpp"
#include "ox/std/cstrops.hpp"
#include "tilesheeteditor-imgui.hpp"
namespace nostalgia::core {
@ -410,13 +412,14 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept {
auto const pages = m_model.pal().pages.size();
if (pages > 1) {
ImGui::Indent(20);
auto numStr = ox::itoa(m_model.palettePage() + 1);
ox::Array<char, 10> numStr;
ox::itoa(m_model.palettePage() + 1, numStr.data());
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x - comboWidthSub);
if (ImGui::BeginCombo("Page", numStr.c_str(), 0)) {
if (ImGui::BeginCombo("Page", numStr.data(), 0)) {
for (auto n = 0u; n < pages; ++n) {
auto const selected = (m_model.palettePage() == n);
numStr = ox::itoa(n + 1);
if (ImGui::Selectable(numStr.c_str(), selected) && m_model.palettePage() != n) {
ox::itoa(n + 1, numStr.data());
if (ImGui::Selectable(numStr.data(), selected) && m_model.palettePage() != n) {
m_model.setPalettePage(n);
}
if (selected) {
@ -439,7 +442,9 @@ void TileSheetEditorImGui::drawPaletteSelector() noexcept {
ImGui::PushID(static_cast<int>(i));
// Column: color idx
ImGui::TableNextColumn();
auto const label = ox::itoa(i + 1);
ox::IString<8> label;
ox::CharBuffWriter w(label.data(), label.bytes());
std::ignore = ox::writeItoa(i + 1, w);
auto const rowSelected = i == m_view.palIdx();
if (ImGui::Selectable(label.c_str(), rowSelected, ImGuiSelectableFlags_SpanAllColumns)) {
m_view.setPalIdx(i);