Go to the documentation of this file.00001 #ifndef UTILMM_CONFIG_SET_HH
00002 #define UTILMM_CONFIG_SET_HH
00003
00004 #include <map>
00005 #include <string>
00006 #include <boost/noncopyable.hpp>
00007 #include <boost/lexical_cast.hpp>
00008 #include <boost/utility/enable_if.hpp>
00009
00010 #include <list>
00011
00012 namespace utilmm
00013 {
00014
00015 namespace details
00016 {
00017 template<typename T> struct is_list
00018 { static const bool value = false; };
00019 template<typename T> struct is_list< std::list<T> >
00020 { static const bool value = true; };
00021 }
00022
00024 class config_set
00025 : private boost::noncopyable
00026 {
00027 friend class ConfigFile;
00028
00029 private:
00030 typedef std::list<std::string> stringlist;
00031 template<typename T>
00032 static T convert(std::string const& value);
00033
00034 protected:
00035 config_set* m_parent;
00036 typedef std::multimap<std::string, std::string> ValueMap;
00037 ValueMap m_values;
00038 typedef std::multimap<std::string, const config_set*> ChildMap;
00039 ChildMap m_children;
00040
00041 protected:
00043 void clear();
00044
00045 public:
00046 explicit config_set(config_set* parent = 0);
00047 ~config_set();
00048
00049 typedef std::list<const config_set*> subsets;
00050
00052 bool empty() const;
00053
00055 bool exists (const std::string& attribute) const;
00056
00060 const config_set* parent() const;
00061 config_set* parent();
00062
00064 std::list<const config_set*> children(const std::string& name) const;
00066 config_set const& child(std::string const& name) const;
00067
00074 template<typename T>
00075 T get(std::string const& name, T const& defval = T(),
00076 typename boost::enable_if< details::is_list<T> >::type *enabler = 0) const;
00084 template<typename T>
00085 T get(std::string const& name, T const& defval = T(),
00086 typename boost::disable_if< details::is_list<T> >::type *enabler = 0) const;
00087
00091 void set(std::string const& name, std::string const& value);
00096 void set(std::string const& name, std::list<std::string> const& value);
00098 void insert(std::string const& name, std::string const& value);
00100 void insert(std::string const& name, std::list<std::string> const& value);
00102 void insert(std::string const& name, config_set const* value);
00104 void erase(std::string const& name);
00105 };
00106
00107 namespace details {
00108 typedef std::list<std::string> stringlist;
00109 }
00110
00111 template<> bool config_set::convert(std::string const& value);
00112 template<typename T>
00113 T config_set::convert(const std::string& value)
00114 { return boost::lexical_cast<T>(value); }
00115
00116
00117 template<>
00118 config_set::stringlist config_set::get(std::string const& name,
00119 config_set::stringlist const& defval,
00120 boost::enable_if< details::is_list<config_set::stringlist> >::type *enabler) const;
00121
00122 template<typename T>
00123 T config_set::get(std::string const& name, T const& defval,
00124 typename boost::enable_if< details::is_list<T> >::type *enabler) const
00125 {
00126 stringlist values = get< stringlist >(name);
00127 if (values.empty())
00128 return defval;
00129
00130 T result;
00131 for (stringlist::const_iterator it = values.begin(); it != values.end(); ++it)
00132 result.push_back(convert<typename T::value_type>(*it));
00133
00134 return result;
00135 }
00136
00137 template<typename T>
00138 T config_set::get(std::string const& name, T const& defval,
00139 typename boost::disable_if< details::is_list<T> >::type *enabler) const
00140 {
00141 std::list<T> deflist;
00142 deflist.push_back(defval);
00143 return get< std::list<T> >(name, deflist).front();
00144 }
00145 }
00146
00147 #endif
00148
00149
00150