Files
TheRock/rocm-systems/projects/rocprofiler-systems/external/dyninst/dataflowAPI/rose/util/BiMap.h
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

136 lines
5.1 KiB
C++

// WARNING: Changes to this file must be contributed back to Sawyer or else they will
// be clobbered by the next update from Sawyer. The Sawyer repository is at
// https://github.com/matzke1/sawyer.
#ifndef Sawyer_BiMap_H
#define Sawyer_BiMap_H
#include "Map.h"
#include "Sawyer.h"
#include <dyncompat/foreach.hpp>
namespace Sawyer {
namespace Container {
/** One-to-one mapping between source and target values.
*
* This container holds a one-to-one mapping from values in a domain to values in a range and can look up values in the
* forward or reverse direction in log time. It does so by consistently maintaining two maps: a forward map and a reverse
* map. The forward map maps values in the domain to values in the range, while the reverse map goes the other direction. The
* @ref forward and @ref reverse methods return const references to these maps. The BiMap container provides methods for
* modifying the mapping. */
template<class S, class T>
class BiMap {
public:
typedef S Source; /**< Type of values in the domain. */
typedef T Target; /**< Type of values in the range. */
typedef Sawyer::Container::Map<Source, Target> Forward; /**< Type for domain-to-range map. */
typedef Sawyer::Container::Map<Target, Source> Reverse; /**< Type for range-to-domain map. */
private:
Forward forward_;
Reverse reverse_;
public:
/** Default constructor.
*
* Constructs an empty mapping. */
BiMap() {}
/** Copy constructor. */
BiMap(const BiMap &other);
/** Construct a new map by composition of two maps.
*
* Given two BiMap objects where the range type of the first is the domain type of the second, construct a new BiMap
* from the domain of the first to the range of the second. The new map will contain only those domain/range pairs that
* map across both input maps. */
template<class U>
BiMap(const BiMap<Source, U> &a, const BiMap<U, Target> &b) {
DYN_FOREACH (const typename Forward::Node &anode, a.forward_.nodes()) {
if (b.forward_.exists(anode.value())) {
const Target &target = b.forward_[anode.value()];
forward_.insert(anode.key(), target);
reverse_.insert(target, anode.key());
}
}
}
/** Erase all mappings.
*
* This results in a map whose state is the same as a default-constructed BiMap. */
void clear() {
forward_.clear();
reverse_.clear();
}
/** Erase domain value and its associated range value.
*
* If @p source exists in this map's domain, then it is removed along with the corresponding value in the range. Otherwise
* the map is not modified. Returns true if the map was modified, false if not. */
bool eraseSource(const Source &source) {
if (!forward_.exists(source))
return false;
reverse_.erase(forward_[source]);
forward_.erase(source);
return true;
}
/** Erase range value and its associated domain value.
*
* If @p target exists in this map's range, then it is removed along with the corresponding value in the domain. Otherwise
* the map is not modified. Returns true if the map was modified, false if not. */
bool eraseTarget(const Target &target) {
if (!reverse_.exists(target))
return false;
forward_.erase(reverse_[target]);
reverse_.erase(target);
return true;
}
/** Erase a specific map entry.
*
* Erases the 1:1 mapping between @p source and @p target if present. This is a no-op unless @p source is a member of the
* domain and @p target is a member of the range and @p source maps to @p target (and vice versa). Returns true if the map
* was modified, false if not. */
bool erase(const Source &source, const Target &target) {
if (!forward_.exists(source) || forward_[source]!=target)
return false;
forward_.erase(source);
reverse_.erase(target);
return true;
}
/** Insert a new mapping.
*
* Creates a new mapping from @p source in the domain to @p target in the range. If @p source is already a member of the
* domain then it is first erased along with its corresponding value in the range; likewise, if @p target is already a
* member of the range then it is first erased along with its corresponding value in the domain. */
void insert(const Source &source, const Target &target) {
eraseSource(source);
eraseTarget(target);
forward_.insert(source, target);
reverse_.insert(target, source);
}
/** Return forward mapping.
*
* The keys of the forward map are values in the domain, and its values are in the range. */
const Forward& forward() const {
return forward_;
}
/** Return reverse mapping.
*
* The keys of the reverse map are values in the range, and its values are in the domain. */
const Reverse& reverse() const {
return reverse_;
}
};
} // namespace
} // namespace
#endif