summaryrefslogtreecommitdiff
path: root/gn/tools/gn/label_ptr.h
diff options
context:
space:
mode:
Diffstat (limited to 'gn/tools/gn/label_ptr.h')
-rw-r--r--gn/tools/gn/label_ptr.h116
1 files changed, 116 insertions, 0 deletions
diff --git a/gn/tools/gn/label_ptr.h b/gn/tools/gn/label_ptr.h
new file mode 100644
index 00000000000..5aaa02d5c91
--- /dev/null
+++ b/gn/tools/gn/label_ptr.h
@@ -0,0 +1,116 @@
+// Copyright (c) 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TOOLS_GN_LABEL_PTR_H_
+#define TOOLS_GN_LABEL_PTR_H_
+
+#include <stddef.h>
+
+#include <functional>
+
+#include "tools/gn/label.h"
+
+class Config;
+class ParseNode;
+class Target;
+
+// Structure that holds a labeled "thing". This is used for various places
+// where we need to store lists of targets or configs. We sometimes populate
+// the pointers on another thread from where we compute the labels, so this
+// structure lets us save them separately. This also allows us to store the
+// location of the thing that added this dependency.
+template <typename T>
+struct LabelPtrPair {
+ typedef T DestType;
+
+ LabelPtrPair() : label(), ptr(nullptr), origin(nullptr) {}
+
+ explicit LabelPtrPair(const Label& l)
+ : label(l), ptr(nullptr), origin(nullptr) {}
+
+ // This contructor is typically used in unit tests, it extracts the label
+ // automatically from a given pointer.
+ explicit LabelPtrPair(const T* p)
+ : label(p->label()), ptr(p), origin(nullptr) {}
+
+ ~LabelPtrPair() {}
+
+ Label label;
+ const T* ptr; // May be NULL.
+
+ // The origin of this dependency. This will be null for internally generated
+ // dependencies. This happens when a group is automatically expanded and that
+ // group's members are added to the target that depends on that group.
+ const ParseNode* origin;
+};
+
+typedef LabelPtrPair<Config> LabelConfigPair;
+typedef LabelPtrPair<Target> LabelTargetPair;
+
+typedef std::vector<LabelConfigPair> LabelConfigVector;
+typedef std::vector<LabelTargetPair> LabelTargetVector;
+
+// Comparison and search functions ---------------------------------------------
+
+// To do a brute-force search by label:
+// std::find_if(vect.begin(), vect.end(), LabelPtrLabelEquals<Config>(label));
+template <typename T>
+struct LabelPtrLabelEquals {
+ explicit LabelPtrLabelEquals(const Label& l) : label(l) {}
+
+ bool operator()(const LabelPtrPair<T>& arg) const {
+ return arg.label == label;
+ }
+
+ const Label& label;
+};
+
+// To do a brute-force search by object pointer:
+// std::find_if(vect.begin(), vect.end(), LabelPtrPtrEquals<Config>(config));
+template <typename T>
+struct LabelPtrPtrEquals {
+ explicit LabelPtrPtrEquals(const T* p) : ptr(p) {}
+
+ bool operator()(const LabelPtrPair<T>& arg) const { return arg.ptr == ptr; }
+
+ const T* ptr;
+};
+
+// To sort by label:
+// std::sort(vect.begin(), vect.end(), LabelPtrLabelLess<Config>());
+template <typename T>
+struct LabelPtrLabelLess {
+ bool operator()(const LabelPtrPair<T>& a, const LabelPtrPair<T>& b) const {
+ return a.label < b.label;
+ }
+};
+
+// Default comparison operators -----------------------------------------------
+//
+// The default hash and comparison operators operate on the label, which should
+// always be valid, whereas the pointer is sometimes null.
+
+template <typename T>
+inline bool operator==(const LabelPtrPair<T>& a, const LabelPtrPair<T>& b) {
+ return a.label == b.label;
+}
+
+template <typename T>
+inline bool operator<(const LabelPtrPair<T>& a, const LabelPtrPair<T>& b) {
+ return a.label < b.label;
+}
+
+namespace std {
+
+template <typename T>
+struct hash<LabelPtrPair<T>> {
+ std::size_t operator()(const LabelPtrPair<T>& v) const {
+ hash<Label> h;
+ return h(v.label);
+ }
+};
+
+} // namespace std
+
+#endif // TOOLS_GN_LABEL_PTR_H_