// See the file "COPYING" in the main distribution directory for copyright. // C++ compiler helper class that tracks distinct instances of a given key, // where the key can have any IntrusivePtr type. The properties of a // tracker are that it (1) supports a notion that two technically distinct // keys in fact reflect the same underlying object, (2) provides an // instance of such keys to consistently serve as their "representative", and // (3) provides names (suitable for use as C++ variables) for representative // keys. // // Notions of "same" are taken from hash values ala those provided by // ProfileFunc. #pragma once #include "zeek/script_opt/CPP/InitsInfo.h" namespace zeek::detail { // T is a type that has an IntrusivePtr instantiation. template class CPPTracker { public: // The base name is used to construct key names. "single_global", // if true, specifies that the names should be constructed as // indexes into a single global, rather than as distinct globals. CPPTracker(const char* _base_name, bool _single_global) : base_name(_base_name), single_global(_single_global) { } // True if the given key has already been entered. bool HasKey(const T* key) const { return map.count(key) > 0; } bool HasKey(IntrusivePtr key) const { return HasKey(key.get()); } // Only adds the key if it's not already present. If a hash // is provided, then refrains from computing it. void AddKey(IntrusivePtr key, p_hash_type h = 0); void AddInitInfo(const T* rep, std::shared_ptr gi) { gi_s[rep] = std::move(gi); } // Returns the (C++ variable) name associated with the given key. std::string KeyName(const T* key); std::string KeyName(IntrusivePtr key) { return KeyName(key.get()); } // Returns all of the distinct keys entered into the tracker. // A key is "distinct" if it's a representative. const std::vector>& DistinctKeys() const { return keys; } // For a given key, get its representative. const T* GetRep(const T* key) { ASSERT(HasKey(key)); return reps[map[key]]; } const T* GetRep(IntrusivePtr key) { return GetRep(key.get()); } private: // Compute a hash for the given key. p_hash_type Hash(IntrusivePtr key) const; // Maps keys to internal representations (i.e., hashes). std::unordered_map map; std::unordered_map> gi_s; // Maps internal representations to distinct values. std::unordered_map map2; // Tracks the set of distinct keys, to facilitate iterating over them. // Each such key also has an entry in map2. std::vector> keys; // Maps internal representations back to keys. std::unordered_map reps; // Used to construct key names. std::string base_name; // Whether to base the names out of a single global, or distinct // globals. bool single_global; }; } // zeek::detail