#ifndef TOOLS_GN_CONFIG_VALUES_EXTRACTORS_H_
#define TOOLS_GN_CONFIG_VALUES_EXTRACTORS_H_
#include <stddef.h>
#include <ostream>
#include <string>
#include <vector>
#include "gn/config.h"
#include "gn/config_values.h"
#include "gn/target.h"
struct EscapeOptions;
class ConfigValuesIterator {
public:
explicit ConfigValuesIterator(const Target* target) : target_(target) {
if (!target->has_config_values()) {
cur_index_ = 0;
}
}
bool done() const {
return cur_index_ >= static_cast<int>(target_->configs().size());
}
const ConfigValues& cur() const {
if (cur_index_ == -1)
return target_->config_values();
return target_->configs()[cur_index_].ptr->resolved_values();
}
const ParseNode* origin() const {
if (cur_index_ == -1)
return nullptr;
return target_->configs()[cur_index_].origin;
}
void Next() { cur_index_++; }
const Config* GetCurrentConfig() const {
if (cur_index_ == -1)
return nullptr;
return target_->configs()[cur_index_].ptr;
}
private:
const Target* target_;
int cur_index_ = -1;
};
enum RecursiveWriterConfig {
kRecursiveWriterKeepDuplicates,
kRecursiveWriterSkipDuplicates,
};
template <typename T, class Writer>
inline void RecursiveTargetConfigToStream(
RecursiveWriterConfig config,
const Target* target,
const std::vector<T>& (ConfigValues::*getter)() const,
const Writer& writer,
std::ostream& out) {
std::set<T> seen;
for (ConfigValuesIterator iter(target); !iter.done(); iter.Next()) {
const std::vector<T>& values = ((iter.cur()).*getter)();
for (size_t i = 0; i < values.size(); i++) {
switch (config) {
case kRecursiveWriterKeepDuplicates:
writer(values[i], out);
break;
case kRecursiveWriterSkipDuplicates:
if (seen.find(values[i]) == seen.end()) {
seen.insert(values[i]);
writer(values[i], out);
}
}
}
}
}
void RecursiveTargetConfigStringsToStream(
RecursiveWriterConfig config,
const Target* target,
const std::vector<std::string>& (ConfigValues::*getter)() const,
const EscapeOptions& escape_options,
std::ostream& out);
#endif