CSS-Sass

 view release on metacpan or  search on metacpan

libsass/ast.hpp  view on Meta::CPAN

      {
        Variable& e = dynamic_cast<Variable&>(rhs);
        return e && name() == e.name();
      }
      catch (std::bad_cast&)
      {
        return false;
      }
      catch (...) { throw; }
    }

    virtual size_t hash()
    {
      return std::hash<string>()(name());
    }

    ATTACH_OPERATIONS();
  };

  ////////////////////////////////////////////////////////////////////////////
  // Textual (i.e., unevaluated) numeric data. Variants are distinguished with
  // a type tag.
  ////////////////////////////////////////////////////////////////////////////
  class Textual : public Expression {
  public:
    enum Type { NUMBER, PERCENTAGE, DIMENSION, HEX };
  private:
    ADD_PROPERTY(Type, type);
    ADD_PROPERTY(string, value);
    size_t hash_;
  public:
    Textual(ParserState pstate, Type t, string val)
    : Expression(pstate, true), type_(t), value_(val),
      hash_(0)
    { }

    virtual bool operator==(Expression& rhs) const
    {
      try
      {
        Textual& e = dynamic_cast<Textual&>(rhs);
        return e && value() == e.value() && type() == e.type();
      }
      catch (std::bad_cast&)
      {
        return false;
      }
      catch (...) { throw; }
    }

    virtual size_t hash()
    {
      if (hash_ == 0) hash_ = std::hash<string>()(value_) ^ std::hash<int>()(type_);
      return hash_;
    }

    ATTACH_OPERATIONS();
  };

  ////////////////////////////////////////////////
  // Numbers, percentages, dimensions, and colors.
  ////////////////////////////////////////////////
  class Number : public Expression {
    ADD_PROPERTY(double, value);
    ADD_PROPERTY(bool, zero);
    vector<string> numerator_units_;
    vector<string> denominator_units_;
    size_t hash_;
  public:
    Number(ParserState pstate, double val, string u = "", bool zero = true)
    : Expression(pstate),
      value_(val),
      zero_(zero),
      numerator_units_(vector<string>()),
      denominator_units_(vector<string>()),
      hash_(0)
    {
      if (!u.empty()) numerator_units_.push_back(u);
      concrete_type(NUMBER);
    }
    bool            zero()              { return zero_; }
    vector<string>& numerator_units()   { return numerator_units_; }
    vector<string>& denominator_units() { return denominator_units_; }
    string type() { return "number"; }
    static string type_name() { return "number"; }
    string unit() const
    {
      stringstream u;
      for (size_t i = 0, S = numerator_units_.size(); i < S; ++i) {
        if (i) u << '*';
        u << numerator_units_[i];
      }
      if (!denominator_units_.empty()) u << '/';
      for (size_t i = 0, S = denominator_units_.size(); i < S; ++i) {
        if (i) u << '*';
        u << denominator_units_[i];
      }
      return u.str();
    }
    bool is_unitless()
    { return numerator_units_.empty() && denominator_units_.empty(); }
    void normalize(string to = "")
    {
      // (multiple passes because I'm too tired to think up something clever)
      // Find a unit to convert everything to, if one isn't provided.
      if (to.empty()) {
        for (size_t i = 0, S = numerator_units_.size(); i < S; ++i) {
          string u(numerator_units_[i]);
          if (string_to_unit(u) == INCOMMENSURABLE) {
            continue;
          }
          else {
            to = u;
            break;
          }
        }
      }
      if (to.empty()) {
        for (size_t i = 0, S = denominator_units_.size(); i < S; ++i) {
          string u(denominator_units_[i]);
          if (string_to_unit(u) == INCOMMENSURABLE) {



( run in 0.594 second using v1.01-cache-2.11-cpan-39bf76dae61 )