开发者

Dynamically storing an internal configuration

I've been thinking of The Right Way (R) to store my program's internal configuration.

Here's the details:

  • The configuration is runtime only, so generated each run.
  • It can be adapted (and should) through directives in a "project" file (the reading of that file is not in the scope of this question)
  • It needs to be extensible, ie there should be a way to add new "variables" with assignes values.

My questions about this:

  1. How should I begin with this? Is a class with accessors and setters with an internal 开发者_JS百科std::map for custom variables a good option?
  2. Are there any known and "good" ways of doing this?
  3. Should there be a difference between integer, boolean and string configuration variables?
  4. Should there be a difference at all between user and built-in (pre-existing as in I already thought of them) variables?

Thanks!

PS: If the question isn't clear, feel free to ask for more info.

UPDATE: Wow, every answer seems to have implicitely or explicitly used boost. I should have mentioned I'd like to avoid boost (I want to explore the Standard libraries' capabilities as is for now).


You could use Boost.PropertyTree for this.

Property trees are versatile data structures, but are particularly suited for holding configuration data. The tree provides its own, tree-specific interface, and each node is also an STL-compatible Sequence for its child nodes.


You could do worse than some kind of a property map (StringMap is just a typedef'd std::map)

class PropertyMap
{
private:
    StringMap m_Map;

public:
    PropertyMap() { };
            ~PropertyMap() { };

    // properties
    template<class T>
    T get(const String& _key, const T& _default = T()) const
    {
        StringMap_cit cit(m_Map.find(_key));
        return (cit != m_Map.end()) ? boost::lexical_cast<T>(cit->second) : _default;
    };  // eo get

    // methods
    void set(const String& _cap, const String& _value)
    { 
        m_Map[_cap] = _value;
    };  // eo set

    template<class T>
    void set(const String& _key, const T& _val)
    {
        set(_key, boost::lexical_cast<String>(_val));
    };  // eo set
};


It is very useful to support nesting in configuration files. Something like JSON.

As parameter values can be scalars, arrays and nested groups of parameters, it could be stored in a std::map of boost::variant's, whose value can be a scalar, array or other std::map recursively. Note that std::map sorts by name, so if the original config file order of parameters is important there should be a sequential index of parameters as well. This can be achieved by using boost::multi_index with an ordered or hashed index for fast lookup and a sequential index for traversing the parameters in the original config file order.

I haven't checked, that boost property map could do that from what I've heard.

It is possible to store all values as strings (or arrays of strings for array values) converting them to the destination type only when accessing it.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜