102 lines
2.4 KiB
C++
102 lines
2.4 KiB
C++
#pragma once
|
|
|
|
#include "Orange/Core/Array.h"
|
|
#include <Orange/Core/Result.h>
|
|
#include <Orange/Core/Span.h>
|
|
|
|
#include <charconv>
|
|
#include <string.h>
|
|
|
|
namespace orange::stream
|
|
{
|
|
template <typename T>
|
|
Result<T> 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<T>::Success(obj);
|
|
}
|
|
|
|
return Result<T>::Error(BasicErrorCode::NotFound);
|
|
}
|
|
|
|
template <typename T>
|
|
Result<T> Parse(const char*& first, size_t length)
|
|
{
|
|
return Parse<T>(first, first + length);
|
|
}
|
|
|
|
template <typename T>
|
|
Result<T> Parse(const char*& first)
|
|
{
|
|
return Parse<T>(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");
|
|
}
|
|
|
|
template <typename OutArray = SmallArray<char, 1>>
|
|
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->PushBack(*first);
|
|
first++;
|
|
count++;
|
|
}
|
|
|
|
if (EndOfStream(first, end))
|
|
return count;
|
|
|
|
first += advancement;
|
|
|
|
return count;
|
|
}
|
|
|
|
template <typename OutArray = SmallArray<char, 1>>
|
|
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);
|
|
}
|
|
}
|