Orange/include/Orange/Core/Parse.h

97 lines
2.2 KiB
C++

#pragma once
#include "Orange/Core/SmallVector.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 CharMatches(char character, StringView delims)
{
for (auto delim : delims)
{
if (character == delim)
return true;
}
return false;
}
inline size_t Consume(const char*& first, StringView delims)
{
size_t count = 0;
while (CharMatches(*first, delims))
{
first++;
count++;
}
return count;
}
inline size_t ConsumeSpace(const char*& first)
{
return Consume(first, " \t");
}
template <typename OutArray = SmallVector<char, 1>>
size_t ReadOrAdvance(const char*& first, StringView delims, size_t advancement = 0, OutArray* array = nullptr)
{
size_t count = 0;
while (!CharMatches(*first, delims) && *first != '\0')
{
if (array)
array->PushBack(*first);
first++;
count++;
}
if (*first == '\0')
return count;
first += advancement;
return count;
}
template <typename OutArray = SmallVector<char, 1>>
size_t ReadString(const char*& first, StringView delims, OutArray& array)
{
return ReadOrAdvance(first, delims, 0, &array);
}
inline size_t AdvancePast(const char*& first, StringView delims)
{
return ReadOrAdvance(first, delims, 1);
}
}