|  | // 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_ |