$search
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 /* To discriminate between list and non-list get<> */ 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