Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:03

0001 //===- DenseMapInfoVariant.h - Type traits for DenseMap<variant> *- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// This file defines DenseMapInfo traits for DenseMap<std::variant<Ts...>>.
0011 ///
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_ADT_DENSEMAPINFOVARIANT_H
0015 #define LLVM_ADT_DENSEMAPINFOVARIANT_H
0016 
0017 #include "llvm/ADT/DenseMapInfo.h"
0018 #include <utility>
0019 #include <variant>
0020 
0021 namespace llvm {
0022 
0023 // Provide DenseMapInfo for variants whose all alternatives have DenseMapInfo.
0024 template <typename... Ts> struct DenseMapInfo<std::variant<Ts...>> {
0025   using Variant = std::variant<Ts...>;
0026   using FirstT = std::variant_alternative_t<0, Variant>;
0027 
0028   static inline Variant getEmptyKey() {
0029     return Variant(std::in_place_index<0>, DenseMapInfo<FirstT>::getEmptyKey());
0030   }
0031 
0032   static inline Variant getTombstoneKey() {
0033     return Variant(std::in_place_index<0>,
0034                    DenseMapInfo<FirstT>::getTombstoneKey());
0035   }
0036 
0037   static unsigned getHashValue(const Variant &Val) {
0038     return std::visit(
0039         [&Val](auto &&Alternative) {
0040           using T = std::decay_t<decltype(Alternative)>;
0041           // Include index in hash to make sure same value as different
0042           // alternatives don't collide.
0043           return DenseMapInfo<std::pair<size_t, T>>::getHashValuePiecewise(
0044               Val.index(), Alternative);
0045         },
0046         Val);
0047   }
0048 
0049   static bool isEqual(const Variant &LHS, const Variant &RHS) {
0050     if (LHS.index() != RHS.index())
0051       return false;
0052     if (LHS.valueless_by_exception())
0053       return true;
0054     // We want to dispatch to DenseMapInfo<T>::isEqual(LHS.get(I), RHS.get(I))
0055     // We know the types are the same, but std::visit(V, LHS, RHS) doesn't.
0056     // We erase the type held in LHS to void*, and dispatch over RHS.
0057     const void *ErasedLHS =
0058         std::visit([](const auto &LHS) -> const void * { return &LHS; }, LHS);
0059     return std::visit(
0060         [&](const auto &RHS) -> bool {
0061           using T = std::remove_cv_t<std::remove_reference_t<decltype(RHS)>>;
0062           return DenseMapInfo<T>::isEqual(*static_cast<const T *>(ErasedLHS),
0063                                           RHS);
0064         },
0065         RHS);
0066   }
0067 };
0068 
0069 } // end namespace llvm
0070 
0071 #endif // LLVM_ADT_DENSEMAPINFOVARIANT_H