Skip to content

Commit ed78539

Browse files
committed
Corpus ordered traverse
#feat
1 parent 9edf3ab commit ed78539

File tree

3 files changed

+143
-14
lines changed

3 files changed

+143
-14
lines changed

include/mrdocs/Corpus.hpp

Lines changed: 77 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77
// Copyright (c) 2023 Vinnie Falco ([email protected])
88
// Copyright (c) 2023 Krystian Stasiowski ([email protected])
9+
// Copyright (c) 2024 Alan de Freitas ([email protected])
910
//
1011
// Official repository: https://github.com/cppalliance/mrdocs
1112
//
@@ -160,6 +161,32 @@ class MRDOCS_VISIBLE
160161
}
161162
}
162163

164+
/** Visit the members of specified Info in a stable order.
165+
166+
@param I The Info to visit.
167+
@param info The Info to visit.
168+
@param f The function to invoke.
169+
@param args The arguments to pass to the function.
170+
*/
171+
template <InfoParent T, class F, class... Args>
172+
void
173+
orderedTraverse(
174+
T const& I, F&& f, Args&&... args) const
175+
{
176+
std::vector<SymbolID> members(I.Members.begin(), I.Members.end());
177+
std::stable_sort(members.begin(), members.end(), [this](SymbolID const& lhs, SymbolID const& rhs)
178+
{
179+
auto const& lhsInfo = get(lhs);
180+
auto const& rhsInfo = get(rhs);
181+
return lhsInfo < rhsInfo;
182+
});
183+
for (auto const& id : members)
184+
{
185+
visit(get(id), std::forward<F>(f),
186+
std::forward<Args>(args)...);
187+
}
188+
}
189+
163190
/** Visit the member overloads of specified ScopeInfo.
164191
165192
This function iterates the members of the
@@ -184,6 +211,14 @@ class MRDOCS_VISIBLE
184211
F&& f,
185212
Args&&... args) const;
186213

214+
/** Visit the member overloads of specified ScopeInfo in stable order
215+
*/
216+
template <class F, class... Args>
217+
void orderedTraverseOverloads(
218+
ScopeInfo const& S,
219+
F&& f,
220+
Args&&... args) const;
221+
187222
//--------------------------------------------
188223

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

239274
template <class F, class... Args>
240275
void
241-
Corpus::
242-
traverseOverloads(
276+
traverseOverloadsImpl(
277+
Corpus const& c,
278+
std::vector<SymbolID> const& members0,
243279
ScopeInfo const& S,
244-
F&& f, Args&&... args) const
280+
F&& f, Args&&... args)
245281
{
246-
MRDOCS_ASSERT(S.Members.empty() == S.Lookups.empty());
247-
for(const SymbolID& id : S.Members)
282+
for(const SymbolID& id : members0)
248283
{
249-
const Info& member = get(id);
284+
const Info& member = c.get(id);
250285
const auto& members = S.Lookups.at(member.Name);
251286
auto first_func = std::ranges::find_if(
252-
members, [this](const SymbolID& elem)
287+
members, [&c](const SymbolID& elem)
253288
{
254-
#if 0
255-
const Info& I = get(elem);
256-
return I.isFunction() || I.isGuide();
257-
#else
258-
return get(elem).isFunction();
259-
#endif
289+
return c.get(elem).isFunction();
260290
});
261291
bool const nonOverloadedFunction = members.size() == 1;
262292
bool const notFunction = first_func == members.end();
@@ -278,6 +308,40 @@ traverseOverloads(
278308
}
279309
}
280310

311+
template <class F, class... Args>
312+
void
313+
Corpus::
314+
traverseOverloads(
315+
ScopeInfo const& S,
316+
F&& f, Args&&... args) const
317+
{
318+
MRDOCS_ASSERT(S.Members.empty() == S.Lookups.empty());
319+
return traverseOverloadsImpl(
320+
*this, S.Members, S, std::forward<F>(f), std::forward<Args>(args)...);
321+
322+
}
323+
324+
template <class F, class... Args>
325+
void
326+
Corpus::
327+
orderedTraverseOverloads(
328+
ScopeInfo const& S,
329+
F&& f,
330+
Args&&... args) const
331+
{
332+
MRDOCS_ASSERT(S.Members.empty() == S.Lookups.empty());
333+
std::vector<SymbolID> members(S.Members.begin(), S.Members.end());
334+
std::stable_sort(members.begin(), members.end(), [this](SymbolID const& lhs, SymbolID const& rhs)
335+
{
336+
auto const& lhsInfo = get(lhs);
337+
auto const& rhsInfo = get(rhs);
338+
return lhsInfo < rhsInfo;
339+
});
340+
return traverseOverloadsImpl(
341+
*this, members, S, std::forward<F>(f), std::forward<Args>(args)...);
342+
}
343+
344+
281345
class Corpus::iterator
282346
{
283347
const Corpus* corpus_;

src/lib/Lib/CorpusImpl.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77
// Copyright (c) 2023 Vinnie Falco ([email protected])
88
// Copyright (c) 2023 Krystian Stasiowski ([email protected])
9+
// Copyright (c) 2024 Alan de Freitas ([email protected])
910
//
1011
// Official repository: https://github.com/cppalliance/mrdocs
1112
//
@@ -18,7 +19,7 @@
1819
#include "lib/Support/Chrono.hpp"
1920
#include <mrdocs/Metadata.hpp>
2021
#include <mrdocs/Support/Error.hpp>
21-
#include <llvm/ADT/STLExtras.h>
22+
#include <mrdocs/Support/ThreadPool.hpp>
2223
#include <chrono>
2324

2425
namespace clang {

src/lib/Metadata/Info.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,70 @@ tag_invoke(
287287
});
288288
}
289289

290+
bool
291+
operator<(
292+
Info const& lhs,
293+
Info const& rhs) noexcept
294+
{
295+
if (lhs.Kind != rhs.Kind)
296+
{
297+
return lhs.Kind < rhs.Kind;
298+
}
299+
if (lhs.Name != rhs.Name)
300+
{
301+
return lhs.Name < rhs.Name;
302+
}
303+
304+
// If kind and name are the same, compare by template arguments
305+
TemplateInfo const* lhsTemplate = visit(lhs, [](auto const& U)
306+
-> TemplateInfo const*
307+
{
308+
if constexpr (requires { U.Template; })
309+
{
310+
if (U.Template)
311+
{
312+
return &*U.Template;
313+
}
314+
}
315+
return nullptr;
316+
});
317+
TemplateInfo const* rhsTemplate = visit(rhs, [](auto const& U)
318+
-> TemplateInfo const*
319+
{
320+
if constexpr (requires { U.Template; })
321+
{
322+
if (U.Template)
323+
{
324+
return &*U.Template;
325+
}
326+
}
327+
return nullptr;
328+
});
329+
if (!lhsTemplate && !rhsTemplate)
330+
{
331+
return false;
332+
}
333+
if (!lhsTemplate)
334+
{
335+
return true;
336+
}
337+
if (!rhsTemplate)
338+
{
339+
return false;
340+
}
341+
if (lhsTemplate->Args.size() != rhsTemplate->Args.size())
342+
{
343+
return lhsTemplate->Args.size() < rhsTemplate->Args.size();
344+
}
345+
for (std::size_t i = 0; i < lhsTemplate->Args.size(); ++i)
346+
{
347+
if (lhsTemplate->Args[i] != rhsTemplate->Args[i])
348+
{
349+
return lhsTemplate->Args[i]->Kind < rhsTemplate->Args[i]->Kind;
350+
}
351+
}
352+
return false;
353+
}
290354

291355
} // mrdocs
292356
} // clang

0 commit comments

Comments
 (0)