Skip to content

Commit

Permalink
Corpus ordered traverse
Browse files Browse the repository at this point in the history
#feat
  • Loading branch information
alandefreitas committed Jan 2, 2025
1 parent 9edf3ab commit ed78539
Show file tree
Hide file tree
Showing 3 changed files with 143 additions and 14 deletions.
90 changes: 77 additions & 13 deletions include/mrdocs/Corpus.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//
// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
// Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com)
// Copyright (c) 2024 Alan de Freitas (alandefreitas@gmail.com)
//
// Official repository: https://github.com/cppalliance/mrdocs
//
Expand Down Expand Up @@ -160,6 +161,32 @@ class MRDOCS_VISIBLE
}
}

/** Visit the members of specified Info in a stable order.
@param I The Info to visit.
@param info The Info to visit.
@param f The function to invoke.
@param args The arguments to pass to the function.
*/
template <InfoParent T, class F, class... Args>
void
orderedTraverse(
T const& I, F&& f, Args&&... args) const
{
std::vector<SymbolID> members(I.Members.begin(), I.Members.end());
std::stable_sort(members.begin(), members.end(), [this](SymbolID const& lhs, SymbolID const& rhs)
{
auto const& lhsInfo = get(lhs);
auto const& rhsInfo = get(rhs);
return lhsInfo < rhsInfo;
});
for (auto const& id : members)
{
visit(get(id), std::forward<F>(f),
std::forward<Args>(args)...);
}
}

/** Visit the member overloads of specified ScopeInfo.
This function iterates the members of the
Expand All @@ -184,6 +211,14 @@ class MRDOCS_VISIBLE
F&& f,
Args&&... args) const;

/** Visit the member overloads of specified ScopeInfo in stable order
*/
template <class F, class... Args>
void orderedTraverseOverloads(
ScopeInfo const& S,
F&& f,
Args&&... args) const;

//--------------------------------------------

/** Return the fully qualified name of the specified Info.
Expand Down Expand Up @@ -238,25 +273,20 @@ get(

template <class F, class... Args>
void
Corpus::
traverseOverloads(
traverseOverloadsImpl(
Corpus const& c,
std::vector<SymbolID> const& members0,
ScopeInfo const& S,
F&& f, Args&&... args) const
F&& f, Args&&... args)
{
MRDOCS_ASSERT(S.Members.empty() == S.Lookups.empty());
for(const SymbolID& id : S.Members)
for(const SymbolID& id : members0)
{
const Info& member = get(id);
const Info& member = c.get(id);
const auto& members = S.Lookups.at(member.Name);
auto first_func = std::ranges::find_if(
members, [this](const SymbolID& elem)
members, [&c](const SymbolID& elem)
{
#if 0
const Info& I = get(elem);
return I.isFunction() || I.isGuide();
#else
return get(elem).isFunction();
#endif
return c.get(elem).isFunction();
});
bool const nonOverloadedFunction = members.size() == 1;
bool const notFunction = first_func == members.end();
Expand All @@ -278,6 +308,40 @@ traverseOverloads(
}
}

template <class F, class... Args>
void
Corpus::
traverseOverloads(
ScopeInfo const& S,
F&& f, Args&&... args) const
{
MRDOCS_ASSERT(S.Members.empty() == S.Lookups.empty());
return traverseOverloadsImpl(
*this, S.Members, S, std::forward<F>(f), std::forward<Args>(args)...);

}

template <class F, class... Args>
void
Corpus::
orderedTraverseOverloads(
ScopeInfo const& S,
F&& f,
Args&&... args) const
{
MRDOCS_ASSERT(S.Members.empty() == S.Lookups.empty());
std::vector<SymbolID> members(S.Members.begin(), S.Members.end());
std::stable_sort(members.begin(), members.end(), [this](SymbolID const& lhs, SymbolID const& rhs)
{
auto const& lhsInfo = get(lhs);
auto const& rhsInfo = get(rhs);
return lhsInfo < rhsInfo;
});
return traverseOverloadsImpl(
*this, members, S, std::forward<F>(f), std::forward<Args>(args)...);
}


class Corpus::iterator
{
const Corpus* corpus_;
Expand Down
3 changes: 2 additions & 1 deletion src/lib/Lib/CorpusImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
//
// Copyright (c) 2023 Vinnie Falco (vinnie.falco@gmail.com)
// Copyright (c) 2023 Krystian Stasiowski (sdkrystian@gmail.com)
// Copyright (c) 2024 Alan de Freitas (alandefreitas@gmail.com)
//
// Official repository: https://github.com/cppalliance/mrdocs
//
Expand All @@ -18,7 +19,7 @@
#include "lib/Support/Chrono.hpp"
#include <mrdocs/Metadata.hpp>
#include <mrdocs/Support/Error.hpp>
#include <llvm/ADT/STLExtras.h>
#include <mrdocs/Support/ThreadPool.hpp>
#include <chrono>

namespace clang {
Expand Down
64 changes: 64 additions & 0 deletions src/lib/Metadata/Info.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,70 @@ tag_invoke(
});
}

bool
operator<(
Info const& lhs,
Info const& rhs) noexcept
{
if (lhs.Kind != rhs.Kind)
{
return lhs.Kind < rhs.Kind;
}
if (lhs.Name != rhs.Name)
{
return lhs.Name < rhs.Name;
}

// If kind and name are the same, compare by template arguments
TemplateInfo const* lhsTemplate = visit(lhs, [](auto const& U)
-> TemplateInfo const*
{
if constexpr (requires { U.Template; })
{
if (U.Template)
{
return &*U.Template;
}
}
return nullptr;
});
TemplateInfo const* rhsTemplate = visit(rhs, [](auto const& U)
-> TemplateInfo const*
{
if constexpr (requires { U.Template; })
{
if (U.Template)
{
return &*U.Template;
}
}
return nullptr;
});
if (!lhsTemplate && !rhsTemplate)
{
return false;
}
if (!lhsTemplate)
{
return true;
}
if (!rhsTemplate)
{
return false;
}
if (lhsTemplate->Args.size() != rhsTemplate->Args.size())
{
return lhsTemplate->Args.size() < rhsTemplate->Args.size();
}
for (std::size_t i = 0; i < lhsTemplate->Args.size(); ++i)
{
if (lhsTemplate->Args[i] != rhsTemplate->Args[i])
{
return lhsTemplate->Args[i]->Kind < rhsTemplate->Args[i]->Kind;
}
}
return false;
}

} // mrdocs
} // clang

0 comments on commit ed78539

Please # to comment.