size_t variant::num_elements() const { if(type_ == TYPE_CALLABLE) { return 1; } must_be(TYPE_LIST); assert(list_); return list_->elements.size(); }
variant variant::get_values() const { must_be(TYPE_MAP); assert(map_); std::vector<variant> tmp; for(std::map<variant,variant>::const_iterator i=map_->elements.begin(); i != map_->elements.end(); ++i) { tmp.push_back(i->second); } return variant(&tmp); }
variant variant::operator()(const std::vector<variant>& args) const { must_be(TYPE_FUNCTION); game_logic::map_formula_callable* callable = new game_logic::map_formula_callable(fn_->callable.get()); variant v(callable); for(size_t n = 0; n != args.size() && n != fn_->end_args - fn_->begin_args; ++n) { callable->add(fn_->begin_args[n], args[n]); } return fn_->fn->execute(*callable); }
const variant& variant::operator[](size_t n) const { if(type_ == TYPE_CALLABLE) { assert(n == 0); return *this; } must_be(TYPE_LIST); assert(list_); if(n >= list_->elements.size()) { throw type_error("invalid index"); } return list_->elements[n]; }
variant variant::list_elements_div(const variant& v) const { must_be(TYPE_LIST); v.must_be(TYPE_LIST); if( num_elements() != v.num_elements() ) throw type_error("Operator './' requires two lists of the same length"); std::vector< variant > res; res.reserve(num_elements()); for(size_t i = 0; i < num_elements(); ++i) { res.push_back( (*this)[i] / v[i] ); } return variant( &res ); }
game_logic::formula_callable* mutable_callable() const { must_be(VARIANT_TYPE_CALLABLE); return mutable_callable_; }
decimal as_decimal(decimal default_value=decimal()) const { if(type_ == VARIANT_TYPE_NULL) { return default_value; } if(type_ == VARIANT_TYPE_INT) { return decimal::from_raw_value(int64_t(int_value_)*VARIANT_DECIMAL_PRECISION); } must_be(VARIANT_TYPE_DECIMAL); return decimal::from_raw_value(decimal_value_); }
int as_int(int default_value=0) const { if(type_ == VARIANT_TYPE_NULL) { return default_value; } if(type_ == VARIANT_TYPE_DECIMAL) { return int( decimal_value_/VARIANT_DECIMAL_PRECISION ); } if(type_ == VARIANT_TYPE_BOOL) { return bool_value_ ? 1 : 0; } must_be(VARIANT_TYPE_INT); return int_value_; }
//unsafe function which is called on an integer variant and returns //direct access to the underlying integer. Should only be used //when high performance is needed. int& int_addr() { must_be(VARIANT_TYPE_INT); return int_value_; }
const std::string& variant::as_string() const { must_be(TYPE_STRING); assert(string_); return string_->str; }
const game_logic::formula_callable* as_callable() const { must_be(TYPE_CALLABLE); return callable_; }
int as_int() const { if(type_ == TYPE_NULL) { return 0; } must_be(TYPE_INT); return int_value_; }
//unsafe function which is called on an integer variant and returns //direct access to the underlying integer. Should only be used //when high performance is needed. int& int_addr() { must_be(TYPE_INT); return int_value_; }