#pragma once #include "Orange/Core/Vector.h" #include #include #include #include namespace orange::stream { template Result Parse(const char*& first, const char* end) { T obj; auto result = std::from_chars(first, end, obj); if (result.ec == std::errc{}) { first = result.ptr; return Result::Success(obj); } return Result::Error(BasicErrorCode::NotFound); } template Result Parse(const char*& first, size_t length) { return Parse(first, first + length); } template Result Parse(const char*& first) { return Parse(first, first + strlen(first)); } inline bool EndOfStream(const char* first, const char* end) { return first == end || *first == '\0'; } inline bool CharMatches(char character, StringView delims) { for (auto delim : delims) { if (character == delim) return true; } return false; } inline size_t Consume(const char*& first, const char* end, StringView delims) { size_t count = 0; while (!EndOfStream(first, end) && CharMatches(*first, delims)) { first++; count++; } return count; } inline size_t ConsumeSpace(const char*& first, const char* end) { return Consume(first, end, " \t"); } inline size_t ConsumeSpaceAndNewLine(const char*& first, const char* end) { return Consume(first, end, " \t\r\n"); } template > size_t ReadOrAdvance(const char*& first, const char* end, StringView delims, size_t advancement = 0, OutArray* array = nullptr) { size_t count = 0; while (!EndOfStream(first, end) && !CharMatches(*first, delims)) { if (array) array->push_back(*first); first++; count++; } if (EndOfStream(first, end)) return count; first += advancement; return count; } template > size_t ReadString(const char*& first, const char* end, StringView delims, OutArray& array) { return ReadOrAdvance(first, end, delims, 0, &array); } inline size_t AdvancePast(const char*& first, const char* end, StringView delims) { return ReadOrAdvance(first, end, delims, 1); } inline bool IsStringToken(StringView fullRange, const char* first) { if (*first != '"') return false; // Make sure we are in-range for the checks below. if (fullRange.begin() == first || fullRange.begin() == first - 1) return true; // Handle \\" if (*(first - 2) == '\\') return true; // Hanle \" if (*(first - 1) == '\\') return false; return true; } inline bool IsCPPComment(StringView fullRange, const char* first) { if (*first != '/') return false; if (fullRange.end() == first + 1) return false; if (*(first + 1) != '/') return false; return true; } }