led_ctrl/include/toml11/impl/literal_impl.hpp
2025-06-05 01:03:12 +00:00

179 lines
5.0 KiB
C++

#ifndef TOML11_LITERAL_IMPL_HPP
#define TOML11_LITERAL_IMPL_HPP
#include "../fwd/literal_fwd.hpp"
#include "../parser.hpp"
#include "../syntax.hpp"
#include "../version.hpp"
namespace toml
{
inline namespace TOML11_INLINE_VERSION_NAMESPACE
{
namespace detail
{
// implementation
TOML11_INLINE ::toml::value literal_internal_impl(location loc)
{
const auto s = ::toml::spec::default_version();
context<type_config> ctx(s);
const auto front = loc;
// ------------------------------------------------------------------------
// check if it is a raw value.
// skip empty lines and comment lines
auto sp = skip_multiline_spacer(loc, ctx);
if(loc.eof())
{
::toml::value val;
if(sp.has_value())
{
for(std::size_t i=0; i<sp.value().comments.size(); ++i)
{
val.comments().push_back(std::move(sp.value().comments.at(i)));
}
}
return val;
}
// to distinguish arrays and tables, first check it is a table or not.
//
// "[1,2,3]"_toml; // json: [1, 2, 3]
// "[table]"_toml; // json: {"table": {}}
// "[[1,2,3]]"_toml; // json: [[1, 2, 3]]
// "[[table]]"_toml; // json: {"table": [{}]}
//
// "[[1]]"_toml; // json: {"1": [{}]}
// "1 = [{}]"_toml; // json: {"1": [{}]}
// "[[1,]]"_toml; // json: [[1]]
// "[[1],]"_toml; // json: [[1]]
const auto val_start = loc;
const bool is_table_key = syntax::std_table(s).scan(loc).is_ok();
loc = val_start;
const bool is_aots_key = syntax::array_table(s).scan(loc).is_ok();
loc = val_start;
// If it is neither a table-key or a array-of-table-key, it may be a value.
if(!is_table_key && !is_aots_key)
{
auto data = parse_value(loc, ctx);
if(data.is_ok())
{
auto val = std::move(data.unwrap());
if(sp.has_value())
{
for(std::size_t i=0; i<sp.value().comments.size(); ++i)
{
val.comments().push_back(std::move(sp.value().comments.at(i)));
}
}
auto com_res = parse_comment_line(loc, ctx);
if(com_res.is_ok() && com_res.unwrap().has_value())
{
val.comments().push_back(com_res.unwrap().value());
}
return val;
}
}
// -------------------------------------------------------------------------
// Note that still it can be a table, because the literal might be something
// like the following.
// ```cpp
// // c++11 raw-string literal
// const auto val = R"(
// key = "value"
// int = 42
// )"_toml;
// ```
// It is a valid toml file.
// It should be parsed as if we parse a file with this content.
loc = front;
auto data = parse_file(loc, ctx);
if(data.is_ok())
{
return data.unwrap();
}
else // not a value && not a file. error.
{
std::string msg;
for(const auto& err : data.unwrap_err())
{
msg += format_error(err);
}
throw ::toml::syntax_error(std::move(msg), std::move(data.unwrap_err()));
}
}
} // detail
inline namespace literals
{
inline namespace toml_literals
{
TOML11_INLINE ::toml::value
operator""_toml(const char* str, std::size_t len)
{
if(len == 0)
{
return ::toml::value{};
}
::toml::detail::location::container_type c(len);
std::copy(reinterpret_cast<const ::toml::detail::location::char_type*>(str),
reinterpret_cast<const ::toml::detail::location::char_type*>(str + len),
c.begin());
if( ! c.empty() && c.back())
{
c.push_back('\n'); // to make it easy to parse comment, we add newline
}
return literal_internal_impl(::toml::detail::location(
std::make_shared<const toml::detail::location::container_type>(std::move(c)),
"TOML literal encoded in a C++ code"));
}
#if defined(__cpp_char8_t)
# if __cpp_char8_t >= 201811L
# define TOML11_HAS_CHAR8_T 1
# endif
#endif
#if defined(TOML11_HAS_CHAR8_T)
// value of u8"" literal has been changed from char to char8_t and char8_t is
// NOT compatible to char
TOML11_INLINE ::toml::value
operator"" _toml(const char8_t* str, std::size_t len)
{
if(len == 0)
{
return ::toml::value{};
}
::toml::detail::location::container_type c(len);
std::copy(reinterpret_cast<const ::toml::detail::location::char_type*>(str),
reinterpret_cast<const ::toml::detail::location::char_type*>(str + len),
c.begin());
if( ! c.empty() && c.back())
{
c.push_back('\n'); // to make it easy to parse comment, we add newline
}
return literal_internal_impl(::toml::detail::location(
std::make_shared<const toml::detail::location::container_type>(std::move(c)),
"TOML literal encoded in a C++ code"));
}
#endif
} // toml_literals
} // literals
} // TOML11_INLINE_VERSION_NAMESPACE
} // toml
#endif // TOML11_LITERAL_IMPL_HPP