Skip to content

corpus lookup matches template arguments #875

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

Merged
merged 4 commits into from
Feb 28, 2025
Merged
Show file tree
Hide file tree
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
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions include/mrdocs/Support/Error.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class MRDOCS_DECL
A default constructed error is
equivalent to success.
*/
Error() noexcept = delete;
Error() noexcept = default;

/** Constructor.
*/
Expand Down Expand Up @@ -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.
Expand Down
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 (alandefreitas@gmail.com)
//
// 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
Expand Up @@ -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
Expand Down
5 changes: 3 additions & 2 deletions mrdocs.rnc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ grammar
attribute is-anonymous { "1" }?,
Javadoc?,
element using-directive { ID } *,
Scope
Scope*
}

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