Boost logo

Boost Users :

Subject: [Boost-users] [variant] assignment with possible casting
From: Brian Budge (brian.budge_at_[hidden])
Date: 2010-10-26 16:58:46


Hi all -

I have a struct which holds parameter name/value pairs. The incoming
data is not always exactly the same, as it's read from different
sources, so sometimes I might have a parameter named "scale" which is
a uint8_t, and other times "scale" is a uint32_t or int32_t. When I
try to get() the data, I grab it as uint32_t, but it may be stored in
the variant as an int32_t.

We're using get<uint32_t> in that case, and this fails if the variant
holds int32_t. On the other hand, since the variant can contain
vector and matrix values, we can't simply use operator = for automatic
casting (compile time errors).

We don't expect to do any non-trivial casts (i.e. matrix to float or
vice-versa). Are there any helper visitors or anything in the
boost::variant library to assist with this, or do we need to write our
own visitor?

Code below.

Thanks,
  Brian

struct ParameterDesc {
    typedef boost::variant<bool, int32_t, uint32_t, float,
                           Vec2f, Vec3f, Vec4f,
                           Mat2f, Mat3f, Mat4f,
                           std::string> ParamValue;

    typedef google::dense_hash_map<std::string, ParamValue> ParamMap;
    typedef ParamMap::iterator ParamMapIter;
    typedef ParamMap::const_iterator ParamMapCIter;

    std::string type;
    std::string name;
    ParamMap params;

    template <typename T>
    bool get(const std::string &name, T &val, const T &defaultValue) const {
        ParamMapCIter p_it;
        if( (p_it = params.find(name)) == params.end() ) {
            val = defaultValue;
            return false;
        }
        val = boost::get<T>(p_it->second);
        return true;
    }

    template <typename T>
    void get(const std::string &name, T &val) const {
        ParamMapCIter p_it;
        if( (p_it = params.find(name)) == params.end() ) {
            throw ParamException("couldn't find parameter with field
name: " + name);
        }
        val = boost::get<T>(p_it->second);
    }

    ParameterDesc() {
        params.set_empty_key("__EMPTY__");
    }
};


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net