Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

corpus lookup matches template arguments #875

Merged
merged 4 commits into from
Feb 28, 2025
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion include/mrdocs/Metadata/Template.hpp
Original file line number Diff line number Diff line change
@@ -34,7 +34,9 @@ enum class TArgKind : int
Template
};

MRDOCS_DECL std::string_view toString(TArgKind kind) noexcept;
MRDOCS_DECL
std::string_view
toString(TArgKind kind) noexcept;

inline
void
4 changes: 2 additions & 2 deletions include/mrdocs/Support/Error.hpp
Original file line number Diff line number Diff line change
@@ -53,7 +53,7 @@ class MRDOCS_DECL
A default constructed error is
equivalent to success.
*/
Error() noexcept = delete;
Error() noexcept = default;

/** Constructor.
*/
@@ -122,7 +122,7 @@ class MRDOCS_DECL
constexpr bool
failed() const noexcept
{
return ! message_.empty();
return !message_.empty();
}

/** Return true if this holds an error.
150 changes: 150 additions & 0 deletions include/mrdocs/Support/Parse.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
//
// Licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// Copyright (c) 2025 Alan de Freitas ([email protected])
//
// Official repository: https://github.com/cppalliance/mrdocs
//

#ifndef MRDOCS_API_SUPPORT_PARSE_HPP
#define MRDOCS_API_SUPPORT_PARSE_HPP

#include <mrdocs/Support/Error.hpp>
#include <mrdocs/Support/Expected.hpp>

namespace clang::mrdocs {

/** The result of a parse operation.
This class holds the result of a parse operation.
The structure is similar to `std::from_chars_result`,
where we have a `ptr` member that points to the
first character not parsed, and a `ec` member that
holds the error code.
If parsing was successful, then `ec` stores
a default constructed `Error` object, which
indicates success. The `operator bool` can
also be used to check for success.
The typical format of a parsing function is:
@code
ParseResult
parseType(
char const* first,
char const* last,
Type& value);
@endcode
where more parameters can be defined as needed for
parsing options.
*/
struct ParseResult {
const char* ptr;
Error ec;

friend
bool
operator==(
const ParseResult&,
const ParseResult& ) = default;

constexpr
explicit
operator bool() const noexcept
{
return !ec.failed();
}
};

/** Concept to determine if there's a parse function for a type.
This concept checks if a type `T` has a parse function
with the signature:
@code
ParseResult
parse(
char const* first,
char const* last,
T& value);
@endcode
*/
template <class T>
concept HasParse = requires(
char const* first,
char const* last,
T& value)
{
{ parse(first, last, value) } -> std::same_as<ParseResult>;
};

/** Parse a string view
This function parses a string view `sv` into a value
of type `T`. The function calls the `parse` function
for the type `T` with the `sv.data()` and `sv.data() + sv.size()`
as the first and last pointers, respectively.
If the parse function returns an error, then the function
returns the error.
If the parse function returns success, but there are
characters left in the string view, then the function
returns an error with the message "trailing characters".
Otherwise, it returns the value.
@param sv The string view to parse
@param value The value to store the result
*/
template <HasParse T>
ParseResult
parse(std::string_view sv, T& value)
{
ParseResult result = parse(sv.data(), sv.data() + sv.size(), value);
if (result)
{
if (result.ptr != sv.data() + sv.size())
{
result.ec = Error("trailing characters");
}
}
return result;
}

/** Parse a string view
Parse a string view `sv` as an object of type `T`.
If parsing fails, the function returns an error.
This overload does not return the `ParseResult` object
containing the pointer to the first character not parsed.
Instead, the position of the error is calculated and
the error message is formatted with the error position.
@copydetails parse(std::string_view, T&)
*/
template <HasParse T>
Expected<T>
parse(std::string_view sv)
{
T v;
ParseResult const result = parse(sv, v);
if (result)
{
return v;
}
std::size_t const pos = result.ptr - sv.data();
return Unexpected(formatError(
"'{}' at position {}: {}",
sv, pos, result.ec.reason()));
}

} // clang::mrdocs

#endif
9 changes: 9 additions & 0 deletions include/mrdocs/Support/String.hpp
Original file line number Diff line number Diff line change
@@ -77,6 +77,15 @@ MRDOCS_DECL
void
replace(std::string& s, std::string_view from, std::string_view to);

/** Determine if a string is only whitespace.
*/
constexpr
bool
isWhitespace(std::string_view s) noexcept
{
return s.find_first_not_of(" \t\n\v\f\r") == std::string::npos;
}


} // mrdocs
} // clang
5 changes: 3 additions & 2 deletions mrdocs.rnc
Original file line number Diff line number Diff line change
@@ -37,7 +37,7 @@ grammar
attribute is-anonymous { "1" }?,
Javadoc?,
element using-directive { ID } *,
Scope
Scope*
}

#---------------------------------------------
@@ -153,7 +153,8 @@ grammar
Name,
ID,
Location *,
TypeInfo
TypeInfo,
Javadoc ?
} |
element typedef
{
Loading