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 )