Skip to content

Commit

Permalink
gui: use custom hasher, comparator classes for typeinfo
Browse files Browse the repository at this point in the history
- replace multiple instances of `#ifdef __GLIBCXX__` with a single one by using custom hasher and comparator classes (where the implementations themselves have the ifdefs)

Signed-off-by: Mohamed Gaber <[email protected]>
  • Loading branch information
donn committed Feb 20, 2025
1 parent 930691a commit 45bc7a4
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 22 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ venv/
include/ord/Version.hh

build
build_linux
build_mac
test/results
flow

Expand Down
31 changes: 25 additions & 6 deletions src/gui/include/gui/gui.h
Original file line number Diff line number Diff line change
Expand Up @@ -803,14 +803,33 @@ class Gui
utl::Logger* logger_;
odb::dbDatabase* db_;

// There are RTTI implementation differences between libstdc++ and libc++,
// where the latter seems to generate multiple typeids for classes including
// but not limited to sta::Instance* in different compile units. We have been
// unable to remedy this.
//
// These classes are a workaround such that unless __GLIBCXX__ is set, hashing
// and comparing are done on the type's name instead, which adds a negligible
// performance penalty but has the distinct advantage of not crashing when an
// Instance is clicked in the GUI.
//
// In the event the RTTI issue is ever resolved, the following two structs may
// be removed.
struct TypeInfoHasher
{
std::size_t operator()(const std::type_index& x) const;
};
struct TypeInfoComparator
{
bool operator()(const std::type_index& a, const std::type_index& b) const;
};

// Maps types to descriptors
#ifdef __GLIBCXX__
std::unordered_map<std::type_index, std::unique_ptr<const Descriptor>>
descriptors_;
#else
std::unordered_map<std::string, std::unique_ptr<const Descriptor>>
std::unordered_map<std::type_index,
std::unique_ptr<const Descriptor>,
TypeInfoHasher,
TypeInfoComparator>
descriptors_;
#endif
// Heatmaps
std::set<HeatMapDataSource*> heat_maps_;

Expand Down
37 changes: 21 additions & 16 deletions src/gui/src/gui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -286,11 +286,8 @@ Selected Gui::makeSelected(const std::any& object)
if (!object.has_value()) {
return Selected();
}
#ifdef __GLIBCXX__

auto it = descriptors_.find(object.type());
#else
auto it = descriptors_.find(object.type().name());
#endif
if (it != descriptors_.end()) {
return it->second->makeSelected(object);
}
Expand Down Expand Up @@ -1170,20 +1167,12 @@ void Gui::fit()
void Gui::registerDescriptor(const std::type_info& type,
const Descriptor* descriptor)
{
#ifdef __GLIBCXX__
descriptors_[type] = std::unique_ptr<const Descriptor>(descriptor);
#else
descriptors_[type.name()] = std::unique_ptr<const Descriptor>(descriptor);
#endif
}

const Descriptor* Gui::getDescriptor(const std::type_info& type) const
{
#ifdef __GLIBCXX__
auto find_descriptor = descriptors_.find(type);
#else
auto find_descriptor = descriptors_.find(type.name());
#endif
if (find_descriptor == descriptors_.end()) {
logger_->error(
utl::GUI, 53, "Unable to find descriptor for: {}", type.name());
Expand All @@ -1194,11 +1183,7 @@ const Descriptor* Gui::getDescriptor(const std::type_info& type) const

void Gui::unregisterDescriptor(const std::type_info& type)
{
#ifdef __GLIBCXX__
descriptors_.erase(type);
#else
descriptors_.erase(type.name());
#endif
}

const Selected& Gui::getInspectorSelection()
Expand Down Expand Up @@ -1351,6 +1336,26 @@ void Gui::updateTimingReport()
main_window->getTimingWidget()->populatePaths();
}

// See class header for documentation.
std::size_t Gui::TypeInfoHasher::operator()(const std::type_index& x) const
{
#ifdef __GLIBCXX__
return std::hash<std::type_index>{}(x);
#else
return std::hash<std::string_view>{}(std::string_view(x.name()));
#endif
}
// See class header for documentation.
bool Gui::TypeInfoComparator::operator()(const std::type_index& a,
const std::type_index& b) const
{
#ifdef __GLIBCXX__
return a == b;
#else
return strcmp(a.name(), b.name()) == 0;
#endif
}

class SafeApplication : public QApplication
{
public:
Expand Down

0 comments on commit 45bc7a4

Please sign in to comment.