Commit b218ac72 authored by Paul Asmuth's avatar Paul Asmuth
Browse files

add DataContext, pipe through default dimensions

parent ccd61e06
Loading
Loading
Loading
Loading
+43 −2
Original line number Diff line number Diff line
@@ -36,6 +36,27 @@ using namespace std::placeholders;

namespace plotfx {

ReturnCode parseAll(
    const plist::PropertyList& plist,
    const ParserDefinitions& pdefs) {
  for (const auto& prop : plist) {
    const auto& pdef = pdefs.find(prop.name);
    if (pdef != pdefs.end()) {
      if (auto rc = pdef->second(prop); !rc.isSuccess()) {
        return ReturnCode::errorf(
            "EPARSE",
            "error while parsing property '$0': $1",
            prop.name,
            rc.getMessage());

        return rc;
      }
    }
  }

  return ReturnCode::success();
}

ReturnCode configure_measure_rel(
    const plist::Property& prop,
    double dpi,
@@ -82,8 +103,16 @@ ReturnCode configure_color(
  return ReturnCode::error("EARG", "invalid color");
}

ParserAtFn<Color> configure_color_fn() {
  return bind(&configure_color, _1, _2);
ParserFn configure_color_opt(std::optional<Color>* var) {
  return [=] (const plist::Property& prop) -> ReturnCode {
    Color c;
    if (auto rc = configure_color(prop, &c); !rc) {
      return rc;
    }

    *var = c;
    return OK;
  };
}

ParserFn configure_color_fn(Color* var) {
@@ -296,5 +325,17 @@ ParserFn configure_series_fn(SeriesRef* series) {
  return bind(&configure_series, _1, series);
}

ParserFn configure_var(
    SeriesRef* series,
    ParserFn parser) {
  return [=] (const plist::Property& prop) -> ReturnCode {
    if (plist::is_enum(prop, "csv")) {
      return configure_series(prop, series);
    } else {
      return parser(prop);
    }
  };
}

} // namespace plotfx
+12 −45
Original line number Diff line number Diff line
@@ -41,31 +41,11 @@ namespace plotfx {

using ParserFn = std::function<ReturnCode (const plist::Property&)>;

template <typename T>
using ParserAtFn = std::function<ReturnCode (const plist::Property&, T*)>;

using ParserDefinitions = std::unordered_map<std::string, ParserFn>;

inline ReturnCode parseAll(
ReturnCode parseAll(
    const plist::PropertyList& plist,
    const ParserDefinitions& pdefs) {
  for (const auto& prop : plist) {
    const auto& pdef = pdefs.find(prop.name);
    if (pdef != pdefs.end()) {
      if (auto rc = pdef->second(prop); !rc.isSuccess()) {
        return ReturnCode::errorf(
            "EPARSE",
            "error while parsing property '$0': $1",
            prop.name,
            rc.getMessage());

        return rc;
      }
    }
  }

  return ReturnCode::success();
}
    const ParserDefinitions& pdefs);

template <typename T>
using EnumDefinitions = std::unordered_map<std::string, T>;
@@ -74,15 +54,7 @@ template<typename T>
ReturnCode parseEnum(
    const EnumDefinitions<T>& defs,
    const std::string& str,
    T* value) {
  const auto& def = defs.find(str);
  if (def == defs.end()) {
    return ReturnCode::errorf("EPARSE", "invalid value '$0'", str);
  }

  *value = def->second;
  return ReturnCode::success();
}
    T* value);

ReturnCode parse_classlike(
    const plist::Property& prop,
@@ -90,20 +62,9 @@ ReturnCode parse_classlike(
    std::vector<std::string>* args);

template <typename T>
struct Variable {
  std::optional<T> constant;
  SeriesRef variable;
};

template <typename T>
std::vector<T> resolve(
    const Variable<T>& var,
    const DimensionMapFn<T>& map);
ParserFn configure_opt(ParserFn parser);

template <typename T>
ParserFn configure_var(
    Variable<T>* var,
    ParserAtFn<T> parser);
ParserFn configure_var(SeriesRef* series, ParserFn parser);

ParserFn configure_multiprop(const std::vector<ParserFn>& parsers);

@@ -120,7 +81,7 @@ ReturnCode configure_color(
    Color* value);

ParserFn configure_color_fn(Color* var);
ParserAtFn<Color> configure_color_fn();
ParserFn configure_color_opt(std::optional<Color>* var);

ReturnCode configure_float(
    const plist::Property& prop,
@@ -144,6 +105,12 @@ ReturnCode configure_series(

ParserFn configure_series_fn(SeriesRef* data);

template <typename H, typename... T>
std::vector<H> fallback(const std::vector<H>& head, const T&... tail);

template <typename H, typename... T>
std::vector<H> fallback(const std::optional<H>& head, const T&... tail);

} // namespace plotfx

#include "config_helpers_impl.h"
+38 −24
Original line number Diff line number Diff line
@@ -32,36 +32,50 @@
namespace plotfx {

template<typename T>
ParserFn configure_var(
    Variable<T>* var,
    ParserAtFn<T> parser) {
  return [=] (const plist::Property& prop) -> ReturnCode {
    if (plist::is_enum(prop, "csv")) {
      return configure_series(prop, &var->variable);
    } else {
      T c;
      if (auto rc = parser(prop, &c); !rc) {
        return rc;
ReturnCode parseEnum(
    const EnumDefinitions<T>& defs,
    const std::string& str,
    T* value) {
  const auto& def = defs.find(str);
  if (def == defs.end()) {
    return ReturnCode::errorf("EPARSE", "invalid value '$0'", str);
  }

      var->constant = c;
      return OK;
  *value = def->second;
  return ReturnCode::success();
}
  };

template <typename H>
std::vector<H> fallback(const std::vector<H>& head) {
  return head;
}

template <typename T>
std::vector<T> resolve(
    const Variable<T>& var,
    const DimensionMapFn<T>& map) {
  if (var.constant) {
    return {*var.constant};
  } else if (var.variable) {
    return map(*var.variable);
template <typename H, typename... T>
std::vector<H> fallback(const std::vector<H>& head, const T&... tail) {
  if (head.empty()) {
    return fallback(tail...);
  } else {
    return head;
  }
}

template <typename H>
std::vector<H> fallback(const std::optional<H>& head) {
  if (head) {
    return {*head};
  } else {
    return {};
  }
}

template <typename H, typename... T>
std::vector<H> fallback(const std::optional<H>& head, const T&... tail) {
  if (head) {
    return {*head};
  } else {
    return fallback(tail...);
  }
}

} // namespace plotfx
+11 −0
Original line number Diff line number Diff line
@@ -62,6 +62,17 @@ Value data_lookup(
  }
}

SeriesRef series_find(
    const SeriesMap& map,
    const std::string& key) {
  const auto& iter = map.find(key);
  if (iter == map.end()) {
    return nullptr;
  } else {
    return iter->second;
  }
}

size_t series_len(const Series& s) {
  return s.size();
}
+11 −1
Original line number Diff line number Diff line
@@ -36,7 +36,8 @@ namespace plotfx {

using Value = std::string;
using Series = std::vector<Value>;
using SeriesRef = std::shared_ptr<Series>;
using SeriesRef = std::shared_ptr<const Series>;
using SeriesMap = std::unordered_map<std::string, SeriesRef>;

// FIXME: rename to column?
struct DataColumn {
@@ -48,6 +49,11 @@ struct DataFrame {
  std::vector<DataColumn> columns;
};

struct DataContext {
  SeriesMap by_name;
  SeriesMap defaults;
};

ReturnCode column_find(
    const DataFrame& frame,
    const std::string& column_name,
@@ -68,6 +74,10 @@ std::vector<DataGroup> column_group(const DataColumn& col);

std::vector<DataGroup> series_group(const Series& data);

SeriesRef series_find(
    const SeriesMap& map,
    const std::string& key);

size_t series_len(const Series& s);

bool series_is_numeric(const Series& s);
Loading